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

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

Issue 2552153002: [BlobStorage] Enabling disk paging and direct storage. (Closed)
Patch Set: added comments to WebContentsImplTest Created 3 years, 11 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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_memory_controller.h" 5 #include "storage/browser/blob/blob_memory_controller.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/files/scoped_temp_dir.h" 9 #include "base/files/scoped_temp_dir.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h" 11 #include "base/run_loop.h"
12 #include "base/sys_info.h"
12 #include "base/test/test_simple_task_runner.h" 13 #include "base/test/test_simple_task_runner.h"
13 #include "base/threading/thread_restrictions.h" 14 #include "base/threading/thread_restrictions.h"
14 #include "base/threading/thread_task_runner_handle.h" 15 #include "base/threading/thread_task_runner_handle.h"
15 #include "storage/browser/blob/blob_data_builder.h" 16 #include "storage/browser/blob/blob_data_builder.h"
16 #include "storage/browser/blob/blob_data_item.h" 17 #include "storage/browser/blob/blob_data_item.h"
17 #include "storage/browser/blob/shareable_blob_data_item.h" 18 #include "storage/browser/blob/shareable_blob_data_item.h"
18 #include "storage/common/data_element.h" 19 #include "storage/common/data_element.h"
19 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
20 21
21 namespace storage { 22 namespace storage {
22 23
23 using Strategy = BlobMemoryController::Strategy; 24 using Strategy = BlobMemoryController::Strategy;
24 using FileCreationInfo = BlobMemoryController::FileCreationInfo; 25 using FileCreationInfo = BlobMemoryController::FileCreationInfo;
25 using base::TestSimpleTaskRunner; 26 using base::TestSimpleTaskRunner;
26 using ItemState = ShareableBlobDataItem::State; 27 using ItemState = ShareableBlobDataItem::State;
27 using QuotaAllocationTask = BlobMemoryController::QuotaAllocationTask; 28 using QuotaAllocationTask = BlobMemoryController::QuotaAllocationTask;
28 29
29 const std::string kBlobStorageDirectory = "blob_storage"; 30 const std::string kBlobStorageDirectory = "blob_storage";
30 const size_t kTestBlobStorageIPCThresholdBytes = 20; 31 const size_t kTestBlobStorageIPCThresholdBytes = 20;
31 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50; 32 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50;
32 const size_t kTestBlobStorageMaxBlobMemorySize = 500; 33 const size_t kTestBlobStorageMaxBlobMemorySize = 500;
33 const uint64_t kTestBlobStorageMaxDiskSpace = 1000; 34 const uint64_t kTestBlobStorageMaxDiskSpace = 1000;
34 const uint64_t kTestBlobStorageMinFileSizeBytes = 10; 35 const uint64_t kTestBlobStorageMinFileSizeBytes = 10;
35 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; 36 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
36 37
38 const uint64_t kTestSmallBlobStorageMaxDiskSpace = 100;
39
40 static int64_t sFakeDiskSpace = 0;
41 static bool sFakeDiskSpaceCalled = true;
42
43 int64_t FakeDiskSpaceMethod(const base::FilePath& path) {
44 EXPECT_FALSE(sFakeDiskSpaceCalled);
45 sFakeDiskSpaceCalled = true;
46 return sFakeDiskSpace;
47 }
48
37 class BlobMemoryControllerTest : public testing::Test { 49 class BlobMemoryControllerTest : public testing::Test {
38 protected: 50 protected:
39 BlobMemoryControllerTest() {} 51 BlobMemoryControllerTest() {}
40 52
41 void SetUp() override { 53 void SetUp() override {
42 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 54 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
43 base::ThreadRestrictions::SetIOAllowed(false); 55 base::ThreadRestrictions::SetIOAllowed(false);
44 }; 56 };
45 57
46 void TearDown() override { 58 void TearDown() override {
47 files_created_.clear(); 59 files_created_.clear();
48 // Make sure we clean up the files. 60 // Make sure we clean up the files.
49 base::RunLoop().RunUntilIdle(); 61 base::RunLoop().RunUntilIdle();
50 RunFileThreadTasks(); 62 RunFileThreadTasks();
51 base::RunLoop().RunUntilIdle(); 63 base::RunLoop().RunUntilIdle();
52 base::ThreadRestrictions::SetIOAllowed(true); 64 base::ThreadRestrictions::SetIOAllowed(true);
53 ASSERT_TRUE(temp_dir_.Delete()); 65 ASSERT_TRUE(temp_dir_.Delete());
54 } 66 }
55 67
68 void AssertEnoughDiskSpace() {
69 base::ThreadRestrictions::SetIOAllowed(true);
70 ASSERT_GT(base::SysInfo::AmountOfFreeDiskSpace(temp_dir_.GetPath()),
71 static_cast<int64_t>(kTestBlobStorageMaxDiskSpace))
72 << "Bot doesn't have enough disk space to run these tests.";
73 base::ThreadRestrictions::SetIOAllowed(false);
74 }
75
56 std::vector<scoped_refptr<ShareableBlobDataItem>> CreateSharedDataItems( 76 std::vector<scoped_refptr<ShareableBlobDataItem>> CreateSharedDataItems(
57 const BlobDataBuilder& builder) { 77 const BlobDataBuilder& builder) {
58 std::vector<scoped_refptr<ShareableBlobDataItem>> result; 78 std::vector<scoped_refptr<ShareableBlobDataItem>> result;
59 for (size_t i = 0; i < builder.items_.size(); ++i) { 79 for (size_t i = 0; i < builder.items_.size(); ++i) {
60 result.push_back(make_scoped_refptr(new ShareableBlobDataItem( 80 result.push_back(make_scoped_refptr(new ShareableBlobDataItem(
61 builder.items_[i], ShareableBlobDataItem::QUOTA_NEEDED))); 81 builder.items_[i], ShareableBlobDataItem::QUOTA_NEEDED)));
62 } 82 }
63 return result; 83 return result;
64 } 84 }
65 85
66 void SetTestMemoryLimits(BlobMemoryController* controller) { 86 void SetTestMemoryLimits(BlobMemoryController* controller) {
67 BlobStorageLimits limits; 87 BlobStorageLimits limits;
68 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes; 88 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
69 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes; 89 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
70 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize; 90 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
71 limits.max_blob_disk_space = kTestBlobStorageMaxDiskSpace; 91 limits.desired_max_disk_space = kTestBlobStorageMaxDiskSpace;
92 limits.effective_max_disk_space = kTestBlobStorageMaxDiskSpace;
72 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes; 93 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
73 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes; 94 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
74 controller->set_limits_for_testing(limits); 95 controller->set_limits_for_testing(limits);
96 }
97
98 void SetSmallDiskTestMemoryLimits(BlobMemoryController* controller) {
99 BlobStorageLimits limits;
100 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
101 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
102 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
103 limits.desired_max_disk_space = kTestSmallBlobStorageMaxDiskSpace;
104 limits.effective_max_disk_space = kTestSmallBlobStorageMaxDiskSpace;
105 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
106 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
107 controller->set_limits_for_testing(limits);
75 } 108 }
76 109
77 void SaveFileCreationInfo(std::vector<FileCreationInfo> info, bool success) { 110 void SaveFileCreationInfo(std::vector<FileCreationInfo> info, bool success) {
78 file_quota_result_ = success; 111 file_quota_result_ = success;
79 if (success) { 112 if (success) {
80 files_created_.swap(info); 113 files_created_.swap(info);
81 } 114 }
82 } 115 }
83 116
117 void SaveMemoryRequestToOutput(bool* output, bool success) {
118 ASSERT_TRUE(output);
119 *output = success;
120 }
84 void SaveMemoryRequest(bool success) { memory_quota_result_ = success; } 121 void SaveMemoryRequest(bool success) { memory_quota_result_ = success; }
85 122
86 BlobMemoryController::FileQuotaRequestCallback GetFileCreationCallback() { 123 BlobMemoryController::FileQuotaRequestCallback GetFileCreationCallback() {
87 return base::Bind(&BlobMemoryControllerTest::SaveFileCreationInfo, 124 return base::Bind(&BlobMemoryControllerTest::SaveFileCreationInfo,
88 base::Unretained(this)); 125 base::Unretained(this));
89 } 126 }
90 127
91 BlobMemoryController::MemoryQuotaRequestCallback GetMemoryRequestCallback() { 128 BlobMemoryController::MemoryQuotaRequestCallback GetMemoryRequestCallback() {
92 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequest, 129 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequest,
93 base::Unretained(this)); 130 base::Unretained(this));
94 } 131 }
95 132
133 BlobMemoryController::MemoryQuotaRequestCallback
134 GetMemoryRequestCallbackToOutput(bool* output) {
135 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequestToOutput,
136 base::Unretained(this), output);
137 }
138
96 void RunFileThreadTasks() { 139 void RunFileThreadTasks() {
97 base::ThreadRestrictions::SetIOAllowed(true); 140 base::ThreadRestrictions::SetIOAllowed(true);
98 file_runner_->RunPendingTasks(); 141 file_runner_->RunPendingTasks();
99 base::ThreadRestrictions::SetIOAllowed(false); 142 base::ThreadRestrictions::SetIOAllowed(false);
100 } 143 }
101 144
102 bool HasMemoryAllocation(ShareableBlobDataItem* item) { 145 bool HasMemoryAllocation(ShareableBlobDataItem* item) {
103 return static_cast<bool>(item->memory_allocation_); 146 return static_cast<bool>(item->memory_allocation_);
104 } 147 }
105 148
149 void set_disk_space(int64_t space) {
150 sFakeDiskSpaceCalled = false;
151 sFakeDiskSpace = space;
152 }
153
154 void ExpectDiskSpaceCalled() { EXPECT_TRUE(sFakeDiskSpaceCalled); }
155
106 bool file_quota_result_ = false; 156 bool file_quota_result_ = false;
107 base::ScopedTempDir temp_dir_; 157 base::ScopedTempDir temp_dir_;
108 std::vector<FileCreationInfo> files_created_; 158 std::vector<FileCreationInfo> files_created_;
109 bool memory_quota_result_ = false; 159 bool memory_quota_result_ = false;
110 160
111 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner(); 161 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
112 162
113 base::MessageLoop fake_io_message_loop_; 163 base::MessageLoop fake_io_message_loop_;
114 }; 164 };
115 165
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 0, kTestBlobStorageMaxBlobMemorySize - 202 0, kTestBlobStorageMaxBlobMemorySize -
153 kTestBlobStorageMinFileSizeBytes + 1)); 203 kTestBlobStorageMinFileSizeBytes + 1));
154 204
155 EXPECT_EQ(Strategy::FILE, controller.DetermineStrategy( 205 EXPECT_EQ(Strategy::FILE, controller.DetermineStrategy(
156 0, kTestBlobStorageMaxBlobMemorySize)); 206 0, kTestBlobStorageMaxBlobMemorySize));
157 207
158 // Too large for disk. 208 // Too large for disk.
159 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy( 209 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(
160 0, kTestBlobStorageMaxDiskSpace + 1)); 210 0, kTestBlobStorageMaxDiskSpace + 1));
161 } 211 }
212 {
213 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
214 SetSmallDiskTestMemoryLimits(&controller);
215
216 EXPECT_TRUE(controller.CanReserveQuota(kTestBlobStorageMaxBlobMemorySize));
217 // Since our disk is too small, this should be sent with shared memory.
218 EXPECT_EQ(
219 Strategy::SHARED_MEMORY,
220 controller.DetermineStrategy(0, kTestBlobStorageMaxBlobMemorySize));
221 }
162 } 222 }
163 223
164 TEST_F(BlobMemoryControllerTest, GrantMemory) { 224 TEST_F(BlobMemoryControllerTest, GrantMemory) {
165 const std::string kId = "id"; 225 const std::string kId = "id";
166 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 226 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
167 SetTestMemoryLimits(&controller); 227 SetTestMemoryLimits(&controller);
168 228
169 BlobDataBuilder builder(kId); 229 BlobDataBuilder builder(kId);
170 builder.AppendFutureData(10); 230 builder.AppendFutureData(10);
171 builder.AppendFutureData(20); 231 builder.AppendFutureData(20);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 268
209 items.clear(); 269 items.clear();
210 EXPECT_EQ(0u, controller.memory_usage()); 270 EXPECT_EQ(0u, controller.memory_usage());
211 } 271 }
212 272
213 TEST_F(BlobMemoryControllerTest, PageToDisk) { 273 TEST_F(BlobMemoryControllerTest, PageToDisk) {
214 const std::string kId = "id"; 274 const std::string kId = "id";
215 const std::string kId2 = "id2"; 275 const std::string kId2 = "id2";
216 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 276 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
217 SetTestMemoryLimits(&controller); 277 SetTestMemoryLimits(&controller);
278 AssertEnoughDiskSpace();
218 279
219 char kData[kTestBlobStorageMaxBlobMemorySize]; 280 char kData[kTestBlobStorageMaxBlobMemorySize];
220 std::memset(kData, 'e', kTestBlobStorageMaxBlobMemorySize); 281 std::memset(kData, 'e', kTestBlobStorageMaxBlobMemorySize);
221 282
222 // Add memory item that is the memory quota. 283 // Add memory item that is the memory quota.
223 BlobDataBuilder builder(kId); 284 BlobDataBuilder builder(kId);
224 builder.AppendFutureData(kTestBlobStorageMaxBlobMemorySize); 285 builder.AppendFutureData(kTestBlobStorageMaxBlobMemorySize);
225 286
226 std::vector<scoped_refptr<ShareableBlobDataItem>> items = 287 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
227 CreateSharedDataItems(builder); 288 CreateSharedDataItems(builder);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 items2.clear(); 335 items2.clear();
275 EXPECT_EQ(0u, controller.memory_usage()); 336 EXPECT_EQ(0u, controller.memory_usage());
276 items.clear(); 337 items.clear();
277 EXPECT_TRUE(file_runner_->HasPendingTask()); 338 EXPECT_TRUE(file_runner_->HasPendingTask());
278 RunFileThreadTasks(); 339 RunFileThreadTasks();
279 base::RunLoop().RunUntilIdle(); 340 base::RunLoop().RunUntilIdle();
280 EXPECT_EQ(0u, controller.disk_usage()); 341 EXPECT_EQ(0u, controller.disk_usage());
281 } 342 }
282 343
283 TEST_F(BlobMemoryControllerTest, NoDiskTooLarge) { 344 TEST_F(BlobMemoryControllerTest, NoDiskTooLarge) {
284 const std::string kId = "id";
285 BlobMemoryController controller(temp_dir_.GetPath(), nullptr); 345 BlobMemoryController controller(temp_dir_.GetPath(), nullptr);
286 SetTestMemoryLimits(&controller); 346 SetTestMemoryLimits(&controller);
287 347
288 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxBlobMemorySize + 348 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxBlobMemorySize +
289 kTestBlobStorageMinFileSizeBytes + 349 kTestBlobStorageMinFileSizeBytes +
290 1)); 350 1));
291 } 351 }
292 352
293 TEST_F(BlobMemoryControllerTest, TooLargeForDisk) { 353 TEST_F(BlobMemoryControllerTest, TooLargeForDisk) {
294 const std::string kId = "id";
295 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 354 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
296 SetTestMemoryLimits(&controller); 355 SetTestMemoryLimits(&controller);
297 356
298 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxDiskSpace + 1)); 357 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxDiskSpace + 1));
299 } 358 }
300 359
301 TEST_F(BlobMemoryControllerTest, CancelMemoryRequest) { 360 TEST_F(BlobMemoryControllerTest, CancelMemoryRequest) {
302 const std::string kId = "id"; 361 const std::string kId = "id";
303 const std::string kId2 = "id2"; 362 const std::string kId2 = "id2";
304 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 363 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 base::WeakPtr<QuotaAllocationTask> task = 493 base::WeakPtr<QuotaAllocationTask> task =
435 controller.ReserveFileQuota(items, GetFileCreationCallback()); 494 controller.ReserveFileQuota(items, GetFileCreationCallback());
436 EXPECT_TRUE(task); 495 EXPECT_TRUE(task);
437 EXPECT_EQ(ItemState::QUOTA_REQUESTED, items[0]->state()); 496 EXPECT_EQ(ItemState::QUOTA_REQUESTED, items[0]->state());
438 EXPECT_TRUE(file_runner_->HasPendingTask()); 497 EXPECT_TRUE(file_runner_->HasPendingTask());
439 EXPECT_EQ(0u, controller.memory_usage()); 498 EXPECT_EQ(0u, controller.memory_usage());
440 EXPECT_EQ(kBlobSize, controller.disk_usage()); 499 EXPECT_EQ(kBlobSize, controller.disk_usage());
441 500
442 task->Cancel(); 501 task->Cancel();
443 EXPECT_FALSE(task); 502 EXPECT_FALSE(task);
444 EXPECT_EQ(kBlobSize, controller.disk_usage()); 503 EXPECT_EQ(0ull, controller.disk_usage());
445 EXPECT_TRUE(file_runner_->HasPendingTask()); 504
446 RunFileThreadTasks(); 505 RunFileThreadTasks();
447 base::RunLoop().RunUntilIdle(); 506 base::RunLoop().RunUntilIdle();
448 EXPECT_EQ(0u, controller.disk_usage());
449 } 507 }
450 508
451 TEST_F(BlobMemoryControllerTest, MultipleFilesPaged) { 509 TEST_F(BlobMemoryControllerTest, MultipleFilesPaged) {
452 const std::string kId1 = "id"; 510 const std::string kId1 = "id";
453 const size_t kSize1 = kTestBlobStorageMaxFileSizeBytes; 511 const size_t kSize1 = kTestBlobStorageMaxFileSizeBytes;
454 char kData1[kSize1]; 512 char kData1[kSize1];
455 std::memset(kData1, 'e', kSize1); 513 std::memset(kData1, 'e', kSize1);
456 514
457 const std::string kId2 = "id2"; 515 const std::string kId2 = "id2";
458 const size_t kSize2 = kTestBlobStorageMaxFileSizeBytes; 516 const size_t kSize2 = kTestBlobStorageMaxFileSizeBytes;
459 char kData2[kSize2]; 517 char kData2[kSize2];
460 std::memset(kData2, 'f', kSize2); 518 std::memset(kData2, 'f', kSize2);
461 519
462 const std::string kId3 = "id3"; 520 const std::string kId3 = "id3";
463 const size_t kSize3 = kTestBlobStorageMaxBlobMemorySize - 1; 521 const size_t kSize3 = kTestBlobStorageMaxBlobMemorySize - 1;
464 522
465 // Assert we shouldn't trigger paging preemptively. 523 // Assert we shouldn't trigger paging preemptively.
466 ASSERT_LE(kSize1 + kSize2, kTestBlobStorageMaxBlobMemorySize); 524 ASSERT_LE(kSize1 + kSize2, kTestBlobStorageMaxBlobMemorySize);
467 525
468 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 526 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
469 SetTestMemoryLimits(&controller); 527 SetTestMemoryLimits(&controller);
528 AssertEnoughDiskSpace();
470 529
471 // We add two items that should be their own files when we page to disk, and 530 // We add two items that should be their own files when we page to disk, and
472 // then add the last item to trigger the paging. 531 // then add the last item to trigger the paging.
473 532
474 BlobDataBuilder builder1(kId1); 533 BlobDataBuilder builder1(kId1);
475 builder1.AppendFutureData(kSize1); 534 builder1.AppendFutureData(kSize1);
476 BlobDataBuilder builder2(kId2); 535 BlobDataBuilder builder2(kId2);
477 builder2.AppendFutureData(kSize2); 536 builder2.AppendFutureData(kSize2);
478 537
479 std::vector<scoped_refptr<ShareableBlobDataItem>> items1 = 538 std::vector<scoped_refptr<ShareableBlobDataItem>> items1 =
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 base::RunLoop().RunUntilIdle(); 595 base::RunLoop().RunUntilIdle();
537 EXPECT_TRUE(file_runner_->HasPendingTask()); 596 EXPECT_TRUE(file_runner_->HasPendingTask());
538 RunFileThreadTasks(); 597 RunFileThreadTasks();
539 base::RunLoop().RunUntilIdle(); 598 base::RunLoop().RunUntilIdle();
540 EXPECT_EQ(0u, controller.disk_usage()); 599 EXPECT_EQ(0u, controller.disk_usage());
541 } 600 }
542 601
543 TEST_F(BlobMemoryControllerTest, FullEviction) { 602 TEST_F(BlobMemoryControllerTest, FullEviction) {
544 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 603 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
545 SetTestMemoryLimits(&controller); 604 SetTestMemoryLimits(&controller);
605 AssertEnoughDiskSpace();
546 606
547 char kData[1]; 607 char kData[1];
548 kData[0] = 'e'; 608 kData[0] = 'e';
549 609
550 // Create a bunch of small stuff. 610 // Create a bunch of small stuff.
551 std::vector<scoped_refptr<ShareableBlobDataItem>> small_items; 611 std::vector<scoped_refptr<ShareableBlobDataItem>> small_items;
552 for (size_t i = 0; 612 for (size_t i = 0;
553 i < kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes; 613 i < kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes;
554 i++) { 614 i++) {
555 BlobDataBuilder builder("fake"); 615 BlobDataBuilder builder("fake");
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 EXPECT_EQ( 647 EXPECT_EQ(
588 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes, 648 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes,
589 controller.memory_usage()); 649 controller.memory_usage());
590 EXPECT_EQ( 650 EXPECT_EQ(
591 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes, 651 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes,
592 controller.disk_usage()); 652 controller.disk_usage());
593 653
594 EXPECT_TRUE(memory_quota_result_); 654 EXPECT_TRUE(memory_quota_result_);
595 } 655 }
596 656
657 TEST_F(BlobMemoryControllerTest, PagingStopsWhenFull) {
658 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
659 SetTestMemoryLimits(&controller);
660 AssertEnoughDiskSpace();
661 const size_t kTotalBlobStorageSize =
662 kTestBlobStorageMaxDiskSpace + kTestBlobStorageMaxBlobMemorySize;
663
664 const size_t kDataSize = 10u;
665 const size_t kBlobsThatCanFit = kTotalBlobStorageSize / kDataSize;
666 const size_t kNumFastBlobs = kTestBlobStorageMaxBlobMemorySize / kDataSize;
667 char kData[10];
668 memset(kData, 'e', kDataSize);
669
670 // Create all of our blobs.
671 std::vector<scoped_refptr<ShareableBlobDataItem>> all_items;
672 std::vector<base::WeakPtr<QuotaAllocationTask>> memory_tasks;
673 bool memory_requested[kBlobsThatCanFit] = {};
674 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
675 BlobDataBuilder builder("fake");
676 builder.AppendData(kData, kDataSize);
677 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
678 CreateSharedDataItems(builder);
679 EXPECT_TRUE(controller.CanReserveQuota(kDataSize));
680 EXPECT_EQ((i < kNumFastBlobs) ? Strategy::NONE_NEEDED : Strategy::IPC,
681 controller.DetermineStrategy(kDataSize, kDataSize))
682 << i;
683 base::WeakPtr<QuotaAllocationTask> memory_task =
684 controller.ReserveMemoryQuota(
685 items, GetMemoryRequestCallbackToOutput(&memory_requested[i]));
686 if (memory_task) {
687 memory_tasks.push_back(std::move(memory_task));
688 }
689 all_items.insert(all_items.end(), items.begin(), items.end());
690 }
691 // We should have stored all of our memory quota, and no disk yet.
692 EXPECT_EQ(500u, controller.memory_usage());
693 EXPECT_EQ(0ull, controller.disk_usage());
694
695 EXPECT_FALSE(controller.CanReserveQuota(1u));
696 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
697 EXPECT_FALSE(file_runner_->HasPendingTask());
698
699 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
700 EXPECT_EQ(i < kBlobsThatCanFit / 3, memory_requested[i]) << i;
701 if (memory_requested[i] &&
702 all_items[i]->state() != ItemState::POPULATED_WITH_QUOTA) {
703 EXPECT_TRUE(memory_requested[i]);
704 all_items[i]->set_state(ItemState::POPULATED_WITH_QUOTA);
705 std::vector<scoped_refptr<ShareableBlobDataItem>> temp_vector;
706 temp_vector.push_back(all_items[i]);
707 controller.NotifyMemoryItemsUsed(temp_vector);
708 }
709 }
710 EXPECT_TRUE(file_runner_->HasPendingTask());
711
712 // This will schedule one task. Paging starts as soon as there is enough
713 // memory to page, and multiple pagings can't happen at the same time.
714 EXPECT_EQ(10ull, controller.disk_usage());
715 RunFileThreadTasks();
716 base::RunLoop().RunUntilIdle();
717 // The rest of the tasks should be scheduled.
718 EXPECT_TRUE(file_runner_->HasPendingTask());
719 RunFileThreadTasks();
720 base::RunLoop().RunUntilIdle();
721 // Everything in memory should be on disk, and next batch of memory items
722 // should be granted.
723 EXPECT_EQ(500u, controller.memory_usage());
724 EXPECT_EQ(500ull, controller.disk_usage());
725
726 // Still can't add anything.
727 EXPECT_FALSE(controller.CanReserveQuota(1u));
728 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
729
730 // Flag next batch for saving to disk.
731 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
732 // Note: this can fail if the bot's disk is almost full.
733 EXPECT_EQ(i < kBlobsThatCanFit * 2 / 3, memory_requested[i]) << i;
734 if (memory_requested[i] &&
735 all_items[i]->state() != ItemState::POPULATED_WITH_QUOTA) {
736 all_items[i]->set_state(ItemState::POPULATED_WITH_QUOTA);
737 std::vector<scoped_refptr<ShareableBlobDataItem>> temp_vector;
738 temp_vector.push_back(all_items[i]);
739 controller.NotifyMemoryItemsUsed(temp_vector);
740 }
741 }
742 EXPECT_TRUE(file_runner_->HasPendingTask());
743
744 // Same as before. One page task is scheduled, so run them twice.
745 EXPECT_EQ(510ull, controller.disk_usage());
746 RunFileThreadTasks();
747 base::RunLoop().RunUntilIdle();
748 // We page one time first, as it blocks paging once it starts.
749 RunFileThreadTasks();
750 base::RunLoop().RunUntilIdle();
751
752 // All quota should be allocated.
753 EXPECT_EQ(kTestBlobStorageMaxBlobMemorySize, controller.memory_usage());
754 EXPECT_EQ(kTestBlobStorageMaxDiskSpace, controller.disk_usage());
755 EXPECT_FALSE(controller.CanReserveQuota(1u));
756 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
757
758 // Flag last batch as populated.
759 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
760 // Note: this can fail if the bot's disk is almost full.
761 EXPECT_TRUE(memory_requested[i]);
762 if (memory_requested[i] &&
763 all_items[i]->state() != ItemState::POPULATED_WITH_QUOTA) {
764 all_items[i]->set_state(ItemState::POPULATED_WITH_QUOTA);
765 std::vector<scoped_refptr<ShareableBlobDataItem>> temp_vector;
766 temp_vector.push_back(all_items[i]);
767 controller.NotifyMemoryItemsUsed(temp_vector);
768 }
769 }
770
771 // There should be no more paging to disk, as we've reached the end.
772 EXPECT_FALSE(file_runner_->HasPendingTask());
773
774 // All quota should be allocated still.
775 EXPECT_EQ(500u, controller.memory_usage());
776 EXPECT_EQ(1000ull, controller.disk_usage());
777
778 // Still can't add anything.
779 EXPECT_FALSE(controller.CanReserveQuota(1u));
780 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
781 }
782
597 TEST_F(BlobMemoryControllerTest, DisableDiskWithFileAndMemoryPending) { 783 TEST_F(BlobMemoryControllerTest, DisableDiskWithFileAndMemoryPending) {
598 const std::string kFirstMemoryId = "id"; 784 const std::string kFirstMemoryId = "id";
599 const uint64_t kFirstMemorySize = kTestBlobStorageMaxBlobMemorySize; 785 const uint64_t kFirstMemorySize = kTestBlobStorageMaxBlobMemorySize;
600 const std::string kSecondMemoryId = "id2"; 786 const std::string kSecondMemoryId = "id2";
601 const uint64_t kSecondMemorySize = 1; 787 const uint64_t kSecondMemorySize = 1;
602 const std::string kFileId = "id2"; 788 const std::string kFileId = "id2";
603 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize; 789 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
604 790
605 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 791 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
606 SetTestMemoryLimits(&controller); 792 SetTestMemoryLimits(&controller);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 856
671 file_items.clear(); 857 file_items.clear();
672 items.clear(); 858 items.clear();
673 859
674 RunFileThreadTasks(); 860 RunFileThreadTasks();
675 base::RunLoop().RunUntilIdle(); 861 base::RunLoop().RunUntilIdle();
676 862
677 EXPECT_EQ(0ull, controller.disk_usage()); 863 EXPECT_EQ(0ull, controller.disk_usage());
678 EXPECT_EQ(0ull, controller.memory_usage()); 864 EXPECT_EQ(0ull, controller.memory_usage());
679 } 865 }
866
867 TEST_F(BlobMemoryControllerTest, DiskSpaceTooSmallForItem) {
868 const std::string kFileId = "id2";
869 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
870
871 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
872 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
873
874 BlobDataBuilder file_builder(kFileId);
875 file_builder.AppendFutureFile(0, kFileBlobSize, 0);
876
877 // When we have < kFileBlobSize, then we cancel our request.
878 SetTestMemoryLimits(&controller);
879
880 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
881 CreateSharedDataItems(file_builder);
882
883 file_quota_result_ = true;
884 controller.ReserveFileQuota(items, GetFileCreationCallback());
885
886 EXPECT_TRUE(file_runner_->HasPendingTask());
887 set_disk_space(kFileBlobSize - 1);
888
889 RunFileThreadTasks();
890 ExpectDiskSpaceCalled();
891 base::RunLoop().RunUntilIdle();
892
893 EXPECT_FALSE(file_quota_result_);
894 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
895 EXPECT_EQ(0ull, controller.limits().effective_max_disk_space);
896
897 EXPECT_EQ(0ull, controller.disk_usage());
898 EXPECT_EQ(0ull, controller.memory_usage());
899 }
900
901 TEST_F(BlobMemoryControllerTest, DiskSpaceHitMinAvailable) {
902 const std::string kFileId = "id2";
903 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
904
905 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
906 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
907
908 BlobDataBuilder file_builder(kFileId);
909 file_builder.AppendFutureFile(0, kFileBlobSize, 0);
910 // When we have < limits.min_available_external_disk_space(), then we'll
911 // modify our effective disk space to match our current usage to stop using
912 // more disk.
913
914 SetTestMemoryLimits(&controller);
915
916 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
917 CreateSharedDataItems(file_builder);
918
919 file_quota_result_ = false;
920 controller.ReserveFileQuota(items, GetFileCreationCallback());
921
922 EXPECT_TRUE(file_runner_->HasPendingTask());
923 set_disk_space(controller.limits().min_available_external_disk_space() - 1);
924
925 RunFileThreadTasks();
926 ExpectDiskSpaceCalled();
927 base::RunLoop().RunUntilIdle();
928
929 EXPECT_TRUE(file_quota_result_);
930 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
931 EXPECT_EQ(kFileBlobSize, controller.limits().effective_max_disk_space);
932
933 items.clear();
934 files_created_.clear();
935
936 RunFileThreadTasks();
937 base::RunLoop().RunUntilIdle();
938
939 EXPECT_EQ(0ull, controller.disk_usage());
940 EXPECT_EQ(0ull, controller.memory_usage());
941 }
942
943 TEST_F(BlobMemoryControllerTest, DiskSpaceBeforeMinAvailable) {
944 const std::string kFileId = "id2";
945
946 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
947 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
948
949 BlobDataBuilder file_builder(kFileId);
950 file_builder.AppendFutureFile(0, kTestBlobStorageMaxBlobMemorySize, 0);
951
952 // When our desired total disk space is less than we're allowed given the
953 // minimum disk availability, we shorten the disk space.
954 SetTestMemoryLimits(&controller);
955
956 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
957 CreateSharedDataItems(file_builder);
958
959 file_quota_result_ = false;
960 controller.ReserveFileQuota(items, GetFileCreationCallback());
961
962 EXPECT_TRUE(file_runner_->HasPendingTask());
963 set_disk_space(controller.limits().desired_max_disk_space +
964 controller.limits().min_available_external_disk_space() + 1);
965
966 RunFileThreadTasks();
967 ExpectDiskSpaceCalled();
968 base::RunLoop().RunUntilIdle();
969
970 EXPECT_TRUE(file_quota_result_);
971 EXPECT_FALSE(controller.limits().IsDiskSpaceConstrained())
972 << controller.limits().effective_max_disk_space;
973
974 items.clear();
975 files_created_.clear();
976
977 RunFileThreadTasks();
978 base::RunLoop().RunUntilIdle();
979
980 EXPECT_EQ(0ull, controller.disk_usage());
981 EXPECT_EQ(0ull, controller.memory_usage());
982 }
983
984 TEST_F(BlobMemoryControllerTest, DiskSpaceNearMinAvailable) {
985 const std::string kFileId = "id2";
986
987 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
988 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
989
990 BlobDataBuilder file_builder(kFileId);
991 file_builder.AppendFutureFile(0, kTestBlobStorageMaxBlobMemorySize, 0);
992
993 // When our desired total disk space is less than we're allowed given the
994 // minimum disk availability, we shorten the disk space.
995 SetTestMemoryLimits(&controller);
996
997 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
998 CreateSharedDataItems(file_builder);
999
1000 file_quota_result_ = false;
1001 controller.ReserveFileQuota(items, GetFileCreationCallback());
1002
1003 EXPECT_TRUE(file_runner_->HasPendingTask());
1004 set_disk_space(controller.limits().desired_max_disk_space +
1005 controller.limits().min_available_external_disk_space() - 1);
1006
1007 RunFileThreadTasks();
1008 ExpectDiskSpaceCalled();
1009 base::RunLoop().RunUntilIdle();
1010
1011 EXPECT_TRUE(file_quota_result_);
1012 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
1013 EXPECT_EQ(controller.limits().desired_max_disk_space - 1,
1014 controller.limits().effective_max_disk_space);
1015
1016 items.clear();
1017 files_created_.clear();
1018
1019 RunFileThreadTasks();
1020 base::RunLoop().RunUntilIdle();
1021
1022 EXPECT_EQ(0ull, controller.disk_usage());
1023 EXPECT_EQ(0ull, controller.memory_usage());
1024 }
1025
1026 TEST_F(BlobMemoryControllerTest, DiskSpaceResetAfterIncrease) {
1027 const std::string kFileId = "id2";
1028 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
1029
1030 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
1031 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
1032
1033 BlobDataBuilder file_builder(kFileId);
1034 file_builder.AppendFutureFile(0, kFileBlobSize, 0);
1035
1036 // When we do a file operation after disk has been freed (after we've been
1037 // limited), our effective size grows correctly.
1038 SetTestMemoryLimits(&controller);
1039
1040 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
1041 CreateSharedDataItems(file_builder);
1042
1043 controller.ReserveFileQuota(items, GetFileCreationCallback());
1044
1045 EXPECT_TRUE(file_runner_->HasPendingTask());
1046 set_disk_space(controller.limits().min_available_external_disk_space() - 1);
1047
1048 RunFileThreadTasks();
1049 base::RunLoop().RunUntilIdle();
1050
1051 // Check the effective limit is constrained.
1052 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
1053 EXPECT_EQ(kFileBlobSize, controller.limits().effective_max_disk_space);
1054
1055 // Delete the item so we have disk quota.
1056 items.clear();
1057 files_created_.clear();
1058
1059 RunFileThreadTasks();
1060 ExpectDiskSpaceCalled();
1061 base::RunLoop().RunUntilIdle();
1062
1063 EXPECT_EQ(0ull, controller.disk_usage());
1064 EXPECT_EQ(0ull, controller.memory_usage());
1065
1066 // Create the same item, but have the disk space report the minimum amount
1067 // needed to have the desired disk size.
1068 items = CreateSharedDataItems(file_builder);
1069
1070 controller.ReserveFileQuota(items, GetFileCreationCallback());
1071
1072 EXPECT_TRUE(file_runner_->HasPendingTask());
1073 set_disk_space(kTestBlobStorageMaxDiskSpace +
1074 controller.limits().min_available_external_disk_space());
1075
1076 RunFileThreadTasks();
1077 ExpectDiskSpaceCalled();
1078 base::RunLoop().RunUntilIdle();
1079
1080 EXPECT_FALSE(controller.limits().IsDiskSpaceConstrained());
1081 EXPECT_EQ(controller.limits().desired_max_disk_space,
1082 controller.limits().effective_max_disk_space);
1083
1084 items.clear();
1085 files_created_.clear();
1086
1087 RunFileThreadTasks();
1088 base::RunLoop().RunUntilIdle();
1089
1090 EXPECT_EQ(0ull, controller.disk_usage());
1091 EXPECT_EQ(0ull, controller.memory_usage());
1092 }
1093
1094 TEST_F(BlobMemoryControllerTest, DiskSpaceUnknown) {
1095 const std::string kFileId = "id2";
1096 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
1097
1098 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
1099 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
1100
1101 BlobDataBuilder file_builder(kFileId);
1102 file_builder.AppendFutureFile(0, kFileBlobSize, 0);
1103
1104 // If the disk space returns an error (-1), then we ignore that signal.
1105 SetTestMemoryLimits(&controller);
1106
1107 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
1108 CreateSharedDataItems(file_builder);
1109
1110 controller.ReserveFileQuota(items, GetFileCreationCallback());
1111
1112 EXPECT_TRUE(file_runner_->HasPendingTask());
1113 set_disk_space(-1ll);
1114
1115 RunFileThreadTasks();
1116 ExpectDiskSpaceCalled();
1117 base::RunLoop().RunUntilIdle();
1118
1119 // Check the effective limit is constrained.
1120 EXPECT_FALSE(controller.limits().IsDiskSpaceConstrained());
1121 }
1122
680 } // namespace storage 1123 } // namespace storage
OLDNEW
« no previous file with comments | « content/browser/blob_storage/blob_flattener_unittest.cc ('k') | content/browser/blob_storage/blob_storage_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698