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

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, 1 month 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;
41 using FileCreationInfo = storage::BlobMemoryController::FileCreationInfo;
37 42
38 namespace storage { 43 namespace storage {
39 namespace { 44 namespace {
45 using base::TestSimpleTaskRunner;
40 46
41 const char kContentType[] = "text/plain";
42 const char kContentDisposition[] = "content_disposition";
43 const int kTestDiskCacheStreamIndex = 0; 47 const int kTestDiskCacheStreamIndex = 0;
44 48
49 const std::string kBlobStorageDirectory = "blob_storage";
50 const size_t kTestBlobStorageIPCThresholdBytes = 20;
51 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50;
52
53 const size_t kTestBlobStorageMaxBlobMemorySize = 400;
54 const uint64_t kTestBlobStorageMaxDiskSpace = 4000;
55 const uint64_t kTestBlobStorageMinFileSizeBytes = 10;
56 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
57
45 // Our disk cache tests don't need a real data handle since the tests themselves 58 // Our disk cache tests don't need a real data handle since the tests themselves
46 // scope the disk cache and entries. 59 // scope the disk cache and entries.
47 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle { 60 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle {
48 private: 61 private:
49 ~EmptyDataHandle() override {} 62 ~EmptyDataHandle() override {}
50 }; 63 };
51 64
52 std::unique_ptr<disk_cache::Backend> CreateInMemoryDiskCache() { 65 std::unique_ptr<disk_cache::Backend> CreateInMemoryDiskCache() {
53 std::unique_ptr<disk_cache::Backend> cache; 66 std::unique_ptr<disk_cache::Backend> cache;
54 net::TestCompletionCallback callback; 67 net::TestCompletionCallback callback;
(...skipping 17 matching lines...) Expand all
72 return nullptr; 85 return nullptr;
73 disk_cache::ScopedEntryPtr entry(temp_entry); 86 disk_cache::ScopedEntryPtr entry(temp_entry);
74 87
75 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data); 88 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data);
76 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(), 89 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(),
77 iobuffer->size(), callback.callback(), false); 90 iobuffer->size(), callback.callback(), false);
78 EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv)); 91 EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv));
79 return entry; 92 return entry;
80 } 93 }
81 94
95 void SaveBlobStatus(BlobStatus* status_ptr, BlobStatus status) {
96 *status_ptr = status;
97 }
98
99 void SaveBlobStatusAndFiles(BlobStatus* status_ptr,
100 std::vector<FileCreationInfo>* files_ptr,
101 BlobStatus status,
102 std::vector<FileCreationInfo> files) {
103 *status_ptr = status;
104 for (FileCreationInfo& info : files) {
105 files_ptr->push_back(std::move(info));
106 }
107 }
108
109 void IncrementPointer(size_t* number, BlobStatus status) {
110 EXPECT_EQ(BlobStatus::DONE, status);
111 *number = *number + 1;
112 }
82 113
83 } // namespace 114 } // namespace
84 115
85 class BlobStorageContextTest : public testing::Test { 116 class BlobStorageContextTest : public testing::Test {
86 protected: 117 protected:
87 BlobStorageContextTest() {} 118 BlobStorageContextTest() {}
88 ~BlobStorageContextTest() override {} 119 ~BlobStorageContextTest() override {}
89 120
121 void SetUp() override {
122 ASSERT_TRUE(base::CreateNewTempDirectory("BlobContextTest", &temp_dir_));
123 context_ = base::MakeUnique<BlobStorageContext>(temp_dir_, file_runner_);
124 }
125
126 void TearDown() override {
127 // Make sure we clean up the files.
128 files_.clear();
129 base::RunLoop().RunUntilIdle();
130 file_runner_->RunPendingTasks();
131 base::RunLoop().RunUntilIdle();
132 ASSERT_EQ(true, base::DeleteFile(temp_dir_, true));
133 }
134
90 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) { 135 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) {
91 BlobDataBuilder builder(id); 136 BlobDataBuilder builder(id);
92 builder.AppendData("1", 1); 137 builder.AppendData("1", 1);
93 builder.set_content_type("text/plain"); 138 builder.set_content_type("text/plain");
94 return context_.AddFinishedBlob(builder); 139 return context_->AddFinishedBlob(builder);
95 } 140 }
96 141
97 BlobStorageContext context_; 142 void SetTestMemoryLimits() {
143 BlobStorageLimits limits;
144 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
145 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
146 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
147 limits.max_blob_disk_space = kTestBlobStorageMaxDiskSpace;
148 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
149 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
150 context_->mutable_memory_controller()->set_limits_for_testing(limits);
151 }
152
153 void IncrementRefCount(const std::string& uuid) {
154 context_->IncrementBlobRefCount(uuid);
155 }
156
157 void DecrementRefCount(const std::string& uuid) {
158 context_->DecrementBlobRefCount(uuid);
159 }
160
161 base::FilePath temp_dir_;
162 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
163 std::vector<FileCreationInfo> files_;
164
165 base::MessageLoop fake_io_message_loop_;
166 std::unique_ptr<BlobStorageContext> context_;
98 }; 167 };
99 168
169 TEST_F(BlobStorageContextTest, BuildBlobAsync) {
170 const std::string kId("id");
171 const size_t kSize = 10u;
172 BlobStatus status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
173
174 BlobDataBuilder builder(kId);
175 builder.AppendFutureData(kSize);
176 builder.set_content_type("text/plain");
177 EXPECT_EQ(0lu, context_->memory_controller().memory_usage());
178 std::unique_ptr<BlobDataHandle> handle = context_->BuildBlob(
179 builder, base::Bind(&SaveBlobStatusAndFiles, &status, &files_));
180 EXPECT_EQ(10lu, context_->memory_controller().memory_usage());
181 EXPECT_TRUE(handle->IsBeingBuilt())
182 << static_cast<int>(handle->GetBlobStatus());
183 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, status);
184
185 BlobStatus construction_done = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
186 handle->RunOnConstructionComplete(
187 base::Bind(&SaveBlobStatus, &construction_done));
188
189 EXPECT_EQ(10u, context_->memory_controller().memory_usage());
190
191 builder.PopulateFutureData(0, "abcdefghij", 0, 10u);
192 context_->FinishedPopulatingPendingBlob(kId);
193
194 // Check we're done.
195 EXPECT_EQ(BlobStatus::DONE, handle->GetBlobStatus());
196 base::RunLoop().RunUntilIdle();
197 EXPECT_EQ(BlobStatus::DONE, construction_done);
198
199 EXPECT_EQ(builder, *handle->CreateSnapshot());
200
201 handle.reset();
202 base::RunLoop().RunUntilIdle();
203 EXPECT_EQ(0lu, context_->memory_controller().memory_usage());
204 }
205
206 TEST_F(BlobStorageContextTest, BuildBlobAndCancel) {
207 const std::string kId("id");
208 const size_t kSize = 10u;
209 BlobStatus status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
210
211 BlobDataBuilder builder(kId);
212 builder.AppendFutureData(kSize);
213 builder.set_content_type("text/plain");
214 EXPECT_EQ(0lu, context_->memory_controller().memory_usage());
215 std::unique_ptr<BlobDataHandle> handle = context_->BuildBlob(
216 builder, base::Bind(&SaveBlobStatusAndFiles, &status, &files_));
217 EXPECT_EQ(10lu, context_->memory_controller().memory_usage());
218 EXPECT_TRUE(handle->IsBeingBuilt());
219 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, status);
220 EXPECT_EQ(10u, context_->memory_controller().memory_usage());
221
222 BlobStatus construction_done = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
223 handle->RunOnConstructionComplete(
224 base::Bind(&SaveBlobStatus, &construction_done));
225
226 context_->BreakAndFinishPendingBlob(kId,
227 BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT);
228 EXPECT_TRUE(handle->IsBroken());
229 EXPECT_EQ(0lu, context_->memory_controller().memory_usage());
230
231 // Check we're broken.
232 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, handle->GetBlobStatus());
233 base::RunLoop().RunUntilIdle();
234 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, construction_done);
235 }
236
237 TEST_F(BlobStorageContextTest, BuildBlobFuzzy) {
238 scoped_refptr<BlobDataBuilder::DataHandle> disk_cache_data_handle =
239 new EmptyDataHandle();
240 const std::string kTestBlobData = "Test Blob Data";
241 const std::string kId("id");
242 const size_t kTotalRawBlobs = 200;
243 const size_t kTotalSlicedBlobs = 100;
244 SetTestMemoryLimits();
245 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache();
246 ASSERT_TRUE(cache);
247 disk_cache::ScopedEntryPtr entry =
248 CreateDiskCacheEntry(cache.get(), "test entry", kTestBlobData);
249
250 // This tests mixed blob content, both async and synchronous content, and
251
252 std::vector<std::unique_ptr<BlobDataBuilder>> builders;
253 std::vector<size_t> sizes;
254
255 for (size_t i = 0; i < kTotalRawBlobs; i++) {
256 builders.emplace_back(new BlobDataBuilder(base::SizeTToString(i)));
257 auto& builder = *builders.back();
258 size_t size = 0;
259 if (i % 2 != 0) {
260 builder.AppendFutureData(5u);
261 size += 5u;
262 if (i % 3 == 1) {
263 builder.AppendData("abcdefghij", 4u);
264 size += 4u;
265 }
266 if (i % 3 == 0) {
267 builder.AppendFutureData(1u);
268 size += 1u;
269 }
270 } else if (i % 3 == 0) {
271 builder.AppendFutureFile(0lu, 3lu, 0);
272 size += 3u;
273 }
274 if (i % 5 != 0) {
275 builder.AppendFile(base::FilePath(base::SizeTToString(i)), 0ul, 20ul,
276 base::Time::Max());
277 size += 20u;
278 }
279 builder.AppendDiskCacheEntry(disk_cache_data_handle, entry.get(),
280 kTestDiskCacheStreamIndex);
281 size += 14;
282 EXPECT_NE(0u, size);
283 sizes.push_back(size);
284 }
285
286 for (size_t i = 0; i < kTotalSlicedBlobs; i++) {
287 builders.emplace_back(
288 new BlobDataBuilder(base::SizeTToString(i + kTotalRawBlobs)));
289 size_t source_size = sizes[i];
290 size_t offset = sizes[i] == 1 ? 0 : i % (source_size - 1);
291 size_t size = (i % (source_size - offset)) + 1;
292 builders.back()->AppendBlob(base::SizeTToString(i), offset, size);
293 sizes.push_back(size);
294 }
295
296 size_t total_finished_blobs = 0;
297 std::vector<std::unique_ptr<BlobDataHandle>> handles;
298 std::vector<BlobStatus> statuses;
299 std::vector<bool> populated;
300 statuses.resize(kTotalRawBlobs,
301 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS);
302 populated.resize(kTotalRawBlobs, false);
303
304 for (size_t i = 0; i < builders.size(); i++) {
305 BlobDataBuilder& builder = *builders[i];
306 builder.set_content_type("text/plain");
307 bool has_pending_memory = i < kTotalRawBlobs && (i % 2 != 0 || i % 3 == 0);
308 std::unique_ptr<BlobDataHandle> handle = context_->BuildBlob(
309 builder,
310 has_pending_memory
311 ? base::Bind(&SaveBlobStatusAndFiles, &statuses[0] + i, &files_)
312 : BlobStorageContext::PopulatationAllowedCallback());
313 handle->RunOnConstructionComplete(
314 base::Bind(&IncrementPointer, &total_finished_blobs));
315 handles.push_back(std::move(handle));
316 }
317 base::RunLoop().RunUntilIdle();
318
319 // We should be needing to send a page or two to disk.
320 EXPECT_TRUE(file_runner_->HasPendingTask());
321
322 do {
323 file_runner_->RunPendingTasks();
324 base::RunLoop().RunUntilIdle();
325
326 // Continue populating data for items that can fit.
327 for (size_t i = 0; i < kTotalRawBlobs; i++) {
328 auto& builder = *builders[i];
329 bool has_pending_memory = (i % 2 != 0 || i % 3 == 0);
330 if (has_pending_memory && !populated[i] &&
331 statuses[i] == BlobStatus::PENDING_TRANSPORT) {
332 if (i % 2 != 0) {
333 builder.PopulateFutureData(0, "abcde", 0, 5);
334 if (i % 3 == 0) {
335 builder.PopulateFutureData(1, "z", 0, 1);
336 }
337 } else if (i % 3 == 0) {
338 scoped_refptr<ShareableFileReference> file_ref =
339 ShareableFileReference::GetOrCreate(
340 base::FilePath(base::SizeTToString(i + kTotalRawBlobs)),
341 ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
342 file_runner_.get());
343 builder.PopulateFutureFile(0, file_ref, base::Time::Max());
344 }
345 context_->FinishedPopulatingPendingBlob(base::SizeTToString(i));
346 populated[i] = true;
347 }
348 }
349 base::RunLoop().RunUntilIdle();
350 } while (file_runner_->HasPendingTask());
351
352 for (size_t i = 0; i < populated.size(); i++) {
353 bool has_pending_memory = (i % 2 != 0 || i % 3 == 0);
354 if (has_pending_memory)
355 EXPECT_TRUE(populated[i]) << i;
356 }
357
358 // We should be completely built now.
359 EXPECT_EQ(kTotalRawBlobs + kTotalSlicedBlobs, total_finished_blobs);
360
361 handles.clear();
362 base::RunLoop().RunUntilIdle();
363 files_.clear();
364 // We should have file cleanup tasks.
365 EXPECT_TRUE(file_runner_->HasPendingTask());
366 file_runner_->RunPendingTasks();
367 base::RunLoop().RunUntilIdle();
368
369 for (size_t i = 0; i < kTotalRawBlobs; i++) {
370 bool has_pending_memory = (i % 2 != 0 || i % 3 == 0);
371 if (has_pending_memory)
372 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, statuses[i]) << i;
373 }
374 EXPECT_EQ(0lu, context_->memory_controller().memory_usage());
375 EXPECT_EQ(0lu, context_->memory_controller().disk_usage());
376 }
377
378 TEST_F(BlobStorageContextTest, CancelledReference) {
379 const std::string kId1("id1");
380 const std::string kId2("id2");
381 const size_t kSize = 10u;
382 BlobStatus status = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
383
384 // Start our first blob.
385 BlobDataBuilder builder(kId1);
386 builder.AppendFutureData(kSize);
387 builder.set_content_type("text/plain");
388 EXPECT_EQ(0lu, context_->memory_controller().memory_usage());
389 std::unique_ptr<BlobDataHandle> handle = context_->BuildBlob(
390 builder, base::Bind(&SaveBlobStatusAndFiles, &status, &files_));
391 EXPECT_EQ(10lu, context_->memory_controller().memory_usage());
392 EXPECT_TRUE(handle->IsBeingBuilt());
393 EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, status);
394
395 BlobStatus construction_done = BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
396 handle->RunOnConstructionComplete(
397 base::Bind(&SaveBlobStatus, &construction_done));
398
399 EXPECT_EQ(10u, context_->memory_controller().memory_usage());
400
401 // Create our second blob, which depends on the first.
402 BlobDataBuilder builder2(kId2);
403 builder2.AppendBlob(kId1);
404 builder2.set_content_type("text/plain");
405 std::unique_ptr<BlobDataHandle> handle2 = context_->BuildBlob(
406 builder2, BlobStorageContext::PopulatationAllowedCallback());
407 BlobStatus construction_done2 =
408 BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
409 handle->RunOnConstructionComplete(
410 base::Bind(&SaveBlobStatus, &construction_done2));
411 EXPECT_TRUE(handle2->IsBeingBuilt());
412
413 EXPECT_EQ(10lu, context_->memory_controller().memory_usage());
414
415 // Cancel the first blob.
416 context_->BreakAndFinishPendingBlob(kId1,
417 BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT);
418
419 base::RunLoop().RunUntilIdle();
420 // Check we broke successfully.
421 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, construction_done);
422 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, handle->GetBlobStatus());
423 EXPECT_EQ(0lu, context_->memory_controller().memory_usage());
424 EXPECT_TRUE(handle->IsBroken());
425
426 // Check that it propagated.
427 EXPECT_TRUE(handle2->IsBroken());
428 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, construction_done2);
429 EXPECT_EQ(BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT, handle->GetBlobStatus());
430 }
431
432 TEST_F(BlobStorageContextTest, IncorrectSlice) {
433 const std::string kId1("id1");
434 const std::string kId2("id2");
435
436 std::unique_ptr<BlobDataHandle> handle = SetupBasicBlob(kId1);
437
438 EXPECT_EQ(1lu, context_->memory_controller().memory_usage());
439
440 BlobDataBuilder builder(kId2);
441 builder.AppendBlob(kId1, 1, 10);
442 std::unique_ptr<BlobDataHandle> handle2 = context_->BuildBlob(
443 builder, BlobStorageContext::PopulatationAllowedCallback());
444
445 EXPECT_TRUE(handle2->IsBroken());
446 EXPECT_EQ(BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS,
447 handle2->GetBlobStatus());
448 }
449
100 TEST_F(BlobStorageContextTest, IncrementDecrementRef) { 450 TEST_F(BlobStorageContextTest, IncrementDecrementRef) {
101 base::MessageLoop fake_io_message_loop;
102
103 // Build up a basic blob. 451 // Build up a basic blob.
104 const std::string kId("id"); 452 const std::string kId("id");
105 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId); 453 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId);
106 454
107 // Do an extra increment to keep it around after we kill the handle. 455 // Do an extra increment to keep it around after we kill the handle.
108 context_.IncrementBlobRefCount(kId); 456 IncrementRefCount(kId);
109 context_.IncrementBlobRefCount(kId); 457 IncrementRefCount(kId);
110 context_.DecrementBlobRefCount(kId); 458 DecrementRefCount(kId);
111 blob_data_handle = context_.GetBlobDataFromUUID(kId); 459 blob_data_handle = context_->GetBlobDataFromUUID(kId);
112 EXPECT_TRUE(blob_data_handle); 460 EXPECT_TRUE(blob_data_handle);
113 blob_data_handle.reset(); 461 blob_data_handle.reset();
114 base::RunLoop().RunUntilIdle(); 462 base::RunLoop().RunUntilIdle();
115 463
116 EXPECT_TRUE(context_.registry().HasEntry(kId)); 464 EXPECT_TRUE(context_->registry().HasEntry(kId));
117 context_.DecrementBlobRefCount(kId); 465 DecrementRefCount(kId);
118 EXPECT_FALSE(context_.registry().HasEntry(kId)); 466 EXPECT_FALSE(context_->registry().HasEntry(kId));
119 467
120 // Make sure it goes away in the end. 468 // Make sure it goes away in the end.
121 blob_data_handle = context_.GetBlobDataFromUUID(kId); 469 blob_data_handle = context_->GetBlobDataFromUUID(kId);
122 EXPECT_FALSE(blob_data_handle); 470 EXPECT_FALSE(blob_data_handle);
123 } 471 }
124 472
125 TEST_F(BlobStorageContextTest, OnCancelBuildingBlob) { 473 TEST_F(BlobStorageContextTest, BlobDataHandle) {
126 base::MessageLoop fake_io_message_loop;
127
128 // Build up a basic blob. 474 // Build up a basic blob.
129 const std::string kId("id"); 475 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) {
140 base::MessageLoop fake_io_message_loop;
141
142 // Build up a basic blob.
143 const std::string kId("id");
144 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId); 476 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId);
145 EXPECT_TRUE(blob_data_handle); 477 EXPECT_TRUE(blob_data_handle);
146 478
147 // Get another handle 479 // Get another handle
148 std::unique_ptr<BlobDataHandle> another_handle = 480 std::unique_ptr<BlobDataHandle> another_handle =
149 context_.GetBlobDataFromUUID(kId); 481 context_->GetBlobDataFromUUID(kId);
150 EXPECT_TRUE(another_handle); 482 EXPECT_TRUE(another_handle);
151 483
152 // Should disappear after dropping both handles. 484 // Should disappear after dropping both handles.
153 blob_data_handle.reset(); 485 blob_data_handle.reset();
154 base::RunLoop().RunUntilIdle(); 486 base::RunLoop().RunUntilIdle();
155 487
156 EXPECT_TRUE(context_.registry().HasEntry(kId)); 488 EXPECT_TRUE(context_->registry().HasEntry(kId));
157 489
158 another_handle.reset(); 490 another_handle.reset();
159 base::RunLoop().RunUntilIdle(); 491 base::RunLoop().RunUntilIdle();
160 492
161 blob_data_handle = context_.GetBlobDataFromUUID(kId); 493 blob_data_handle = context_->GetBlobDataFromUUID(kId);
162 EXPECT_FALSE(blob_data_handle); 494 EXPECT_FALSE(blob_data_handle);
163 } 495 }
164 496
165 TEST_F(BlobStorageContextTest, MemoryUsage) { 497 TEST_F(BlobStorageContextTest, MemoryUsage) {
166 const std::string kId1("id1"); 498 const std::string kId1("id1");
167 const std::string kId2("id2"); 499 const std::string kId2("id2");
168 500
169 base::MessageLoop fake_io_message_loop;
170
171 BlobDataBuilder builder1(kId1); 501 BlobDataBuilder builder1(kId1);
172 BlobDataBuilder builder2(kId2); 502 BlobDataBuilder builder2(kId2);
173 builder1.AppendData("Data1Data2"); 503 builder1.AppendData("Data1Data2");
174 builder2.AppendBlob(kId1); 504 builder2.AppendBlob(kId1);
175 builder2.AppendBlob(kId1); 505 builder2.AppendBlob(kId1);
176 builder2.AppendBlob(kId1); 506 builder2.AppendBlob(kId1);
177 builder2.AppendBlob(kId1); 507 builder2.AppendBlob(kId1);
178 builder2.AppendBlob(kId1); 508 builder2.AppendBlob(kId1);
179 builder2.AppendBlob(kId1); 509 builder2.AppendBlob(kId1);
180 builder2.AppendBlob(kId1); 510 builder2.AppendBlob(kId1);
181 511
182 EXPECT_EQ(0lu, context_.memory_usage()); 512 EXPECT_EQ(0lu, context_->memory_controller().memory_usage());
183 513
184 std::unique_ptr<BlobDataHandle> blob_data_handle = 514 std::unique_ptr<BlobDataHandle> blob_data_handle =
185 context_.AddFinishedBlob(&builder1); 515 context_->AddFinishedBlob(&builder1);
186 EXPECT_EQ(10lu, context_.memory_usage()); 516 EXPECT_EQ(10lu, context_->memory_controller().memory_usage());
187 std::unique_ptr<BlobDataHandle> blob_data_handle2 = 517 std::unique_ptr<BlobDataHandle> blob_data_handle2 =
188 context_.AddFinishedBlob(&builder2); 518 context_->AddFinishedBlob(&builder2);
189 EXPECT_EQ(10lu, context_.memory_usage()); 519 EXPECT_EQ(10lu, context_->memory_controller().memory_usage());
190 520
191 EXPECT_EQ(2u, context_.registry().blob_count()); 521 EXPECT_EQ(2u, context_->registry().blob_count());
192 522
193 blob_data_handle.reset(); 523 blob_data_handle.reset();
194 base::RunLoop().RunUntilIdle(); 524 base::RunLoop().RunUntilIdle();
195 525
196 EXPECT_EQ(10lu, context_.memory_usage()); 526 EXPECT_EQ(10lu, context_->memory_controller().memory_usage());
197 EXPECT_EQ(1u, context_.registry().blob_count()); 527 EXPECT_EQ(1u, context_->registry().blob_count());
198 blob_data_handle2.reset(); 528 blob_data_handle2.reset();
199 base::RunLoop().RunUntilIdle(); 529 base::RunLoop().RunUntilIdle();
200 530
201 EXPECT_EQ(0lu, context_.memory_usage()); 531 EXPECT_EQ(0lu, context_->memory_controller().memory_usage());
202 EXPECT_EQ(0u, context_.registry().blob_count()); 532 EXPECT_EQ(0u, context_->registry().blob_count());
203 } 533 }
204 534
205 TEST_F(BlobStorageContextTest, AddFinishedBlob) { 535 TEST_F(BlobStorageContextTest, AddFinishedBlob) {
206 const std::string kId1("id1"); 536 const std::string kId1("id1");
207 const std::string kId2("id12"); 537 const std::string kId2("id12");
208 const std::string kId2Prime("id2.prime");
209 const std::string kId3("id3"); 538 const std::string kId3("id3");
210 const std::string kId3Prime("id3.prime");
211
212 base::MessageLoop fake_io_message_loop;
213 539
214 BlobDataBuilder builder1(kId1); 540 BlobDataBuilder builder1(kId1);
215 BlobDataBuilder builder2(kId2); 541 BlobDataBuilder builder2(kId2);
216 BlobDataBuilder canonicalized_blob_data2(kId2Prime); 542 BlobDataBuilder canonicalized_blob_data2(kId2);
217 builder1.AppendData("Data1Data2"); 543 builder1.AppendData("Data1Data2");
218 builder2.AppendBlob(kId1, 5, 5); 544 builder2.AppendBlob(kId1, 5, 5);
219 builder2.AppendData(" is the best"); 545 builder2.AppendData(" is the best");
220 canonicalized_blob_data2.AppendData("Data2"); 546 canonicalized_blob_data2.AppendData("Data2");
221 canonicalized_blob_data2.AppendData(" is the best"); 547 canonicalized_blob_data2.AppendData(" is the best");
222 548
223 BlobStorageContext context; 549 BlobStorageContext context;
224 550
225 std::unique_ptr<BlobDataHandle> blob_data_handle = 551 std::unique_ptr<BlobDataHandle> blob_data_handle =
226 context_.AddFinishedBlob(&builder1); 552 context_->AddFinishedBlob(&builder1);
227 std::unique_ptr<BlobDataHandle> blob_data_handle2 = 553 std::unique_ptr<BlobDataHandle> blob_data_handle2 =
228 context_.AddFinishedBlob(&builder2); 554 context_->AddFinishedBlob(&builder2);
555
556 EXPECT_EQ(10u + 12u + 5u, context_->memory_controller().memory_usage());
229 557
230 ASSERT_TRUE(blob_data_handle); 558 ASSERT_TRUE(blob_data_handle);
231 ASSERT_TRUE(blob_data_handle2); 559 ASSERT_TRUE(blob_data_handle2);
232 std::unique_ptr<BlobDataSnapshot> data1 = blob_data_handle->CreateSnapshot(); 560 std::unique_ptr<BlobDataSnapshot> data1 = blob_data_handle->CreateSnapshot();
233 std::unique_ptr<BlobDataSnapshot> data2 = blob_data_handle2->CreateSnapshot(); 561 std::unique_ptr<BlobDataSnapshot> data2 = blob_data_handle2->CreateSnapshot();
234 EXPECT_EQ(*data1, builder1); 562 EXPECT_EQ(*data1, builder1);
235 EXPECT_EQ(*data2, canonicalized_blob_data2); 563 EXPECT_EQ(*data2, canonicalized_blob_data2);
236 blob_data_handle.reset(); 564 blob_data_handle.reset();
237 data2.reset(); 565 data2.reset();
238 566
239 base::RunLoop().RunUntilIdle(); 567 base::RunLoop().RunUntilIdle();
240 568
241 blob_data_handle = context_.GetBlobDataFromUUID(kId1); 569 EXPECT_EQ(12u + 5u, context_->memory_controller().memory_usage());
570
571 blob_data_handle = context_->GetBlobDataFromUUID(kId1);
242 EXPECT_FALSE(blob_data_handle); 572 EXPECT_FALSE(blob_data_handle);
243 EXPECT_TRUE(blob_data_handle2); 573 EXPECT_TRUE(blob_data_handle2);
244 data2 = blob_data_handle2->CreateSnapshot(); 574 data2 = blob_data_handle2->CreateSnapshot();
245 EXPECT_EQ(*data2, canonicalized_blob_data2); 575 EXPECT_EQ(*data2, canonicalized_blob_data2);
246 576
247 // Test shared elements stick around. 577 // Test shared elements stick around.
248 BlobDataBuilder builder3(kId3); 578 BlobDataBuilder builder3(kId3);
249 builder3.AppendBlob(kId2); 579 builder3.AppendBlob(kId2);
250 builder3.AppendBlob(kId2); 580 builder3.AppendBlob(kId2);
251 std::unique_ptr<BlobDataHandle> blob_data_handle3 = 581 std::unique_ptr<BlobDataHandle> blob_data_handle3 =
252 context_.AddFinishedBlob(&builder3); 582 context_->AddFinishedBlob(&builder3);
583 EXPECT_FALSE(blob_data_handle3->IsBeingBuilt());
253 blob_data_handle2.reset(); 584 blob_data_handle2.reset();
254 base::RunLoop().RunUntilIdle(); 585 base::RunLoop().RunUntilIdle();
255 586
256 blob_data_handle2 = context_.GetBlobDataFromUUID(kId2); 587 EXPECT_EQ(12u + 5u, context_->memory_controller().memory_usage());
588
589 blob_data_handle2 = context_->GetBlobDataFromUUID(kId2);
257 EXPECT_FALSE(blob_data_handle2); 590 EXPECT_FALSE(blob_data_handle2);
258 EXPECT_TRUE(blob_data_handle3); 591 EXPECT_TRUE(blob_data_handle3);
259 std::unique_ptr<BlobDataSnapshot> data3 = blob_data_handle3->CreateSnapshot(); 592 std::unique_ptr<BlobDataSnapshot> data3 = blob_data_handle3->CreateSnapshot();
260 593
261 BlobDataBuilder canonicalized_blob_data3(kId3Prime); 594 BlobDataBuilder canonicalized_blob_data3(kId3);
262 canonicalized_blob_data3.AppendData("Data2"); 595 canonicalized_blob_data3.AppendData("Data2");
263 canonicalized_blob_data3.AppendData(" is the best"); 596 canonicalized_blob_data3.AppendData(" is the best");
264 canonicalized_blob_data3.AppendData("Data2"); 597 canonicalized_blob_data3.AppendData("Data2");
265 canonicalized_blob_data3.AppendData(" is the best"); 598 canonicalized_blob_data3.AppendData(" is the best");
266 EXPECT_EQ(*data3, canonicalized_blob_data3); 599 EXPECT_EQ(*data3, canonicalized_blob_data3);
267 600
268 blob_data_handle.reset(); 601 blob_data_handle.reset();
269 blob_data_handle2.reset(); 602 blob_data_handle2.reset();
270 blob_data_handle3.reset(); 603 blob_data_handle3.reset();
271 base::RunLoop().RunUntilIdle(); 604 base::RunLoop().RunUntilIdle();
272 } 605 }
273 606
274 TEST_F(BlobStorageContextTest, AddFinishedBlob_LargeOffset) { 607 TEST_F(BlobStorageContextTest, AddFinishedBlob_LargeOffset) {
275 // A value which does not fit in a 4-byte data type. Used to confirm that 608 // 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: 609 // large values are supported on 32-bit Chromium builds. Regression test for:
277 // crbug.com/458122. 610 // crbug.com/458122.
278 const uint64_t kLargeSize = std::numeric_limits<uint64_t>::max(); 611 const uint64_t kLargeSize = std::numeric_limits<uint64_t>::max() - 1;
279 612
280 const uint64_t kBlobLength = 5; 613 const uint64_t kBlobLength = 5;
281 const std::string kId1("id1"); 614 const std::string kId1("id1");
282 const std::string kId2("id2"); 615 const std::string kId2("id2");
283 base::MessageLoop fake_io_message_loop;
284 616
285 BlobDataBuilder builder1(kId1); 617 BlobDataBuilder builder1(kId1);
286 builder1.AppendFileSystemFile(GURL(), 0, kLargeSize, base::Time::Now()); 618 builder1.AppendFileSystemFile(GURL(), 0, kLargeSize, base::Time::Now());
287 619
288 BlobDataBuilder builder2(kId2); 620 BlobDataBuilder builder2(kId2);
289 builder2.AppendBlob(kId1, kLargeSize - kBlobLength, kBlobLength); 621 builder2.AppendBlob(kId1, kLargeSize - kBlobLength, kBlobLength);
290 622
291 std::unique_ptr<BlobDataHandle> blob_data_handle1 = 623 std::unique_ptr<BlobDataHandle> blob_data_handle1 =
292 context_.AddFinishedBlob(&builder1); 624 context_->AddFinishedBlob(&builder1);
293 std::unique_ptr<BlobDataHandle> blob_data_handle2 = 625 std::unique_ptr<BlobDataHandle> blob_data_handle2 =
294 context_.AddFinishedBlob(&builder2); 626 context_->AddFinishedBlob(&builder2);
295 627
296 ASSERT_TRUE(blob_data_handle1); 628 ASSERT_TRUE(blob_data_handle1);
297 ASSERT_TRUE(blob_data_handle2); 629 ASSERT_TRUE(blob_data_handle2);
298 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle2->CreateSnapshot(); 630 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle2->CreateSnapshot();
299 ASSERT_EQ(1u, data->items().size()); 631 ASSERT_EQ(1u, data->items().size());
300 const scoped_refptr<BlobDataItem> item = data->items()[0]; 632 const scoped_refptr<BlobDataItem> item = data->items()[0];
301 EXPECT_EQ(kLargeSize - kBlobLength, item->offset()); 633 EXPECT_EQ(kLargeSize - kBlobLength, item->offset());
302 EXPECT_EQ(kBlobLength, item->length()); 634 EXPECT_EQ(kBlobLength, item->length());
303 635
304 blob_data_handle1.reset(); 636 blob_data_handle1.reset();
305 blob_data_handle2.reset(); 637 blob_data_handle2.reset();
306 base::RunLoop().RunUntilIdle(); 638 base::RunLoop().RunUntilIdle();
307 } 639 }
308 640
309 TEST_F(BlobStorageContextTest, BuildDiskCacheBlob) { 641 TEST_F(BlobStorageContextTest, BuildDiskCacheBlob) {
310 base::MessageLoop fake_io_message_loop;
311 scoped_refptr<BlobDataBuilder::DataHandle> 642 scoped_refptr<BlobDataBuilder::DataHandle>
312 data_handle = new EmptyDataHandle(); 643 data_handle = new EmptyDataHandle();
313 644
314 { 645 {
315 BlobStorageContext context; 646 BlobStorageContext context;
316 647
317 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache(); 648 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache();
318 ASSERT_TRUE(cache); 649 ASSERT_TRUE(cache);
319 650
320 const std::string kTestBlobData = "Test Blob Data"; 651 const std::string kTestBlobData = "Test Blob Data";
(...skipping 19 matching lines...) Expand all
340 } 671 }
341 EXPECT_TRUE(data_handle->HasOneRef()) 672 EXPECT_TRUE(data_handle->HasOneRef())
342 << "Data handle was not destructed along with blob storage context."; 673 << "Data handle was not destructed along with blob storage context.";
343 base::RunLoop().RunUntilIdle(); 674 base::RunLoop().RunUntilIdle();
344 } 675 }
345 676
346 TEST_F(BlobStorageContextTest, CompoundBlobs) { 677 TEST_F(BlobStorageContextTest, CompoundBlobs) {
347 const std::string kId1("id1"); 678 const std::string kId1("id1");
348 const std::string kId2("id2"); 679 const std::string kId2("id2");
349 const std::string kId3("id3"); 680 const std::string kId3("id3");
350 const std::string kId2Prime("id2.prime");
351
352 base::MessageLoop fake_io_message_loop;
353 681
354 // Setup a set of blob data for testing. 682 // Setup a set of blob data for testing.
355 base::Time time1, time2; 683 base::Time time1, time2;
356 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1); 684 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); 685 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2);
358 686
359 BlobDataBuilder blob_data1(kId1); 687 BlobDataBuilder blob_data1(kId1);
360 blob_data1.AppendData("Data1"); 688 blob_data1.AppendData("Data1");
361 blob_data1.AppendData("Data2"); 689 blob_data1.AppendData("Data2");
362 blob_data1.AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, 690 blob_data1.AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10,
363 1024, time1); 691 1024, time1);
364 692
365 BlobDataBuilder blob_data2(kId2); 693 BlobDataBuilder blob_data2(kId2);
366 blob_data2.AppendData("Data3"); 694 blob_data2.AppendData("Data3");
367 blob_data2.AppendBlob(kId1, 8, 100); 695 blob_data2.AppendBlob(kId1, 8, 100);
368 blob_data2.AppendFile(base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, 696 blob_data2.AppendFile(base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20,
369 time2); 697 time2);
370 698
371 BlobDataBuilder blob_data3(kId3); 699 BlobDataBuilder blob_data3(kId3);
372 blob_data3.AppendData("Data4"); 700 blob_data3.AppendData("Data4");
373 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache(); 701 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache();
374 ASSERT_TRUE(cache); 702 ASSERT_TRUE(cache);
375 disk_cache::ScopedEntryPtr disk_cache_entry = 703 disk_cache::ScopedEntryPtr disk_cache_entry =
376 CreateDiskCacheEntry(cache.get(), "another key", "Data5"); 704 CreateDiskCacheEntry(cache.get(), "another key", "Data5");
377 blob_data3.AppendDiskCacheEntry(new EmptyDataHandle(), disk_cache_entry.get(), 705 blob_data3.AppendDiskCacheEntry(new EmptyDataHandle(), disk_cache_entry.get(),
378 kTestDiskCacheStreamIndex); 706 kTestDiskCacheStreamIndex);
379 707
380 BlobDataBuilder canonicalized_blob_data2(kId2Prime); 708 BlobDataBuilder canonicalized_blob_data2(kId2);
381 canonicalized_blob_data2.AppendData("Data3"); 709 canonicalized_blob_data2.AppendData("Data3");
382 canonicalized_blob_data2.AppendData("a2___", 2); 710 canonicalized_blob_data2.AppendData("a2___", 2);
383 canonicalized_blob_data2.AppendFile( 711 canonicalized_blob_data2.AppendFile(
384 base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, 98, time1); 712 base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, 98, time1);
385 canonicalized_blob_data2.AppendFile( 713 canonicalized_blob_data2.AppendFile(
386 base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, time2); 714 base::FilePath(FILE_PATH_LITERAL("File2.txt")), 0, 20, time2);
387 715
388 BlobStorageContext context; 716 BlobStorageContext context;
389 std::unique_ptr<BlobDataHandle> blob_data_handle; 717 std::unique_ptr<BlobDataHandle> blob_data_handle;
390 718
391 // Test a blob referring to only data and a file. 719 // Test a blob referring to only data and a file.
392 blob_data_handle = context_.AddFinishedBlob(&blob_data1); 720 blob_data_handle = context_->AddFinishedBlob(&blob_data1);
393 721
394 ASSERT_TRUE(blob_data_handle); 722 ASSERT_TRUE(blob_data_handle);
395 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); 723 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot();
396 ASSERT_TRUE(blob_data_handle); 724 ASSERT_TRUE(blob_data_handle);
397 EXPECT_EQ(*data, blob_data1); 725 EXPECT_EQ(*data, blob_data1);
398 726
399 // Test a blob composed in part with another blob. 727 // Test a blob composed in part with another blob.
400 blob_data_handle = context_.AddFinishedBlob(&blob_data2); 728 blob_data_handle = context_->AddFinishedBlob(&blob_data2);
401 data = blob_data_handle->CreateSnapshot(); 729 data = blob_data_handle->CreateSnapshot();
402 ASSERT_TRUE(blob_data_handle); 730 ASSERT_TRUE(blob_data_handle);
403 ASSERT_TRUE(data); 731 ASSERT_TRUE(data);
404 EXPECT_EQ(*data, canonicalized_blob_data2); 732 EXPECT_EQ(*data, canonicalized_blob_data2);
405 733
406 // Test a blob referring to only data and a disk cache entry. 734 // Test a blob referring to only data and a disk cache entry.
407 blob_data_handle = context_.AddFinishedBlob(&blob_data3); 735 blob_data_handle = context_->AddFinishedBlob(&blob_data3);
408 data = blob_data_handle->CreateSnapshot(); 736 data = blob_data_handle->CreateSnapshot();
409 ASSERT_TRUE(blob_data_handle); 737 ASSERT_TRUE(blob_data_handle);
410 EXPECT_EQ(*data, blob_data3); 738 EXPECT_EQ(*data, blob_data3);
411 739
412 blob_data_handle.reset(); 740 blob_data_handle.reset();
413 base::RunLoop().RunUntilIdle(); 741 base::RunLoop().RunUntilIdle();
414 } 742 }
415 743
416 TEST_F(BlobStorageContextTest, PublicBlobUrls) { 744 TEST_F(BlobStorageContextTest, PublicBlobUrls) {
417 base::MessageLoop fake_io_message_loop;
418
419 // Build up a basic blob. 745 // Build up a basic blob.
420 const std::string kId("id"); 746 const std::string kId("id");
421 std::unique_ptr<BlobDataHandle> first_handle = SetupBasicBlob(kId); 747 std::unique_ptr<BlobDataHandle> first_handle = SetupBasicBlob(kId);
422 748
423 // Now register a url for that blob. 749 // Now register a url for that blob.
424 GURL kUrl("blob:id"); 750 GURL kUrl("blob:id");
425 context_.RegisterPublicBlobURL(kUrl, kId); 751 context_->RegisterPublicBlobURL(kUrl, kId);
426 std::unique_ptr<BlobDataHandle> blob_data_handle = 752 std::unique_ptr<BlobDataHandle> blob_data_handle =
427 context_.GetBlobDataFromPublicURL(kUrl); 753 context_->GetBlobDataFromPublicURL(kUrl);
428 ASSERT_TRUE(blob_data_handle.get()); 754 ASSERT_TRUE(blob_data_handle.get());
429 EXPECT_EQ(kId, blob_data_handle->uuid()); 755 EXPECT_EQ(kId, blob_data_handle->uuid());
430 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); 756 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot();
431 blob_data_handle.reset(); 757 blob_data_handle.reset();
432 first_handle.reset(); 758 first_handle.reset();
433 base::RunLoop().RunUntilIdle(); 759 base::RunLoop().RunUntilIdle();
434 760
435 // The url registration should keep the blob alive even after 761 // The url registration should keep the blob alive even after
436 // explicit references are dropped. 762 // explicit references are dropped.
437 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl); 763 blob_data_handle = context_->GetBlobDataFromPublicURL(kUrl);
438 EXPECT_TRUE(blob_data_handle); 764 EXPECT_TRUE(blob_data_handle);
439 blob_data_handle.reset(); 765 blob_data_handle.reset();
766
440 base::RunLoop().RunUntilIdle(); 767 base::RunLoop().RunUntilIdle();
441
442 // Finally get rid of the url registration and the blob. 768 // Finally get rid of the url registration and the blob.
443 context_.RevokePublicBlobURL(kUrl); 769 context_->RevokePublicBlobURL(kUrl);
444 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl); 770 blob_data_handle = context_->GetBlobDataFromPublicURL(kUrl);
445 EXPECT_FALSE(blob_data_handle.get()); 771 EXPECT_FALSE(blob_data_handle.get());
446 EXPECT_FALSE(context_.registry().HasEntry(kId)); 772 EXPECT_FALSE(context_->registry().HasEntry(kId));
447 } 773 }
448 774
449 TEST_F(BlobStorageContextTest, TestUnknownBrokenAndBuildingBlobReference) { 775 TEST_F(BlobStorageContextTest, TestUnknownBrokenAndBuildingBlobReference) {
450 base::MessageLoop fake_io_message_loop;
451 const std::string kBrokenId("broken_id"); 776 const std::string kBrokenId("broken_id");
452 const std::string kBuildingId("building_id"); 777 const std::string kBuildingId("building_id");
453 const std::string kReferencingId("referencing_id"); 778 const std::string kReferencingId("referencing_id");
454 const std::string kUnknownId("unknown_id"); 779 const std::string kUnknownId("unknown_id");
455 780
456 // Create a broken blob and a building blob. 781 // Create a broken blob.
457 context_.CreatePendingBlob(kBuildingId, "", ""); 782 std::unique_ptr<BlobDataHandle> broken_handle =
458 context_.CreatePendingBlob(kBrokenId, "", ""); 783 context_->AddBrokenBlob(kBrokenId, "", "", BlobStatus::ERR_OUT_OF_MEMORY);
459 context_.CancelPendingBlob(kBrokenId, IPCBlobCreationCancelCode::UNKNOWN); 784 EXPECT_TRUE(broken_handle->GetBlobStatus() == BlobStatus::ERR_OUT_OF_MEMORY);
460 EXPECT_TRUE(context_.IsBroken(kBrokenId)); 785 EXPECT_TRUE(context_->registry().HasEntry(kBrokenId));
461 EXPECT_TRUE(context_.registry().HasEntry(kBrokenId));
462 786
463 // Try to create a blob with a reference to an unknown blob. 787 // Try to create a blob with a reference to an unknown blob.
464 BlobDataBuilder builder(kReferencingId); 788 BlobDataBuilder builder(kReferencingId);
465 builder.AppendData("data"); 789 builder.AppendData("data");
466 builder.AppendBlob(kUnknownId); 790 builder.AppendBlob(kUnknownId);
467 std::unique_ptr<BlobDataHandle> handle = context_.AddFinishedBlob(builder); 791 std::unique_ptr<BlobDataHandle> handle = context_->AddFinishedBlob(builder);
468 EXPECT_TRUE(handle->IsBroken()); 792 EXPECT_TRUE(handle->IsBroken());
469 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId)); 793 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId));
470 handle.reset(); 794 handle.reset();
471 base::RunLoop().RunUntilIdle(); 795 base::RunLoop().RunUntilIdle();
472 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId)); 796 EXPECT_FALSE(context_->registry().HasEntry(kReferencingId));
473 797
474 // Try to create a blob with a reference to the broken blob. 798 // Try to create a blob with a reference to the broken blob.
475 BlobDataBuilder builder2(kReferencingId); 799 BlobDataBuilder builder2(kReferencingId);
476 builder2.AppendData("data"); 800 builder2.AppendData("data");
477 builder2.AppendBlob(kBrokenId); 801 builder2.AppendBlob(kBrokenId);
478 handle = context_.AddFinishedBlob(builder2); 802 handle = context_->AddFinishedBlob(builder2);
479 EXPECT_TRUE(handle->IsBroken()); 803 EXPECT_TRUE(handle->IsBroken());
480 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId)); 804 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId));
481 handle.reset(); 805 handle.reset();
482 base::RunLoop().RunUntilIdle(); 806 base::RunLoop().RunUntilIdle();
483 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId)); 807 EXPECT_FALSE(context_->registry().HasEntry(kReferencingId));
484 808
485 // Try to create a blob with a reference to the building blob. 809 // Try to create a blob with a reference to the building blob.
486 BlobDataBuilder builder3(kReferencingId); 810 BlobDataBuilder builder3(kReferencingId);
487 builder3.AppendData("data"); 811 builder3.AppendData("data");
488 builder3.AppendBlob(kBuildingId); 812 builder3.AppendBlob(kBuildingId);
489 handle = context_.AddFinishedBlob(builder3); 813 handle = context_->AddFinishedBlob(builder3);
490 EXPECT_TRUE(handle->IsBroken()); 814 EXPECT_TRUE(handle->IsBroken());
491 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId)); 815 EXPECT_TRUE(context_->registry().HasEntry(kReferencingId));
492 handle.reset(); 816 handle.reset();
493 base::RunLoop().RunUntilIdle(); 817 base::RunLoop().RunUntilIdle();
494 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId)); 818 EXPECT_FALSE(context_->registry().HasEntry(kReferencingId));
495 } 819 }
496 820
497 // TODO(michaeln): tests for the depcrecated url stuff 821 // TODO(michaeln): tests for the depcrecated url stuff
498 822
499 } // namespace content 823 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/blob_storage/blob_slice_unittest.cc ('k') | content/browser/blob_storage/blob_storage_registry_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698