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

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

Issue 2055053003: [BlobAsync] Disk support for blob storage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 5 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "storage/browser/blob/blob_storage_context.h" 5 #include "storage/browser/blob/blob_storage_context.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <limits> 9 #include <limits>
10 #include <memory> 10 #include <memory>
11 #include <string> 11 #include <string>
12 12
13 #include "base/bind.h"
13 #include "base/files/file.h" 14 #include "base/files/file.h"
14 #include "base/files/file_path.h" 15 #include "base/files/file_path.h"
16 #include "base/files/file_util.h"
15 #include "base/memory/ref_counted.h" 17 #include "base/memory/ref_counted.h"
16 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
17 #include "base/run_loop.h" 19 #include "base/run_loop.h"
20 #include "base/strings/string_number_conversions.h"
21 #include "base/test/test_simple_task_runner.h"
22 #include "base/threading/thread_task_runner_handle.h"
18 #include "base/time/time.h" 23 #include "base/time/time.h"
19 #include "content/browser/blob_storage/blob_dispatcher_host.h" 24 #include "content/browser/blob_storage/blob_dispatcher_host.h"
20 #include "content/browser/blob_storage/chrome_blob_storage_context.h" 25 #include "content/browser/blob_storage/chrome_blob_storage_context.h"
21 #include "content/public/test/test_browser_context.h" 26 #include "content/public/test/test_browser_context.h"
22 #include "net/base/io_buffer.h" 27 #include "net/base/io_buffer.h"
23 #include "net/base/test_completion_callback.h" 28 #include "net/base/test_completion_callback.h"
24 #include "net/disk_cache/disk_cache.h" 29 #include "net/disk_cache/disk_cache.h"
25 #include "storage/browser/blob/blob_async_builder_host.h" 30 #include "storage/browser/blob/blob_async_builder_host.h"
26 #include "storage/browser/blob/blob_data_builder.h" 31 #include "storage/browser/blob/blob_data_builder.h"
27 #include "storage/browser/blob/blob_data_handle.h" 32 #include "storage/browser/blob/blob_data_handle.h"
28 #include "storage/browser/blob/blob_data_item.h" 33 #include "storage/browser/blob/blob_data_item.h"
29 #include "storage/browser/blob/blob_data_snapshot.h" 34 #include "storage/browser/blob/blob_data_snapshot.h"
30 #include "storage/browser/blob/blob_transport_result.h"
31 #include "storage/common/blob_storage/blob_item_bytes_request.h" 35 #include "storage/common/blob_storage/blob_item_bytes_request.h"
32 #include "storage/common/blob_storage/blob_item_bytes_response.h" 36 #include "storage/common/blob_storage/blob_item_bytes_response.h"
33 #include "testing/gtest/include/gtest/gtest.h" 37 #include "testing/gtest/include/gtest/gtest.h"
34 38
35 using RequestMemoryCallback = 39 using RequestMemoryCallback =
36 storage::BlobAsyncBuilderHost::RequestMemoryCallback; 40 storage::BlobAsyncBuilderHost::RequestMemoryCallback;
37 41
38 namespace storage { 42 namespace storage {
39 namespace { 43 namespace {
44 using base::TestSimpleTaskRunner;
40 45
41 const char kContentType[] = "text/plain";
42 const char kContentDisposition[] = "content_disposition";
43 const int kTestDiskCacheStreamIndex = 0; 46 const int kTestDiskCacheStreamIndex = 0;
44 47
48 const std::string kBlobStorageDirectory = "blob_storage";
49 const size_t kTestBlobStorageIPCThresholdBytes = 20;
50 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50;
51
52 const size_t kTestBlobStorageMaxBlobMemorySize = 400;
53 const size_t kTestBlobStorageMaxMemoryUsage = 500;
54 const uint64_t kTestBlobStorageMaxDiskSpace = 4000;
55 const size_t kTestBlobStorageInFlightMemory = 10;
56 const uint64_t kTestBlobStorageMinFileSizeBytes = 10;
57 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
58
45 // Our disk cache tests don't need a real data handle since the tests themselves 59 // Our disk cache tests don't need a real data handle since the tests themselves
46 // scope the disk cache and entries. 60 // scope the disk cache and entries.
47 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle { 61 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle {
48 private: 62 private:
49 ~EmptyDataHandle() override {} 63 ~EmptyDataHandle() override {}
50 }; 64 };
51 65
52 std::unique_ptr<disk_cache::Backend> CreateInMemoryDiskCache() { 66 std::unique_ptr<disk_cache::Backend> CreateInMemoryDiskCache() {
53 std::unique_ptr<disk_cache::Backend> cache; 67 std::unique_ptr<disk_cache::Backend> cache;
54 net::TestCompletionCallback callback; 68 net::TestCompletionCallback callback;
(...skipping 17 matching lines...) Expand all
72 return nullptr; 86 return nullptr;
73 disk_cache::ScopedEntryPtr entry(temp_entry); 87 disk_cache::ScopedEntryPtr entry(temp_entry);
74 88
75 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data); 89 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data);
76 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(), 90 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(),
77 iobuffer->size(), callback.callback(), false); 91 iobuffer->size(), callback.callback(), false);
78 EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv)); 92 EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv));
79 return entry; 93 return entry;
80 } 94 }
81 95
96 void SaveBlobStatus(BlobStatus* status_ptr, BlobStatus status) {
97 *status_ptr = status;
98 }
99
100 void IncrementPointer(size_t* number, BlobStatus status) {
101 EXPECT_EQ(BlobStatus::DONE, status);
102 *number = *number + 1;
103 }
82 104
83 } // namespace 105 } // namespace
84 106
85 class BlobStorageContextTest : public testing::Test { 107 class BlobStorageContextTest : public testing::Test {
86 protected: 108 protected:
87 BlobStorageContextTest() {} 109 BlobStorageContextTest() {}
88 ~BlobStorageContextTest() override {} 110 ~BlobStorageContextTest() override {}
89 111
112 void TearDown() override {
113 // Make sure we clean up the files.
114 base::RunLoop().RunUntilIdle();
115 file_runner_->RunPendingTasks();
116 ASSERT_EQ(true, base::DeleteFile(temp_dir_, true));
117 }
118
90 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) { 119 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) {
91 BlobDataBuilder builder(id); 120 BlobDataBuilder builder(id);
92 builder.AppendData("1", 1); 121 builder.AppendData("1", 1);
93 builder.set_content_type("text/plain"); 122 builder.set_content_type("text/plain");
94 return context_.AddFinishedBlob(builder); 123 return context_.AddFinishedBlob(builder);
95 } 124 }
96 125
126 void SetTestMemoryLimits() {
127 context_.mutable_memory_controller()->SetMemoryConstantsForTesting(
128 kTestBlobStorageIPCThresholdBytes, kTestBlobStorageMaxSharedMemoryBytes,
129 kTestBlobStorageMaxBlobMemorySize, kTestBlobStorageMaxMemoryUsage,
130 kTestBlobStorageMaxDiskSpace, kTestBlobStorageInFlightMemory,
131 kTestBlobStorageMinFileSizeBytes, kTestBlobStorageMaxFileSizeBytes);
132 }
133
134 base::FilePath temp_dir_;
135 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
136
137 base::MessageLoop fake_io_message_loop;
97 BlobStorageContext context_; 138 BlobStorageContext context_;
98 }; 139 };
99 140
141 TEST_F(BlobStorageContextTest, BuildBlobAsync) {
142 const std::string kId("id");
143 const size_t kSize = 10u;
144 BlobStatus status = BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS;
145
146 BlobDataBuilder builder(kId);
147 builder.AppendFutureData(kSize);
148 builder.set_content_type("text/plain");
149 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
150 std::unique_ptr<BlobDataHandle> handle =
151 context_.BuildBlob(builder, base::Bind(&SaveBlobStatus, &status));
152 EXPECT_EQ(10lu, context_.memory_controller().memory_usage());
153 EXPECT_TRUE(handle->IsBeingBuilt());
154 EXPECT_EQ(BlobStatus::PENDING, status);
155
156 BlobStatus construction_done = BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS;
157 handle->RunOnConstructionComplete(
158 base::Bind(&SaveBlobStatus, &construction_done));
159
160 EXPECT_EQ(10u, context_.memory_controller().memory_usage());
161
162 builder.PopulateFutureData(0, "abcdefghij", 0, 10u);
163 context_.FinishedPopulatingBlob(kId);
164
165 // Check we're done.
166 EXPECT_EQ(BlobStatus::DONE, context_.GetBlobStatus(kId));
167 base::RunLoop().RunUntilIdle();
168 EXPECT_EQ(BlobStatus::DONE, construction_done);
169
170 EXPECT_EQ(builder, *context_.CreateSnapshot(kId));
171
172 handle.reset();
173 base::RunLoop().RunUntilIdle();
174 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
175 }
176
177 TEST_F(BlobStorageContextTest, BuildBlobAndCancel) {
178 const std::string kId("id");
179 const size_t kSize = 10u;
180 BlobStatus status = BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS;
181
182 BlobDataBuilder builder(kId);
183 builder.AppendFutureData(kSize);
184 builder.set_content_type("text/plain");
185 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
186 std::unique_ptr<BlobDataHandle> handle =
187 context_.BuildBlob(builder, base::Bind(&SaveBlobStatus, &status));
188 EXPECT_EQ(10lu, context_.memory_controller().memory_usage());
189 EXPECT_TRUE(handle->IsBeingBuilt());
190 EXPECT_EQ(BlobStatus::PENDING, status);
191 EXPECT_EQ(10u, context_.memory_controller().memory_usage());
192
193 BlobStatus construction_done = BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS;
194 handle->RunOnConstructionComplete(
195 base::Bind(&SaveBlobStatus, &construction_done));
196
197 context_.BreakAndFinishBlob(kId, BlobStatus::SOURCE_DIED_IN_TRANSIT);
198 EXPECT_TRUE(handle->IsBroken());
199 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
200
201 // Check we're broken.
202 EXPECT_EQ(BlobStatus::SOURCE_DIED_IN_TRANSIT, context_.GetBlobStatus(kId));
203 base::RunLoop().RunUntilIdle();
204 EXPECT_EQ(BlobStatus::SOURCE_DIED_IN_TRANSIT, construction_done);
205 }
206
207 TEST_F(BlobStorageContextTest, BuildBlobFuzzish) {
208 const std::string kId("id");
209 const size_t kTotalRawBlobs = 200;
210 const size_t kTotalSlicedBlobs = 100;
211 SetTestMemoryLimits();
212
213 // This tests mixed blob content, both async and synchronous content, and
214
215 std::vector<std::unique_ptr<BlobDataBuilder>> builders;
216 std::vector<size_t> sizes;
217
218 for (size_t i = 0; i < kTotalRawBlobs; i++) {
219 builders.emplace_back(new BlobDataBuilder(base::SizeTToString(i)));
220 auto& builder = *builders.back();
221 size_t size = 0;
222 if (i % 2 != 0) {
223 builder.AppendFutureData(5u);
224 size += 5u;
225 }
226 if (i % 5 != 0) {
227 builder.AppendFile(base::FilePath(base::SizeTToString(i)), 0ul, 20ul,
228 base::Time::Max());
229 size += 20u;
230 }
231 if (i % 3 != 0) {
232 builder.AppendData("abcdefghij", 4u);
233 size += 4u;
234 }
235 if (i % 3 == 0) {
236 builder.AppendFutureData(1u);
237 size += 1u;
238 }
239 if (i % 7 == 0) {
240 builder.AppendFutureFile(0lu, 3lu);
241 size += 3u;
242 }
243 sizes.push_back(size);
244 }
245
246 for (size_t i = 0; i < kTotalSlicedBlobs; i++) {
247 builders.emplace_back(
248 new BlobDataBuilder(base::SizeTToString(i + kTotalRawBlobs)));
249 size_t source_size = sizes[i];
250 size_t offset = sizes[i] == 1 ? 0 : i % (source_size - 1);
251 size_t size = (i % (source_size - offset)) + 1;
252 builders.back()->AppendBlob(base::SizeTToString(i), offset, size);
253 sizes.push_back(size);
254 }
255
256 size_t total_finished_blobs = 0;
257 std::vector<std::unique_ptr<BlobDataHandle>> handles;
258 std::vector<BlobStatus> statuses;
259 std::vector<bool> populated;
260 statuses.resize(kTotalRawBlobs, BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS);
261 populated.resize(kTotalRawBlobs, false);
262 context_.EnableDisk(temp_dir_, file_runner_);
263
264 for (size_t i = 0; i < builders.size(); i++) {
265 BlobDataBuilder& builder = *builders[i];
266 builder.set_content_type("text/plain");
267 bool has_pending_memory =
268 i < kTotalRawBlobs && (i % 3 == 0 || i % 2 != 0 || i % 7 == 0);
269 std::unique_ptr<BlobDataHandle> handle = context_.BuildBlob(
270 builder, has_pending_memory
271 ? base::Bind(&SaveBlobStatus, &statuses[0] + i)
272 : BlobStatusCallback());
273 handle->RunOnConstructionComplete(
274 base::Bind(&IncrementPointer, &total_finished_blobs));
275 handles.push_back(std::move(handle));
276 }
277 base::RunLoop().RunUntilIdle();
278
279 // We should be needing to send a page or two to disk.
280 EXPECT_TRUE(file_runner_->HasPendingTask());
281
282 do {
283 file_runner_->RunPendingTasks();
284 base::RunLoop().RunUntilIdle();
285
286 // Continue populating data for items that can fit.
287 for (size_t i = 0; i < kTotalRawBlobs; i++) {
288 auto& builder = *builders[i];
289 bool has_pending_memory = i % 3 == 0 || i % 2 != 0 || i % 7 == 0;
290 if (has_pending_memory && !populated[i] &&
291 statuses[i] == BlobStatus::PENDING) {
292 if (i % 2 != 0) {
293 builder.PopulateFutureData(0, "abcde", 0, 5);
294 }
295 if (i % 3 == 0) {
296 size_t index = i % 7 == 0 ? builder.items_.size() - 2
297 : builder.items_.size() - 1;
298 builder.PopulateFutureData(index, "z", 0, 1);
299 }
300 if (i % 7 == 0) {
301 scoped_refptr<ShareableFileReference> file_ref =
302 ShareableFileReference::GetOrCreate(
303 base::FilePath(base::SizeTToString(i + kTotalRawBlobs)),
304 ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
305 file_runner_.get());
306 builder.PopulateFutureFile(builder.items_.size() - 1, file_ref,
307 base::Time::Max());
308 }
309 context_.FinishedPopulatingBlob(base::SizeTToString(i));
310 populated[i] = true;
311 }
312 }
313 base::RunLoop().RunUntilIdle();
314 } while (file_runner_->HasPendingTask());
315
316 // We should be completely built now.
317 EXPECT_EQ(kTotalRawBlobs + kTotalSlicedBlobs, total_finished_blobs);
318
319 handles.clear();
320 base::RunLoop().RunUntilIdle();
321 // We should have file cleanup tasks.
322 EXPECT_TRUE(file_runner_->HasPendingTask());
323 file_runner_->RunPendingTasks();
324
325 for (size_t i = 0; i < kTotalRawBlobs; i++) {
326 bool has_pending_memory = i % 3 == 0 || i % 2 != 0;
327 if (has_pending_memory)
328 EXPECT_EQ(BlobStatus::PENDING, statuses[i]) << i;
329 }
330 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
331 EXPECT_EQ(0lu, context_.memory_controller().disk_usage());
332 }
333
334 TEST_F(BlobStorageContextTest, TestErrors) {
335 // bad slice offset & size
336 // Finish before finished
337 }
338
100 TEST_F(BlobStorageContextTest, IncrementDecrementRef) { 339 TEST_F(BlobStorageContextTest, IncrementDecrementRef) {
101 base::MessageLoop fake_io_message_loop;
102
103 // Build up a basic blob. 340 // Build up a basic blob.
104 const std::string kId("id"); 341 const std::string kId("id");
105 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId); 342 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId);
106 343
107 // Do an extra increment to keep it around after we kill the handle. 344 // Do an extra increment to keep it around after we kill the handle.
108 context_.IncrementBlobRefCount(kId); 345 context_.IncrementBlobRefCount(kId);
109 context_.IncrementBlobRefCount(kId); 346 context_.IncrementBlobRefCount(kId);
110 context_.DecrementBlobRefCount(kId); 347 context_.DecrementBlobRefCount(kId);
111 blob_data_handle = context_.GetBlobDataFromUUID(kId); 348 blob_data_handle = context_.GetBlobDataFromUUID(kId);
112 EXPECT_TRUE(blob_data_handle); 349 EXPECT_TRUE(blob_data_handle);
113 blob_data_handle.reset(); 350 blob_data_handle.reset();
114 base::RunLoop().RunUntilIdle(); 351 base::RunLoop().RunUntilIdle();
115 352
116 EXPECT_TRUE(context_.registry().HasEntry(kId)); 353 EXPECT_TRUE(context_.registry().HasEntry(kId));
117 context_.DecrementBlobRefCount(kId); 354 context_.DecrementBlobRefCount(kId);
118 EXPECT_FALSE(context_.registry().HasEntry(kId)); 355 EXPECT_FALSE(context_.registry().HasEntry(kId));
119 356
120 // Make sure it goes away in the end. 357 // Make sure it goes away in the end.
121 blob_data_handle = context_.GetBlobDataFromUUID(kId); 358 blob_data_handle = context_.GetBlobDataFromUUID(kId);
122 EXPECT_FALSE(blob_data_handle); 359 EXPECT_FALSE(blob_data_handle);
123 } 360 }
124 361
125 TEST_F(BlobStorageContextTest, OnCancelBuildingBlob) {
126 base::MessageLoop fake_io_message_loop;
127
128 // Build up a basic blob.
129 const std::string kId("id");
130 context_.CreatePendingBlob(kId, std::string(kContentType),
131 std::string(kContentDisposition));
132 EXPECT_TRUE(context_.IsBeingBuilt(kId));
133 context_.CancelPendingBlob(kId, IPCBlobCreationCancelCode::OUT_OF_MEMORY);
134 EXPECT_TRUE(context_.registry().HasEntry(kId));
135 EXPECT_FALSE(context_.IsBeingBuilt(kId));
136 EXPECT_TRUE(context_.IsBroken(kId));
137 }
138
139 TEST_F(BlobStorageContextTest, BlobDataHandle) { 362 TEST_F(BlobStorageContextTest, BlobDataHandle) {
140 base::MessageLoop fake_io_message_loop;
141
142 // Build up a basic blob. 363 // Build up a basic blob.
143 const std::string kId("id"); 364 const std::string kId("id");
144 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId); 365 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId);
145 EXPECT_TRUE(blob_data_handle); 366 EXPECT_TRUE(blob_data_handle);
146 367
147 // Get another handle 368 // Get another handle
148 std::unique_ptr<BlobDataHandle> another_handle = 369 std::unique_ptr<BlobDataHandle> another_handle =
149 context_.GetBlobDataFromUUID(kId); 370 context_.GetBlobDataFromUUID(kId);
150 EXPECT_TRUE(another_handle); 371 EXPECT_TRUE(another_handle);
151 372
152 // Should disappear after dropping both handles. 373 // Should disappear after dropping both handles.
153 blob_data_handle.reset(); 374 blob_data_handle.reset();
154 base::RunLoop().RunUntilIdle(); 375 base::RunLoop().RunUntilIdle();
155 376
156 EXPECT_TRUE(context_.registry().HasEntry(kId)); 377 EXPECT_TRUE(context_.registry().HasEntry(kId));
157 378
158 another_handle.reset(); 379 another_handle.reset();
159 base::RunLoop().RunUntilIdle(); 380 base::RunLoop().RunUntilIdle();
160 381
161 blob_data_handle = context_.GetBlobDataFromUUID(kId); 382 blob_data_handle = context_.GetBlobDataFromUUID(kId);
162 EXPECT_FALSE(blob_data_handle); 383 EXPECT_FALSE(blob_data_handle);
163 } 384 }
164 385
165 TEST_F(BlobStorageContextTest, MemoryUsage) { 386 TEST_F(BlobStorageContextTest, MemoryUsage) {
166 const std::string kId1("id1"); 387 const std::string kId1("id1");
167 const std::string kId2("id2"); 388 const std::string kId2("id2");
168 389
169 base::MessageLoop fake_io_message_loop;
170
171 BlobDataBuilder builder1(kId1); 390 BlobDataBuilder builder1(kId1);
172 BlobDataBuilder builder2(kId2); 391 BlobDataBuilder builder2(kId2);
173 builder1.AppendData("Data1Data2"); 392 builder1.AppendData("Data1Data2");
174 builder2.AppendBlob(kId1); 393 builder2.AppendBlob(kId1);
175 builder2.AppendBlob(kId1); 394 builder2.AppendBlob(kId1);
176 builder2.AppendBlob(kId1); 395 builder2.AppendBlob(kId1);
177 builder2.AppendBlob(kId1); 396 builder2.AppendBlob(kId1);
178 builder2.AppendBlob(kId1); 397 builder2.AppendBlob(kId1);
179 builder2.AppendBlob(kId1); 398 builder2.AppendBlob(kId1);
180 builder2.AppendBlob(kId1); 399 builder2.AppendBlob(kId1);
181 400
182 EXPECT_EQ(0lu, context_.memory_usage()); 401 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
183 402
184 std::unique_ptr<BlobDataHandle> blob_data_handle = 403 std::unique_ptr<BlobDataHandle> blob_data_handle =
185 context_.AddFinishedBlob(&builder1); 404 context_.AddFinishedBlob(&builder1);
186 EXPECT_EQ(10lu, context_.memory_usage()); 405 EXPECT_EQ(10lu, context_.memory_controller().memory_usage());
187 std::unique_ptr<BlobDataHandle> blob_data_handle2 = 406 std::unique_ptr<BlobDataHandle> blob_data_handle2 =
188 context_.AddFinishedBlob(&builder2); 407 context_.AddFinishedBlob(&builder2);
189 EXPECT_EQ(10lu, context_.memory_usage()); 408 EXPECT_EQ(10lu, context_.memory_controller().memory_usage());
190 409
191 EXPECT_EQ(2u, context_.registry().blob_count()); 410 EXPECT_EQ(2u, context_.registry().blob_count());
192 411
193 blob_data_handle.reset(); 412 blob_data_handle.reset();
194 base::RunLoop().RunUntilIdle(); 413 base::RunLoop().RunUntilIdle();
195 414
196 EXPECT_EQ(10lu, context_.memory_usage()); 415 EXPECT_EQ(10lu, context_.memory_controller().memory_usage());
197 EXPECT_EQ(1u, context_.registry().blob_count()); 416 EXPECT_EQ(1u, context_.registry().blob_count());
198 blob_data_handle2.reset(); 417 blob_data_handle2.reset();
199 base::RunLoop().RunUntilIdle(); 418 base::RunLoop().RunUntilIdle();
200 419
201 EXPECT_EQ(0lu, context_.memory_usage()); 420 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
202 EXPECT_EQ(0u, context_.registry().blob_count()); 421 EXPECT_EQ(0u, context_.registry().blob_count());
203 } 422 }
204 423
205 TEST_F(BlobStorageContextTest, AddFinishedBlob) { 424 TEST_F(BlobStorageContextTest, AddFinishedBlob) {
206 const std::string kId1("id1"); 425 const std::string kId1("id1");
207 const std::string kId2("id12"); 426 const std::string kId2("id12");
208 const std::string kId2Prime("id2.prime"); 427 const std::string kId2Prime("id2.prime");
209 const std::string kId3("id3"); 428 const std::string kId3("id3");
210 const std::string kId3Prime("id3.prime"); 429 const std::string kId3Prime("id3.prime");
211 430
212 base::MessageLoop fake_io_message_loop;
213
214 BlobDataBuilder builder1(kId1); 431 BlobDataBuilder builder1(kId1);
215 BlobDataBuilder builder2(kId2); 432 BlobDataBuilder builder2(kId2);
216 BlobDataBuilder canonicalized_blob_data2(kId2Prime); 433 BlobDataBuilder canonicalized_blob_data2(kId2Prime);
217 builder1.AppendData("Data1Data2"); 434 builder1.AppendData("Data1Data2");
218 builder2.AppendBlob(kId1, 5, 5); 435 builder2.AppendBlob(kId1, 5, 5);
219 builder2.AppendData(" is the best"); 436 builder2.AppendData(" is the best");
220 canonicalized_blob_data2.AppendData("Data2"); 437 canonicalized_blob_data2.AppendData("Data2");
221 canonicalized_blob_data2.AppendData(" is the best"); 438 canonicalized_blob_data2.AppendData(" is the best");
222 439
223 BlobStorageContext context; 440 BlobStorageContext context;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 blob_data_handle.reset(); 485 blob_data_handle.reset();
269 blob_data_handle2.reset(); 486 blob_data_handle2.reset();
270 blob_data_handle3.reset(); 487 blob_data_handle3.reset();
271 base::RunLoop().RunUntilIdle(); 488 base::RunLoop().RunUntilIdle();
272 } 489 }
273 490
274 TEST_F(BlobStorageContextTest, AddFinishedBlob_LargeOffset) { 491 TEST_F(BlobStorageContextTest, AddFinishedBlob_LargeOffset) {
275 // A value which does not fit in a 4-byte data type. Used to confirm that 492 // A value which does not fit in a 4-byte data type. Used to confirm that
276 // large values are supported on 32-bit Chromium builds. Regression test for: 493 // large values are supported on 32-bit Chromium builds. Regression test for:
277 // crbug.com/458122. 494 // crbug.com/458122.
278 const uint64_t kLargeSize = std::numeric_limits<uint64_t>::max(); 495 const uint64_t kLargeSize = std::numeric_limits<uint64_t>::max() - 1;
279 496
280 const uint64_t kBlobLength = 5; 497 const uint64_t kBlobLength = 5;
281 const std::string kId1("id1"); 498 const std::string kId1("id1");
282 const std::string kId2("id2"); 499 const std::string kId2("id2");
283 base::MessageLoop fake_io_message_loop;
284 500
285 BlobDataBuilder builder1(kId1); 501 BlobDataBuilder builder1(kId1);
286 builder1.AppendFileSystemFile(GURL(), 0, kLargeSize, base::Time::Now()); 502 builder1.AppendFileSystemFile(GURL(), 0, kLargeSize, base::Time::Now());
287 503
288 BlobDataBuilder builder2(kId2); 504 BlobDataBuilder builder2(kId2);
289 builder2.AppendBlob(kId1, kLargeSize - kBlobLength, kBlobLength); 505 builder2.AppendBlob(kId1, kLargeSize - kBlobLength, kBlobLength);
290 506
291 std::unique_ptr<BlobDataHandle> blob_data_handle1 = 507 std::unique_ptr<BlobDataHandle> blob_data_handle1 =
292 context_.AddFinishedBlob(&builder1); 508 context_.AddFinishedBlob(&builder1);
293 std::unique_ptr<BlobDataHandle> blob_data_handle2 = 509 std::unique_ptr<BlobDataHandle> blob_data_handle2 =
294 context_.AddFinishedBlob(&builder2); 510 context_.AddFinishedBlob(&builder2);
295 511
296 ASSERT_TRUE(blob_data_handle1); 512 ASSERT_TRUE(blob_data_handle1);
297 ASSERT_TRUE(blob_data_handle2); 513 ASSERT_TRUE(blob_data_handle2);
298 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle2->CreateSnapshot(); 514 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle2->CreateSnapshot();
299 ASSERT_EQ(1u, data->items().size()); 515 ASSERT_EQ(1u, data->items().size());
300 const scoped_refptr<BlobDataItem> item = data->items()[0]; 516 const scoped_refptr<BlobDataItem> item = data->items()[0];
301 EXPECT_EQ(kLargeSize - kBlobLength, item->offset()); 517 EXPECT_EQ(kLargeSize - kBlobLength, item->offset());
302 EXPECT_EQ(kBlobLength, item->length()); 518 EXPECT_EQ(kBlobLength, item->length());
303 519
304 blob_data_handle1.reset(); 520 blob_data_handle1.reset();
305 blob_data_handle2.reset(); 521 blob_data_handle2.reset();
306 base::RunLoop().RunUntilIdle(); 522 base::RunLoop().RunUntilIdle();
307 } 523 }
308 524
309 TEST_F(BlobStorageContextTest, BuildDiskCacheBlob) { 525 TEST_F(BlobStorageContextTest, BuildDiskCacheBlob) {
310 base::MessageLoop fake_io_message_loop;
311 scoped_refptr<BlobDataBuilder::DataHandle> 526 scoped_refptr<BlobDataBuilder::DataHandle>
312 data_handle = new EmptyDataHandle(); 527 data_handle = new EmptyDataHandle();
313 528
314 { 529 {
315 BlobStorageContext context; 530 BlobStorageContext context;
316 531
317 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache(); 532 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache();
318 ASSERT_TRUE(cache); 533 ASSERT_TRUE(cache);
319 534
320 const std::string kTestBlobData = "Test Blob Data"; 535 const std::string kTestBlobData = "Test Blob Data";
(...skipping 21 matching lines...) Expand all
342 << "Data handle was not destructed along with blob storage context."; 557 << "Data handle was not destructed along with blob storage context.";
343 base::RunLoop().RunUntilIdle(); 558 base::RunLoop().RunUntilIdle();
344 } 559 }
345 560
346 TEST_F(BlobStorageContextTest, CompoundBlobs) { 561 TEST_F(BlobStorageContextTest, CompoundBlobs) {
347 const std::string kId1("id1"); 562 const std::string kId1("id1");
348 const std::string kId2("id2"); 563 const std::string kId2("id2");
349 const std::string kId3("id3"); 564 const std::string kId3("id3");
350 const std::string kId2Prime("id2.prime"); 565 const std::string kId2Prime("id2.prime");
351 566
352 base::MessageLoop fake_io_message_loop;
353
354 // Setup a set of blob data for testing. 567 // Setup a set of blob data for testing.
355 base::Time time1, time2; 568 base::Time time1, time2;
356 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1); 569 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1);
357 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2); 570 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2);
358 571
359 BlobDataBuilder blob_data1(kId1); 572 BlobDataBuilder blob_data1(kId1);
360 blob_data1.AppendData("Data1"); 573 blob_data1.AppendData("Data1");
361 blob_data1.AppendData("Data2"); 574 blob_data1.AppendData("Data2");
362 blob_data1.AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, 575 blob_data1.AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10,
363 1024, time1); 576 1024, time1);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 blob_data_handle = context_.AddFinishedBlob(&blob_data3); 620 blob_data_handle = context_.AddFinishedBlob(&blob_data3);
408 data = blob_data_handle->CreateSnapshot(); 621 data = blob_data_handle->CreateSnapshot();
409 ASSERT_TRUE(blob_data_handle); 622 ASSERT_TRUE(blob_data_handle);
410 EXPECT_EQ(*data, blob_data3); 623 EXPECT_EQ(*data, blob_data3);
411 624
412 blob_data_handle.reset(); 625 blob_data_handle.reset();
413 base::RunLoop().RunUntilIdle(); 626 base::RunLoop().RunUntilIdle();
414 } 627 }
415 628
416 TEST_F(BlobStorageContextTest, PublicBlobUrls) { 629 TEST_F(BlobStorageContextTest, PublicBlobUrls) {
417 base::MessageLoop fake_io_message_loop;
418
419 // Build up a basic blob. 630 // Build up a basic blob.
420 const std::string kId("id"); 631 const std::string kId("id");
421 std::unique_ptr<BlobDataHandle> first_handle = SetupBasicBlob(kId); 632 std::unique_ptr<BlobDataHandle> first_handle = SetupBasicBlob(kId);
422 633
423 // Now register a url for that blob. 634 // Now register a url for that blob.
424 GURL kUrl("blob:id"); 635 GURL kUrl("blob:id");
425 context_.RegisterPublicBlobURL(kUrl, kId); 636 context_.RegisterPublicBlobURL(kUrl, kId);
426 std::unique_ptr<BlobDataHandle> blob_data_handle = 637 std::unique_ptr<BlobDataHandle> blob_data_handle =
427 context_.GetBlobDataFromPublicURL(kUrl); 638 context_.GetBlobDataFromPublicURL(kUrl);
428 ASSERT_TRUE(blob_data_handle.get()); 639 ASSERT_TRUE(blob_data_handle.get());
429 EXPECT_EQ(kId, blob_data_handle->uuid()); 640 EXPECT_EQ(kId, blob_data_handle->uuid());
430 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); 641 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot();
431 blob_data_handle.reset(); 642 blob_data_handle.reset();
432 first_handle.reset(); 643 first_handle.reset();
433 base::RunLoop().RunUntilIdle(); 644 base::RunLoop().RunUntilIdle();
434 645
435 // The url registration should keep the blob alive even after 646 // The url registration should keep the blob alive even after
436 // explicit references are dropped. 647 // explicit references are dropped.
437 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl); 648 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl);
438 EXPECT_TRUE(blob_data_handle); 649 EXPECT_TRUE(blob_data_handle);
439 blob_data_handle.reset(); 650 blob_data_handle.reset();
651
440 base::RunLoop().RunUntilIdle(); 652 base::RunLoop().RunUntilIdle();
441
442 // Finally get rid of the url registration and the blob. 653 // Finally get rid of the url registration and the blob.
443 context_.RevokePublicBlobURL(kUrl); 654 context_.RevokePublicBlobURL(kUrl);
444 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl); 655 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl);
445 EXPECT_FALSE(blob_data_handle.get()); 656 EXPECT_FALSE(blob_data_handle.get());
446 EXPECT_FALSE(context_.registry().HasEntry(kId)); 657 EXPECT_FALSE(context_.registry().HasEntry(kId));
447 } 658 }
448 659
449 TEST_F(BlobStorageContextTest, TestUnknownBrokenAndBuildingBlobReference) { 660 TEST_F(BlobStorageContextTest, TestUnknownBrokenAndBuildingBlobReference) {
450 base::MessageLoop fake_io_message_loop;
451 const std::string kBrokenId("broken_id"); 661 const std::string kBrokenId("broken_id");
452 const std::string kBuildingId("building_id"); 662 const std::string kBuildingId("building_id");
453 const std::string kReferencingId("referencing_id"); 663 const std::string kReferencingId("referencing_id");
454 const std::string kUnknownId("unknown_id"); 664 const std::string kUnknownId("unknown_id");
455 665
456 // Create a broken blob and a building blob. 666 // Create a broken blob.
457 context_.CreatePendingBlob(kBuildingId, "", ""); 667 std::unique_ptr<BlobDataHandle> broken_handle =
458 context_.CreatePendingBlob(kBrokenId, "", ""); 668 context_.BuildBrokenBlob(kBrokenId, "", "", BlobStatus::OUT_OF_MEMORY);
459 context_.CancelPendingBlob(kBrokenId, IPCBlobCreationCancelCode::UNKNOWN); 669 EXPECT_TRUE(context_.GetBlobStatus(kBrokenId) == BlobStatus::OUT_OF_MEMORY);
460 EXPECT_TRUE(context_.IsBroken(kBrokenId));
461 EXPECT_TRUE(context_.registry().HasEntry(kBrokenId)); 670 EXPECT_TRUE(context_.registry().HasEntry(kBrokenId));
462 671
463 // Try to create a blob with a reference to an unknown blob. 672 // Try to create a blob with a reference to an unknown blob.
464 BlobDataBuilder builder(kReferencingId); 673 BlobDataBuilder builder(kReferencingId);
465 builder.AppendData("data"); 674 builder.AppendData("data");
466 builder.AppendBlob(kUnknownId); 675 builder.AppendBlob(kUnknownId);
467 std::unique_ptr<BlobDataHandle> handle = context_.AddFinishedBlob(builder); 676 std::unique_ptr<BlobDataHandle> handle = context_.AddFinishedBlob(builder);
468 EXPECT_TRUE(handle->IsBroken()); 677 EXPECT_TRUE(handle->IsBroken());
469 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId)); 678 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId));
470 handle.reset(); 679 handle.reset();
(...skipping 19 matching lines...) Expand all
490 EXPECT_TRUE(handle->IsBroken()); 699 EXPECT_TRUE(handle->IsBroken());
491 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId)); 700 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId));
492 handle.reset(); 701 handle.reset();
493 base::RunLoop().RunUntilIdle(); 702 base::RunLoop().RunUntilIdle();
494 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId)); 703 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId));
495 } 704 }
496 705
497 // TODO(michaeln): tests for the depcrecated url stuff 706 // TODO(michaeln): tests for the depcrecated url stuff
498 707
499 } // namespace content 708 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698