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

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: Finished comments, added new pending enum state 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 uint64_t kTestBlobStorageMaxDiskSpace = 4000;
54 const size_t kTestBlobStorageInFlightMemory = 10;
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 IncrementPointer(size_t* number, BlobStatus status) {
100 EXPECT_EQ(BlobStatus::DONE, status);
101 *number = *number + 1;
102 }
82 103
83 } // namespace 104 } // namespace
84 105
85 class BlobStorageContextTest : public testing::Test { 106 class BlobStorageContextTest : public testing::Test {
86 protected: 107 protected:
87 BlobStorageContextTest() {} 108 BlobStorageContextTest() {}
88 ~BlobStorageContextTest() override {} 109 ~BlobStorageContextTest() override {}
89 110
111 void TearDown() override {
112 // Make sure we clean up the files.
113 base::RunLoop().RunUntilIdle();
114 file_runner_->RunPendingTasks();
115 ASSERT_EQ(true, base::DeleteFile(temp_dir_, true));
116 }
117
90 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) { 118 std::unique_ptr<BlobDataHandle> SetupBasicBlob(const std::string& id) {
91 BlobDataBuilder builder(id); 119 BlobDataBuilder builder(id);
92 builder.AppendData("1", 1); 120 builder.AppendData("1", 1);
93 builder.set_content_type("text/plain"); 121 builder.set_content_type("text/plain");
94 return context_.AddFinishedBlob(builder); 122 return context_.AddFinishedBlob(builder);
95 } 123 }
96 124
125 void SetTestMemoryLimits() {
126 context_.mutable_memory_controller()->SetMemoryConstantsForTesting(
127 kTestBlobStorageIPCThresholdBytes, kTestBlobStorageMaxSharedMemoryBytes,
128 kTestBlobStorageMaxBlobMemorySize, kTestBlobStorageMaxDiskSpace,
129 kTestBlobStorageInFlightMemory, kTestBlobStorageMinFileSizeBytes,
130 kTestBlobStorageMaxFileSizeBytes);
131 }
132
133 base::FilePath temp_dir_;
134 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
135
136 base::MessageLoop fake_io_message_loop;
97 BlobStorageContext context_; 137 BlobStorageContext context_;
98 }; 138 };
99 139
140 TEST_F(BlobStorageContextTest, BuildBlobAsync) {
141 const std::string kId("id");
142 const size_t kSize = 10u;
143 BlobStatus status = BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS;
144
145 BlobDataBuilder builder(kId);
146 builder.AppendFutureData(kSize);
147 builder.set_content_type("text/plain");
148 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
149 std::unique_ptr<BlobDataHandle> handle =
150 context_.BuildBlob(builder, base::Bind(&SaveBlobStatus, &status));
151 EXPECT_EQ(10lu, context_.memory_controller().memory_usage());
152 EXPECT_TRUE(handle->IsBeingBuilt());
153 EXPECT_EQ(BlobStatus::PENDING_DATA_POPULATION, status);
154
155 BlobStatus construction_done = BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS;
156 handle->RunOnConstructionComplete(
157 base::Bind(&SaveBlobStatus, &construction_done));
158
159 EXPECT_EQ(10u, context_.memory_controller().memory_usage());
160
161 builder.PopulateFutureData(0, "abcdefghij", 0, 10u);
162 context_.FinishedPopulatingPendingBlob(kId);
163
164 // Check we're done.
165 EXPECT_EQ(BlobStatus::DONE, context_.GetBlobStatus(kId));
166 base::RunLoop().RunUntilIdle();
167 EXPECT_EQ(BlobStatus::DONE, construction_done);
168
169 EXPECT_EQ(builder, *context_.CreateSnapshot(kId));
170
171 handle.reset();
172 base::RunLoop().RunUntilIdle();
173 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
174 }
175
176 TEST_F(BlobStorageContextTest, BuildBlobAndCancel) {
177 const std::string kId("id");
178 const size_t kSize = 10u;
179 BlobStatus status = BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS;
180
181 BlobDataBuilder builder(kId);
182 builder.AppendFutureData(kSize);
183 builder.set_content_type("text/plain");
184 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
185 std::unique_ptr<BlobDataHandle> handle =
186 context_.BuildBlob(builder, base::Bind(&SaveBlobStatus, &status));
187 EXPECT_EQ(10lu, context_.memory_controller().memory_usage());
188 EXPECT_TRUE(handle->IsBeingBuilt());
189 EXPECT_EQ(BlobStatus::PENDING_DATA_POPULATION, status);
190 EXPECT_EQ(10u, context_.memory_controller().memory_usage());
191
192 BlobStatus construction_done = BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS;
193 handle->RunOnConstructionComplete(
194 base::Bind(&SaveBlobStatus, &construction_done));
195
196 context_.BreakAndFinishPendingBlob(kId, BlobStatus::SOURCE_DIED_IN_TRANSIT);
197 EXPECT_TRUE(handle->IsBroken());
198 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
199
200 // Check we're broken.
201 EXPECT_EQ(BlobStatus::SOURCE_DIED_IN_TRANSIT, context_.GetBlobStatus(kId));
202 base::RunLoop().RunUntilIdle();
203 EXPECT_EQ(BlobStatus::SOURCE_DIED_IN_TRANSIT, construction_done);
204 }
205
206 TEST_F(BlobStorageContextTest, BuildBlobFuzzish) {
207 const std::string kId("id");
208 const size_t kTotalRawBlobs = 200;
209 const size_t kTotalSlicedBlobs = 100;
210 SetTestMemoryLimits();
211
212 // This tests mixed blob content, both async and synchronous content, and
213
214 std::vector<std::unique_ptr<BlobDataBuilder>> builders;
215 std::vector<size_t> sizes;
216
217 for (size_t i = 0; i < kTotalRawBlobs; i++) {
218 builders.emplace_back(new BlobDataBuilder(base::SizeTToString(i)));
219 auto& builder = *builders.back();
220 size_t size = 0;
221 if (i % 2 != 0) {
222 builder.AppendFutureData(5u);
223 size += 5u;
224 }
225 if (i % 5 != 0) {
226 builder.AppendFile(base::FilePath(base::SizeTToString(i)), 0ul, 20ul,
227 base::Time::Max());
228 size += 20u;
229 }
230 if (i % 3 != 0) {
231 builder.AppendData("abcdefghij", 4u);
232 size += 4u;
233 }
234 if (i % 3 == 0) {
235 builder.AppendFutureData(1u);
236 size += 1u;
237 }
238 if (i % 7 == 0) {
239 builder.AppendFutureFile(0lu, 3lu);
240 size += 3u;
241 }
242 sizes.push_back(size);
243 }
244
245 for (size_t i = 0; i < kTotalSlicedBlobs; i++) {
246 builders.emplace_back(
247 new BlobDataBuilder(base::SizeTToString(i + kTotalRawBlobs)));
248 size_t source_size = sizes[i];
249 size_t offset = sizes[i] == 1 ? 0 : i % (source_size - 1);
250 size_t size = (i % (source_size - offset)) + 1;
251 builders.back()->AppendBlob(base::SizeTToString(i), offset, size);
252 sizes.push_back(size);
253 }
254
255 size_t total_finished_blobs = 0;
256 std::vector<std::unique_ptr<BlobDataHandle>> handles;
257 std::vector<BlobStatus> statuses;
258 std::vector<bool> populated;
259 statuses.resize(kTotalRawBlobs, BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS);
260 populated.resize(kTotalRawBlobs, false);
261 context_.EnableDisk(temp_dir_, file_runner_);
262
263 for (size_t i = 0; i < builders.size(); i++) {
264 BlobDataBuilder& builder = *builders[i];
265 builder.set_content_type("text/plain");
266 bool has_pending_memory =
267 i < kTotalRawBlobs && (i % 3 == 0 || i % 2 != 0 || i % 7 == 0);
268 std::unique_ptr<BlobDataHandle> handle = context_.BuildBlob(
269 builder, has_pending_memory
270 ? base::Bind(&SaveBlobStatus, &statuses[0] + i)
271 : BlobStatusCallback());
272 handle->RunOnConstructionComplete(
273 base::Bind(&IncrementPointer, &total_finished_blobs));
274 handles.push_back(std::move(handle));
275 }
276 base::RunLoop().RunUntilIdle();
277
278 // We should be needing to send a page or two to disk.
279 EXPECT_TRUE(file_runner_->HasPendingTask());
280
281 do {
282 file_runner_->RunPendingTasks();
283 base::RunLoop().RunUntilIdle();
284
285 // Continue populating data for items that can fit.
286 for (size_t i = 0; i < kTotalRawBlobs; i++) {
287 auto& builder = *builders[i];
288 bool has_pending_memory = i % 3 == 0 || i % 2 != 0 || i % 7 == 0;
289 if (has_pending_memory && !populated[i] &&
290 statuses[i] == BlobStatus::PENDING_DATA_POPULATION) {
291 if (i % 2 != 0) {
292 builder.PopulateFutureData(0, "abcde", 0, 5);
293 }
294 if (i % 3 == 0) {
295 size_t index = i % 7 == 0 ? builder.items_.size() - 2
296 : builder.items_.size() - 1;
297 builder.PopulateFutureData(index, "z", 0, 1);
298 }
299 if (i % 7 == 0) {
300 scoped_refptr<ShareableFileReference> file_ref =
301 ShareableFileReference::GetOrCreate(
302 base::FilePath(base::SizeTToString(i + kTotalRawBlobs)),
303 ShareableFileReference::DONT_DELETE_ON_FINAL_RELEASE,
304 file_runner_.get());
305 builder.PopulateFutureFile(builder.items_.size() - 1, file_ref,
306 base::Time::Max());
307 }
308 context_.FinishedPopulatingPendingBlob(base::SizeTToString(i));
309 populated[i] = true;
310 }
311 }
312 base::RunLoop().RunUntilIdle();
313 } while (file_runner_->HasPendingTask());
314
315 // We should be completely built now.
316 EXPECT_EQ(kTotalRawBlobs + kTotalSlicedBlobs, total_finished_blobs);
317
318 handles.clear();
319 base::RunLoop().RunUntilIdle();
320 // We should have file cleanup tasks.
321 EXPECT_TRUE(file_runner_->HasPendingTask());
322 file_runner_->RunPendingTasks();
323
324 for (size_t i = 0; i < kTotalRawBlobs; i++) {
325 bool has_pending_memory = i % 3 == 0 || i % 2 != 0;
326 if (has_pending_memory)
327 EXPECT_EQ(BlobStatus::PENDING_DATA_POPULATION, statuses[i]) << i;
328 }
329 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
330 EXPECT_EQ(0lu, context_.memory_controller().disk_usage());
331 }
332
333 TEST_F(BlobStorageContextTest, CancelledReference) {
334 const std::string kId1("id1");
335 const std::string kId2("id2");
336 const size_t kSize = 10u;
337 BlobStatus status = BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS;
338
339 // Start our first blob.
340 BlobDataBuilder builder(kId1);
341 builder.AppendFutureData(kSize);
342 builder.set_content_type("text/plain");
343 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
344 std::unique_ptr<BlobDataHandle> handle =
345 context_.BuildBlob(builder, base::Bind(&SaveBlobStatus, &status));
346 EXPECT_EQ(10lu, context_.memory_controller().memory_usage());
347 EXPECT_TRUE(handle->IsBeingBuilt());
348 EXPECT_EQ(BlobStatus::PENDING_DATA_POPULATION, status);
349
350 BlobStatus construction_done = BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS;
351 handle->RunOnConstructionComplete(
352 base::Bind(&SaveBlobStatus, &construction_done));
353
354 EXPECT_EQ(10u, context_.memory_controller().memory_usage());
355
356 // Create our second blob, which depends on the first.
357 BlobDataBuilder builder2(kId2);
358 builder2.AppendBlob(kId1);
359 builder2.set_content_type("text/plain");
360 std::unique_ptr<BlobDataHandle> handle2 =
361 context_.BuildBlob(builder2, BlobStatusCallback());
362 BlobStatus construction_done2 = BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS;
363 handle->RunOnConstructionComplete(
364 base::Bind(&SaveBlobStatus, &construction_done2));
365 EXPECT_TRUE(handle2->IsBeingBuilt());
366
367 EXPECT_EQ(10lu, context_.memory_controller().memory_usage());
368
369 // Cancel the first blob.
370 context_.BreakAndFinishPendingBlob(kId1, BlobStatus::SOURCE_DIED_IN_TRANSIT);
371
372 base::RunLoop().RunUntilIdle();
373 // Check we broke successfully.
374 EXPECT_EQ(BlobStatus::SOURCE_DIED_IN_TRANSIT, construction_done);
375 EXPECT_EQ(BlobStatus::SOURCE_DIED_IN_TRANSIT, handle->GetBlobStatus());
376 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
377 EXPECT_TRUE(handle->IsBroken());
378
379 // Check that it propagated.
380 EXPECT_TRUE(handle2->IsBroken());
381 EXPECT_EQ(BlobStatus::SOURCE_DIED_IN_TRANSIT, construction_done2);
382 EXPECT_EQ(BlobStatus::SOURCE_DIED_IN_TRANSIT, handle->GetBlobStatus());
383 }
384
385 TEST_F(BlobStorageContextTest, IncorrectSlice) {
386 const std::string kId1("id1");
387 const std::string kId2("id2");
388
389 std::unique_ptr<BlobDataHandle> handle = SetupBasicBlob(kId1);
390
391 EXPECT_EQ(1lu, context_.memory_controller().memory_usage());
392
393 BlobDataBuilder builder(kId2);
394 builder.AppendBlob(kId1, 1, 10);
395 std::unique_ptr<BlobDataHandle> handle2 =
396 context_.BuildBlob(builder, BlobStatusCallback());
397
398 EXPECT_TRUE(handle2->IsBroken());
399 EXPECT_EQ(BlobStatus::INVALID_CONSTRUCTION_ARGUMENTS,
400 handle2->GetBlobStatus());
401 }
402
100 TEST_F(BlobStorageContextTest, IncrementDecrementRef) { 403 TEST_F(BlobStorageContextTest, IncrementDecrementRef) {
101 base::MessageLoop fake_io_message_loop;
102
103 // Build up a basic blob. 404 // Build up a basic blob.
104 const std::string kId("id"); 405 const std::string kId("id");
105 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId); 406 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId);
106 407
107 // Do an extra increment to keep it around after we kill the handle. 408 // Do an extra increment to keep it around after we kill the handle.
108 context_.IncrementBlobRefCount(kId); 409 context_.IncrementBlobRefCount(kId);
109 context_.IncrementBlobRefCount(kId); 410 context_.IncrementBlobRefCount(kId);
110 context_.DecrementBlobRefCount(kId); 411 context_.DecrementBlobRefCount(kId);
111 blob_data_handle = context_.GetBlobDataFromUUID(kId); 412 blob_data_handle = context_.GetBlobDataFromUUID(kId);
112 EXPECT_TRUE(blob_data_handle); 413 EXPECT_TRUE(blob_data_handle);
113 blob_data_handle.reset(); 414 blob_data_handle.reset();
114 base::RunLoop().RunUntilIdle(); 415 base::RunLoop().RunUntilIdle();
115 416
116 EXPECT_TRUE(context_.registry().HasEntry(kId)); 417 EXPECT_TRUE(context_.registry().HasEntry(kId));
117 context_.DecrementBlobRefCount(kId); 418 context_.DecrementBlobRefCount(kId);
118 EXPECT_FALSE(context_.registry().HasEntry(kId)); 419 EXPECT_FALSE(context_.registry().HasEntry(kId));
119 420
120 // Make sure it goes away in the end. 421 // Make sure it goes away in the end.
121 blob_data_handle = context_.GetBlobDataFromUUID(kId); 422 blob_data_handle = context_.GetBlobDataFromUUID(kId);
122 EXPECT_FALSE(blob_data_handle); 423 EXPECT_FALSE(blob_data_handle);
123 } 424 }
124 425
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) { 426 TEST_F(BlobStorageContextTest, BlobDataHandle) {
140 base::MessageLoop fake_io_message_loop;
141
142 // Build up a basic blob. 427 // Build up a basic blob.
143 const std::string kId("id"); 428 const std::string kId("id");
144 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId); 429 std::unique_ptr<BlobDataHandle> blob_data_handle = SetupBasicBlob(kId);
145 EXPECT_TRUE(blob_data_handle); 430 EXPECT_TRUE(blob_data_handle);
146 431
147 // Get another handle 432 // Get another handle
148 std::unique_ptr<BlobDataHandle> another_handle = 433 std::unique_ptr<BlobDataHandle> another_handle =
149 context_.GetBlobDataFromUUID(kId); 434 context_.GetBlobDataFromUUID(kId);
150 EXPECT_TRUE(another_handle); 435 EXPECT_TRUE(another_handle);
151 436
152 // Should disappear after dropping both handles. 437 // Should disappear after dropping both handles.
153 blob_data_handle.reset(); 438 blob_data_handle.reset();
154 base::RunLoop().RunUntilIdle(); 439 base::RunLoop().RunUntilIdle();
155 440
156 EXPECT_TRUE(context_.registry().HasEntry(kId)); 441 EXPECT_TRUE(context_.registry().HasEntry(kId));
157 442
158 another_handle.reset(); 443 another_handle.reset();
159 base::RunLoop().RunUntilIdle(); 444 base::RunLoop().RunUntilIdle();
160 445
161 blob_data_handle = context_.GetBlobDataFromUUID(kId); 446 blob_data_handle = context_.GetBlobDataFromUUID(kId);
162 EXPECT_FALSE(blob_data_handle); 447 EXPECT_FALSE(blob_data_handle);
163 } 448 }
164 449
165 TEST_F(BlobStorageContextTest, MemoryUsage) { 450 TEST_F(BlobStorageContextTest, MemoryUsage) {
166 const std::string kId1("id1"); 451 const std::string kId1("id1");
167 const std::string kId2("id2"); 452 const std::string kId2("id2");
168 453
169 base::MessageLoop fake_io_message_loop;
170
171 BlobDataBuilder builder1(kId1); 454 BlobDataBuilder builder1(kId1);
172 BlobDataBuilder builder2(kId2); 455 BlobDataBuilder builder2(kId2);
173 builder1.AppendData("Data1Data2"); 456 builder1.AppendData("Data1Data2");
174 builder2.AppendBlob(kId1); 457 builder2.AppendBlob(kId1);
175 builder2.AppendBlob(kId1); 458 builder2.AppendBlob(kId1);
176 builder2.AppendBlob(kId1); 459 builder2.AppendBlob(kId1);
177 builder2.AppendBlob(kId1); 460 builder2.AppendBlob(kId1);
178 builder2.AppendBlob(kId1); 461 builder2.AppendBlob(kId1);
179 builder2.AppendBlob(kId1); 462 builder2.AppendBlob(kId1);
180 builder2.AppendBlob(kId1); 463 builder2.AppendBlob(kId1);
181 464
182 EXPECT_EQ(0lu, context_.memory_usage()); 465 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
183 466
184 std::unique_ptr<BlobDataHandle> blob_data_handle = 467 std::unique_ptr<BlobDataHandle> blob_data_handle =
185 context_.AddFinishedBlob(&builder1); 468 context_.AddFinishedBlob(&builder1);
186 EXPECT_EQ(10lu, context_.memory_usage()); 469 EXPECT_EQ(10lu, context_.memory_controller().memory_usage());
187 std::unique_ptr<BlobDataHandle> blob_data_handle2 = 470 std::unique_ptr<BlobDataHandle> blob_data_handle2 =
188 context_.AddFinishedBlob(&builder2); 471 context_.AddFinishedBlob(&builder2);
189 EXPECT_EQ(10lu, context_.memory_usage()); 472 EXPECT_EQ(10lu, context_.memory_controller().memory_usage());
190 473
191 EXPECT_EQ(2u, context_.registry().blob_count()); 474 EXPECT_EQ(2u, context_.registry().blob_count());
192 475
193 blob_data_handle.reset(); 476 blob_data_handle.reset();
194 base::RunLoop().RunUntilIdle(); 477 base::RunLoop().RunUntilIdle();
195 478
196 EXPECT_EQ(10lu, context_.memory_usage()); 479 EXPECT_EQ(10lu, context_.memory_controller().memory_usage());
197 EXPECT_EQ(1u, context_.registry().blob_count()); 480 EXPECT_EQ(1u, context_.registry().blob_count());
198 blob_data_handle2.reset(); 481 blob_data_handle2.reset();
199 base::RunLoop().RunUntilIdle(); 482 base::RunLoop().RunUntilIdle();
200 483
201 EXPECT_EQ(0lu, context_.memory_usage()); 484 EXPECT_EQ(0lu, context_.memory_controller().memory_usage());
202 EXPECT_EQ(0u, context_.registry().blob_count()); 485 EXPECT_EQ(0u, context_.registry().blob_count());
203 } 486 }
204 487
205 TEST_F(BlobStorageContextTest, AddFinishedBlob) { 488 TEST_F(BlobStorageContextTest, AddFinishedBlob) {
206 const std::string kId1("id1"); 489 const std::string kId1("id1");
207 const std::string kId2("id12"); 490 const std::string kId2("id12");
208 const std::string kId2Prime("id2.prime"); 491 const std::string kId2Prime("id2.prime");
209 const std::string kId3("id3"); 492 const std::string kId3("id3");
210 const std::string kId3Prime("id3.prime"); 493 const std::string kId3Prime("id3.prime");
211 494
212 base::MessageLoop fake_io_message_loop;
213
214 BlobDataBuilder builder1(kId1); 495 BlobDataBuilder builder1(kId1);
215 BlobDataBuilder builder2(kId2); 496 BlobDataBuilder builder2(kId2);
216 BlobDataBuilder canonicalized_blob_data2(kId2Prime); 497 BlobDataBuilder canonicalized_blob_data2(kId2Prime);
217 builder1.AppendData("Data1Data2"); 498 builder1.AppendData("Data1Data2");
218 builder2.AppendBlob(kId1, 5, 5); 499 builder2.AppendBlob(kId1, 5, 5);
219 builder2.AppendData(" is the best"); 500 builder2.AppendData(" is the best");
220 canonicalized_blob_data2.AppendData("Data2"); 501 canonicalized_blob_data2.AppendData("Data2");
221 canonicalized_blob_data2.AppendData(" is the best"); 502 canonicalized_blob_data2.AppendData(" is the best");
222 503
223 BlobStorageContext context; 504 BlobStorageContext context;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 blob_data_handle.reset(); 549 blob_data_handle.reset();
269 blob_data_handle2.reset(); 550 blob_data_handle2.reset();
270 blob_data_handle3.reset(); 551 blob_data_handle3.reset();
271 base::RunLoop().RunUntilIdle(); 552 base::RunLoop().RunUntilIdle();
272 } 553 }
273 554
274 TEST_F(BlobStorageContextTest, AddFinishedBlob_LargeOffset) { 555 TEST_F(BlobStorageContextTest, AddFinishedBlob_LargeOffset) {
275 // A value which does not fit in a 4-byte data type. Used to confirm that 556 // 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: 557 // large values are supported on 32-bit Chromium builds. Regression test for:
277 // crbug.com/458122. 558 // crbug.com/458122.
278 const uint64_t kLargeSize = std::numeric_limits<uint64_t>::max(); 559 const uint64_t kLargeSize = std::numeric_limits<uint64_t>::max() - 1;
279 560
280 const uint64_t kBlobLength = 5; 561 const uint64_t kBlobLength = 5;
281 const std::string kId1("id1"); 562 const std::string kId1("id1");
282 const std::string kId2("id2"); 563 const std::string kId2("id2");
283 base::MessageLoop fake_io_message_loop;
284 564
285 BlobDataBuilder builder1(kId1); 565 BlobDataBuilder builder1(kId1);
286 builder1.AppendFileSystemFile(GURL(), 0, kLargeSize, base::Time::Now()); 566 builder1.AppendFileSystemFile(GURL(), 0, kLargeSize, base::Time::Now());
287 567
288 BlobDataBuilder builder2(kId2); 568 BlobDataBuilder builder2(kId2);
289 builder2.AppendBlob(kId1, kLargeSize - kBlobLength, kBlobLength); 569 builder2.AppendBlob(kId1, kLargeSize - kBlobLength, kBlobLength);
290 570
291 std::unique_ptr<BlobDataHandle> blob_data_handle1 = 571 std::unique_ptr<BlobDataHandle> blob_data_handle1 =
292 context_.AddFinishedBlob(&builder1); 572 context_.AddFinishedBlob(&builder1);
293 std::unique_ptr<BlobDataHandle> blob_data_handle2 = 573 std::unique_ptr<BlobDataHandle> blob_data_handle2 =
294 context_.AddFinishedBlob(&builder2); 574 context_.AddFinishedBlob(&builder2);
295 575
296 ASSERT_TRUE(blob_data_handle1); 576 ASSERT_TRUE(blob_data_handle1);
297 ASSERT_TRUE(blob_data_handle2); 577 ASSERT_TRUE(blob_data_handle2);
298 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle2->CreateSnapshot(); 578 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle2->CreateSnapshot();
299 ASSERT_EQ(1u, data->items().size()); 579 ASSERT_EQ(1u, data->items().size());
300 const scoped_refptr<BlobDataItem> item = data->items()[0]; 580 const scoped_refptr<BlobDataItem> item = data->items()[0];
301 EXPECT_EQ(kLargeSize - kBlobLength, item->offset()); 581 EXPECT_EQ(kLargeSize - kBlobLength, item->offset());
302 EXPECT_EQ(kBlobLength, item->length()); 582 EXPECT_EQ(kBlobLength, item->length());
303 583
304 blob_data_handle1.reset(); 584 blob_data_handle1.reset();
305 blob_data_handle2.reset(); 585 blob_data_handle2.reset();
306 base::RunLoop().RunUntilIdle(); 586 base::RunLoop().RunUntilIdle();
307 } 587 }
308 588
309 TEST_F(BlobStorageContextTest, BuildDiskCacheBlob) { 589 TEST_F(BlobStorageContextTest, BuildDiskCacheBlob) {
310 base::MessageLoop fake_io_message_loop;
311 scoped_refptr<BlobDataBuilder::DataHandle> 590 scoped_refptr<BlobDataBuilder::DataHandle>
312 data_handle = new EmptyDataHandle(); 591 data_handle = new EmptyDataHandle();
313 592
314 { 593 {
315 BlobStorageContext context; 594 BlobStorageContext context;
316 595
317 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache(); 596 std::unique_ptr<disk_cache::Backend> cache = CreateInMemoryDiskCache();
318 ASSERT_TRUE(cache); 597 ASSERT_TRUE(cache);
319 598
320 const std::string kTestBlobData = "Test Blob Data"; 599 const std::string kTestBlobData = "Test Blob Data";
(...skipping 21 matching lines...) Expand all
342 << "Data handle was not destructed along with blob storage context."; 621 << "Data handle was not destructed along with blob storage context.";
343 base::RunLoop().RunUntilIdle(); 622 base::RunLoop().RunUntilIdle();
344 } 623 }
345 624
346 TEST_F(BlobStorageContextTest, CompoundBlobs) { 625 TEST_F(BlobStorageContextTest, CompoundBlobs) {
347 const std::string kId1("id1"); 626 const std::string kId1("id1");
348 const std::string kId2("id2"); 627 const std::string kId2("id2");
349 const std::string kId3("id3"); 628 const std::string kId3("id3");
350 const std::string kId2Prime("id2.prime"); 629 const std::string kId2Prime("id2.prime");
351 630
352 base::MessageLoop fake_io_message_loop;
353
354 // Setup a set of blob data for testing. 631 // Setup a set of blob data for testing.
355 base::Time time1, time2; 632 base::Time time1, time2;
356 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1); 633 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); 634 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2);
358 635
359 BlobDataBuilder blob_data1(kId1); 636 BlobDataBuilder blob_data1(kId1);
360 blob_data1.AppendData("Data1"); 637 blob_data1.AppendData("Data1");
361 blob_data1.AppendData("Data2"); 638 blob_data1.AppendData("Data2");
362 blob_data1.AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10, 639 blob_data1.AppendFile(base::FilePath(FILE_PATH_LITERAL("File1.txt")), 10,
363 1024, time1); 640 1024, time1);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 blob_data_handle = context_.AddFinishedBlob(&blob_data3); 684 blob_data_handle = context_.AddFinishedBlob(&blob_data3);
408 data = blob_data_handle->CreateSnapshot(); 685 data = blob_data_handle->CreateSnapshot();
409 ASSERT_TRUE(blob_data_handle); 686 ASSERT_TRUE(blob_data_handle);
410 EXPECT_EQ(*data, blob_data3); 687 EXPECT_EQ(*data, blob_data3);
411 688
412 blob_data_handle.reset(); 689 blob_data_handle.reset();
413 base::RunLoop().RunUntilIdle(); 690 base::RunLoop().RunUntilIdle();
414 } 691 }
415 692
416 TEST_F(BlobStorageContextTest, PublicBlobUrls) { 693 TEST_F(BlobStorageContextTest, PublicBlobUrls) {
417 base::MessageLoop fake_io_message_loop;
418
419 // Build up a basic blob. 694 // Build up a basic blob.
420 const std::string kId("id"); 695 const std::string kId("id");
421 std::unique_ptr<BlobDataHandle> first_handle = SetupBasicBlob(kId); 696 std::unique_ptr<BlobDataHandle> first_handle = SetupBasicBlob(kId);
422 697
423 // Now register a url for that blob. 698 // Now register a url for that blob.
424 GURL kUrl("blob:id"); 699 GURL kUrl("blob:id");
425 context_.RegisterPublicBlobURL(kUrl, kId); 700 context_.RegisterPublicBlobURL(kUrl, kId);
426 std::unique_ptr<BlobDataHandle> blob_data_handle = 701 std::unique_ptr<BlobDataHandle> blob_data_handle =
427 context_.GetBlobDataFromPublicURL(kUrl); 702 context_.GetBlobDataFromPublicURL(kUrl);
428 ASSERT_TRUE(blob_data_handle.get()); 703 ASSERT_TRUE(blob_data_handle.get());
429 EXPECT_EQ(kId, blob_data_handle->uuid()); 704 EXPECT_EQ(kId, blob_data_handle->uuid());
430 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot(); 705 std::unique_ptr<BlobDataSnapshot> data = blob_data_handle->CreateSnapshot();
431 blob_data_handle.reset(); 706 blob_data_handle.reset();
432 first_handle.reset(); 707 first_handle.reset();
433 base::RunLoop().RunUntilIdle(); 708 base::RunLoop().RunUntilIdle();
434 709
435 // The url registration should keep the blob alive even after 710 // The url registration should keep the blob alive even after
436 // explicit references are dropped. 711 // explicit references are dropped.
437 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl); 712 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl);
438 EXPECT_TRUE(blob_data_handle); 713 EXPECT_TRUE(blob_data_handle);
439 blob_data_handle.reset(); 714 blob_data_handle.reset();
715
440 base::RunLoop().RunUntilIdle(); 716 base::RunLoop().RunUntilIdle();
441
442 // Finally get rid of the url registration and the blob. 717 // Finally get rid of the url registration and the blob.
443 context_.RevokePublicBlobURL(kUrl); 718 context_.RevokePublicBlobURL(kUrl);
444 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl); 719 blob_data_handle = context_.GetBlobDataFromPublicURL(kUrl);
445 EXPECT_FALSE(blob_data_handle.get()); 720 EXPECT_FALSE(blob_data_handle.get());
446 EXPECT_FALSE(context_.registry().HasEntry(kId)); 721 EXPECT_FALSE(context_.registry().HasEntry(kId));
447 } 722 }
448 723
449 TEST_F(BlobStorageContextTest, TestUnknownBrokenAndBuildingBlobReference) { 724 TEST_F(BlobStorageContextTest, TestUnknownBrokenAndBuildingBlobReference) {
450 base::MessageLoop fake_io_message_loop;
451 const std::string kBrokenId("broken_id"); 725 const std::string kBrokenId("broken_id");
452 const std::string kBuildingId("building_id"); 726 const std::string kBuildingId("building_id");
453 const std::string kReferencingId("referencing_id"); 727 const std::string kReferencingId("referencing_id");
454 const std::string kUnknownId("unknown_id"); 728 const std::string kUnknownId("unknown_id");
455 729
456 // Create a broken blob and a building blob. 730 // Create a broken blob.
457 context_.CreatePendingBlob(kBuildingId, "", ""); 731 std::unique_ptr<BlobDataHandle> broken_handle =
458 context_.CreatePendingBlob(kBrokenId, "", ""); 732 context_.AddBrokenBlob(kBrokenId, "", "", BlobStatus::OUT_OF_MEMORY);
459 context_.CancelPendingBlob(kBrokenId, IPCBlobCreationCancelCode::UNKNOWN); 733 EXPECT_TRUE(context_.GetBlobStatus(kBrokenId) == BlobStatus::OUT_OF_MEMORY);
460 EXPECT_TRUE(context_.IsBroken(kBrokenId));
461 EXPECT_TRUE(context_.registry().HasEntry(kBrokenId)); 734 EXPECT_TRUE(context_.registry().HasEntry(kBrokenId));
462 735
463 // Try to create a blob with a reference to an unknown blob. 736 // Try to create a blob with a reference to an unknown blob.
464 BlobDataBuilder builder(kReferencingId); 737 BlobDataBuilder builder(kReferencingId);
465 builder.AppendData("data"); 738 builder.AppendData("data");
466 builder.AppendBlob(kUnknownId); 739 builder.AppendBlob(kUnknownId);
467 std::unique_ptr<BlobDataHandle> handle = context_.AddFinishedBlob(builder); 740 std::unique_ptr<BlobDataHandle> handle = context_.AddFinishedBlob(builder);
468 EXPECT_TRUE(handle->IsBroken()); 741 EXPECT_TRUE(handle->IsBroken());
469 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId)); 742 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId));
470 handle.reset(); 743 handle.reset();
(...skipping 19 matching lines...) Expand all
490 EXPECT_TRUE(handle->IsBroken()); 763 EXPECT_TRUE(handle->IsBroken());
491 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId)); 764 EXPECT_TRUE(context_.registry().HasEntry(kReferencingId));
492 handle.reset(); 765 handle.reset();
493 base::RunLoop().RunUntilIdle(); 766 base::RunLoop().RunUntilIdle();
494 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId)); 767 EXPECT_FALSE(context_.registry().HasEntry(kReferencingId));
495 } 768 }
496 769
497 // TODO(michaeln): tests for the depcrecated url stuff 770 // TODO(michaeln): tests for the depcrecated url stuff
498 771
499 } // namespace content 772 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698