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

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

Issue 1098853003: [BlobAsync] Patch 4: Browser Classes & Logic. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: maybe fixed windows Created 5 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
(Empty)
1 // Copyright 2015 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_async_builder_host.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/shared_memory.h"
10 #include "storage/common/blob_storage/blob_storage_constants.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace storage {
14 namespace {
15 const std::string kBlobUUID = "blobUUIDYAY";
16 const std::string kFakeBlobUUID = "fakeBlob";
17 const std::string kBlobType = "blobtypeYAY";
18
19 const size_t kTestBlobStorageIPCThresholdBytes = 5;
20 const size_t kTestBlobStorageMaxSharedMemoryBytes = 20;
21 const uint64_t kTestBlobStorageMaxFileSizeBytes = 100;
22
23 void PopulateBytes(char* bytes, size_t length) {
24 for (size_t i = 0; i < length; i++) {
25 bytes[i] = static_cast<char>(i);
26 }
27 }
28
29 void AddMemoryItem(size_t length, std::vector<DataElement>* out) {
30 DataElement bytes;
31 bytes.SetToBytesDescription(length);
32 out->push_back(bytes);
33 }
34
35 void AddShortcutMemoryItem(size_t length, std::vector<DataElement>* out) {
36 DataElement bytes;
37 bytes.SetToAllocatedBytes(length);
38 PopulateBytes(bytes.mutable_bytes(), length);
39 out->push_back(bytes);
40 }
41
42 void AddShortcutMemoryItem(size_t length, BlobDataBuilder* out) {
43 DataElement bytes;
44 bytes.SetToAllocatedBytes(length);
45 PopulateBytes(bytes.mutable_bytes(), length);
46 out->AppendData(bytes.bytes(), length);
47 }
48
49 void AddBlobItem(std::vector<DataElement>* out) {
50 DataElement blob;
51 blob.SetToBlob(kFakeBlobUUID);
52 out->push_back(blob);
53 }
54
55 class BlobAsyncBuilderHostTest : public testing::Test {
56 protected:
57 BlobAsyncBuilderHostTest()
58 : matching_builder_(nullptr),
59 done_called_(false),
60 cancel_called_(false),
61 cancel_code_(IPCBlobCreationCancelCode::UNKNOWN),
62 request_called_(false) {}
63 ~BlobAsyncBuilderHostTest() override {}
64
65 void SetUp() override {
66 logging::SetMinLogLevel(-1);
67 matching_builder_ = nullptr;
68 done_called_ = false;
69 cancel_called_ = false;
70 cancel_code_ = IPCBlobCreationCancelCode::UNKNOWN;
71 request_called_ = false;
72 requests_.clear();
73 memory_handles_.clear();
74 file_handles_.clear();
75 host_.SetMemoryConstantsForTesting(kTestBlobStorageIPCThresholdBytes,
76 kTestBlobStorageMaxSharedMemoryBytes,
77 kTestBlobStorageMaxFileSizeBytes);
78 }
79
80 void SetMatchingBuilder(BlobDataBuilder* builder) {
81 matching_builder_ = builder;
82 }
83
84 void CancelCallback(IPCBlobCreationCancelCode code) {
85 cancel_called_ = true;
86 cancel_code_ = code;
87 }
88
89 void DoneCallback(const BlobDataBuilder& builder) {
90 // This does a deep comparison, including internal data items.
91 if (matching_builder_)
92 EXPECT_EQ(*matching_builder_, builder);
93 done_called_ = true;
94 }
95
96 void RequestMemoryCallback(
97 const std::vector<storage::BlobItemBytesRequest>& requests,
98 const std::vector<base::SharedMemoryHandle>& shared_memory_handles,
99 const std::vector<uint64_t>& file_sizes) {
100 this->requests_ = requests;
101 memory_handles_ = shared_memory_handles;
102 file_handles_ = file_sizes;
103 request_called_ = true;
104 }
105
106 bool BuildBlobAsync(const std::vector<DataElement>& descriptions,
107 size_t memory_available) {
108 done_called_ = false;
109 cancel_called_ = false;
110 request_called_ = false;
111 return host_.StartBuildingBlob(
112 kBlobUUID, kBlobType, descriptions, memory_available,
113 base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback,
114 base::Unretained(this)),
115 base::Bind(&BlobAsyncBuilderHostTest::DoneCallback,
116 base::Unretained(this)),
117 base::Bind(&BlobAsyncBuilderHostTest::CancelCallback,
118 base::Unretained(this)));
119 }
120
121 BlobDataBuilder* matching_builder_;
122 BlobAsyncBuilderHost host_;
123 bool done_called_;
124 bool cancel_called_;
125 IPCBlobCreationCancelCode cancel_code_;
126
127 bool request_called_;
128 std::vector<storage::BlobItemBytesRequest> requests_;
129 std::vector<base::SharedMemoryHandle> memory_handles_;
130 std::vector<uint64_t> file_handles_;
131 };
132
133 TEST_F(BlobAsyncBuilderHostTest, TestShortcut) {
134 std::vector<DataElement> descriptions;
135
136 AddShortcutMemoryItem(10, &descriptions);
137 AddBlobItem(&descriptions);
138 AddShortcutMemoryItem(5000, &descriptions);
139
140 BlobDataBuilder expected(kBlobUUID);
141 expected.set_content_type(kBlobType);
142 AddShortcutMemoryItem(10, &expected);
143 expected.AppendBlob(kFakeBlobUUID);
144 AddShortcutMemoryItem(5000, &expected);
145 SetMatchingBuilder(&expected);
146
147 EXPECT_TRUE(BuildBlobAsync(descriptions, 5010));
148
149 EXPECT_TRUE(done_called_);
150 EXPECT_FALSE(cancel_called_);
151 EXPECT_FALSE(request_called_);
152 EXPECT_EQ(0u, host_.blob_building_count());
153 };
154
155 TEST_F(BlobAsyncBuilderHostTest, TestSingleSharedMemRequest) {
156 std::vector<DataElement> descriptions;
157 const size_t kSize = kTestBlobStorageIPCThresholdBytes + 1;
158 AddMemoryItem(kSize, &descriptions);
159
160 EXPECT_TRUE(
161 BuildBlobAsync(descriptions, kTestBlobStorageIPCThresholdBytes + 1));
162
163 EXPECT_FALSE(done_called_);
164 EXPECT_FALSE(cancel_called_);
165 EXPECT_TRUE(request_called_);
166 EXPECT_EQ(1u, host_.blob_building_count());
167 ASSERT_EQ(1u, requests_.size());
168 request_called_ = false;
169
170 EXPECT_EQ(
171 BlobItemBytesRequest::CreateSharedMemoryRequest(0, 0, 0, kSize, 0, 0),
172 requests_.at(0));
173 };
174
175 TEST_F(BlobAsyncBuilderHostTest, TestMultipleSharedMemRequests) {
176 std::vector<DataElement> descriptions;
177 const size_t kSize = kTestBlobStorageMaxSharedMemoryBytes + 1;
178 const char kFirstBlockByte = 7;
179 const char kSecondBlockByte = 19;
180 AddMemoryItem(kSize, &descriptions);
181
182 BlobDataBuilder expected(kBlobUUID);
183 expected.set_content_type(kBlobType);
184 char data[kSize];
185 memset(data, kFirstBlockByte, kTestBlobStorageMaxSharedMemoryBytes);
186 expected.AppendData(data, kTestBlobStorageMaxSharedMemoryBytes);
187 expected.AppendData(&kSecondBlockByte, 1);
188 SetMatchingBuilder(&expected);
189
190 EXPECT_TRUE(
191 BuildBlobAsync(descriptions, kTestBlobStorageMaxSharedMemoryBytes + 1));
192
193 EXPECT_FALSE(done_called_);
194 EXPECT_FALSE(cancel_called_);
195 EXPECT_TRUE(request_called_);
196 EXPECT_EQ(1u, host_.blob_building_count());
197 ASSERT_EQ(1u, requests_.size());
198 request_called_ = false;
199
200 // We need to grab a duplicate handle so we can have two blocks open at the
201 // same time.
202 base::SharedMemoryHandle handle =
203 base::SharedMemory::DuplicateHandle(memory_handles_.at(0));
204 EXPECT_TRUE(base::SharedMemory::IsHandleValid(handle));
205 base::SharedMemory shared_memory(handle, false);
206 EXPECT_TRUE(shared_memory.Map(kTestBlobStorageMaxSharedMemoryBytes));
207
208 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(
209 0, 0, 0, kTestBlobStorageMaxSharedMemoryBytes, 0, 0),
210 requests_.at(0));
211
212 memset(shared_memory.memory(), kFirstBlockByte,
213 kTestBlobStorageMaxSharedMemoryBytes);
214
215 BlobItemBytesResponse response(0);
216 std::vector<BlobItemBytesResponse> responses = {response};
217 EXPECT_TRUE(host_.OnMemoryResponses(kBlobUUID, responses));
218
219 EXPECT_FALSE(done_called_);
220 EXPECT_FALSE(cancel_called_);
221 EXPECT_TRUE(request_called_);
222 EXPECT_EQ(1u, host_.blob_building_count());
223 ASSERT_EQ(1u, requests_.size());
224 request_called_ = false;
225
226 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(
227 1, 0, kTestBlobStorageMaxSharedMemoryBytes, 1, 0, 0),
228 requests_.at(0));
229
230 memset(shared_memory.memory(), kSecondBlockByte, 1);
231
232 response.request_number = 1;
233 responses[0] = response;
234 EXPECT_TRUE(host_.OnMemoryResponses(kBlobUUID, responses));
235 EXPECT_TRUE(done_called_);
236 EXPECT_FALSE(cancel_called_);
237 EXPECT_FALSE(request_called_);
238 EXPECT_EQ(0u, host_.blob_building_count());
239 };
240
241 TEST_F(BlobAsyncBuilderHostTest, TestBasicIPCAndStopBuilding) {
242 std::vector<DataElement> descriptions;
243
244 AddMemoryItem(2, &descriptions);
245 AddBlobItem(&descriptions);
246 AddMemoryItem(2, &descriptions);
247
248 BlobDataBuilder expected(kBlobUUID);
249 expected.set_content_type(kBlobType);
250 AddShortcutMemoryItem(2, &expected);
251 expected.AppendBlob(kFakeBlobUUID);
252 AddShortcutMemoryItem(2, &expected);
253 SetMatchingBuilder(&expected);
254
255 EXPECT_TRUE(BuildBlobAsync(descriptions, 5010));
256 host_.StopBuildingBlob(kBlobUUID);
257 EXPECT_TRUE(BuildBlobAsync(descriptions, 5010));
258
259 EXPECT_FALSE(done_called_);
260 EXPECT_FALSE(cancel_called_);
261 EXPECT_TRUE(request_called_);
262 EXPECT_EQ(1u, host_.blob_building_count());
263 request_called_ = false;
264
265 BlobItemBytesResponse response1(0);
266 PopulateBytes(response1.allocate_mutable_data(2), 2);
267 BlobItemBytesResponse response2(1);
268 PopulateBytes(response2.allocate_mutable_data(2), 2);
269 std::vector<BlobItemBytesResponse> responses = {response1, response2};
270 EXPECT_TRUE(host_.OnMemoryResponses(kBlobUUID, responses));
271 EXPECT_TRUE(done_called_);
272 EXPECT_FALSE(cancel_called_);
273 EXPECT_FALSE(request_called_);
274 EXPECT_EQ(0u, host_.blob_building_count());
275 };
276
277 TEST_F(BlobAsyncBuilderHostTest, TestBadIPCs) {
278 std::vector<DataElement> descriptions;
279
280 // Test strategy invalid params.
281 AddMemoryItem(std::numeric_limits<size_t>::max(), &descriptions);
282 AddMemoryItem(1, &descriptions);
283 EXPECT_FALSE(BuildBlobAsync(descriptions, 5010));
284 EXPECT_FALSE(done_called_);
285 EXPECT_FALSE(cancel_called_);
286 EXPECT_FALSE(request_called_);
287 EXPECT_EQ(0u, host_.blob_building_count());
288
289 // Test reusing same id.
290 descriptions.clear();
291 SetMatchingBuilder(nullptr);
292 AddMemoryItem(10, &descriptions);
293 AddBlobItem(&descriptions);
294 AddMemoryItem(5000, &descriptions);
295 EXPECT_TRUE(BuildBlobAsync(descriptions, 5010));
296 EXPECT_FALSE(BuildBlobAsync(descriptions, 5010));
297 EXPECT_FALSE(done_called_);
298 EXPECT_FALSE(cancel_called_);
299 EXPECT_FALSE(request_called_);
300 host_.StopBuildingBlob(kBlobUUID);
301
302 // Test we're _not_ an error if we get a bad uuid for responses.
303 BlobItemBytesResponse response(0);
304 std::vector<BlobItemBytesResponse> responses = {response};
305 EXPECT_TRUE(host_.OnMemoryResponses(kBlobUUID, responses));
306
307 // Test empty responses.
308 responses.clear();
309 EXPECT_FALSE(host_.OnMemoryResponses(kBlobUUID, responses));
310
311 // Test response problems below here.
312 descriptions.clear();
313 AddMemoryItem(2, &descriptions);
314 AddBlobItem(&descriptions);
315 AddMemoryItem(2, &descriptions);
316 EXPECT_TRUE(BuildBlobAsync(descriptions, 5010));
317
318 // Invalid request number.
319 BlobItemBytesResponse response1(3);
320 PopulateBytes(response1.allocate_mutable_data(2), 2);
321 responses = {response1};
322 EXPECT_FALSE(host_.OnMemoryResponses(kBlobUUID, responses));
323
324 // Duplicate request number responses.
325 EXPECT_TRUE(BuildBlobAsync(descriptions, 5010));
326 response1.request_number = 0;
327 BlobItemBytesResponse response2(0);
328 PopulateBytes(response2.allocate_mutable_data(2), 2);
329 responses = {response1, response2};
330 EXPECT_FALSE(host_.OnMemoryResponses(kBlobUUID, responses));
331 };
332
333 } // namespace
334 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698