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