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

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

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

Powered by Google App Engine
This is Rietveld 408576698