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

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: Disk space getter is now a func ptr 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/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;
30 using ::testing::StrictMock;
pwnall 2017/01/07 00:46:21 Is this used anywhere? I don't see it in the diff.
dmurph 2017/01/07 02:26:26 Done.
28 31
29 const std::string kBlobStorageDirectory = "blob_storage"; 32 const std::string kBlobStorageDirectory = "blob_storage";
30 const size_t kTestBlobStorageIPCThresholdBytes = 20; 33 const size_t kTestBlobStorageIPCThresholdBytes = 20;
31 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50; 34 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50;
32 const size_t kTestBlobStorageMaxBlobMemorySize = 500; 35 const size_t kTestBlobStorageMaxBlobMemorySize = 500;
33 const uint64_t kTestBlobStorageMaxDiskSpace = 1000; 36 const uint64_t kTestBlobStorageMaxDiskSpace = 1000;
34 const uint64_t kTestBlobStorageMinFileSizeBytes = 10; 37 const uint64_t kTestBlobStorageMinFileSizeBytes = 10;
35 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100; 38 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
36 39
40 const uint64_t kTestSmallBlobStorageMaxDiskSpace = 100;
41
42 static int64_t sFakeDiskSpace = 0;
43 static bool sFakeDiskSpaceCalled = true;
44
45 int64_t FakeDiskSpaceMethod(const base::FilePath& path) {
46 EXPECT_FALSE(sFakeDiskSpaceCalled);
47 sFakeDiskSpaceCalled = true;
48 return sFakeDiskSpace;
49 }
50
37 class BlobMemoryControllerTest : public testing::Test { 51 class BlobMemoryControllerTest : public testing::Test {
38 protected: 52 protected:
39 BlobMemoryControllerTest() {} 53 BlobMemoryControllerTest() {}
40 54
41 void SetUp() override { 55 void SetUp() override {
42 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 56 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
43 base::ThreadRestrictions::SetIOAllowed(false); 57 base::ThreadRestrictions::SetIOAllowed(false);
44 }; 58 };
45 59
46 void TearDown() override { 60 void TearDown() override {
(...skipping 14 matching lines...) Expand all
61 builder.items_[i], ShareableBlobDataItem::QUOTA_NEEDED))); 75 builder.items_[i], ShareableBlobDataItem::QUOTA_NEEDED)));
62 } 76 }
63 return result; 77 return result;
64 } 78 }
65 79
66 void SetTestMemoryLimits(BlobMemoryController* controller) { 80 void SetTestMemoryLimits(BlobMemoryController* controller) {
67 BlobStorageLimits limits; 81 BlobStorageLimits limits;
68 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes; 82 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
69 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes; 83 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
70 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize; 84 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
71 limits.max_blob_disk_space = kTestBlobStorageMaxDiskSpace; 85 limits.desired_max_disk_space = kTestBlobStorageMaxDiskSpace;
86 limits.effective_max_disk_space = kTestBlobStorageMaxDiskSpace;
72 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes; 87 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
73 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes; 88 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
74 controller->set_limits_for_testing(limits); 89 controller->set_limits_for_testing(limits);
90 }
91
92 void SetSmallDiskTestMemoryLimits(BlobMemoryController* controller) {
93 BlobStorageLimits limits;
94 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
95 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
96 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
97 limits.desired_max_disk_space = kTestSmallBlobStorageMaxDiskSpace;
98 limits.effective_max_disk_space = kTestSmallBlobStorageMaxDiskSpace;
99 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
100 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
101 controller->set_limits_for_testing(limits);
75 } 102 }
76 103
77 void SaveFileCreationInfo(std::vector<FileCreationInfo> info, bool success) { 104 void SaveFileCreationInfo(std::vector<FileCreationInfo> info, bool success) {
78 file_quota_result_ = success; 105 file_quota_result_ = success;
79 if (success) { 106 if (success) {
80 files_created_.swap(info); 107 files_created_.swap(info);
81 } 108 }
82 } 109 }
83 110
111 void SaveMemoryRequestToOutput(bool* output, bool success) {
112 ASSERT_TRUE(output);
113 *output = success;
114 }
84 void SaveMemoryRequest(bool success) { memory_quota_result_ = success; } 115 void SaveMemoryRequest(bool success) { memory_quota_result_ = success; }
85 116
86 BlobMemoryController::FileQuotaRequestCallback GetFileCreationCallback() { 117 BlobMemoryController::FileQuotaRequestCallback GetFileCreationCallback() {
87 return base::Bind(&BlobMemoryControllerTest::SaveFileCreationInfo, 118 return base::Bind(&BlobMemoryControllerTest::SaveFileCreationInfo,
88 base::Unretained(this)); 119 base::Unretained(this));
89 } 120 }
90 121
91 BlobMemoryController::MemoryQuotaRequestCallback GetMemoryRequestCallback() { 122 BlobMemoryController::MemoryQuotaRequestCallback GetMemoryRequestCallback() {
92 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequest, 123 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequest,
93 base::Unretained(this)); 124 base::Unretained(this));
94 } 125 }
95 126
127 BlobMemoryController::MemoryQuotaRequestCallback
128 GetMemoryRequestCallbackToOutput(bool* output) {
129 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequestToOutput,
130 base::Unretained(this), output);
131 }
132
96 void RunFileThreadTasks() { 133 void RunFileThreadTasks() {
97 base::ThreadRestrictions::SetIOAllowed(true); 134 base::ThreadRestrictions::SetIOAllowed(true);
98 file_runner_->RunPendingTasks(); 135 file_runner_->RunPendingTasks();
99 base::ThreadRestrictions::SetIOAllowed(false); 136 base::ThreadRestrictions::SetIOAllowed(false);
100 } 137 }
101 138
102 bool HasMemoryAllocation(ShareableBlobDataItem* item) { 139 bool HasMemoryAllocation(ShareableBlobDataItem* item) {
103 return static_cast<bool>(item->memory_allocation_); 140 return static_cast<bool>(item->memory_allocation_);
104 } 141 }
105 142
143 void set_disk_space(int64_t space) {
144 sFakeDiskSpaceCalled = false;
145 sFakeDiskSpace = space;
146 }
147
148 void ExpectDiskSpaceCalled() {
149 EXPECT_TRUE(sFakeDiskSpaceCalled);
150 }
151
106 bool file_quota_result_ = false; 152 bool file_quota_result_ = false;
107 base::ScopedTempDir temp_dir_; 153 base::ScopedTempDir temp_dir_;
108 std::vector<FileCreationInfo> files_created_; 154 std::vector<FileCreationInfo> files_created_;
109 bool memory_quota_result_ = false; 155 bool memory_quota_result_ = false;
110 156
111 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner(); 157 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
112 158
113 base::MessageLoop fake_io_message_loop_; 159 base::MessageLoop fake_io_message_loop_;
114 }; 160 };
115 161
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 0, kTestBlobStorageMaxBlobMemorySize - 198 0, kTestBlobStorageMaxBlobMemorySize -
153 kTestBlobStorageMinFileSizeBytes + 1)); 199 kTestBlobStorageMinFileSizeBytes + 1));
154 200
155 EXPECT_EQ(Strategy::FILE, controller.DetermineStrategy( 201 EXPECT_EQ(Strategy::FILE, controller.DetermineStrategy(
156 0, kTestBlobStorageMaxBlobMemorySize)); 202 0, kTestBlobStorageMaxBlobMemorySize));
157 203
158 // Too large for disk. 204 // Too large for disk.
159 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy( 205 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(
160 0, kTestBlobStorageMaxDiskSpace + 1)); 206 0, kTestBlobStorageMaxDiskSpace + 1));
161 } 207 }
208 {
209 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
210 SetSmallDiskTestMemoryLimits(&controller);
211
212 EXPECT_TRUE(controller.CanReserveQuota(kTestBlobStorageMaxBlobMemorySize));
213 // Since our disk is too small, this should be sent with shared memory.
214 EXPECT_EQ(
215 Strategy::SHARED_MEMORY,
216 controller.DetermineStrategy(0, kTestBlobStorageMaxBlobMemorySize));
217 }
162 } 218 }
163 219
164 TEST_F(BlobMemoryControllerTest, GrantMemory) { 220 TEST_F(BlobMemoryControllerTest, GrantMemory) {
165 const std::string kId = "id"; 221 const std::string kId = "id";
166 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 222 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
167 SetTestMemoryLimits(&controller); 223 SetTestMemoryLimits(&controller);
168 224
169 BlobDataBuilder builder(kId); 225 BlobDataBuilder builder(kId);
170 builder.AppendFutureData(10); 226 builder.AppendFutureData(10);
171 builder.AppendFutureData(20); 227 builder.AppendFutureData(20);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 items2.clear(); 330 items2.clear();
275 EXPECT_EQ(0u, controller.memory_usage()); 331 EXPECT_EQ(0u, controller.memory_usage());
276 items.clear(); 332 items.clear();
277 EXPECT_TRUE(file_runner_->HasPendingTask()); 333 EXPECT_TRUE(file_runner_->HasPendingTask());
278 RunFileThreadTasks(); 334 RunFileThreadTasks();
279 base::RunLoop().RunUntilIdle(); 335 base::RunLoop().RunUntilIdle();
280 EXPECT_EQ(0u, controller.disk_usage()); 336 EXPECT_EQ(0u, controller.disk_usage());
281 } 337 }
282 338
283 TEST_F(BlobMemoryControllerTest, NoDiskTooLarge) { 339 TEST_F(BlobMemoryControllerTest, NoDiskTooLarge) {
284 const std::string kId = "id";
285 BlobMemoryController controller(temp_dir_.GetPath(), nullptr); 340 BlobMemoryController controller(temp_dir_.GetPath(), nullptr);
286 SetTestMemoryLimits(&controller); 341 SetTestMemoryLimits(&controller);
287 342
288 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxBlobMemorySize + 343 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxBlobMemorySize +
289 kTestBlobStorageMinFileSizeBytes + 344 kTestBlobStorageMinFileSizeBytes +
290 1)); 345 1));
291 } 346 }
292 347
293 TEST_F(BlobMemoryControllerTest, TooLargeForDisk) { 348 TEST_F(BlobMemoryControllerTest, TooLargeForDisk) {
294 const std::string kId = "id";
295 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 349 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
296 SetTestMemoryLimits(&controller); 350 SetTestMemoryLimits(&controller);
297 351
298 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxDiskSpace + 1)); 352 EXPECT_FALSE(controller.CanReserveQuota(kTestBlobStorageMaxDiskSpace + 1));
299 } 353 }
300 354
301 TEST_F(BlobMemoryControllerTest, CancelMemoryRequest) { 355 TEST_F(BlobMemoryControllerTest, CancelMemoryRequest) {
302 const std::string kId = "id"; 356 const std::string kId = "id";
303 const std::string kId2 = "id2"; 357 const std::string kId2 = "id2";
304 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 358 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 base::WeakPtr<QuotaAllocationTask> task = 488 base::WeakPtr<QuotaAllocationTask> task =
435 controller.ReserveFileQuota(items, GetFileCreationCallback()); 489 controller.ReserveFileQuota(items, GetFileCreationCallback());
436 EXPECT_TRUE(task); 490 EXPECT_TRUE(task);
437 EXPECT_EQ(ItemState::QUOTA_REQUESTED, items[0]->state()); 491 EXPECT_EQ(ItemState::QUOTA_REQUESTED, items[0]->state());
438 EXPECT_TRUE(file_runner_->HasPendingTask()); 492 EXPECT_TRUE(file_runner_->HasPendingTask());
439 EXPECT_EQ(0u, controller.memory_usage()); 493 EXPECT_EQ(0u, controller.memory_usage());
440 EXPECT_EQ(kBlobSize, controller.disk_usage()); 494 EXPECT_EQ(kBlobSize, controller.disk_usage());
441 495
442 task->Cancel(); 496 task->Cancel();
443 EXPECT_FALSE(task); 497 EXPECT_FALSE(task);
444 EXPECT_EQ(kBlobSize, controller.disk_usage()); 498 EXPECT_EQ(0ull, controller.disk_usage());
445 EXPECT_TRUE(file_runner_->HasPendingTask()); 499
446 RunFileThreadTasks(); 500 RunFileThreadTasks();
447 base::RunLoop().RunUntilIdle(); 501 base::RunLoop().RunUntilIdle();
448 EXPECT_EQ(0u, controller.disk_usage());
449 } 502 }
450 503
451 TEST_F(BlobMemoryControllerTest, MultipleFilesPaged) { 504 TEST_F(BlobMemoryControllerTest, MultipleFilesPaged) {
452 const std::string kId1 = "id"; 505 const std::string kId1 = "id";
453 const size_t kSize1 = kTestBlobStorageMaxFileSizeBytes; 506 const size_t kSize1 = kTestBlobStorageMaxFileSizeBytes;
454 char kData1[kSize1]; 507 char kData1[kSize1];
455 std::memset(kData1, 'e', kSize1); 508 std::memset(kData1, 'e', kSize1);
456 509
457 const std::string kId2 = "id2"; 510 const std::string kId2 = "id2";
458 const size_t kSize2 = kTestBlobStorageMaxFileSizeBytes; 511 const size_t kSize2 = kTestBlobStorageMaxFileSizeBytes;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 EXPECT_EQ( 640 EXPECT_EQ(
588 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes, 641 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes,
589 controller.memory_usage()); 642 controller.memory_usage());
590 EXPECT_EQ( 643 EXPECT_EQ(
591 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes, 644 kTestBlobStorageMaxBlobMemorySize - kTestBlobStorageMinFileSizeBytes,
592 controller.disk_usage()); 645 controller.disk_usage());
593 646
594 EXPECT_TRUE(memory_quota_result_); 647 EXPECT_TRUE(memory_quota_result_);
595 } 648 }
596 649
650 TEST_F(BlobMemoryControllerTest, PagingStopsWhenFull) {
651 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
652 SetTestMemoryLimits(&controller);
653 const size_t kTotalBlobStorageSize =
654 kTestBlobStorageMaxDiskSpace + kTestBlobStorageMaxBlobMemorySize;
655
656 const size_t kDataSize = 10u;
657 const size_t kBlobsThatCanFit = kTotalBlobStorageSize / kDataSize;
658 const size_t kNumFastBlobs = kTestBlobStorageMaxBlobMemorySize / kDataSize;
659 char kData[10];
660 memset(kData, 'e', kDataSize);
661
662 // Create all of our blobs.
663 std::vector<scoped_refptr<ShareableBlobDataItem>> all_items;
664 std::vector<base::WeakPtr<QuotaAllocationTask>> memory_tasks;
665 bool memory_requested[kBlobsThatCanFit] = {};
666 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
667 BlobDataBuilder builder("fake");
668 builder.AppendData(kData, kDataSize);
669 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
670 CreateSharedDataItems(builder);
671 EXPECT_TRUE(controller.CanReserveQuota(kDataSize));
672 EXPECT_EQ((i < kNumFastBlobs) ? Strategy::NONE_NEEDED : Strategy::IPC,
673 controller.DetermineStrategy(kDataSize, kDataSize))
674 << i;
675 base::WeakPtr<QuotaAllocationTask> memory_task =
676 controller.ReserveMemoryQuota(
677 items, GetMemoryRequestCallbackToOutput(memory_requested + i));
pwnall 2017/01/07 00:46:21 I'm not an expert in the style guide around pointe
dmurph 2017/01/07 02:26:26 Done.
678 if (memory_task) {
679 memory_tasks.push_back(std::move(memory_task));
680 }
681 all_items.insert(all_items.end(), items.begin(), items.end());
682 }
683 // We should have stored all of our memory quota, and no disk yet.
684 EXPECT_EQ(500u, controller.memory_usage());
685 EXPECT_EQ(0ull, controller.disk_usage());
686
687 EXPECT_FALSE(controller.CanReserveQuota(1u));
688 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
689 EXPECT_FALSE(file_runner_->HasPendingTask());
690
691 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
692 // Note: this can fail if the bot's disk is almost full.
pwnall 2017/01/07 00:46:21 Can you add an ASSERT above that checks for as muc
dmurph 2017/01/07 02:26:26 Done. I added a check for the most we'll ever use,
693 EXPECT_EQ(i < kBlobsThatCanFit / 3, memory_requested[i]) << i;
694 if (memory_requested[i] &&
695 all_items[i]->state() != ItemState::POPULATED_WITH_QUOTA) {
696 EXPECT_TRUE(memory_requested[i]);
697 all_items[i]->set_state(ItemState::POPULATED_WITH_QUOTA);
698 std::vector<scoped_refptr<ShareableBlobDataItem>> temp_vector;
699 temp_vector.push_back(all_items[i]);
700 controller.NotifyMemoryItemsUsed(temp_vector);
701 }
702 }
703 EXPECT_TRUE(file_runner_->HasPendingTask());
704
705 // This will schedule one task. Paging starts as soon as there is enough
706 // memory to page, and multiple pagings can't happen at the same time.
707 EXPECT_EQ(10ull, controller.disk_usage());
708 RunFileThreadTasks();
709 base::RunLoop().RunUntilIdle();
710 // The rest of the tasks should be scheduled.
711 EXPECT_TRUE(file_runner_->HasPendingTask());
712 RunFileThreadTasks();
713 base::RunLoop().RunUntilIdle();
714 // Everything in memory should be on disk, and next batch of memory items
715 // should be granted.
716 EXPECT_EQ(500u, controller.memory_usage());
717 EXPECT_EQ(500ull, controller.disk_usage());
718
719 // Still can't add anything.
720 EXPECT_FALSE(controller.CanReserveQuota(1u));
721 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
722
723 // Flag next batch for saving to disk.
724 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
725 // Note: this can fail if the bot's disk is almost full.
726 EXPECT_EQ(i < kBlobsThatCanFit * 2 / 3, memory_requested[i]) << i;
727 if (memory_requested[i] &&
728 all_items[i]->state() != ItemState::POPULATED_WITH_QUOTA) {
729 all_items[i]->set_state(ItemState::POPULATED_WITH_QUOTA);
730 std::vector<scoped_refptr<ShareableBlobDataItem>> temp_vector;
731 temp_vector.push_back(all_items[i]);
732 controller.NotifyMemoryItemsUsed(temp_vector);
733 }
734 }
735 EXPECT_TRUE(file_runner_->HasPendingTask());
736
737 // Same as before. One page task is scheduled, so run them twice.
738 EXPECT_EQ(510ull, controller.disk_usage());
739 RunFileThreadTasks();
740 base::RunLoop().RunUntilIdle();
741 // We page one time first, as it blocks paging once it starts.
742 RunFileThreadTasks();
743 base::RunLoop().RunUntilIdle();
744
745 // All quota should be allocated.
746 EXPECT_EQ(500u, controller.memory_usage());
747 EXPECT_EQ(1000ull, controller.disk_usage());
748
749 // Still can't add anything.
pwnall 2017/01/07 00:46:21 It seems to me that the 2 expectations here are de
dmurph 2017/01/07 02:26:26 Done.
750 EXPECT_FALSE(controller.CanReserveQuota(1u));
751 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
752
753 // Flag last batch as populated.
754 for (size_t i = 0; i < kBlobsThatCanFit; i++) {
755 // Note: this can fail if the bot's disk is almost full.
756 EXPECT_TRUE(memory_requested[i]);
757 if (memory_requested[i] &&
758 all_items[i]->state() != ItemState::POPULATED_WITH_QUOTA) {
759 all_items[i]->set_state(ItemState::POPULATED_WITH_QUOTA);
760 std::vector<scoped_refptr<ShareableBlobDataItem>> temp_vector;
761 temp_vector.push_back(all_items[i]);
762 controller.NotifyMemoryItemsUsed(temp_vector);
763 }
764 }
765
766 // There should be no more paging to disk, as we've reached the end.
767 EXPECT_FALSE(file_runner_->HasPendingTask());
768
769 // All quota should be allocated still.
770 EXPECT_EQ(500u, controller.memory_usage());
771 EXPECT_EQ(1000ull, controller.disk_usage());
772
773 // Still can't add anything.
774 EXPECT_FALSE(controller.CanReserveQuota(1u));
775 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(1u, 1ull));
776 EXPECT_FALSE(file_runner_->HasPendingTask());
pwnall 2017/01/07 00:46:21 Is this check redundant with the one on line 767?
dmurph 2017/01/07 02:26:26 Done.
777 }
778
597 TEST_F(BlobMemoryControllerTest, DisableDiskWithFileAndMemoryPending) { 779 TEST_F(BlobMemoryControllerTest, DisableDiskWithFileAndMemoryPending) {
598 const std::string kFirstMemoryId = "id"; 780 const std::string kFirstMemoryId = "id";
599 const uint64_t kFirstMemorySize = kTestBlobStorageMaxBlobMemorySize; 781 const uint64_t kFirstMemorySize = kTestBlobStorageMaxBlobMemorySize;
600 const std::string kSecondMemoryId = "id2"; 782 const std::string kSecondMemoryId = "id2";
601 const uint64_t kSecondMemorySize = 1; 783 const uint64_t kSecondMemorySize = 1;
602 const std::string kFileId = "id2"; 784 const std::string kFileId = "id2";
603 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize; 785 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
604 786
605 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_); 787 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
606 SetTestMemoryLimits(&controller); 788 SetTestMemoryLimits(&controller);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 852
671 file_items.clear(); 853 file_items.clear();
672 items.clear(); 854 items.clear();
673 855
674 RunFileThreadTasks(); 856 RunFileThreadTasks();
675 base::RunLoop().RunUntilIdle(); 857 base::RunLoop().RunUntilIdle();
676 858
677 EXPECT_EQ(0ull, controller.disk_usage()); 859 EXPECT_EQ(0ull, controller.disk_usage());
678 EXPECT_EQ(0ull, controller.memory_usage()); 860 EXPECT_EQ(0ull, controller.memory_usage());
679 } 861 }
862
863 TEST_F(BlobMemoryControllerTest, DiskSpaceTooSmallForItem) {
864 const std::string kFileId = "id2";
865 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
866
867 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
868 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
869
870 BlobDataBuilder file_builder(kFileId);
871 file_builder.AppendFutureFile(0, kFileBlobSize, 0);
872
873 // When we have < kFileBlobSize, then we cancel our request.
874 SetTestMemoryLimits(&controller);
875
876 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
877 CreateSharedDataItems(file_builder);
878
879 file_quota_result_ = true;
880 controller.ReserveFileQuota(items, GetFileCreationCallback());
881
882 EXPECT_TRUE(file_runner_->HasPendingTask());
883 set_disk_space(kFileBlobSize - 1);
884
885 RunFileThreadTasks();
886 ExpectDiskSpaceCalled();
887 base::RunLoop().RunUntilIdle();
888
889 EXPECT_FALSE(file_quota_result_);
890 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
891 EXPECT_EQ(0ull, controller.limits().effective_max_disk_space);
892
893 EXPECT_EQ(0ull, controller.disk_usage());
894 EXPECT_EQ(0ull, controller.memory_usage());
895 }
896
897 TEST_F(BlobMemoryControllerTest, DiskSpaceHitMinAvailable) {
898 const std::string kFileId = "id2";
899 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
900
901 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
902 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
903
904 BlobDataBuilder file_builder(kFileId);
905 file_builder.AppendFutureFile(0, kFileBlobSize, 0);
906 // When we have < limits.min_available_disk_space(), then we'll modify our
907 // effective disk space to match our current usage to stop using more disk.
908
909 SetTestMemoryLimits(&controller);
910
911 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
912 CreateSharedDataItems(file_builder);
913
914 file_quota_result_ = false;
915 controller.ReserveFileQuota(items, GetFileCreationCallback());
916
917 EXPECT_TRUE(file_runner_->HasPendingTask());
918 set_disk_space(controller.limits().min_available_disk_space() - 1);
919
920 RunFileThreadTasks();
921 ExpectDiskSpaceCalled();
922 base::RunLoop().RunUntilIdle();
923
924 EXPECT_TRUE(file_quota_result_);
925 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
926 EXPECT_EQ(kFileBlobSize, controller.limits().effective_max_disk_space);
927
928 items.clear();
929 files_created_.clear();
930
931 RunFileThreadTasks();
932 base::RunLoop().RunUntilIdle();
933
934 EXPECT_EQ(0ull, controller.disk_usage());
935 EXPECT_EQ(0ull, controller.memory_usage());
936 }
937
938 TEST_F(BlobMemoryControllerTest, DiskSpaceNearMinAvailable) {
939 const std::string kFileId = "id2";
940 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
941
942 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
943 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
944
945 BlobDataBuilder file_builder(kFileId);
946 file_builder.AppendFutureFile(0, kFileBlobSize, 0);
947
948 // When our desired total disk space is less than we're allowed given the
949 // minimum disk availability, we shorten the disk space.
950 SetTestMemoryLimits(&controller);
951
952 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
953 CreateSharedDataItems(file_builder);
954
955 file_quota_result_ = false;
956 controller.ReserveFileQuota(items, GetFileCreationCallback());
957
958 EXPECT_TRUE(file_runner_->HasPendingTask());
959 set_disk_space(controller.limits().desired_max_disk_space +
960 controller.limits().min_available_disk_space() - 1);
961
962 RunFileThreadTasks();
963 ExpectDiskSpaceCalled();
964 base::RunLoop().RunUntilIdle();
965
966 EXPECT_TRUE(file_quota_result_);
967 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
968 EXPECT_EQ(controller.limits().desired_max_disk_space - 1,
969 controller.limits().effective_max_disk_space);
970
971 items.clear();
972 files_created_.clear();
973
974 RunFileThreadTasks();
975 base::RunLoop().RunUntilIdle();
976
977 EXPECT_EQ(0ull, controller.disk_usage());
978 EXPECT_EQ(0ull, controller.memory_usage());
979 }
980
981 TEST_F(BlobMemoryControllerTest, DiskSpaceResetAfterIncrease) {
982 const std::string kFileId = "id2";
983 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
984
985 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
986 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
987
988 BlobDataBuilder file_builder(kFileId);
989 file_builder.AppendFutureFile(0, kFileBlobSize, 0);
990
991 // When we do a file operation after disk has been freed (after we've been
992 // limited), our effective size grows correctly.
993 SetTestMemoryLimits(&controller);
994
995 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
996 CreateSharedDataItems(file_builder);
997
998 controller.ReserveFileQuota(items, GetFileCreationCallback());
999
1000 EXPECT_TRUE(file_runner_->HasPendingTask());
1001 set_disk_space(controller.limits().min_available_disk_space() - 1);
1002
1003 RunFileThreadTasks();
1004 base::RunLoop().RunUntilIdle();
1005
1006 // Check the effective limit is constrained.
1007 EXPECT_TRUE(controller.limits().IsDiskSpaceConstrained());
1008 EXPECT_EQ(kFileBlobSize, controller.limits().effective_max_disk_space);
1009
1010 // Delete the item so we have disk quota.
1011 items.clear();
1012 files_created_.clear();
1013
1014 RunFileThreadTasks();
1015 ExpectDiskSpaceCalled();
1016 base::RunLoop().RunUntilIdle();
1017
1018 EXPECT_EQ(0ull, controller.disk_usage());
1019 EXPECT_EQ(0ull, controller.memory_usage());
1020
1021 // Create the same item, but have the disk space report the minimum amount
1022 // needed to have the desired disk size.
1023 items = CreateSharedDataItems(file_builder);
1024
1025 controller.ReserveFileQuota(items, GetFileCreationCallback());
1026
1027 EXPECT_TRUE(file_runner_->HasPendingTask());
1028 set_disk_space(kTestBlobStorageMaxDiskSpace +
1029 controller.limits().min_available_disk_space());
1030
1031 RunFileThreadTasks();
1032 ExpectDiskSpaceCalled();
1033 base::RunLoop().RunUntilIdle();
1034
1035 EXPECT_FALSE(controller.limits().IsDiskSpaceConstrained());
1036 EXPECT_EQ(controller.limits().desired_max_disk_space,
1037 controller.limits().effective_max_disk_space);
1038
1039 items.clear();
1040 files_created_.clear();
1041
1042 RunFileThreadTasks();
1043 base::RunLoop().RunUntilIdle();
1044
1045 EXPECT_EQ(0ull, controller.disk_usage());
1046 EXPECT_EQ(0ull, controller.memory_usage());
1047 }
1048
1049 TEST_F(BlobMemoryControllerTest, DiskSpaceUnknown) {
1050 const std::string kFileId = "id2";
1051 const uint64_t kFileBlobSize = kTestBlobStorageMaxBlobMemorySize;
1052
1053 BlobMemoryController controller(temp_dir_.GetPath(), file_runner_);
1054 controller.set_testing_disk_space(&FakeDiskSpaceMethod);
1055
1056 BlobDataBuilder file_builder(kFileId);
1057 file_builder.AppendFutureFile(0, kFileBlobSize, 0);
1058
1059 // If the disk space returns an error (-1), then we ignore that signal.
1060 SetTestMemoryLimits(&controller);
1061
1062 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
1063 CreateSharedDataItems(file_builder);
1064
1065 controller.ReserveFileQuota(items, GetFileCreationCallback());
1066
1067 EXPECT_TRUE(file_runner_->HasPendingTask());
1068 set_disk_space(-1ll);
1069
1070 RunFileThreadTasks();
1071 ExpectDiskSpaceCalled();
1072 base::RunLoop().RunUntilIdle();
1073
1074 // Check the effective limit is constrained.
1075 EXPECT_FALSE(controller.limits().IsDiskSpaceConstrained());
1076 }
1077
680 } // namespace storage 1078 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698