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

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

Powered by Google App Engine
This is Rietveld 408576698