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

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

Powered by Google App Engine
This is Rietveld 408576698