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

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

Issue 2774413002: Move some blob tests next to the files they cover. (Closed)
Patch Set: Created 3 years, 9 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/bind.h"
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h"
16 #include "base/test/test_simple_task_runner.h"
17 #include "base/time/time.h"
18 #include "storage/browser/blob/blob_data_builder.h"
19 #include "storage/browser/blob/blob_data_handle.h"
20 #include "storage/browser/blob/blob_data_item.h"
21 #include "storage/browser/blob/blob_entry.h"
22 #include "storage/browser/blob/blob_memory_controller.h"
23 #include "storage/browser/blob/blob_storage_registry.h"
24 #include "storage/browser/blob/shareable_blob_data_item.h"
25 #include "storage/common/data_element.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 namespace storage {
29 namespace {
30 using base::TestSimpleTaskRunner;
31 using FileCreationInfo = BlobMemoryController::FileCreationInfo;
32
33 const char kType[] = "type";
34 const char kDisposition[] = "";
35 const size_t kTestBlobStorageIPCThresholdBytes = 20;
36 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50;
37
38 const size_t kTestBlobStorageMaxBlobMemorySize = 400;
39 const uint64_t kTestBlobStorageMaxDiskSpace = 4000;
40 const uint64_t kTestBlobStorageMinFileSizeBytes = 10;
41 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
42
43 void SaveBlobStatusAndFiles(BlobStatus* status_ptr,
44 std::vector<FileCreationInfo>* files_ptr,
45 BlobStatus status,
46 std::vector<FileCreationInfo> files) {
47 EXPECT_FALSE(BlobStatusIsError(status));
48 *status_ptr = status;
49 std::move(files.begin(), files.end(), std::back_inserter(*files_ptr));
50 }
51
52 } // namespace
53
54 class BlobFlattenerTest : public testing::Test {
55 protected:
56 using BlobFlattener = BlobStorageContext::BlobFlattener;
57
58 BlobFlattenerTest()
59 : fake_file_path_(base::FilePath(FILE_PATH_LITERAL("kFakePath"))) {}
60 ~BlobFlattenerTest() override {}
61
62 void SetUp() override {
63 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
64 context_ = base::MakeUnique<BlobStorageContext>();
65 }
66
67 void TearDown() override {
68 base::RunLoop().RunUntilIdle();
69 file_runner_->RunPendingTasks();
70 base::RunLoop().RunUntilIdle();
71 ASSERT_TRUE(temp_dir_.Delete());
72 }
73
74 scoped_refptr<BlobDataItem> CreateDataDescriptionItem(size_t size) {
75 std::unique_ptr<DataElement> element(new DataElement());
76 element->SetToBytesDescription(size);
77 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
78 };
79
80 scoped_refptr<BlobDataItem> CreateDataItem(const char* memory, size_t size) {
81 std::unique_ptr<DataElement> element(new DataElement());
82 element->SetToBytes(memory, size);
83 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
84 };
85
86 scoped_refptr<BlobDataItem> CreateFileItem(size_t offset, size_t size) {
87 std::unique_ptr<DataElement> element(new DataElement());
88 element->SetToFilePathRange(fake_file_path_, offset, size,
89 base::Time::Max());
90 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
91 };
92
93 scoped_refptr<BlobDataItem> CreateFutureFileItem(size_t offset, size_t size) {
94 std::unique_ptr<DataElement> element(new DataElement());
95 element->SetToFilePathRange(BlobDataBuilder::GetFutureFileItemPath(0),
96 offset, size, base::Time());
97 return scoped_refptr<BlobDataItem>(new BlobDataItem(std::move(element)));
98 };
99
100 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) {
101 BlobDataBuilder builder(id);
102 builder.AppendData("1", 1);
103 builder.set_content_type("text/plain");
104 return context_->AddFinishedBlob(builder);
105 }
106
107 BlobStorageRegistry* registry() { return context_->mutable_registry(); }
108
109 const ShareableBlobDataItem& GetItemInBlob(const std::string& uuid,
110 size_t index) {
111 BlobEntry* entry = registry()->GetEntry(uuid);
112 EXPECT_TRUE(entry);
113 return *entry->items()[index];
114 }
115
116 void SetTestMemoryLimits() {
117 BlobStorageLimits limits;
118 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
119 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
120 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
121 limits.desired_max_disk_space = kTestBlobStorageMaxDiskSpace;
122 limits.effective_max_disk_space = kTestBlobStorageMaxDiskSpace;
123 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
124 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
125 context_->mutable_memory_controller()->set_limits_for_testing(limits);
126 }
127
128 base::FilePath fake_file_path_;
129 base::ScopedTempDir temp_dir_;
130 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
131
132 base::MessageLoop fake_io_message_loop;
133 std::unique_ptr<BlobStorageContext> context_;
134 };
135
136 TEST_F(BlobFlattenerTest, NoBlobItems) {
137 const std::string kBlobUUID = "kId";
138
139 BlobDataBuilder builder(kBlobUUID);
140 builder.AppendData("hi", 2u);
141 builder.AppendFile(fake_file_path_, 0u, 10u, base::Time::Max());
142 BlobEntry output(kType, kDisposition);
143 BlobFlattener flattener(builder, &output, registry());
144
145 EXPECT_EQ(BlobStatus::PENDING_QUOTA, flattener.status);
146 EXPECT_EQ(0u, flattener.dependent_blobs.size());
147 EXPECT_EQ(0u, flattener.copies.size());
148 EXPECT_EQ(12u, flattener.total_size);
149 EXPECT_EQ(2u, flattener.transport_quota_needed);
150
151 ASSERT_EQ(2u, output.items().size());
152 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
153 EXPECT_EQ(*CreateFileItem(0, 10u), *output.items()[1]->item());
154 }
155
156 TEST_F(BlobFlattenerTest, ErrorCases) {
157 const std::string kBlobUUID = "kId";
158 const std::string kBlob2UUID = "kId2";
159
160 // Invalid blob reference.
161 {
162 BlobDataBuilder builder(kBlobUUID);
163 builder.AppendBlob("doesnotexist");
164 BlobEntry output(kType, kDisposition);
165 BlobFlattener flattener(builder, &output, registry());
166 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
167 }
168
169 // Circular reference.
170 {
171 BlobDataBuilder builder(kBlobUUID);
172 builder.AppendBlob(kBlobUUID);
173 BlobEntry output(kType, kDisposition);
174 BlobFlattener flattener(builder, &output, registry());
175 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
176 }
177
178 // Bad slice.
179 {
180 std::unique_ptr<BlobDataHandle> handle = SetupBasicBlob(kBlob2UUID);
181 BlobDataBuilder builder(kBlobUUID);
182 builder.AppendBlob(kBlob2UUID, 1, 2);
183 BlobEntry output(kType, kDisposition);
184 BlobFlattener flattener(builder, &output, registry());
185 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS, flattener.status);
186 }
187 }
188
189 TEST_F(BlobFlattenerTest, BlobWithSlices) {
190 const std::string kBlobUUID = "kId";
191 const std::string kDataBlob = "kId2";
192 const std::string kFileBlob = "kId3";
193 const std::string kPendingFileBlob = "kId4";
194
195 // We have the following:
196 // * data,
197 // * sliced data blob,
198 // * file
199 // * full data blob,
200 // * pending data,
201
202 context_ =
203 base::MakeUnique<BlobStorageContext>(temp_dir_.GetPath(), file_runner_);
204 SetTestMemoryLimits();
205
206 std::unique_ptr<BlobDataHandle> data_blob;
207 {
208 BlobDataBuilder builder(kDataBlob);
209 builder.AppendData("12345", 5);
210 builder.set_content_type("text/plain");
211 data_blob = context_->AddFinishedBlob(builder);
212 }
213
214 std::unique_ptr<BlobDataHandle> file_blob;
215 {
216 BlobDataBuilder builder(kFileBlob);
217 builder.AppendFile(fake_file_path_, 1u, 10u, base::Time::Max());
218 file_blob = context_->AddFinishedBlob(builder);
219 }
220
221 BlobStatus file_status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
222 std::vector<FileCreationInfo> file_handles;
223 std::unique_ptr<BlobDataHandle> future_file_blob;
224 {
225 BlobDataBuilder builder(kPendingFileBlob);
226 builder.AppendFutureFile(0u, 2u, 0);
227 builder.AppendFutureFile(2u, 5u, 0);
228 future_file_blob = context_->BuildBlob(
229 builder,
230 base::Bind(&SaveBlobStatusAndFiles, &file_status, &file_handles));
231 }
232
233 BlobDataBuilder builder(kBlobUUID);
234 builder.AppendData("hi", 2u);
235 builder.AppendBlob(kDataBlob, 1u, 2u);
236 builder.AppendFile(fake_file_path_, 3u, 5u, base::Time::Max());
237 builder.AppendBlob(kDataBlob);
238 builder.AppendBlob(kFileBlob, 1u, 3u);
239 builder.AppendFutureData(12u);
240 builder.AppendBlob(kPendingFileBlob, 1u, 3u);
241
242 BlobEntry output(kType, kDisposition);
243 BlobFlattener flattener(builder, &output, registry());
244 EXPECT_EQ(BlobStatus::PENDING_QUOTA, flattener.status);
245
246 EXPECT_EQ(3u, flattener.dependent_blobs.size());
247 EXPECT_EQ(32u, flattener.total_size);
248 EXPECT_EQ(14u, flattener.transport_quota_needed);
249 EXPECT_EQ(2u, flattener.copy_quota_needed);
250
251 ASSERT_EQ(8u, output.items().size());
252 EXPECT_EQ(*CreateDataItem("hi", 2u), *output.items()[0]->item());
253 EXPECT_EQ(*CreateDataDescriptionItem(2u), *output.items()[1]->item());
254 EXPECT_EQ(*CreateFileItem(3u, 5u), *output.items()[2]->item());
255 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *output.items()[3]);
256 EXPECT_EQ(*CreateFileItem(2u, 3u), *output.items()[4]->item());
257 EXPECT_EQ(*CreateDataDescriptionItem(12u), *output.items()[5]->item());
258 EXPECT_EQ(*CreateFutureFileItem(1u, 1u), *output.items()[6]->item());
259 EXPECT_EQ(*CreateFutureFileItem(2u, 2u), *output.items()[7]->item());
260
261 // We're copying items at index 1, 6, and 7.
262 ASSERT_EQ(3u, flattener.copies.size());
263 EXPECT_EQ(*flattener.copies[0].dest_item, *output.items()[1]);
264 EXPECT_EQ(GetItemInBlob(kDataBlob, 0), *flattener.copies[0].source_item);
265 EXPECT_EQ(1u, flattener.copies[0].source_item_offset);
266 EXPECT_EQ(*flattener.copies[1].dest_item, *output.items()[6]);
267 EXPECT_EQ(GetItemInBlob(kPendingFileBlob, 0),
268 *flattener.copies[1].source_item);
269 EXPECT_EQ(1u, flattener.copies[1].source_item_offset);
270 EXPECT_EQ(*flattener.copies[2].dest_item, *output.items()[7]);
271 EXPECT_EQ(GetItemInBlob(kPendingFileBlob, 1),
272 *flattener.copies[2].source_item);
273 EXPECT_EQ(0u, flattener.copies[2].source_item_offset);
274
275 // Clean up temp files.
276 EXPECT_TRUE(file_runner_->HasPendingTask());
277 file_runner_->RunPendingTasks();
278 base::RunLoop().RunUntilIdle();
279 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, file_status);
280 EXPECT_FALSE(file_handles.empty());
281 }
282
283 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698