Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: content/browser/blob_storage/blob_flattener_unittest.cc

Issue 2055053003: [BlobAsync] Disk support for blob storage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: half of comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "storage/browser/blob/blob_storage_context.h"
6
7 #include <memory>
8
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/test/test_simple_task_runner.h"
14 #include "base/time/time.h"
15 #include "storage/browser/blob/blob_data_builder.h"
16 #include "storage/browser/blob/blob_data_handle.h"
17 #include "storage/browser/blob/blob_data_item.h"
18 #include "storage/browser/blob/blob_storage_registry.h"
19 #include "storage/browser/blob/internal_blob_data.h"
20 #include "storage/browser/blob/shareable_blob_data_item.h"
21 #include "storage/common/data_element.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 namespace storage {
25 namespace {
26 using base::TestSimpleTaskRunner;
27
28 const char kType[] = "type";
29 const char kDisposition[] = "";
30
31 scoped_refptr<BlobDataItem> CreateDataDescriptionItem(size_t size) {
32 std::unique_ptr<DataElement> element(new DataElement());
33 element->SetToBytesDescription(size);
34 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
35 };
36
37 scoped_refptr<BlobDataItem> CreateDataItem(const char* memory, size_t size) {
38 std::unique_ptr<DataElement> element(new DataElement());
39 element->SetToBytes(memory, size);
40 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
41 };
42
43 scoped_refptr<BlobDataItem> CreateFileItem(size_t offset, size_t size) {
44 std::unique_ptr<DataElement> element(new DataElement());
45 element->SetToFilePathRange(base::FilePath("kFakePath"), offset, size,
46 base::Time::Max());
47 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
48 };
49
50 scoped_refptr<BlobDataItem> CreateFutureFileItem(size_t offset, size_t size) {
51 std::unique_ptr<DataElement> element(new DataElement());
52 element->SetToFilePathRange(
53 base::FilePath(BlobDataBuilder::kFutureFileName),
54 offset, size, base::Time::Max());
55 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
56 };
57
58 } // namespace
59
60 class BlobFlattenerTest : public testing::Test {
61 protected:
62 using BlobFlattener = BlobStorageContext::BlobFlattener;
63
64 BlobFlattenerTest() {}
65 ~BlobFlattenerTest() override {}
66
67 void SetUp() override {
68 ASSERT_TRUE(base::CreateNewTempDirectory("BlobFlattenerTest", &temp_dir_));
69 }
70
71 void TearDown() override {
72 base::RunLoop().RunUntilIdle();
73 file_runner_->RunPendingTasks();
74 ASSERT_EQ(true, base::DeleteFile(temp_dir_, true));
75 }
76
77 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) {
78 BlobDataBuilder builder(id);
79 builder.AppendData("1", 1);
80 builder.set_content_type("text/plain");
81 return context_.AddFinishedBlob(builder);
82 }
83
84 BlobStorageRegistry* registry() { return context_.mutable_registry(); }
85
86 const ShareableBlobDataItem& GetItemInBlob(const std::string& uuid,
87 size_t index) {
88 InternalBlobData* entry = registry()->GetEntry(uuid);
89 EXPECT_TRUE(entry);
90 return *entry->items()[index];
91 }
92
93 base::FilePath temp_dir_;
94 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
95
96 base::MessageLoop fake_io_message_loop;
97 BlobStorageContext context_;
98 };
99
100 TEST_F(BlobFlattenerTest, NoBlobItems) {
101 const std::string kBlobUUID = "kId";
102
103 BlobDataBuilder builder(kBlobUUID);
104 builder.AppendData("hi", 2u);
105 builder.AppendFile(base::FilePath("kFakePath"), 0u, 10u, base::Time::Max());
106 InternalBlobData output(kType, kDisposition);
107 BlobFlattener flattener(builder, &output, registry());
108
109 EXPECT_EQ(BlobStatus::DONE, flattener.status);
110 EXPECT_EQ(0u, flattener.dependent_blobs.size());
111 EXPECT_EQ(0u, flattener.copies.size());
112 EXPECT_EQ(12u, flattener.total_size.ValueOrDie());
113 EXPECT_EQ(2u, flattener.transport_quota_needed.ValueOrDie());
114
115 ASSERT_EQ(2u, output.items().size());
116 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
117 EXPECT_EQ(*CreateFileItem(0, 10u), *output.items()[1]->item());
118 }
119
120 TEST_F(BlobFlattenerTest, ErrorCases) {
121 const std::string kBlobUUID = "kId";
122 const std::string kBlob2UUID = "kId2";
123
124 // Invalid blob reference.
125 {
126 BlobDataBuilder builder(kBlobUUID);
127 builder.AppendBlob("doesnotexist");
128 InternalBlobData output(kType, kDisposition);
129 BlobFlattener flattener(builder, &output, registry());
130 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
131 }
132
133 // Circular reference.
134 {
135 BlobDataBuilder builder(kBlobUUID);
136 builder.AppendBlob(kBlobUUID);
137 InternalBlobData output(kType, kDisposition);
138 BlobFlattener flattener(builder, &output, registry());
139 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
140 }
141
142 // Bad slice.
143 {
144 std::unique_ptr<BlobDataHandle> handle = SetupBasicBlob(kBlob2UUID);
145 BlobDataBuilder builder(kBlobUUID);
146 builder.AppendBlob(kBlob2UUID, 1, 2);
147 InternalBlobData output(kType, kDisposition);
148 BlobFlattener flattener(builder, &output, registry());
149 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
150 }
151 }
152
153 TEST_F(BlobFlattenerTest, BlobWithSlices) {
154 const std::string kBlobUUID = "kId";
155 const std::string kDataBlob = "kId2";
156 const std::string kFileBlob = "kId3";
157 const std::string kPendingFileBlob = "kId4";
158
159 // We have the following:
160 // * data,
161 // * sliced data blob,
162 // * file
163 // * full data blob,
164 // * pending data,
165 // * sliced pending file.
166
167 context_.EnableDisk(temp_dir_, file_runner_);
168
169 std::unique_ptr<BlobDataHandle> data_blob;
170 {
171 BlobDataBuilder builder(kDataBlob);
172 builder.AppendData("12345", 5);
173 builder.set_content_type("text/plain");
174 data_blob = context_.AddFinishedBlob(builder);
175 }
176
177 std::unique_ptr<BlobDataHandle> file_blob;
178 {
179 BlobDataBuilder builder(kFileBlob);
180 builder.AppendFile(base::FilePath("kFakePath"), 1u, 10u, base::Time::Max());
181 file_blob = context_.AddFinishedBlob(builder);
182 }
183
184 std::unique_ptr<BlobDataHandle> future_file_blob;
185 {
186 BlobDataBuilder builder(kPendingFileBlob);
187 builder.AppendFile(
188 base::FilePath(BlobDataBuilder::kFutureFileName), 2u,
189 5u, base::Time::Max());
190 future_file_blob = context_.AddFinishedBlob(builder);
191 }
192
193 BlobDataBuilder builder(kBlobUUID);
194 builder.AppendData("hi", 2u);
195 builder.AppendBlob(kDataBlob, 1u, 2u);
196 builder.AppendFile(base::FilePath("kFakePath"), 3u, 5u, base::Time::Max());
197 builder.AppendBlob(kDataBlob);
198 builder.AppendBlob(kFileBlob, 1u, 3u);
199 builder.AppendFutureData(12u);
200 builder.AppendBlob(kPendingFileBlob, 1u, 2u);
201
202 InternalBlobData output(kType, kDisposition);
203 BlobFlattener flattener(builder, &output, registry());
204 EXPECT_EQ(BlobStatus::PENDING, flattener.status);
205
206 EXPECT_EQ(3u, flattener.dependent_blobs.size());
207 EXPECT_EQ(31u, flattener.total_size.ValueOrDie());
208 EXPECT_EQ(14u, flattener.transport_quota_needed.ValueOrDie());
209 EXPECT_EQ(2u, flattener.copy_quota_needed.ValueOrDie());
210
211 ASSERT_EQ(7u, output.items().size());
212 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
213 EXPECT_EQ(*CreateDataDescriptionItem(2u), *output.items()[1]->item());
214 EXPECT_EQ(*CreateFileItem(3u, 5u), *output.items()[2]->item());
215 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *output.items()[3]);
216 EXPECT_EQ(*CreateFileItem(2u, 3u), *output.items()[4]->item());
217 EXPECT_EQ(*CreateDataDescriptionItem(12u), *output.items()[5]->item());
218 EXPECT_EQ(*CreateFutureFileItem(3u, 2u), *output.items()[6]->item());
219
220 // We're copying item at index 1 and 6.
221 ASSERT_EQ(2u, flattener.copies.size());
222 EXPECT_EQ(*flattener.copies[0].dest_item, *output.items()[1]);
223 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *flattener.copies[0].source_item);
224 EXPECT_EQ(1u, flattener.copies[0].source_item_offset);
225
226 EXPECT_EQ(*flattener.copies[1].dest_item, *output.items()[6]);
227 EXPECT_EQ(GetItemInBlob(kPendingFileBlob, 0),
228 *flattener.copies[1].source_item);
229 EXPECT_EQ(1u, flattener.copies[0].source_item_offset);
230 }
231
232 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698