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

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

Issue 2339933004: [BlobStorage] BlobMemoryController & tests (Closed)
Patch Set: comments, more tests are next Created 4 years, 2 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_));
michaeln 2016/10/04 00:11:54 i think base::ScopedTempDir would be a good fit fo
dmurph 2016/10/06 00:45:39 Ah, nice catch.
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 {
108 BlobMemoryController controller(temp_dir_, nullptr);
109 SetTestMemoryLimits(&controller);
110
111 // No transportation needed.
112 EXPECT_EQ(Strategy::NONE_NEEDED, controller.DetermineStrategy(0, 0));
113
114 // IPC.
115 EXPECT_EQ(Strategy::IPC, controller.DetermineStrategy(
116 0, kTestBlobStorageIPCThresholdBytes));
117
118 // Shared Memory.
119 EXPECT_EQ(
120 Strategy::SHARED_MEMORY,
121 controller.DetermineStrategy(kTestBlobStorageIPCThresholdBytes,
122 kTestBlobStorageMaxSharedMemoryBytes));
123
124 // Not too large, as disk isn't enabled.
125 EXPECT_EQ(
126 Strategy::SHARED_MEMORY,
127 controller.DetermineStrategy(0, kTestBlobStorageMaxBlobMemorySize +
128 kTestBlobStorageInFlightMemory));
129
130 // Too large.
131 EXPECT_EQ(Strategy::TOO_LARGE,
132 controller.DetermineStrategy(
133 0, kTestBlobStorageMaxBlobMemorySize +
134 kTestBlobStorageInFlightMemory + 1));
135 }
136 {
137 // Enable disk, and check file strategies.
138 BlobMemoryController controller(temp_dir_, file_runner_);
139 SetTestMemoryLimits(&controller);
140 EXPECT_EQ(Strategy::FILE, controller.DetermineStrategy(
141 0, kTestBlobStorageMaxBlobMemorySize + 1));
142
143 // Too large for disk.
144 EXPECT_EQ(Strategy::TOO_LARGE, controller.DetermineStrategy(
145 0, kTestBlobStorageMaxDiskSpace + 1));
146 }
147 }
148
149 TEST_F(BlobMemoryControllerTest, GrantMemory) {
150 const std::string kId = "id";
151 BlobMemoryController controller(temp_dir_, file_runner_);
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(temp_dir_, file_runner_);
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 EXPECT_FALSE(file_runner_->HasPendingTask());
194
195 // Create an item that is just a little too big.
196 BlobDataBuilder builder2(kId);
197 builder2.AppendFutureData(kTestBlobStorageInFlightMemory + 1);
198
199 // Reserve memory, which should request successfuly but we can't fit it yet
200 // (no callback).
201 pointers.clear();
202 std::vector<scoped_refptr<ShareableBlobDataItem>> items2 =
203 CreateSharedDataItems(builder2, {ItemState::QUOTA_NEEDED}, &pointers);
204 controller.ReserveMemoryQuota(pointers, GetMemoryRequestCallback());
205
206 EXPECT_EQ(false, memory_quota_result_);
207 EXPECT_EQ(ItemState::QUOTA_REQUESTED, items2[0]->state());
208 EXPECT_FALSE(file_runner_->HasPendingTask());
209
210 // Add our original item as populated so it's paged to disk.
211 items[0]->item()->data_element_ptr()->SetToBytes(
212 kData, kTestBlobStorageMaxBlobMemorySize);
213 items[0]->set_state(ItemState::POPULATED_WITH_QUOTA);
214 controller.NotifyMemoryItemUsed(items[0].get());
215
216 EXPECT_TRUE(file_runner_->HasPendingTask());
217 file_runner_->RunPendingTasks();
218 base::RunLoop().RunUntilIdle();
219 EXPECT_EQ(ItemState::QUOTA_GRANTED, items2[0]->state());
220 EXPECT_EQ(DataElement::TYPE_FILE, items[0]->item()->type());
221 }
222
223 // TODO(dmurph):
224 // * Write test for memory request when quota is available.
michaeln 2016/10/04 00:11:54 do you plan on filling in more test coverage in th
dmurph 2016/10/06 00:45:39 This cl :)
225 // * Write test for memory request that fails because disk isn't enabled.
226 // * Write test for memory request when quota isn't available and we're waiting
227 // on disk paging.
228 // * Same as above but then we cancel it.
229 // * Write test for memory request that's pending, and then disk is disabled.
230 // * Write test for file request where we have quota.
231 // * Write test for file request where we don't have quota (and just fail).
232 // * Write test for file request and then we disable disk.
233
234 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698