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

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: build fix, adding UMA metrics Created 4 years 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/test/test_simple_task_runner.h" 12 #include "base/test/test_simple_task_runner.h"
13 #include "base/threading/thread_restrictions.h" 13 #include "base/threading/thread_restrictions.h"
14 #include "base/threading/thread_task_runner_handle.h" 14 #include "base/threading/thread_task_runner_handle.h"
15 #include "storage/browser/blob/blob_data_builder.h" 15 #include "storage/browser/blob/blob_data_builder.h"
16 #include "storage/browser/blob/blob_data_item.h" 16 #include "storage/browser/blob/blob_data_item.h"
17 #include "storage/browser/blob/shareable_blob_data_item.h" 17 #include "storage/browser/blob/shareable_blob_data_item.h"
18 #include "storage/common/data_element.h" 18 #include "storage/common/data_element.h"
19 #include "testing/gmock/include/gmock/gmock.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;
29 using ::testing::Return;
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 class MockDiskSpaceTestGetter
42 : public BlobMemoryController::DiskSpaceTestGetter {
43 public:
44 MockDiskSpaceTestGetter() {}
45 virtual ~MockDiskSpaceTestGetter() {}
46
47 MOCK_CONST_METHOD0(AmountOfFreeDiskSpace, int64_t());
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 {
(...skipping 14 matching lines...) Expand all
61 builder.items_[i], ShareableBlobDataItem::QUOTA_NEEDED))); 74 builder.items_[i], ShareableBlobDataItem::QUOTA_NEEDED)));
62 } 75 }
63 return result; 76 return result;
64 } 77 }
65 78
66 void SetTestMemoryLimits(BlobMemoryController* controller) { 79 void SetTestMemoryLimits(BlobMemoryController* controller) {
67 BlobStorageLimits limits; 80 BlobStorageLimits limits;
68 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes; 81 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
69 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes; 82 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
70 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize; 83 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
71 limits.max_blob_disk_space = kTestBlobStorageMaxDiskSpace; 84 limits.desired_max_disk_space = kTestBlobStorageMaxDiskSpace;
85 limits.effective_max_disk_space = kTestBlobStorageMaxDiskSpace;
72 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes; 86 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
73 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes; 87 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
74 controller->set_limits_for_testing(limits); 88 controller->set_limits_for_testing(limits);
89 }
90
91 void SetSmallDiskTestMemoryLimits(BlobMemoryController* controller) {
92 BlobStorageLimits limits;
93 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
94 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
95 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
96 limits.desired_max_disk_space = kTestSmallBlobStorageMaxDiskSpace;
97 limits.effective_max_disk_space = kTestSmallBlobStorageMaxDiskSpace;
98 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
99 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
100 controller->set_limits_for_testing(limits);
75 } 101 }
76 102
77 void SaveFileCreationInfo(std::vector<FileCreationInfo> info, bool success) { 103 void SaveFileCreationInfo(std::vector<FileCreationInfo> info, bool success) {
78 file_quota_result_ = success; 104 file_quota_result_ = success;
79 if (success) { 105 if (success) {
80 files_created_.swap(info); 106 files_created_.swap(info);
81 } 107 }
82 } 108 }
83 109
110 void SaveMemoryRequestToOutput(bool* output, bool success) {
111 ASSERT_TRUE(output);
112 *output = success;
113 }
84 void SaveMemoryRequest(bool success) { memory_quota_result_ = success; } 114 void SaveMemoryRequest(bool success) { memory_quota_result_ = success; }
85 115
86 BlobMemoryController::FileQuotaRequestCallback GetFileCreationCallback() { 116 BlobMemoryController::FileQuotaRequestCallback GetFileCreationCallback() {
87 return base::Bind(&BlobMemoryControllerTest::SaveFileCreationInfo, 117 return base::Bind(&BlobMemoryControllerTest::SaveFileCreationInfo,
88 base::Unretained(this)); 118 base::Unretained(this));
89 } 119 }
90 120
91 BlobMemoryController::MemoryQuotaRequestCallback GetMemoryRequestCallback() { 121 BlobMemoryController::MemoryQuotaRequestCallback GetMemoryRequestCallback() {
92 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequest, 122 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequest,
93 base::Unretained(this)); 123 base::Unretained(this));
94 } 124 }
95 125
126 BlobMemoryController::MemoryQuotaRequestCallback
127 GetMemoryRequestCallbackToOutput(bool* output) {
128 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequestToOutput,
129 base::Unretained(this), output);
130 }
131
96 void RunFileThreadTasks() { 132 void RunFileThreadTasks() {
97 base::ThreadRestrictions::SetIOAllowed(true); 133 base::ThreadRestrictions::SetIOAllowed(true);
98 file_runner_->RunPendingTasks(); 134 file_runner_->RunPendingTasks();
99 base::ThreadRestrictions::SetIOAllowed(false); 135 base::ThreadRestrictions::SetIOAllowed(false);
100 } 136 }
101 137
102 bool HasMemoryAllocation(ShareableBlobDataItem* item) { 138 bool HasMemoryAllocation(ShareableBlobDataItem* item) {
103 return static_cast<bool>(item->memory_allocation_); 139 return static_cast<bool>(item->memory_allocation_);
104 } 140 }
105 141
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 0, kTestBlobStorageMaxBlobMemorySize - 188 0, kTestBlobStorageMaxBlobMemorySize -
153 kTestBlobStorageMinFileSizeBytes + 1)); 189 kTestBlobStorageMinFileSizeBytes + 1));
154 190
155 EXPECT_EQ(Strategy::FILE, controller.DetermineStrategy( 191 EXPECT_EQ(Strategy::FILE, controller.DetermineStrategy(
156 0, kTestBlobStorageMaxBlobMemorySize)); 192 0, kTestBlobStorageMaxBlobMemorySize));
157 193
158 // Too large for disk. 194 // Too large for disk.
159 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy( 195 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(
160 0, kTestBlobStorageMaxDiskSpace + 1)); 196 0, kTestBlobStorageMaxDiskSpace + 1));
161 } 197 }
198 {
199 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
200 SetSmallDiskTestMemoryLimits(&controller);
201
202 EXPECT_TRUE(controller.CanReserveQuota(kTestBlobStorageMaxBlobMemorySize));
203 // Since our disk is too small, this should be sent with shared memory.
204 EXPECT_EQ(
205 Strategy::SHARED_MEMORY,
206 controller.DetermineStrategy(0, kTestBlobStorageMaxBlobMemorySize));
207 }
162 } 208 }
163 209
164 TEST_F(BlobMemoryControllerTest, GrantMemory) { 210 TEST_F(BlobMemoryControllerTest, GrantMemory) {
165 const std::string kId = "id"; 211 const std::string kId = "id";
166 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 212 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
167 SetTestMemoryLimits(&controller); 213 SetTestMemoryLimits(&controller);
168 214
169 BlobDataBuilder builder(kId); 215 BlobDataBuilder builder(kId);
170 builder.AppendFutureData(10); 216 builder.AppendFutureData(10);
171 builder.AppendFutureData(20); 217 builder.AppendFutureData(20);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 items2.clear(); 320 items2.clear();
275 EXPECT_EQ(0u, controller.memory_usage()); 321 EXPECT_EQ(0u, controller.memory_usage());
276 items.clear(); 322 items.clear();
277 EXPECT_TRUE(file_runner_->HasPendingTask()); 323 EXPECT_TRUE(file_runner_->HasPendingTask());
278 RunFileThreadTasks(); 324 RunFileThreadTasks();
279 base::RunLoop().RunUntilIdle(); 325 base::RunLoop().RunUntilIdle();
280 EXPECT_EQ(0u, controller.disk_usage()); 326 EXPECT_EQ(0u, controller.disk_usage());
281 } 327 }
282 328
283 TEST_F(BlobMemoryControllerTest, NoDiskTooLarge) { 329 TEST_F(BlobMemoryControllerTest, NoDiskTooLarge) {
284 const std::string kId = "id";
285 BlobMemoryController controller(temp_dir_.GetPath(), nullptr); 330 BlobMemoryController controller(temp_dir_.GetPath(), nullptr);
286 SetTestMemoryLimits(&controller); 331 SetTestMemoryLimits(&controller);
287 332
288 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxBlobMemorySize + 333 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxBlobMemorySize +
289 kTestBlobStorageMinFileSizeBytes + 334 kTestBlobStorageMinFileSizeBytes +
290 1)); 335 1));
291 } 336 }
292 337
293 TEST_F(BlobMemoryControllerTest, TooLargeForDisk) { 338 TEST_F(BlobMemoryControllerTest, TooLargeForDisk) {
294 const std::string kId = "id";
295 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 339 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
296 SetTestMemoryLimits(&controller); 340 SetTestMemoryLimits(&controller);
297 341
298 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxDiskSpace + 1)); 342 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxDiskSpace + 1));
299 } 343 }
300 344
301 TEST_F(BlobMemoryControllerTest, CancelMemoryRequest) { 345 TEST_F(BlobMemoryControllerTest, CancelMemoryRequest) {
302 const std::string kId = "id"; 346 const std::string kId = "id";
303 const std::string kId2 = "id2"; 347 const std::string kId2 = "id2";
304 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 348 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 base::WeakPtr<QuotaAllocationTask> task = 478 base::WeakPtr<QuotaAllocationTask> task =
435 controller.ReserveFileQuota(items, GetFileCreationCallback()); 479 controller.ReserveFileQuota(items, GetFileCreationCallback());
436 EXPECT_TRUE(task); 480 EXPECT_TRUE(task);
437 EXPECT_EQ(ItemState::QUOTA_REQUESTED, items[0]->state()); 481 EXPECT_EQ(ItemState::QUOTA_REQUESTED, items[0]->state());
438 EXPECT_TRUE(file_runner_->HasPendingTask()); 482 EXPECT_TRUE(file_runner_->HasPendingTask());
439 EXPECT_EQ(0u, controller.memory_usage()); 483 EXPECT_EQ(0u, controller.memory_usage());
440 EXPECT_EQ(kBlobSize, controller.disk_usage()); 484 EXPECT_EQ(kBlobSize, controller.disk_usage());
441 485
442 task->Cancel(); 486 task->Cancel();
443 EXPECT_FALSE(task); 487 EXPECT_FALSE(task);
444 EXPECT_EQ(kBlobSize, controller.disk_usage()); 488 EXPECT_EQ(0ull, controller.disk_usage());
445 EXPECT_TRUE(file_runner_->HasPendingTask()); 489
446 RunFileThreadTasks(); 490 RunFileThreadTasks();
447 base::RunLoop().RunUntilIdle(); 491 base::RunLoop().RunUntilIdle();
448 EXPECT_EQ(0u, controller.disk_usage());
449 } 492 }
450 493
451 TEST_F(BlobMemoryControllerTest, MultipleFilesPaged) { 494 TEST_F(BlobMemoryControllerTest, MultipleFilesPaged) {
452 const std::string kId1 = "id"; 495 const std::string kId1 = "id";
453 const size_t kSize1 = kTestBlobStorageMaxFileSizeBytes; 496 const size_t kSize1 = kTestBlobStorageMaxFileSizeBytes;
454 char kData1[kSize1]; 497 char kData1[kSize1];
455 std::memset(kData1, 'e', kSize1); 498 std::memset(kData1, 'e', kSize1);
456 499
457 const std::string kId2 = "id2"; 500 const std::string kId2 = "id2";
458 const size_t kSize2 = kTestBlobStorageMaxFileSizeBytes; 501 const size_t kSize2 = kTestBlobStorageMaxFileSizeBytes;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 EXPECT_EQ( 630 EXPECT_EQ(
588 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes, 631 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes,
589 controller.memory_usage()); 632 controller.memory_usage());
590 EXPECT_EQ( 633 EXPECT_EQ(
591 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes, 634 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes,
592 controller.disk_usage()); 635 controller.disk_usage());
593 636
594 EXPECT_TRUE(memory_quota_result_); 637 EXPECT_TRUE(memory_quota_result_);
595 } 638 }
596 639
640 TEST_F(BlobMemoryControllerTest, PagingStopsWhenFull) {
641 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
642 SetTestMemoryLimits(&controller);
643 const size_t kTotalBlobStorageSize =
644 kTestBlobStorageMaxDiskSpace + kTestBlobStorageMaxBlobMemorySize;
645
646 const size_t kDataSize = 10u;
647 const size_t kBlobsThatCanFit = kTotalBlobStorageSize / kDataSize;
648 const size_t kNumFastBlobs = kTestBlobStorageMaxBlobMemorySize / kDataSize;
649 char kData[10];
650 memset(kData, 'e', kDataSize);
651
652 // Create all of our blobs.
653 std::vector<scoped_refptr<ShareableBlobDataItem>> all_items;
654 std::vector<base::WeakPtr<QuotaAllocationTask>> memory_tasks;
655 bool memory_requested[kBlobsThatCanFit] = {};
656 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
657 BlobDataBuilder builder("fake");
658 builder.AppendData(kData, kDataSize);
659 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
660 CreateSharedDataItems(builder);
661 EXPECT_TRUE(controller.CanReserveQuota(kDataSize));
662 EXPECT_EQ((i < kNumFastBlobs) ? Strategy::NONE_NEEDED : Strategy::IPC,
663 controller.DetermineStrategy(kDataSize, kDataSize))
664 << i;
665 base::WeakPtr<QuotaAllocationTask> memory_task =
666 controller.ReserveMemoryQuota(
667 items, GetMemoryRequestCallbackToOutput(memory_requested + i));
668 if (memory_task) {
669 memory_tasks.push_back(std::move(memory_task));
670 }
671 all_items.insert(all_items.end(), items.begin(), items.end());
672 }
673 // We should have stored all of our memory quota, and no disk yet.
674 EXPECT_EQ(500u, controller.memory_usage());
675 EXPECT_EQ(0ull, controller.disk_usage());
676
677 EXPECT_FALSE(controller.CanReserveQuota(1u));
678 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
679 EXPECT_FALSE(file_runner_->HasPendingTask());
680
681 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
682 // Note: this can fail if the bot's disk is almost full.
683 EXPECT_EQ(i < kBlobsThatCanFit / 3, memory_requested[i]) << i;
684 if (memory_requested[i] &&
685 all_items[i]->state() != ItemState::POPULATED_WITH_QUOTA) {
686 EXPECT_TRUE(memory_requested[i]);
687 all_items[i]->set_state(ItemState::POPULATED_WITH_QUOTA);
688 std::vector<scoped_refptr<ShareableBlobDataItem>> temp_vector;
689 temp_vector.push_back(all_items[i]);
690 controller.NotifyMemoryItemsUsed(temp_vector);
691 }
692 }
693 EXPECT_TRUE(file_runner_->HasPendingTask());
694
695 // This will schedule one task. Paging starts as soon as there is enough
696 // memory to page, and multiple pagings can't happen at the same time.
697 EXPECT_EQ(10ull, controller.disk_usage());
698 RunFileThreadTasks();
699 base::RunLoop().RunUntilIdle();
700 // The rest of the tasks should be scheduled.
701 EXPECT_TRUE(file_runner_->HasPendingTask());
702 RunFileThreadTasks();
703 base::RunLoop().RunUntilIdle();
704 // Everything in memory should be on disk, and next batch of memory items
705 // should be granted.
706 EXPECT_EQ(500u, controller.memory_usage());
707 EXPECT_EQ(500ull, controller.disk_usage());
708
709 // Still can't add anything.
710 EXPECT_FALSE(controller.CanReserveQuota(1u));
711 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
712
713 // Flag next batch for saving to disk.
714 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
715 // Note: this can fail if the bot's disk is almost full.
716 EXPECT_EQ(i < kBlobsThatCanFit * 2 / 3, memory_requested[i]) << i;
717 if (memory_requested[i] &&
718 all_items[i]->state() != ItemState::POPULATED_WITH_QUOTA) {
719 all_items[i]->set_state(ItemState::POPULATED_WITH_QUOTA);
720 std::vector<scoped_refptr<ShareableBlobDataItem>> temp_vector;
721 temp_vector.push_back(all_items[i]);
722 controller.NotifyMemoryItemsUsed(temp_vector);
723 }
724 }
725 EXPECT_TRUE(file_runner_->HasPendingTask());
726
727 // Same as before. One page task is scheduled, so run them twice.
728 EXPECT_EQ(510ull, controller.disk_usage());
729 RunFileThreadTasks();
730 base::RunLoop().RunUntilIdle();
731 // We page one time first, as it blocks paging once it starts.
732 RunFileThreadTasks();
733 base::RunLoop().RunUntilIdle();
734
735 // All quota should be allocated.
736 EXPECT_EQ(500u, controller.memory_usage());
737 EXPECT_EQ(1000ull, controller.disk_usage());
738
739 // Still can't add anything.
740 EXPECT_FALSE(controller.CanReserveQuota(1u));
741 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
742
743 // Flag last batch as populated.
744 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
745 // Note: this can fail if the bot's disk is almost full.
746 EXPECT_TRUE(memory_requested[i]);
747 if (memory_requested[i] &&
748 all_items[i]->state() != ItemState::POPULATED_WITH_QUOTA) {
749 all_items[i]->set_state(ItemState::POPULATED_WITH_QUOTA);
750 std::vector<scoped_refptr<ShareableBlobDataItem>> temp_vector;
751 temp_vector.push_back(all_items[i]);
752 controller.NotifyMemoryItemsUsed(temp_vector);
753 }
754 }
755
756 // There should be no more paging to disk, as we've reached the end.
757 EXPECT_FALSE(file_runner_->HasPendingTask());
758
759 // All quota should be allocated still.
760 EXPECT_EQ(500u, controller.memory_usage());
761 EXPECT_EQ(1000ull, controller.disk_usage());
762
763 // Still can't add anything.
764 EXPECT_FALSE(controller.CanReserveQuota(1u));
765 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
766 EXPECT_FALSE(file_runner_->HasPendingTask());
767 }
768
597 TEST_F(BlobMemoryControllerTest, DisableDiskWithFileAndMemoryPending) { 769 TEST_F(BlobMemoryControllerTest, DisableDiskWithFileAndMemoryPending) {
598 const std::string kFirstMemoryId = "id"; 770 const std::string kFirstMemoryId = "id";
599 const uint64_t kFirstMemorySize = kTestBlobStorageMaxBlobMemorySize; 771 const uint64_t kFirstMemorySize = kTestBlobStorageMaxBlobMemorySize;
600 const std::string kSecondMemoryId = "id2"; 772 const std::string kSecondMemoryId = "id2";
601 const uint64_t kSecondMemorySize = 1; 773 const uint64_t kSecondMemorySize = 1;
602 const std::string kFileId = "id2"; 774 const std::string kFileId = "id2";
603 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize; 775 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
604 776
605 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 777 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
606 SetTestMemoryLimits(&controller); 778 SetTestMemoryLimits(&controller);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 842
671 file_items.clear(); 843 file_items.clear();
672 items.clear(); 844 items.clear();
673 845
674 RunFileThreadTasks(); 846 RunFileThreadTasks();
675 base::RunLoop().RunUntilIdle(); 847 base::RunLoop().RunUntilIdle();
676 848
677 EXPECT_EQ(0ull, controller.disk_usage()); 849 EXPECT_EQ(0ull, controller.disk_usage());
678 EXPECT_EQ(0ull, controller.memory_usage()); 850 EXPECT_EQ(0ull, controller.memory_usage());
679 } 851 }
852
853 TEST_F(BlobMemoryControllerTest, MemoryPressureAndReset) {
854 const std::string kFileId = "id2";
855 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
856
857 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
858 MockDiskSpaceTestGetter mock_disk_space;
859 controller.set_testing_disk_space(&mock_disk_space);
860
861 BlobDataBuilder file_builder(kFileId);
862 file_builder.AppendFutureFile(0, kFileBlobSize, 0);
863
864 // 1. When we have < kFileBlobSize, then we cancel our request.
865 {
866 SetTestMemoryLimits(&controller);
867
868 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
869 CreateSharedDataItems(file_builder);
870
871 file_quota_result_ = true;
872 controller.ReserveFileQuota(items, GetFileCreationCallback());
873
874 EXPECT_TRUE(file_runner_->HasPendingTask());
875 EXPECT_CALL(mock_disk_space, AmountOfFreeDiskSpace())
Marijn Kruisselbrink 2016/12/21 17:40:36 It seems a bit overkill to use gmock for this... Y
dmurph 2016/12/21 22:27:58 Done.
876 .WillOnce(Return(kFileBlobSize - 1));
877
878 RunFileThreadTasks();
879 base::RunLoop().RunUntilIdle();
880
881 EXPECT_FALSE(file_quota_result_);
882 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
883 EXPECT_EQ(0ull, controller.limits().effective_max_disk_space);
884
885 EXPECT_EQ(0ull, controller.disk_usage());
886 EXPECT_EQ(0ull, controller.memory_usage());
887 }
888
889 // 2. When we have < limits.min_available_disk_space(), then we'll modify our
Marijn Kruisselbrink 2016/12/21 17:40:36 It's not quite clear to me what if any the depende
dmurph 2016/12/21 22:27:58 Sounds good, done.
890 // effective disk space to match our current usage to stop using more disk.
891 {
892 SetTestMemoryLimits(&controller);
893
894 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
895 CreateSharedDataItems(file_builder);
896
897 file_quota_result_ = false;
898 controller.ReserveFileQuota(items, GetFileCreationCallback());
899
900 EXPECT_TRUE(file_runner_->HasPendingTask());
901 EXPECT_CALL(mock_disk_space, AmountOfFreeDiskSpace())
902 .WillOnce(Return(controller.limits().min_available_disk_space() - 1));
903
904 RunFileThreadTasks();
905 base::RunLoop().RunUntilIdle();
906
907 EXPECT_TRUE(file_quota_result_);
908 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
909 EXPECT_EQ(kFileBlobSize, controller.limits().effective_max_disk_space);
910
911 items.clear();
912 files_created_.clear();
913
914 RunFileThreadTasks();
915 base::RunLoop().RunUntilIdle();
916
917 EXPECT_EQ(0ull, controller.disk_usage());
918 EXPECT_EQ(0ull, controller.memory_usage());
919 }
920
921 // 3. When our desired total disk space is less than we're allowed given the
922 // minimum disk availability, we shorten the disk space.
923 {
924 SetTestMemoryLimits(&controller);
925
926 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
927 CreateSharedDataItems(file_builder);
928
929 file_quota_result_ = false;
930 controller.ReserveFileQuota(items, GetFileCreationCallback());
931
932 EXPECT_TRUE(file_runner_->HasPendingTask());
933 EXPECT_CALL(mock_disk_space, AmountOfFreeDiskSpace())
934 .WillOnce(Return(controller.limits().desired_max_disk_space +
935 controller.limits().min_available_disk_space() - 1));
936
937 RunFileThreadTasks();
938 base::RunLoop().RunUntilIdle();
939
940 EXPECT_TRUE(file_quota_result_);
941 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
942 EXPECT_EQ(controller.limits().desired_max_disk_space - 1,
943 controller.limits().effective_max_disk_space);
944
945 items.clear();
946 files_created_.clear();
947
948 RunFileThreadTasks();
949 base::RunLoop().RunUntilIdle();
950
951 EXPECT_EQ(0ull, controller.disk_usage());
952 EXPECT_EQ(0ull, controller.memory_usage());
953 }
954
955 // 4. When we do a file operation after disk has been freed (after we've been
956 // limited), our effective size grows correctly.
957 {
958 SetTestMemoryLimits(&controller);
959
960 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
961 CreateSharedDataItems(file_builder);
962
963 controller.ReserveFileQuota(items, GetFileCreationCallback());
964
965 EXPECT_TRUE(file_runner_->HasPendingTask());
966 EXPECT_CALL(mock_disk_space, AmountOfFreeDiskSpace())
967 .WillOnce(Return(controller.limits().min_available_disk_space() - 1));
968
969 RunFileThreadTasks();
970 base::RunLoop().RunUntilIdle();
971
972 // Check the effective limit is constrained.
973 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
974 EXPECT_EQ(kFileBlobSize, controller.limits().effective_max_disk_space);
975
976 // Delete the item so we have disk quota.
977 items.clear();
978 files_created_.clear();
979
980 RunFileThreadTasks();
981 base::RunLoop().RunUntilIdle();
982
983 EXPECT_EQ(0ull, controller.disk_usage());
984 EXPECT_EQ(0ull, controller.memory_usage());
985
986 // Create the same item, but have the disk space report the minimum amount
987 // needed to have the desired disk size.
988 items = CreateSharedDataItems(file_builder);
989
990 controller.ReserveFileQuota(items, GetFileCreationCallback());
991
992 EXPECT_TRUE(file_runner_->HasPendingTask());
993 EXPECT_CALL(mock_disk_space, AmountOfFreeDiskSpace())
994 .WillOnce(Return(kTestBlobStorageMaxDiskSpace +
995 controller.limits().min_available_disk_space()));
996
997 RunFileThreadTasks();
998 base::RunLoop().RunUntilIdle();
999
1000 EXPECT_FALSE(controller.limits().IsDiskSpaceConstrained());
1001 EXPECT_EQ(controller.limits().desired_max_disk_space,
1002 controller.limits().effective_max_disk_space);
1003
1004 items.clear();
1005 files_created_.clear();
1006
1007 RunFileThreadTasks();
1008 base::RunLoop().RunUntilIdle();
1009
1010 EXPECT_EQ(0ull, controller.disk_usage());
1011 EXPECT_EQ(0ull, controller.memory_usage());
1012 }
1013 }
680 } // namespace storage 1014 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698