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

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

Issue 2339933004: [BlobStorage] BlobMemoryController & tests (Closed)
Patch Set: Comments, and made task base class for hopefully more simplicity 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 bool file_quota_result_ = false;
97 base::FilePath temp_dir_;
98 std::vector<FileCreationInfo> files_created_;
99 bool memory_quota_result_ = false;
100
101 scoped_refptr<TestSimpleTaskRunner> file_runner_ = new TestSimpleTaskRunner();
102
103 base::MessageLoop fake_io_message_loop_;
104 };
105
106 TEST_F(BlobMemoryControllerTest, Strategy) {
107 BlobMemoryController controller;
108 SetTestMemoryLimits(&controller);
109
110 // No transportation needed.
111 EXPECT_EQ(Strategy::NONE_NEEDED, controller.DetermineStrategy(0, 0));
112
113 // IPC.
114 EXPECT_EQ(Strategy::IPC,
115 controller.DetermineStrategy(0, kTestBlobStorageIPCThresholdBytes));
116
117 // Shared Memory.
118 EXPECT_EQ(Strategy::SHARED_MEMORY,
119 controller.DetermineStrategy(kTestBlobStorageIPCThresholdBytes,
120 kTestBlobStorageMaxSharedMemoryBytes));
121
122 // Not too large, as disk isn't enabled.
123 EXPECT_EQ(
124 Strategy::SHARED_MEMORY,
125 controller.DetermineStrategy(0, kTestBlobStorageMaxBlobMemorySize +
126 kTestBlobStorageInFlightMemory));
127
128 // Too large.
129 EXPECT_EQ(
130 Strategy::TOO_LARGE,
131 controller.DetermineStrategy(0, kTestBlobStorageMaxBlobMemorySize +
132 kTestBlobStorageInFlightMemory + 1));
133
134 // Enable disk, and check file strategies.
135 controller.EnableFilePaging(temp_dir_, file_runner_);
136 EXPECT_EQ(Strategy::FILE, controller.DetermineStrategy(
137 0, kTestBlobStorageMaxBlobMemorySize + 1));
138
139 // Too large for disk.
140 controller.EnableFilePaging(temp_dir_, file_runner_);
141 EXPECT_EQ(Strategy::TOO_LARGE,
142 controller.DetermineStrategy(0, kTestBlobStorageMaxDiskSpace + 1));
143 }
144
145 TEST_F(BlobMemoryControllerTest, GrantMemory) {
146 const std::string kId = "id";
147 BlobMemoryController controller;
148 SetTestMemoryLimits(&controller);
149
150 BlobDataBuilder builder(kId);
151 builder.AppendFutureData(10);
152 builder.AppendFutureData(20);
153 builder.AppendFutureData(30);
154
155 std::vector<ShareableBlobDataItem*> pointers;
156 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
157 CreateSharedDataItems(builder,
158 {ItemState::QUOTA_NEEDED, ItemState::QUOTA_NEEDED,
159 ItemState::QUOTA_NEEDED},
160 &pointers);
161
162 controller.ReserveMemoryQuota(pointers, GetMemoryRequestCallback());
163 EXPECT_EQ(true, memory_quota_result_);
164 EXPECT_EQ(ItemState::QUOTA_GRANTED, items[0]->state());
165 EXPECT_EQ(ItemState::QUOTA_GRANTED, items[1]->state());
166 EXPECT_EQ(ItemState::QUOTA_GRANTED, items[2]->state());
167 }
168
169 TEST_F(BlobMemoryControllerTest, GrantMemoryWithPagingFileWaiting) {
170 const std::string kId = "id";
171 BlobMemoryController controller;
172 SetTestMemoryLimits(&controller);
173
174 char kData[kTestBlobStorageMaxBlobMemorySize];
175 std::memset(kData, kTestBlobStorageMaxBlobMemorySize, 'e');
176
177 // Add memory item that is the memory quota.
178 BlobDataBuilder builder(kId);
179 builder.AppendFutureData(kTestBlobStorageMaxBlobMemorySize);
180
181 std::vector<ShareableBlobDataItem*> pointers;
182 std::vector<scoped_refptr<ShareableBlobDataItem>> items =
183 CreateSharedDataItems(builder, {ItemState::QUOTA_NEEDED}, &pointers);
184
185 controller.ReserveMemoryQuota(pointers, GetMemoryRequestCallback());
186 EXPECT_EQ(true, memory_quota_result_);
187 memory_quota_result_ = false;
188 EXPECT_EQ(ItemState::QUOTA_GRANTED, items[0]->state());
189
190 // Enable disk.
191 controller.EnableFilePaging(temp_dir_, file_runner_);
192
193 // Create an item that is just a little too big.
194 BlobDataBuilder builder2(kId);
195 builder2.AppendFutureData(kTestBlobStorageInFlightMemory + 1);
196
197 // Reserve memory, which should request successfuly but we can't fit it yet
198 // (no callback).
199 pointers.clear();
200 std::vector<scoped_refptr<ShareableBlobDataItem>> items2 =
201 CreateSharedDataItems(builder2, {ItemState::QUOTA_NEEDED}, &pointers);
202 controller.ReserveMemoryQuota(pointers, GetMemoryRequestCallback());
203
204 EXPECT_EQ(false, memory_quota_result_);
205 EXPECT_EQ(ItemState::QUOTA_REQUESTED, items2[0]->state());
206 EXPECT_FALSE(file_runner_->HasPendingTask());
207
208 // Add our original item as populated so it's paged to disk.
209 items[0]->item()->data_element_ptr()->SetToBytes(
210 kData, kTestBlobStorageMaxBlobMemorySize);
211 items[0]->set_state(ItemState::POPULATED_WITH_QUOTA);
212 controller.UpdateBlobItemInRecents(items[0].get());
213
214 EXPECT_TRUE(file_runner_->HasPendingTask());
215 file_runner_->RunPendingTasks();
216 base::RunLoop().RunUntilIdle();
217 EXPECT_EQ(ItemState::QUOTA_GRANTED, items2[0]->state());
218 EXPECT_EQ(DataElement::TYPE_FILE, items[0]->item()->type());
219 }
220
221 // TODO(dmurph):
222 // * Write test for memory request when quota is available.
223 // * Write test for memory request that fails because disk isn't enabled.
224 // * Write test for memory request when quota isn't available and we're waiting
225 // on disk paging.
226 // * Same as above but then we cancel it.
227 // * Write test for memory request that's pending, and then disk is disabled.
228 // * Write test for file request where we have quota.
229 // * Write test for file request where we don't have quota (and just fail).
230 // * Write test for file request and then we disable disk.
231
232 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698