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

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: Fixed & added test for disk quota near min_available, and comments 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"
20 #include "testing/gmock/include/gmock/gmock.h"
Marijn Kruisselbrink 2017/01/10 21:41:06 nit: You're no longer using gmock I believe?
dmurph 2017/01/10 21:49:19 good catch, thanks.
19 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
20 22
21 namespace storage { 23 namespace storage {
22 24
23 using Strategy = BlobMemoryController::Strategy; 25 using Strategy = BlobMemoryController::Strategy;
24 using FileCreationInfo = BlobMemoryController::FileCreationInfo; 26 using FileCreationInfo = BlobMemoryController::FileCreationInfo;
25 using base::TestSimpleTaskRunner; 27 using base::TestSimpleTaskRunner;
26 using ItemState = ShareableBlobDataItem::State; 28 using ItemState = ShareableBlobDataItem::State;
27 using QuotaAllocationTask = BlobMemoryController::QuotaAllocationTask; 29 using QuotaAllocationTask = BlobMemoryController::QuotaAllocationTask;
28 30
29 const std::string kBlobStorageDirectory = "blob_storage"; 31 const std::string kBlobStorageDirectory = "blob_storage";
30 const size_t kTestBlobStorageIPCThresholdBytes = 20; 32 const size_t kTestBlobStorageIPCThresholdBytes = 20;
31 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50; 33 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50;
32 const size_t kTestBlobStorageMaxBlobMemorySize = 500; 34 const size_t kTestBlobStorageMaxBlobMemorySize = 500;
33 const uint64_t kTestBlobStorageMaxDiskSpace = 1000; 35 const uint64_t kTestBlobStorageMaxDiskSpace = 1000;
34 const uint64_t kTestBlobStorageMinFileSizeBytes = 10; 36 const uint64_t kTestBlobStorageMinFileSizeBytes = 10;
35 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; 37 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
36 38
39 const uint64_t kTestSmallBlobStorageMaxDiskSpace = 100;
40
41 static int64_t sFakeDiskSpace = 0;
42 static bool sFakeDiskSpaceCalled = true;
43
44 int64_t FakeDiskSpaceMethod(const base::FilePath& path) {
45 EXPECT_FALSE(sFakeDiskSpaceCalled);
46 sFakeDiskSpaceCalled = true;
47 return sFakeDiskSpace;
48 }
49
37 class BlobMemoryControllerTest : public testing::Test { 50 class BlobMemoryControllerTest : public testing::Test {
38 protected: 51 protected:
39 BlobMemoryControllerTest() {} 52 BlobMemoryControllerTest() {}
40 53
41 void SetUp() override { 54 void SetUp() override {
42 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 55 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
43 base::ThreadRestrictions::SetIOAllowed(false); 56 base::ThreadRestrictions::SetIOAllowed(false);
44 }; 57 };
45 58
46 void TearDown() override { 59 void TearDown() override {
47 files_created_.clear(); 60 files_created_.clear();
48 // Make sure we clean up the files. 61 // Make sure we clean up the files.
49 base::RunLoop().RunUntilIdle(); 62 base::RunLoop().RunUntilIdle();
50 RunFileThreadTasks(); 63 RunFileThreadTasks();
51 base::RunLoop().RunUntilIdle(); 64 base::RunLoop().RunUntilIdle();
52 base::ThreadRestrictions::SetIOAllowed(true); 65 base::ThreadRestrictions::SetIOAllowed(true);
53 ASSERT_TRUE(temp_dir_.Delete()); 66 ASSERT_TRUE(temp_dir_.Delete());
54 } 67 }
55 68
69 void AssertEnoughDiskSpace() {
70 base::ThreadRestrictions::SetIOAllowed(true);
71 ASSERT_GT(base::SysInfo::AmountOfFreeDiskSpace(temp_dir_.GetPath()),
72 static_cast<int64_t>(kTestBlobStorageMaxDiskSpace))
73 << "Bot doesn't have enough disk space to run these tests.";
74 base::ThreadRestrictions::SetIOAllowed(false);
75 }
76
56 std::vector<scoped_refptr<ShareableBlobDataItem>> CreateSharedDataItems( 77 std::vector<scoped_refptr<ShareableBlobDataItem>> CreateSharedDataItems(
57 const BlobDataBuilder& builder) { 78 const BlobDataBuilder& builder) {
58 std::vector<scoped_refptr<ShareableBlobDataItem>> result; 79 std::vector<scoped_refptr<ShareableBlobDataItem>> result;
59 for (size_t i = 0; i < builder.items_.size(); ++i) { 80 for (size_t i = 0; i < builder.items_.size(); ++i) {
60 result.push_back(make_scoped_refptr(new ShareableBlobDataItem( 81 result.push_back(make_scoped_refptr(new ShareableBlobDataItem(
61 builder.items_[i], ShareableBlobDataItem::QUOTA_NEEDED))); 82 builder.items_[i], ShareableBlobDataItem::QUOTA_NEEDED)));
62 } 83 }
63 return result; 84 return result;
64 } 85 }
65 86
66 void SetTestMemoryLimits(BlobMemoryController* controller) { 87 void SetTestMemoryLimits(BlobMemoryController* controller) {
67 BlobStorageLimits limits; 88 BlobStorageLimits limits;
68 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes; 89 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
69 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes; 90 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
70 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize; 91 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
71 limits.max_blob_disk_space = kTestBlobStorageMaxDiskSpace; 92 limits.desired_max_disk_space = kTestBlobStorageMaxDiskSpace;
93 limits.effective_max_disk_space = kTestBlobStorageMaxDiskSpace;
72 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes; 94 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
73 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes; 95 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
74 controller->set_limits_for_testing(limits); 96 controller->set_limits_for_testing(limits);
97 }
98
99 void SetSmallDiskTestMemoryLimits(BlobMemoryController* controller) {
100 BlobStorageLimits limits;
101 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
102 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
103 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
104 limits.desired_max_disk_space = kTestSmallBlobStorageMaxDiskSpace;
105 limits.effective_max_disk_space = kTestSmallBlobStorageMaxDiskSpace;
106 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
107 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
108 controller->set_limits_for_testing(limits);
75 } 109 }
76 110
77 void SaveFileCreationInfo(std::vector<FileCreationInfo> info, bool success) { 111 void SaveFileCreationInfo(std::vector<FileCreationInfo> info, bool success) {
78 file_quota_result_ = success; 112 file_quota_result_ = success;
79 if (success) { 113 if (success) {
80 files_created_.swap(info); 114 files_created_.swap(info);
81 } 115 }
82 } 116 }
83 117
118 void SaveMemoryRequestToOutput(bool* output, bool success) {
119 ASSERT_TRUE(output);
120 *output = success;
121 }
84 void SaveMemoryRequest(bool success) { memory_quota_result_ = success; } 122 void SaveMemoryRequest(bool success) { memory_quota_result_ = success; }
85 123
86 BlobMemoryController::FileQuotaRequestCallback GetFileCreationCallback() { 124 BlobMemoryController::FileQuotaRequestCallback GetFileCreationCallback() {
87 return base::Bind(&BlobMemoryControllerTest::SaveFileCreationInfo, 125 return base::Bind(&BlobMemoryControllerTest::SaveFileCreationInfo,
88 base::Unretained(this)); 126 base::Unretained(this));
89 } 127 }
90 128
91 BlobMemoryController::MemoryQuotaRequestCallback GetMemoryRequestCallback() { 129 BlobMemoryController::MemoryQuotaRequestCallback GetMemoryRequestCallback() {
92 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequest, 130 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequest,
93 base::Unretained(this)); 131 base::Unretained(this));
94 } 132 }
95 133
134 BlobMemoryController::MemoryQuotaRequestCallback
135 GetMemoryRequestCallbackToOutput(bool* output) {
136 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequestToOutput,
137 base::Unretained(this), output);
138 }
139
96 void RunFileThreadTasks() { 140 void RunFileThreadTasks() {
97 base::ThreadRestrictions::SetIOAllowed(true); 141 base::ThreadRestrictions::SetIOAllowed(true);
98 file_runner_->RunPendingTasks(); 142 file_runner_->RunPendingTasks();
99 base::ThreadRestrictions::SetIOAllowed(false); 143 base::ThreadRestrictions::SetIOAllowed(false);
100 } 144 }
101 145
102 bool HasMemoryAllocation(ShareableBlobDataItem* item) { 146 bool HasMemoryAllocation(ShareableBlobDataItem* item) {
103 return static_cast<bool>(item->memory_allocation_); 147 return static_cast<bool>(item->memory_allocation_);
104 } 148 }
105 149
150 void set_disk_space(int64_t space) {
151 sFakeDiskSpaceCalled = false;
152 sFakeDiskSpace = space;
153 }
154
155 void ExpectDiskSpaceCalled() { EXPECT_TRUE(sFakeDiskSpaceCalled); }
156
106 bool file_quota_result_ = false; 157 bool file_quota_result_ = false;
107 base::ScopedTempDir temp_dir_; 158 base::ScopedTempDir temp_dir_;
108 std::vector<FileCreationInfo> files_created_; 159 std::vector<FileCreationInfo> files_created_;
109 bool memory_quota_result_ = false; 160 bool memory_quota_result_ = false;
110 161
111 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner(); 162 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
112 163
113 base::MessageLoop fake_io_message_loop_; 164 base::MessageLoop fake_io_message_loop_;
114 }; 165 };
115 166
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 0, kTestBlobStorageMaxBlobMemorySize - 203 0, kTestBlobStorageMaxBlobMemorySize -
153 kTestBlobStorageMinFileSizeBytes + 1)); 204 kTestBlobStorageMinFileSizeBytes + 1));
154 205
155 EXPECT_EQ(Strategy::FILE, controller.DetermineStrategy( 206 EXPECT_EQ(Strategy::FILE, controller.DetermineStrategy(
156 0, kTestBlobStorageMaxBlobMemorySize)); 207 0, kTestBlobStorageMaxBlobMemorySize));
157 208
158 // Too large for disk. 209 // Too large for disk.
159 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy( 210 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(
160 0, kTestBlobStorageMaxDiskSpace + 1)); 211 0, kTestBlobStorageMaxDiskSpace + 1));
161 } 212 }
213 {
214 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
215 SetSmallDiskTestMemoryLimits(&controller);
216
217 EXPECT_TRUE(controller.CanReserveQuota(kTestBlobStorageMaxBlobMemorySize));
218 // Since our disk is too small, this should be sent with shared memory.
219 EXPECT_EQ(
220 Strategy::SHARED_MEMORY,
221 controller.DetermineStrategy(0, kTestBlobStorageMaxBlobMemorySize));
222 }
162 } 223 }
163 224
164 TEST_F(BlobMemoryControllerTest, GrantMemory) { 225 TEST_F(BlobMemoryControllerTest, GrantMemory) {
165 const std::string kId = "id"; 226 const std::string kId = "id";
166 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 227 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
167 SetTestMemoryLimits(&controller); 228 SetTestMemoryLimits(&controller);
168 229
169 BlobDataBuilder builder(kId); 230 BlobDataBuilder builder(kId);
170 builder.AppendFutureData(10); 231 builder.AppendFutureData(10);
171 builder.AppendFutureData(20); 232 builder.AppendFutureData(20);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 269
209 items.clear(); 270 items.clear();
210 EXPECT_EQ(0u, controller.memory_usage()); 271 EXPECT_EQ(0u, controller.memory_usage());
211 } 272 }
212 273
213 TEST_F(BlobMemoryControllerTest, PageToDisk) { 274 TEST_F(BlobMemoryControllerTest, PageToDisk) {
214 const std::string kId = "id"; 275 const std::string kId = "id";
215 const std::string kId2 = "id2"; 276 const std::string kId2 = "id2";
216 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 277 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
217 SetTestMemoryLimits(&controller); 278 SetTestMemoryLimits(&controller);
279 AssertEnoughDiskSpace();
218 280
219 char kData[kTestBlobStorageMaxBlobMemorySize]; 281 char kData[kTestBlobStorageMaxBlobMemorySize];
220 std::memset(kData, 'e', kTestBlobStorageMaxBlobMemorySize); 282 std::memset(kData, 'e', kTestBlobStorageMaxBlobMemorySize);
221 283
222 // Add memory item that is the memory quota. 284 // Add memory item that is the memory quota.
223 BlobDataBuilder builder(kId); 285 BlobDataBuilder builder(kId);
224 builder.AppendFutureData(kTestBlobStorageMaxBlobMemorySize); 286 builder.AppendFutureData(kTestBlobStorageMaxBlobMemorySize);
225 287
226 std::vector<scoped_refptr<ShareableBlobDataItem>> items = 288 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
227 CreateSharedDataItems(builder); 289 CreateSharedDataItems(builder);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 items2.clear(); 336 items2.clear();
275 EXPECT_EQ(0u, controller.memory_usage()); 337 EXPECT_EQ(0u, controller.memory_usage());
276 items.clear(); 338 items.clear();
277 EXPECT_TRUE(file_runner_->HasPendingTask()); 339 EXPECT_TRUE(file_runner_->HasPendingTask());
278 RunFileThreadTasks(); 340 RunFileThreadTasks();
279 base::RunLoop().RunUntilIdle(); 341 base::RunLoop().RunUntilIdle();
280 EXPECT_EQ(0u, controller.disk_usage()); 342 EXPECT_EQ(0u, controller.disk_usage());
281 } 343 }
282 344
283 TEST_F(BlobMemoryControllerTest, NoDiskTooLarge) { 345 TEST_F(BlobMemoryControllerTest, NoDiskTooLarge) {
284 const std::string kId = "id";
285 BlobMemoryController controller(temp_dir_.GetPath(), nullptr); 346 BlobMemoryController controller(temp_dir_.GetPath(), nullptr);
286 SetTestMemoryLimits(&controller); 347 SetTestMemoryLimits(&controller);
287 348
288 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxBlobMemorySize + 349 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxBlobMemorySize +
289 kTestBlobStorageMinFileSizeBytes + 350 kTestBlobStorageMinFileSizeBytes +
290 1)); 351 1));
291 } 352 }
292 353
293 TEST_F(BlobMemoryControllerTest, TooLargeForDisk) { 354 TEST_F(BlobMemoryControllerTest, TooLargeForDisk) {
294 const std::string kId = "id";
295 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 355 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
296 SetTestMemoryLimits(&controller); 356 SetTestMemoryLimits(&controller);
297 357
298 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxDiskSpace + 1)); 358 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxDiskSpace + 1));
299 } 359 }
300 360
301 TEST_F(BlobMemoryControllerTest, CancelMemoryRequest) { 361 TEST_F(BlobMemoryControllerTest, CancelMemoryRequest) {
302 const std::string kId = "id"; 362 const std::string kId = "id";
303 const std::string kId2 = "id2"; 363 const std::string kId2 = "id2";
304 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 364 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 base::WeakPtr<QuotaAllocationTask> task = 494 base::WeakPtr<QuotaAllocationTask> task =
435 controller.ReserveFileQuota(items, GetFileCreationCallback()); 495 controller.ReserveFileQuota(items, GetFileCreationCallback());
436 EXPECT_TRUE(task); 496 EXPECT_TRUE(task);
437 EXPECT_EQ(ItemState::QUOTA_REQUESTED, items[0]->state()); 497 EXPECT_EQ(ItemState::QUOTA_REQUESTED, items[0]->state());
438 EXPECT_TRUE(file_runner_->HasPendingTask()); 498 EXPECT_TRUE(file_runner_->HasPendingTask());
439 EXPECT_EQ(0u, controller.memory_usage()); 499 EXPECT_EQ(0u, controller.memory_usage());
440 EXPECT_EQ(kBlobSize, controller.disk_usage()); 500 EXPECT_EQ(kBlobSize, controller.disk_usage());
441 501
442 task->Cancel(); 502 task->Cancel();
443 EXPECT_FALSE(task); 503 EXPECT_FALSE(task);
444 EXPECT_EQ(kBlobSize, controller.disk_usage()); 504 EXPECT_EQ(0ull, controller.disk_usage());
445 EXPECT_TRUE(file_runner_->HasPendingTask()); 505
446 RunFileThreadTasks(); 506 RunFileThreadTasks();
447 base::RunLoop().RunUntilIdle(); 507 base::RunLoop().RunUntilIdle();
448 EXPECT_EQ(0u, controller.disk_usage());
449 } 508 }
450 509
451 TEST_F(BlobMemoryControllerTest, MultipleFilesPaged) { 510 TEST_F(BlobMemoryControllerTest, MultipleFilesPaged) {
452 const std::string kId1 = "id"; 511 const std::string kId1 = "id";
453 const size_t kSize1 = kTestBlobStorageMaxFileSizeBytes; 512 const size_t kSize1 = kTestBlobStorageMaxFileSizeBytes;
454 char kData1[kSize1]; 513 char kData1[kSize1];
455 std::memset(kData1, 'e', kSize1); 514 std::memset(kData1, 'e', kSize1);
456 515
457 const std::string kId2 = "id2"; 516 const std::string kId2 = "id2";
458 const size_t kSize2 = kTestBlobStorageMaxFileSizeBytes; 517 const size_t kSize2 = kTestBlobStorageMaxFileSizeBytes;
459 char kData2[kSize2]; 518 char kData2[kSize2];
460 std::memset(kData2, 'f', kSize2); 519 std::memset(kData2, 'f', kSize2);
461 520
462 const std::string kId3 = "id3"; 521 const std::string kId3 = "id3";
463 const size_t kSize3 = kTestBlobStorageMaxBlobMemorySize - 1; 522 const size_t kSize3 = kTestBlobStorageMaxBlobMemorySize - 1;
464 523
465 // Assert we shouldn't trigger paging preemptively. 524 // Assert we shouldn't trigger paging preemptively.
466 ASSERT_LE(kSize1 + kSize2, kTestBlobStorageMaxBlobMemorySize); 525 ASSERT_LE(kSize1 + kSize2, kTestBlobStorageMaxBlobMemorySize);
467 526
468 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 527 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
469 SetTestMemoryLimits(&controller); 528 SetTestMemoryLimits(&controller);
529 AssertEnoughDiskSpace();
470 530
471 // We add two items that should be their own files when we page to disk, and 531 // 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. 532 // then add the last item to trigger the paging.
473 533
474 BlobDataBuilder builder1(kId1); 534 BlobDataBuilder builder1(kId1);
475 builder1.AppendFutureData(kSize1); 535 builder1.AppendFutureData(kSize1);
476 BlobDataBuilder builder2(kId2); 536 BlobDataBuilder builder2(kId2);
477 builder2.AppendFutureData(kSize2); 537 builder2.AppendFutureData(kSize2);
478 538
479 std::vector<scoped_refptr<ShareableBlobDataItem>> items1 = 539 std::vector<scoped_refptr<ShareableBlobDataItem>> items1 =
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 base::RunLoop().RunUntilIdle(); 596 base::RunLoop().RunUntilIdle();
537 EXPECT_TRUE(file_runner_->HasPendingTask()); 597 EXPECT_TRUE(file_runner_->HasPendingTask());
538 RunFileThreadTasks(); 598 RunFileThreadTasks();
539 base::RunLoop().RunUntilIdle(); 599 base::RunLoop().RunUntilIdle();
540 EXPECT_EQ(0u, controller.disk_usage()); 600 EXPECT_EQ(0u, controller.disk_usage());
541 } 601 }
542 602
543 TEST_F(BlobMemoryControllerTest, FullEviction) { 603 TEST_F(BlobMemoryControllerTest, FullEviction) {
544 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 604 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
545 SetTestMemoryLimits(&controller); 605 SetTestMemoryLimits(&controller);
606 AssertEnoughDiskSpace();
546 607
547 char kData[1]; 608 char kData[1];
548 kData[0] = 'e'; 609 kData[0] = 'e';
549 610
550 // Create a bunch of small stuff. 611 // Create a bunch of small stuff.
551 std::vector<scoped_refptr<ShareableBlobDataItem>> small_items; 612 std::vector<scoped_refptr<ShareableBlobDataItem>> small_items;
552 for (size_t i = 0; 613 for (size_t i = 0;
553 i < kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes; 614 i < kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes;
554 i++) { 615 i++) {
555 BlobDataBuilder builder("fake"); 616 BlobDataBuilder builder("fake");
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 EXPECT_EQ( 648 EXPECT_EQ(
588 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes, 649 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes,
589 controller.memory_usage()); 650 controller.memory_usage());
590 EXPECT_EQ( 651 EXPECT_EQ(
591 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes, 652 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes,
592 controller.disk_usage()); 653 controller.disk_usage());
593 654
594 EXPECT_TRUE(memory_quota_result_); 655 EXPECT_TRUE(memory_quota_result_);
595 } 656 }
596 657
658 TEST_F(BlobMemoryControllerTest, PagingStopsWhenFull) {
659 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
660 SetTestMemoryLimits(&controller);
661 AssertEnoughDiskSpace();
662 const size_t kTotalBlobStorageSize =
663 kTestBlobStorageMaxDiskSpace + kTestBlobStorageMaxBlobMemorySize;
664
665 const size_t kDataSize = 10u;
666 const size_t kBlobsThatCanFit = kTotalBlobStorageSize / kDataSize;
667 const size_t kNumFastBlobs = kTestBlobStorageMaxBlobMemorySize / kDataSize;
668 char kData[10];
669 memset(kData, 'e', kDataSize);
670
671 // Create all of our blobs.
672 std::vector<scoped_refptr<ShareableBlobDataItem>> all_items;
673 std::vector<base::WeakPtr<QuotaAllocationTask>> memory_tasks;
674 bool memory_requested[kBlobsThatCanFit] = {};
675 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
676 BlobDataBuilder builder("fake");
677 builder.AppendData(kData, kDataSize);
678 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
679 CreateSharedDataItems(builder);
680 EXPECT_TRUE(controller.CanReserveQuota(kDataSize));
681 EXPECT_EQ((i < kNumFastBlobs) ? Strategy::NONE_NEEDED : Strategy::IPC,
682 controller.DetermineStrategy(kDataSize, kDataSize))
683 << i;
684 base::WeakPtr<QuotaAllocationTask> memory_task =
685 controller.ReserveMemoryQuota(
686 items, GetMemoryRequestCallbackToOutput(&memory_requested[i]));
687 if (memory_task) {
688 memory_tasks.push_back(std::move(memory_task));
689 }
690 all_items.insert(all_items.end(), items.begin(), items.end());
691 }
692 // We should have stored all of our memory quota, and no disk yet.
693 EXPECT_EQ(500u, controller.memory_usage());
694 EXPECT_EQ(0ull, controller.disk_usage());
695
696 EXPECT_FALSE(controller.CanReserveQuota(1u));
697 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
698 EXPECT_FALSE(file_runner_->HasPendingTask());
699
700 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
701 EXPECT_EQ(i < kBlobsThatCanFit / 3, memory_requested[i]) << i;
702 if (memory_requested[i] &&
703 all_items[i]->state() != ItemState::POPULATED_WITH_QUOTA) {
704 EXPECT_TRUE(memory_requested[i]);
705 all_items[i]->set_state(ItemState::POPULATED_WITH_QUOTA);
706 std::vector<scoped_refptr<ShareableBlobDataItem>> temp_vector;
707 temp_vector.push_back(all_items[i]);
708 controller.NotifyMemoryItemsUsed(temp_vector);
709 }
710 }
711 EXPECT_TRUE(file_runner_->HasPendingTask());
712
713 // This will schedule one task. Paging starts as soon as there is enough
714 // memory to page, and multiple pagings can't happen at the same time.
715 EXPECT_EQ(10ull, controller.disk_usage());
716 RunFileThreadTasks();
717 base::RunLoop().RunUntilIdle();
718 // The rest of the tasks should be scheduled.
719 EXPECT_TRUE(file_runner_->HasPendingTask());
720 RunFileThreadTasks();
721 base::RunLoop().RunUntilIdle();
722 // Everything in memory should be on disk, and next batch of memory items
723 // should be granted.
724 EXPECT_EQ(500u, controller.memory_usage());
725 EXPECT_EQ(500ull, controller.disk_usage());
726
727 // Still can't add anything.
728 EXPECT_FALSE(controller.CanReserveQuota(1u));
729 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
730
731 // Flag next batch for saving to disk.
732 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
733 // Note: this can fail if the bot's disk is almost full.
734 EXPECT_EQ(i < kBlobsThatCanFit * 2 / 3, memory_requested[i]) << i;
735 if (memory_requested[i] &&
736 all_items[i]->state() != ItemState::POPULATED_WITH_QUOTA) {
737 all_items[i]->set_state(ItemState::POPULATED_WITH_QUOTA);
738 std::vector<scoped_refptr<ShareableBlobDataItem>> temp_vector;
739 temp_vector.push_back(all_items[i]);
740 controller.NotifyMemoryItemsUsed(temp_vector);
741 }
742 }
743 EXPECT_TRUE(file_runner_->HasPendingTask());
744
745 // Same as before. One page task is scheduled, so run them twice.
746 EXPECT_EQ(510ull, controller.disk_usage());
747 RunFileThreadTasks();
748 base::RunLoop().RunUntilIdle();
749 // We page one time first, as it blocks paging once it starts.
750 RunFileThreadTasks();
751 base::RunLoop().RunUntilIdle();
752
753 // All quota should be allocated.
754 EXPECT_EQ(kTestBlobStorageMaxBlobMemorySize, controller.memory_usage());
755 EXPECT_EQ(kTestBlobStorageMaxDiskSpace, controller.disk_usage());
756 EXPECT_FALSE(controller.CanReserveQuota(1u));
757 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
758
759 // Flag last batch as populated.
760 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
761 // Note: this can fail if the bot's disk is almost full.
762 EXPECT_TRUE(memory_requested[i]);
763 if (memory_requested[i] &&
764 all_items[i]->state() != ItemState::POPULATED_WITH_QUOTA) {
765 all_items[i]->set_state(ItemState::POPULATED_WITH_QUOTA);
766 std::vector<scoped_refptr<ShareableBlobDataItem>> temp_vector;
767 temp_vector.push_back(all_items[i]);
768 controller.NotifyMemoryItemsUsed(temp_vector);
769 }
770 }
771
772 // There should be no more paging to disk, as we've reached the end.
773 EXPECT_FALSE(file_runner_->HasPendingTask());
774
775 // All quota should be allocated still.
776 EXPECT_EQ(500u, controller.memory_usage());
777 EXPECT_EQ(1000ull, controller.disk_usage());
778
779 // Still can't add anything.
780 EXPECT_FALSE(controller.CanReserveQuota(1u));
781 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
782 }
783
597 TEST_F(BlobMemoryControllerTest, DisableDiskWithFileAndMemoryPending) { 784 TEST_F(BlobMemoryControllerTest, DisableDiskWithFileAndMemoryPending) {
598 const std::string kFirstMemoryId = "id"; 785 const std::string kFirstMemoryId = "id";
599 const uint64_t kFirstMemorySize = kTestBlobStorageMaxBlobMemorySize; 786 const uint64_t kFirstMemorySize = kTestBlobStorageMaxBlobMemorySize;
600 const std::string kSecondMemoryId = "id2"; 787 const std::string kSecondMemoryId = "id2";
601 const uint64_t kSecondMemorySize = 1; 788 const uint64_t kSecondMemorySize = 1;
602 const std::string kFileId = "id2"; 789 const std::string kFileId = "id2";
603 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize; 790 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
604 791
605 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 792 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
606 SetTestMemoryLimits(&controller); 793 SetTestMemoryLimits(&controller);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 857
671 file_items.clear(); 858 file_items.clear();
672 items.clear(); 859 items.clear();
673 860
674 RunFileThreadTasks(); 861 RunFileThreadTasks();
675 base::RunLoop().RunUntilIdle(); 862 base::RunLoop().RunUntilIdle();
676 863
677 EXPECT_EQ(0ull, controller.disk_usage()); 864 EXPECT_EQ(0ull, controller.disk_usage());
678 EXPECT_EQ(0ull, controller.memory_usage()); 865 EXPECT_EQ(0ull, controller.memory_usage());
679 } 866 }
867
868 TEST_F(BlobMemoryControllerTest, DiskSpaceTooSmallForItem) {
869 const std::string kFileId = "id2";
870 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
871
872 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
873 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
874
875 BlobDataBuilder file_builder(kFileId);
876 file_builder.AppendFutureFile(0, kFileBlobSize, 0);
877
878 // When we have < kFileBlobSize, then we cancel our request.
879 SetTestMemoryLimits(&controller);
880
881 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
882 CreateSharedDataItems(file_builder);
883
884 file_quota_result_ = true;
885 controller.ReserveFileQuota(items, GetFileCreationCallback());
886
887 EXPECT_TRUE(file_runner_->HasPendingTask());
888 set_disk_space(kFileBlobSize - 1);
889
890 RunFileThreadTasks();
891 ExpectDiskSpaceCalled();
892 base::RunLoop().RunUntilIdle();
893
894 EXPECT_FALSE(file_quota_result_);
895 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
896 EXPECT_EQ(0ull, controller.limits().effective_max_disk_space);
897
898 EXPECT_EQ(0ull, controller.disk_usage());
899 EXPECT_EQ(0ull, controller.memory_usage());
900 }
901
902 TEST_F(BlobMemoryControllerTest, DiskSpaceHitMinAvailable) {
903 const std::string kFileId = "id2";
904 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
905
906 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
907 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
908
909 BlobDataBuilder file_builder(kFileId);
910 file_builder.AppendFutureFile(0, kFileBlobSize, 0);
911 // When we have < limits.min_available_disk_space(), then we'll modify our
912 // effective disk space to match our current usage to stop using 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_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_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_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_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_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