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

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

Issue 1098853003: [BlobAsync] Patch 4: Browser Classes & Logic. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: consolidated handle sizes 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_transport_strategy.h"
6
7 #include <string>
8
9 #include "base/logging.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace storage {
13 namespace {
14
15 const char kNewUUID[] = "newUUID";
16 const base::FilePath kFuturePopulatingFilePath = base::FilePath::FromUTF8Unsafe(
17 std::string(BlobDataBuilder::kAppendFutureFileTemporaryFileName));
18 const char kFakeBlobUUID[] = "fakeBlob";
19
20 void AddMemoryItem(size_t length, std::vector<DataElement>* out) {
21 DataElement bytes;
22 bytes.SetToBytesDescription(length);
23 out->push_back(bytes);
24 }
25
26 void AddShortcutMemoryItem(size_t length, std::vector<DataElement>* out) {
27 DataElement bytes;
28 bytes.SetToAllocatedBytes(length);
29 for (size_t i = 0; i < length; i++) {
30 bytes.mutable_bytes()[i] = static_cast<char>(i);
31 }
32 out->push_back(bytes);
33 }
34
35 void AddBlobItem(std::vector<DataElement>* out) {
36 DataElement blob;
37 blob.SetToBlob(kFakeBlobUUID);
38 out->push_back(blob);
39 }
40
41 TEST(BlobAsyncTransportStrategyTest, TestNoMemoryItems) {
42 BlobAsyncTransportStrategy strategy;
43 std::vector<DataElement> infos;
44
45 // Here we test that we don't do any requests when there are no memory items.
46 AddBlobItem(&infos);
47 AddBlobItem(&infos);
48 AddBlobItem(&infos);
49 strategy.Initialize(100, // max_ipc_memory_size
50 200, // max_shared_memory_size
51 400, // max_file_size
52 5000, // disk_space_left
53 100, // memory_available
54 kNewUUID, infos);
55
56 EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
57
58 EXPECT_EQ(0u, strategy.handle_sizes().size());
59 EXPECT_EQ(0u, strategy.requests().size());
60
61 BlobDataBuilder builder(kNewUUID);
62 builder.AppendBlob(kFakeBlobUUID);
63 builder.AppendBlob(kFakeBlobUUID);
64 builder.AppendBlob(kFakeBlobUUID);
65 EXPECT_EQ(builder, *strategy.blob_builder());
66 }
67
68 TEST(BlobAsyncTransportStrategyTest, TestLargeBlockToFile) {
69 BlobAsyncTransportStrategy strategy;
70 std::vector<DataElement> infos;
71
72 // Here we test our size > max_blob_in_memory_size (100),
73 // and we save to one file. (size < max_file_size)
74 AddMemoryItem(305, &infos);
75 strategy.Initialize(100, // max_ipc_memory_size
76 200, // max_shared_memory_size
77 400, // max_file_size
78 5000, // disk_space_left
79 100, // memory_available
80 kNewUUID, infos);
81
82 EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
83
84 EXPECT_EQ(1u, strategy.handle_sizes().size());
85 EXPECT_EQ(305ul, strategy.handle_sizes().at(0));
86 EXPECT_EQ(1u, strategy.requests().size());
87
88 auto& memory_item_request = strategy.requests().at(0);
89 EXPECT_EQ(0u, memory_item_request.browser_item_index);
90 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
91 EXPECT_EQ(
92 BlobItemBytesRequest::CreateFileRequest(0u, 0u, 0ull, 305ull, 0u, 0ull),
93 memory_item_request.message);
94
95 BlobDataBuilder builder(kNewUUID);
96 builder.AppendFile(kFuturePopulatingFilePath, 0, 305,
97 base::Time::FromDoubleT(0));
98 EXPECT_EQ(builder, *strategy.blob_builder());
99 }
100
101 TEST(BlobAsyncTransportStrategyTest, TestLargeBlockToFiles) {
102 BlobAsyncTransportStrategy strategy;
103 std::vector<DataElement> infos;
104
105 // Here we test our size > max_blob_in_memory_size (300),
106 // and we save 3 files. (size > max_file_size)
107 AddMemoryItem(1000, &infos);
108 strategy.Initialize(100, // max_ipc_memory_size
109 200, // max_shared_memory_size
110 400, // max_file_size
111 5000, // disk_space_left
112 100, // memory_available
113 kNewUUID, infos);
114 EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
115
116 EXPECT_EQ(3u, strategy.handle_sizes().size());
117 EXPECT_EQ(400ul, strategy.handle_sizes().at(0));
118 EXPECT_EQ(400ul, strategy.handle_sizes().at(1));
119 EXPECT_EQ(200ul, strategy.handle_sizes().at(2));
120 EXPECT_EQ(3u, strategy.requests().size());
121
122 auto memory_item_request = strategy.requests().at(0);
123 EXPECT_EQ(0u, memory_item_request.browser_item_index);
124 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
125 EXPECT_EQ(
126 BlobItemBytesRequest::CreateFileRequest(0u, 0u, 0ull, 400ull, 0u, 0ull),
127 memory_item_request.message);
128
129 memory_item_request = strategy.requests().at(1);
130 EXPECT_EQ(1u, memory_item_request.browser_item_index);
131 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
132 EXPECT_EQ(
133 BlobItemBytesRequest::CreateFileRequest(1u, 0u, 400ull, 400ull, 1u, 0ull),
134 memory_item_request.message);
135
136 memory_item_request = strategy.requests().at(2);
137 EXPECT_EQ(2u, memory_item_request.browser_item_index);
138 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
139 EXPECT_EQ(
140 BlobItemBytesRequest::CreateFileRequest(2u, 0u, 800ull, 200ull, 2u, 0ull),
141 memory_item_request.message);
142
143 BlobDataBuilder builder(kNewUUID);
144 builder.AppendFile(kFuturePopulatingFilePath, 0, 400,
145 base::Time::FromDoubleT(0));
146 builder.AppendFile(kFuturePopulatingFilePath, 0, 400,
147 base::Time::FromDoubleT(0));
148 builder.AppendFile(kFuturePopulatingFilePath, 0, 200,
149 base::Time::FromDoubleT(0));
150 EXPECT_EQ(builder, *strategy.blob_builder());
151 }
152
153 TEST(BlobAsyncTransportStrategyTest, TestLargeBlocksConsolidatingInFiles) {
154 BlobAsyncTransportStrategy strategy;
155 std::vector<DataElement> infos;
156
157 // We should have 3 storage items for the memory, two files, 400 each.
158 // We end up with storage items:
159 // 1: File A, 300MB
160 // 2: Blob
161 // 3: File A, 100MB (300MB offset)
162 // 4: File B, 400MB
163 AddMemoryItem(300, &infos);
164 AddBlobItem(&infos);
165 AddMemoryItem(500, &infos);
166
167 strategy.Initialize(100, // max_ipc_memory_size
168 200, // max_shared_memory_size
169 400, // max_file_size
170 5000, // disk_space_left
171 100, // memory_available
172 kNewUUID, infos);
173 EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
174
175 EXPECT_EQ(2u, strategy.handle_sizes().size());
176 EXPECT_EQ(400ul, strategy.handle_sizes().at(0));
177 EXPECT_EQ(400ul, strategy.handle_sizes().at(1));
178 EXPECT_EQ(3u, strategy.requests().size());
179
180 auto memory_item_request = strategy.requests().at(0);
181 EXPECT_EQ(0u, memory_item_request.browser_item_index);
182 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
183 EXPECT_EQ(
184 BlobItemBytesRequest::CreateFileRequest(0u, 0u, 0ull, 300ull, 0u, 0ull),
185 memory_item_request.message);
186
187 memory_item_request = strategy.requests().at(1);
188 EXPECT_EQ(2u, memory_item_request.browser_item_index);
189 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
190 EXPECT_EQ(
191 BlobItemBytesRequest::CreateFileRequest(1u, 2u, 0ull, 100ull, 0u, 300ull),
192 memory_item_request.message);
193
194 memory_item_request = strategy.requests().at(2);
195 EXPECT_EQ(3u, memory_item_request.browser_item_index);
196 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
197 EXPECT_EQ(
198 BlobItemBytesRequest::CreateFileRequest(2u, 2u, 100ull, 400ull, 1u, 0ull),
199 memory_item_request.message);
200 }
201
202 TEST(BlobAsyncTransportStrategyTest, TestSharedMemorySegmentation) {
203 BlobAsyncTransportStrategy strategy;
204 std::vector<DataElement> infos;
205
206 // For transport we should have 3 shared memories, and then storage in 3
207 // browser items.
208 // (size > max_shared_memory_size and size < max_blob_in_memory_size
209 AddMemoryItem(500, &infos);
210 strategy.Initialize(100, // max_ipc_memory_size
211 200, // max_shared_memory_size
212 300, // max_file_size
213 5000, // disk_space_left
214 500, // memory_available
215 kNewUUID, infos);
216 EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
217
218 EXPECT_EQ(3u, strategy.handle_sizes().size());
219 EXPECT_EQ(200u, strategy.handle_sizes().at(0));
220 EXPECT_EQ(200u, strategy.handle_sizes().at(1));
221 EXPECT_EQ(100u, strategy.handle_sizes().at(2));
222 EXPECT_EQ(3u, strategy.requests().size());
223
224 auto memory_item_request = strategy.requests().at(0);
225 EXPECT_EQ(0u, memory_item_request.browser_item_index);
226 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
227 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(0u, 0u, 0ull,
228 200ull, 0u, 0ull),
229 memory_item_request.message);
230
231 memory_item_request = strategy.requests().at(1);
232 EXPECT_EQ(1u, memory_item_request.browser_item_index);
233 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
234 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(1u, 0u, 200ull,
235 200ull, 1u, 0ull),
236 memory_item_request.message);
237
238 memory_item_request = strategy.requests().at(2);
239 EXPECT_EQ(2u, memory_item_request.browser_item_index);
240 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
241 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(2u, 0u, 400ull,
242 100ull, 2u, 0ull),
243 memory_item_request.message);
244
245 BlobDataBuilder builder(kNewUUID);
246 builder.AppendFutureData(200);
247 builder.AppendFutureData(200);
248 builder.AppendFutureData(100);
249
250 EXPECT_EQ(builder, *strategy.blob_builder());
251 }
252
253 TEST(BlobAsyncTransportStrategyTest, TestSharedMemorySegmentationAndStorage) {
254 BlobAsyncTransportStrategy strategy;
255 std::vector<DataElement> infos;
256
257 // For transport, we should have 2 shared memories, where the first one
258 // have half 0 and half 3, and then the last one has half 3.
259 //
260 // For storage, we should have 3 browser items that match the pre-transport
261 // version:
262 // 1: Bytes 100MB
263 // 2: Blob
264 // 3: Bytes 200MB
265 AddShortcutMemoryItem(100, &infos); // should have no behavior change
266 AddBlobItem(&infos);
267 AddMemoryItem(200, &infos);
268
269 strategy.Initialize(100, // max_ipc_memory_size
270 200, // max_shared_memory_size
271 300, // max_file_size
272 5000, // disk_space_left
273 300, // memory_available
274 kNewUUID, infos);
275 EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
276
277 EXPECT_EQ(2u, strategy.handle_sizes().size());
278 EXPECT_EQ(200u, strategy.handle_sizes().at(0));
279 EXPECT_EQ(100u, strategy.handle_sizes().at(1));
280 EXPECT_EQ(3u, strategy.requests().size());
281
282 auto memory_item_request = strategy.requests().at(0);
283 EXPECT_EQ(0u, memory_item_request.browser_item_index);
284 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
285 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(0u, 0u, 0ull,
286 100ull, 0u, 0ull),
287 memory_item_request.message);
288
289 memory_item_request = strategy.requests().at(1);
290 EXPECT_EQ(2u, memory_item_request.browser_item_index);
291 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
292 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(1u, 2u, 0ull,
293 100ull, 0u, 100ull),
294 memory_item_request.message);
295
296 memory_item_request = strategy.requests().at(2);
297 EXPECT_EQ(2u, memory_item_request.browser_item_index);
298 EXPECT_EQ(100u, memory_item_request.browser_item_offset);
299 EXPECT_EQ(BlobItemBytesRequest::CreateSharedMemoryRequest(2u, 2u, 100ull,
300 100ull, 1u, 0ull),
301 memory_item_request.message);
302
303 BlobDataBuilder builder(kNewUUID);
304 builder.AppendFutureData(100);
305 builder.AppendBlob(kFakeBlobUUID);
306 builder.AppendFutureData(200);
307
308 EXPECT_EQ(builder, *strategy.blob_builder());
309 }
310
311 TEST(BlobAsyncTransportStrategyTest, TestTooLarge) {
312 BlobAsyncTransportStrategy strategy;
313 std::vector<DataElement> infos;
314
315 // Our item is too large for disk, so error out.
316 AddMemoryItem(5001, &infos);
317
318 strategy.Initialize(100, // max_ipc_memory_size
319 200, // max_shared_memory_size
320 400, // max_file_size
321 5000, // disk_space_left
322 100, // memory_left
323 kNewUUID, infos);
324
325 EXPECT_EQ(0u, strategy.handle_sizes().size());
326 EXPECT_EQ(0u, strategy.handle_sizes().size());
327 EXPECT_EQ(0u, strategy.requests().size());
328 EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_TOO_LARGE, strategy.error());
329 }
330
331 TEST(BlobAsyncTransportStrategyTest, TestNoDisk) {
332 BlobAsyncTransportStrategy strategy;
333 std::vector<DataElement> infos;
334
335 // Our item is too large for memory, and we are in no_disk mode (incognito)
336 AddMemoryItem(301, &infos);
337
338 strategy.Initialize(100, // max_ipc_memory_size
339 200, // max_shared_memory_size
340 400, // max_file_size
341 0, // disk_space_left
342 300, // memory_available
343 kNewUUID, infos);
344
345 EXPECT_EQ(0u, strategy.handle_sizes().size());
346 EXPECT_EQ(0u, strategy.handle_sizes().size());
347 EXPECT_EQ(0u, strategy.requests().size());
348 EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_TOO_LARGE, strategy.error());
349 }
350
351 TEST(BlobAsyncTransportStrategyTest, TestSimpleIPC) {
352 // Test simple IPC strategy, where size < max_ipc_memory_size and we have
353 // just one item.
354 std::vector<DataElement> infos;
355 BlobAsyncTransportStrategy strategy;
356 AddMemoryItem(10, &infos);
357 AddBlobItem(&infos);
358
359 strategy.Initialize(100, // max_ipc_memory_size
360 200, // max_shared_memory_size
361 400, // max_file_size
362 5000, // disk_space_left
363 100, // memory_left
364 kNewUUID, infos);
365 EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
366
367 ASSERT_EQ(1u, strategy.requests().size());
368
369 auto memory_item_request = strategy.requests().at(0);
370 EXPECT_EQ(0u, memory_item_request.browser_item_index);
371 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
372 EXPECT_EQ(BlobItemBytesRequest::CreateIPCRequest(0u, 0u, 0ull, 10ull),
373 memory_item_request.message);
374 }
375
376 TEST(BlobAsyncTransportStrategyTest, TestMultipleIPC) {
377 // Same as above, but with 2 items and a blob in-between.
378 std::vector<DataElement> infos;
379 BlobAsyncTransportStrategy strategy;
380 infos.clear();
381 AddShortcutMemoryItem(10, &infos); // should have no behavior change
382 AddBlobItem(&infos);
383 AddMemoryItem(80, &infos);
384
385 strategy.Initialize(100, // max_ipc_memory_size
386 200, // max_shared_memory_size
387 400, // max_file_size
388 5000, // disk_space_left
389 100, // memory_left
390 kNewUUID, infos);
391 EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_NONE, strategy.error());
392
393 ASSERT_EQ(2u, strategy.requests().size());
394
395 auto memory_item_request = strategy.requests().at(0);
396 EXPECT_EQ(0u, memory_item_request.browser_item_index);
397 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
398 EXPECT_EQ(BlobItemBytesRequest::CreateIPCRequest(0u, 0u, 0ull, 10ull),
399 memory_item_request.message);
400
401 memory_item_request = strategy.requests().at(1);
402 EXPECT_EQ(2u, memory_item_request.browser_item_index);
403 EXPECT_EQ(0u, memory_item_request.browser_item_offset);
404 EXPECT_EQ(BlobItemBytesRequest::CreateIPCRequest(1u, 2u, 0ull, 80ull),
405 memory_item_request.message);
406
407 // We still populate future data, as the strategy assumes we will be
408 // requesting the data.
409 BlobDataBuilder builder(kNewUUID);
410 builder.AppendFutureData(10);
411 builder.AppendBlob(kFakeBlobUUID);
412 builder.AppendFutureData(80);
413
414 EXPECT_EQ(builder, *strategy.blob_builder());
415 }
416
417 TEST(BlobAsyncTransportStrategyTest, Shortcut) {
418 std::vector<DataElement> infos;
419 AddMemoryItem(100, &infos);
420 AddBlobItem(&infos);
421 EXPECT_FALSE(BlobAsyncTransportStrategy::ShouldBeShortcut(infos, 200));
422
423 infos.clear();
424 AddShortcutMemoryItem(100, &infos);
425 AddBlobItem(&infos);
426 EXPECT_TRUE(BlobAsyncTransportStrategy::ShouldBeShortcut(infos, 200));
427
428 infos.clear();
429 AddShortcutMemoryItem(100, &infos);
430 EXPECT_FALSE(BlobAsyncTransportStrategy::ShouldBeShortcut(infos, 99));
431 }
432 } // namespace
433
434 TEST(BlobAsyncTransportStrategyTest, TestInvalidParams) {
435 std::vector<DataElement> infos;
436 // In order to test uin64_t overflow, we would need to have an array with more
437 // than size_t entries (for 32 byte stuff). So this would only happen if the
438 // IPC was malformed. We instead have to friend this test from DataElement so
439 // we can modify the length to be > size_t.
440 {
441 // Test uint64_t overflow.
442 BlobAsyncTransportStrategy strategy;
443 AddMemoryItem(1, &infos);
444 AddMemoryItem(1, &infos);
445 infos.back().length_ = std::numeric_limits<uint64_t>::max();
446 strategy.Initialize(100, // max_ipc_memory_size
447 200, // max_shared_memory_size
448 400, // max_file_size
449 5000, // disk_space_left
450 100, // memory_left
451 kNewUUID, infos);
452 EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_INVALID_PARAMS,
453 strategy.error());
454 }
455 {
456 // Test size_t overflow.
457 infos.clear();
458 BlobAsyncTransportStrategy strategy;
459 AddMemoryItem(std::numeric_limits<size_t>::max(), &infos);
460 AddMemoryItem(1, &infos);
461
462 strategy.Initialize(100, // max_ipc_memory_size
463 200, // max_shared_memory_size
464 400, // max_file_size
465 5000, // disk_space_left
466 100, // memory_left
467 kNewUUID, infos);
468 EXPECT_EQ(BlobAsyncTransportStrategy::ERROR_INVALID_PARAMS,
469 strategy.error());
470 }
471 }
472 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698