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

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

Issue 2339933004: [BlobStorage] BlobMemoryController & tests (Closed)
Patch Set: rebase Created 4 years, 3 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "storage/browser/blob/blob_memory_controller.h"
6
7 #include "base/bind.h"
8 #include "base/files/file_util.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/test/test_simple_task_runner.h"
12 #include "base/threading/thread_task_runner_handle.h"
13 #include "storage/browser/blob/blob_data_builder.h"
14 #include "storage/browser/blob/blob_data_item.h"
15 #include "storage/browser/blob/shareable_blob_data_item.h"
16 #include "storage/common/data_element.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace storage {
20
21 using Strategy = BlobMemoryController::Strategy;
22 using FileCreationInfo = BlobMemoryController::FileCreationInfo;
23 using base::TestSimpleTaskRunner;
24 using ItemState = ShareableBlobDataItem::State;
25
26 const std::string kBlobStorageDirectory = "blob_storage";
27 const size_t kTestBlobStorageIPCThresholdBytes = 20;
28 const size_t kTestBlobStorageMaxSharedMemoryBytes = 50;
29 const size_t kTestBlobStorageMaxBlobMemorySize = 400;
30 const size_t kTestBlobStorageInFlightMemory = 10;
31 const uint64_t kTestBlobStorageMaxDiskSpace = 1000;
32 const uint64_t kTestBlobStorageMinFileSizeBytes = 10;
33 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
34
35 class BlobMemoryControllerTest : public testing::Test {
36 protected:
37 BlobMemoryControllerTest() {}
38
39 void SetUp() override {
40 ASSERT_EQ(true, base::CreateNewTempDirectory("blob_storage", &temp_dir_));
41 };
42
43 void TearDown() override {
44 files_created_.clear();
45 // Make sure we clean up the files.
46 base::RunLoop().RunUntilIdle();
47 file_runner_->RunPendingTasks();
48 base::RunLoop().RunUntilIdle();
49 ASSERT_EQ(true, base::DeleteFile(temp_dir_, true));
50 }
51
52 std::vector<scoped_refptr<ShareableBlobDataItem>> CreateSharedDataItems(
53 const BlobDataBuilder& builder,
54 const std::vector<ItemState>& states,
55 std::vector<ShareableBlobDataItem*>* pointers_out) {
56 std::vector<scoped_refptr<ShareableBlobDataItem>> result;
57 EXPECT_EQ(builder.items_.size(), states.size());
58 for (size_t i = 0; i < builder.items_.size(); ++i) {
59 result.push_back(make_scoped_refptr(new ShareableBlobDataItem(
60 builder.uuid(), builder.items_[i], states[i])));
61 pointers_out->push_back(result.back().get());
62 }
63 return result;
64 }
65
66 void SetTestMemoryLimits(BlobMemoryController* controller) {
67 BlobStorageLimits limits;
68 limits.max_ipc_memory_size = kTestBlobStorageIPCThresholdBytes;
69 limits.max_shared_memory_size = kTestBlobStorageMaxSharedMemoryBytes;
70 limits.max_blob_in_memory_space = kTestBlobStorageMaxBlobMemorySize;
71 limits.in_flight_space = kTestBlobStorageInFlightMemory;
72 limits.max_blob_disk_space = kTestBlobStorageMaxDiskSpace;
73 limits.min_page_file_size = kTestBlobStorageMinFileSizeBytes;
74 limits.max_file_size = kTestBlobStorageMaxFileSizeBytes;
75 controller->SetLimitsForTesting(limits);
76 }
77
78 void SaveFileCreationInfo(bool success, std::vector<FileCreationInfo> info) {
79 file_quota_result_ = success;
80 if (success)
81 files_created_.swap(info);
82 }
83
84 void SaveMemoryRequest(bool success) { memory_quota_result_ = success; }
85
86 BlobMemoryController::FileQuotaRequestCallback GetFileCreationCallback() {
87 return base::Bind(&BlobMemoryControllerTest::SaveFileCreationInfo,
88 base::Unretained(this));
89 }
90
91 BlobMemoryController::MemoryQuotaRequestCallback GetMemoryRequestCallback() {
92 return base::Bind(&BlobMemoryControllerTest::SaveMemoryRequest,
93 base::Unretained(this));
94 }
95
96 void SetItemState(ShareableBlobDataItem* item, ItemState state) {
97 item->state_ = state;
98 }
99
100 bool file_quota_result_ = false;
101 base::FilePath temp_dir_;
102 std::vector<FileCreationInfo> files_created_;
103 bool memory_quota_result_ = false;
104
105 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
106
107 base::MessageLoop fake_io_message_loop_;
108 };
109
110 TEST_F(BlobMemoryControllerTest, Strategy) {
111 BlobMemoryController controller;
112 SetTestMemoryLimits(&controller);
113
114 // No transportation needed.
115 EXPECT_EQ(Strategy::NONE_NEEDED, controller.DetermineStrategy(0, 0));
116
117 // IPC.
118 EXPECT_EQ(Strategy::IPC,
119 controller.DetermineStrategy(0, kTestBlobStorageIPCThresholdBytes));
120
121 // Shared Memory.
122 EXPECT_EQ(Strategy::SHARED_MEMORY,
123 controller.DetermineStrategy(kTestBlobStorageIPCThresholdBytes,
124 kTestBlobStorageMaxSharedMemoryBytes));
125
126 // Not too large, as disk isn't enabled.
127 EXPECT_EQ(
128 Strategy::SHARED_MEMORY,
129 controller.DetermineStrategy(0, kTestBlobStorageMaxBlobMemorySize +
130 kTestBlobStorageInFlightMemory));
131
132 // Too large.
133 EXPECT_EQ(
134 Strategy::TOO_LARGE,
135 controller.DetermineStrategy(0, kTestBlobStorageMaxBlobMemorySize +
136 kTestBlobStorageInFlightMemory + 1));
137
138 // Enable disk, and check file strategies.
139 controller.EnableFilePaging(temp_dir_, file_runner_);
140 EXPECT_EQ(Strategy::FILE, controller.DetermineStrategy(
141 0, kTestBlobStorageMaxBlobMemorySize + 1));
142
143 // Too large for disk.
144 controller.EnableFilePaging(temp_dir_, file_runner_);
145 EXPECT_EQ(Strategy::TOO_LARGE,
146 controller.DetermineStrategy(0, kTestBlobStorageMaxDiskSpace + 1));
147 }
148
149 TEST_F(BlobMemoryControllerTest, GrantMemory) {
150 const std::string kId = "id";
151 BlobMemoryController controller;
152 SetTestMemoryLimits(&controller);
153
154 BlobDataBuilder builder(kId);
155 builder.AppendFutureData(10);
156 builder.AppendFutureData(20);
157 builder.AppendFutureData(30);
158
159 std::vector<ShareableBlobDataItem*> pointers;
160 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
161 CreateSharedDataItems(builder,
162 {ItemState::QUOTA_NEEDED, ItemState::QUOTA_NEEDED,
163 ItemState::QUOTA_NEEDED},
164 &pointers);
165
166 controller.ReserveMemoryQuota(pointers, GetMemoryRequestCallback());
167 EXPECT_EQ(true, memory_quota_result_);
168 EXPECT_EQ(ItemState::QUOTA_GRANTED, items[0]->state());
169 EXPECT_EQ(ItemState::QUOTA_GRANTED, items[1]->state());
170 EXPECT_EQ(ItemState::QUOTA_GRANTED, items[2]->state());
171 }
172
173 TEST_F(BlobMemoryControllerTest, GrantMemoryWithPagingFileWaiting) {
174 const std::string kId = "id";
175 BlobMemoryController controller;
176 SetTestMemoryLimits(&controller);
177
178 char kData[kTestBlobStorageMaxBlobMemorySize];
179 std::memset(kData, kTestBlobStorageMaxBlobMemorySize, 'e');
180
181 // Add memory item that is the memory quota.
182 BlobDataBuilder builder(kId);
183 builder.AppendFutureData(kTestBlobStorageMaxBlobMemorySize);
184
185 std::vector<ShareableBlobDataItem*> pointers;
186 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
187 CreateSharedDataItems(builder, {ItemState::QUOTA_NEEDED}, &pointers);
188
189 controller.ReserveMemoryQuota(pointers, GetMemoryRequestCallback());
190 EXPECT_EQ(true, memory_quota_result_);
191 memory_quota_result_ = false;
192 EXPECT_EQ(ItemState::QUOTA_GRANTED, items[0]->state());
193
194 // Enable disk.
195 controller.EnableFilePaging(temp_dir_, file_runner_);
196
197 // Create an item that is just a little too big.
198 BlobDataBuilder builder2(kId);
199 builder2.AppendFutureData(kTestBlobStorageInFlightMemory + 1);
200
201 // Reserve memory, which should request successfuly but we can't fit it yet
202 // (no callback).
203 pointers.clear();
204 std::vector<scoped_refptr<ShareableBlobDataItem>> items2 =
205 CreateSharedDataItems(builder2, {ItemState::QUOTA_NEEDED}, &pointers);
206 controller.ReserveMemoryQuota(pointers, GetMemoryRequestCallback());
207
208 EXPECT_EQ(false, memory_quota_result_);
209 EXPECT_EQ(ItemState::QUOTA_REQUESTED, items2[0]->state());
210 EXPECT_FALSE(file_runner_->HasPendingTask());
211
212 // Add our original item as populated so it's paged to disk.
213 items[0]->item()->data_element_ptr()->SetToBytes(
214 kData, kTestBlobStorageMaxBlobMemorySize);
215 SetItemState(items[0].get(), ItemState::POPULATED_WITH_QUOTA);
216 controller.UpdateBlobItemInRecents(items[0].get());
217
218 EXPECT_TRUE(file_runner_->HasPendingTask());
219 file_runner_->RunPendingTasks();
220 base::RunLoop().RunUntilIdle();
221 EXPECT_EQ(ItemState::QUOTA_GRANTED, items2[0]->state());
222 EXPECT_EQ(DataElement::TYPE_FILE, items[0]->item()->type());
223 }
224
225 // TODO(dmurph):
pwnall 2016/09/21 09:03:35 Can you crbug this please?
dmurph 2016/09/21 23:45:52 This will be in this patch, no need for crbug. Jus
226 // * Write test for memory request when quota is available.
227 // * Write test for memory request that fails because disk isn't enabled.
228 // * Write test for memory request when quota isn't available and we're waiting
229 // on disk paging.
230 // * Same as above but then we cancel it.
231 // * Write test for memory request that's pending, and then disk is disabled.
232 // * Write test for file request where we have quota.
233 // * Write test for file request where we don't have quota (and just fail).
234 // * Write test for file request and then we disable disk.
235
236 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698