OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/loader/upload_data_stream_builder.h" | 5 #include "content/browser/loader/upload_data_stream_builder.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
13 #include "base/thread_task_runner_handle.h" | 13 #include "base/thread_task_runner_handle.h" |
14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
15 #include "content/common/resource_request_body.h" | 15 #include "content/common/resource_request_body.h" |
16 #include "net/base/io_buffer.h" | 16 #include "net/base/io_buffer.h" |
17 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
18 #include "net/base/test_completion_callback.h" | 18 #include "net/base/test_completion_callback.h" |
19 #include "net/base/upload_bytes_element_reader.h" | 19 #include "net/base/upload_bytes_element_reader.h" |
20 #include "net/base/upload_data_stream.h" | 20 #include "net/base/upload_data_stream.h" |
21 #include "net/base/upload_disk_cache_entry_element_reader.h" | |
22 #include "net/base/upload_file_element_reader.h" | 21 #include "net/base/upload_file_element_reader.h" |
23 #include "net/disk_cache/disk_cache.h" | |
24 #include "storage/browser/blob/blob_data_builder.h" | 22 #include "storage/browser/blob/blob_data_builder.h" |
| 23 #include "storage/browser/blob/blob_data_handle.h" |
25 #include "storage/browser/blob/blob_storage_context.h" | 24 #include "storage/browser/blob/blob_storage_context.h" |
| 25 #include "storage/browser/blob/upload_blob_element_reader.h" |
26 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
27 #include "url/gurl.h" | 27 #include "url/gurl.h" |
28 | 28 |
29 using storage::BlobDataBuilder; | 29 using storage::BlobDataBuilder; |
30 using storage::BlobDataHandle; | 30 using storage::BlobDataHandle; |
31 using storage::BlobStorageContext; | 31 using storage::BlobStorageContext; |
32 | 32 |
33 namespace content { | 33 namespace content { |
34 namespace { | |
35 | 34 |
36 const int kTestDiskCacheStreamIndex = 0; | 35 TEST(UploadDataStreamBuilderTest, CreateUploadDataStream) { |
37 | |
38 // Our disk cache tests don't need a real data handle since the tests themselves | |
39 // scope the disk cache and entries. | |
40 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle { | |
41 private: | |
42 ~EmptyDataHandle() override {} | |
43 }; | |
44 | |
45 scoped_ptr<disk_cache::Backend> CreateInMemoryDiskCache() { | |
46 scoped_ptr<disk_cache::Backend> cache; | |
47 net::TestCompletionCallback callback; | |
48 int rv = disk_cache::CreateCacheBackend(net::MEMORY_CACHE, | |
49 net::CACHE_BACKEND_DEFAULT, | |
50 base::FilePath(), 0, | |
51 false, nullptr, nullptr, &cache, | |
52 callback.callback()); | |
53 EXPECT_EQ(net::OK, callback.GetResult(rv)); | |
54 | |
55 return cache.Pass(); | |
56 } | |
57 | |
58 disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache, | |
59 const char* key, | |
60 const std::string& data) { | |
61 disk_cache::Entry* temp_entry = nullptr; | |
62 net::TestCompletionCallback callback; | |
63 int rv = cache->CreateEntry(key, &temp_entry, callback.callback()); | |
64 if (callback.GetResult(rv) != net::OK) | |
65 return nullptr; | |
66 disk_cache::ScopedEntryPtr entry(temp_entry); | |
67 | |
68 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data); | |
69 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(), | |
70 iobuffer->size(), callback.callback(), false); | |
71 EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv)); | |
72 return entry.Pass(); | |
73 } | |
74 | |
75 bool AreElementsEqual(const net::UploadElementReader& reader, | |
76 const ResourceRequestBody::Element& element) { | |
77 switch(element.type()) { | |
78 case ResourceRequestBody::Element::TYPE_BYTES: { | |
79 const net::UploadBytesElementReader* bytes_reader = | |
80 reader.AsBytesReader(); | |
81 return bytes_reader && | |
82 element.length() == bytes_reader->length() && | |
83 std::equal(element.bytes(), element.bytes() + element.length(), | |
84 bytes_reader->bytes()); | |
85 } | |
86 case ResourceRequestBody::Element::TYPE_FILE: { | |
87 const net::UploadFileElementReader* file_reader = reader.AsFileReader(); | |
88 return file_reader && | |
89 file_reader->path() == element.path() && | |
90 file_reader->range_offset() == element.offset() && | |
91 file_reader->range_length() == element.length() && | |
92 file_reader->expected_modification_time() == | |
93 element.expected_modification_time(); | |
94 break; | |
95 } | |
96 case ResourceRequestBody::Element::TYPE_DISK_CACHE_ENTRY: { | |
97 // TODO(gavinp): Should we be comparing a higher level structure | |
98 // such as the BlobDataItem so that we can do stronger equality | |
99 // comparisons? | |
100 const net::UploadDiskCacheEntryElementReader* disk_cache_entry_reader = | |
101 reader.AsDiskCacheEntryReaderForTests(); | |
102 return disk_cache_entry_reader && | |
103 disk_cache_entry_reader->range_offset_for_tests() == | |
104 static_cast<int>(element.offset()) && | |
105 disk_cache_entry_reader->range_length_for_tests() == | |
106 static_cast<int>(element.length()); | |
107 break; | |
108 } | |
109 default: | |
110 NOTREACHED(); | |
111 } | |
112 return false; | |
113 } | |
114 | |
115 } // namespace | |
116 | |
117 TEST(UploadDataStreamBuilderTest, CreateUploadDataStreamWithoutBlob) { | |
118 base::MessageLoop message_loop; | |
119 scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody; | |
120 | |
121 const char kData[] = "123"; | |
122 const base::FilePath::StringType kFilePath = FILE_PATH_LITERAL("abc"); | |
123 const uint64 kFileOffset = 10U; | |
124 const uint64 kFileLength = 100U; | |
125 const base::Time kFileTime = base::Time::FromDoubleT(999); | |
126 const int64 kIdentifier = 12345; | |
127 | |
128 request_body->AppendBytes(kData, arraysize(kData) - 1); | |
129 request_body->AppendFileRange(base::FilePath(kFilePath), | |
130 kFileOffset, kFileLength, kFileTime); | |
131 request_body->set_identifier(kIdentifier); | |
132 | |
133 scoped_ptr<net::UploadDataStream> upload(UploadDataStreamBuilder::Build( | |
134 request_body.get(), NULL, NULL, | |
135 base::ThreadTaskRunnerHandle::Get().get())); | |
136 | |
137 EXPECT_EQ(kIdentifier, upload->identifier()); | |
138 ASSERT_TRUE(upload->GetElementReaders()); | |
139 ASSERT_EQ(request_body->elements()->size(), | |
140 upload->GetElementReaders()->size()); | |
141 | |
142 const net::UploadBytesElementReader* r1 = | |
143 (*upload->GetElementReaders())[0]->AsBytesReader(); | |
144 ASSERT_TRUE(r1); | |
145 EXPECT_EQ(kData, std::string(r1->bytes(), r1->length())); | |
146 | |
147 const net::UploadFileElementReader* r2 = | |
148 (*upload->GetElementReaders())[1]->AsFileReader(); | |
149 ASSERT_TRUE(r2); | |
150 EXPECT_EQ(kFilePath, r2->path().value()); | |
151 EXPECT_EQ(kFileOffset, r2->range_offset()); | |
152 EXPECT_EQ(kFileLength, r2->range_length()); | |
153 EXPECT_EQ(kFileTime, r2->expected_modification_time()); | |
154 } | |
155 | |
156 TEST(UploadDataStreamBuilderTest, ResolveBlobAndCreateUploadDataStream) { | |
157 base::MessageLoop message_loop; | 36 base::MessageLoop message_loop; |
158 { | 37 { |
159 // Setup blob data for testing. | 38 scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody; |
160 base::Time time1, time2; | |
161 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1); | |
162 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2); | |
163 | 39 |
164 BlobStorageContext blob_storage_context; | 40 const std::string kBlob = "blobuuid"; |
| 41 const std::string kBlobData = "blobdata"; |
| 42 const char kData[] = "123"; |
| 43 const base::FilePath::StringType kFilePath = FILE_PATH_LITERAL("abc"); |
| 44 const uint64 kFileOffset = 10U; |
| 45 const uint64 kFileLength = 100U; |
| 46 const base::Time kFileTime = base::Time::FromDoubleT(999); |
| 47 const int64 kIdentifier = 12345; |
165 | 48 |
166 const std::string blob_id0("id-0"); | 49 BlobStorageContext context; |
167 scoped_ptr<BlobDataBuilder> blob_data_builder( | 50 BlobDataBuilder builder(kBlob); |
168 new BlobDataBuilder(blob_id0)); | 51 builder.AppendData(kBlobData); |
169 scoped_ptr<BlobDataHandle> handle1 = | 52 scoped_ptr<BlobDataHandle> handle = context.AddFinishedBlob(&builder); |
170 blob_storage_context.AddFinishedBlob(blob_data_builder.get()); | |
171 | 53 |
172 const std::string blob_id1("id-1"); | 54 request_body->AppendBytes(kData, arraysize(kData) - 1); |
173 const std::string kBlobData = "BlobData"; | 55 request_body->AppendFileRange(base::FilePath(kFilePath), kFileOffset, |
174 blob_data_builder.reset(new BlobDataBuilder(blob_id1)); | 56 kFileLength, kFileTime); |
175 blob_data_builder->AppendData(kBlobData); | 57 request_body->AppendBlob(kBlob); |
176 blob_data_builder->AppendFile( | 58 request_body->set_identifier(kIdentifier); |
177 base::FilePath(FILE_PATH_LITERAL("BlobFile.txt")), 0, 20, time1); | |
178 scoped_ptr<BlobDataHandle> handle2 = | |
179 blob_storage_context.AddFinishedBlob(blob_data_builder.get()); | |
180 | |
181 const std::string blob_id2("id-2"); | |
182 const std::string kDiskCacheData = "DiskCacheData"; | |
183 scoped_ptr<disk_cache::Backend> disk_cache_backend = | |
184 CreateInMemoryDiskCache(); | |
185 ASSERT_TRUE(disk_cache_backend); | |
186 disk_cache::ScopedEntryPtr disk_cache_entry = | |
187 CreateDiskCacheEntry(disk_cache_backend.get(), "a key", kDiskCacheData); | |
188 ASSERT_TRUE(disk_cache_entry); | |
189 blob_data_builder.reset(new BlobDataBuilder(blob_id2)); | |
190 blob_data_builder->AppendDiskCacheEntry( | |
191 new EmptyDataHandle(), disk_cache_entry.get(), | |
192 kTestDiskCacheStreamIndex); | |
193 scoped_ptr<BlobDataHandle> handle3 = | |
194 blob_storage_context.AddFinishedBlob(blob_data_builder.get()); | |
195 | |
196 // Setup upload data elements for comparison. | |
197 ResourceRequestBody::Element blob_element1, blob_element2, blob_element3; | |
198 blob_element1.SetToBytes(kBlobData.c_str(), kBlobData.size()); | |
199 blob_element2.SetToFilePathRange( | |
200 base::FilePath(FILE_PATH_LITERAL("BlobFile.txt")), 0, 20, time1); | |
201 blob_element3.SetToDiskCacheEntryRange(0, kDiskCacheData.size()); | |
202 | |
203 ResourceRequestBody::Element upload_element1, upload_element2; | |
204 upload_element1.SetToBytes("Hello", 5); | |
205 upload_element2.SetToFilePathRange( | |
206 base::FilePath(FILE_PATH_LITERAL("foo1.txt")), 0, 20, time2); | |
207 | |
208 // Test no blob reference. | |
209 scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody()); | |
210 request_body->AppendBytes( | |
211 upload_element1.bytes(), | |
212 upload_element1.length()); | |
213 request_body->AppendFileRange( | |
214 upload_element2.path(), | |
215 upload_element2.offset(), | |
216 upload_element2.length(), | |
217 upload_element2.expected_modification_time()); | |
218 | 59 |
219 scoped_ptr<net::UploadDataStream> upload(UploadDataStreamBuilder::Build( | 60 scoped_ptr<net::UploadDataStream> upload(UploadDataStreamBuilder::Build( |
220 request_body.get(), &blob_storage_context, NULL, | 61 request_body.get(), &context, NULL, |
221 base::ThreadTaskRunnerHandle::Get().get())); | 62 base::ThreadTaskRunnerHandle::Get().get())); |
222 | 63 |
| 64 EXPECT_EQ(kIdentifier, upload->identifier()); |
223 ASSERT_TRUE(upload->GetElementReaders()); | 65 ASSERT_TRUE(upload->GetElementReaders()); |
224 ASSERT_EQ(2U, upload->GetElementReaders()->size()); | 66 ASSERT_EQ(request_body->elements()->size(), |
225 EXPECT_TRUE(AreElementsEqual( | 67 upload->GetElementReaders()->size()); |
226 *(*upload->GetElementReaders())[0], upload_element1)); | |
227 EXPECT_TRUE(AreElementsEqual( | |
228 *(*upload->GetElementReaders())[1], upload_element2)); | |
229 | 68 |
230 // Test having only one blob reference that refers to empty blob data. | 69 const net::UploadBytesElementReader* r1 = |
231 request_body = new ResourceRequestBody(); | 70 (*upload->GetElementReaders())[0]->AsBytesReader(); |
232 request_body->AppendBlob(blob_id0); | 71 ASSERT_TRUE(r1); |
| 72 EXPECT_EQ(kData, std::string(r1->bytes(), r1->length())); |
233 | 73 |
234 upload = UploadDataStreamBuilder::Build( | 74 const net::UploadFileElementReader* r2 = |
235 request_body.get(), &blob_storage_context, NULL, | 75 (*upload->GetElementReaders())[1]->AsFileReader(); |
236 base::ThreadTaskRunnerHandle::Get().get()); | 76 ASSERT_TRUE(r2); |
237 ASSERT_TRUE(upload->GetElementReaders()); | 77 EXPECT_EQ(kFilePath, r2->path().value()); |
238 ASSERT_EQ(0U, upload->GetElementReaders()->size()); | 78 EXPECT_EQ(kFileOffset, r2->range_offset()); |
| 79 EXPECT_EQ(kFileLength, r2->range_length()); |
| 80 EXPECT_EQ(kFileTime, r2->expected_modification_time()); |
239 | 81 |
240 // Test having only one blob reference. | 82 const storage::UploadBlobElementReader* r3 = |
241 request_body = new ResourceRequestBody(); | 83 static_cast<storage::UploadBlobElementReader*>( |
242 request_body->AppendBlob(blob_id1); | 84 (*upload->GetElementReaders())[2]); |
243 | 85 ASSERT_TRUE(r3); |
244 upload = UploadDataStreamBuilder::Build( | 86 EXPECT_EQ("blobuuid", r3->uuid()); |
245 request_body.get(), &blob_storage_context, NULL, | |
246 base::ThreadTaskRunnerHandle::Get().get()); | |
247 ASSERT_TRUE(upload->GetElementReaders()); | |
248 ASSERT_EQ(2U, upload->GetElementReaders()->size()); | |
249 EXPECT_TRUE(AreElementsEqual( | |
250 *(*upload->GetElementReaders())[0], blob_element1)); | |
251 EXPECT_TRUE(AreElementsEqual( | |
252 *(*upload->GetElementReaders())[1], blob_element2)); | |
253 | |
254 // Test having one blob reference which refers to a disk cache entry. | |
255 request_body = new ResourceRequestBody(); | |
256 request_body->AppendBlob(blob_id2); | |
257 | |
258 upload = UploadDataStreamBuilder::Build( | |
259 request_body.get(), &blob_storage_context, nullptr, | |
260 base::ThreadTaskRunnerHandle::Get().get()); | |
261 ASSERT_TRUE(upload->GetElementReaders()); | |
262 ASSERT_EQ(1U, upload->GetElementReaders()->size()); | |
263 EXPECT_TRUE(AreElementsEqual( | |
264 *(*upload->GetElementReaders())[0], blob_element3)); | |
265 | |
266 // Test having one blob reference at the beginning. | |
267 request_body = new ResourceRequestBody(); | |
268 request_body->AppendBlob(blob_id1); | |
269 request_body->AppendBytes( | |
270 upload_element1.bytes(), | |
271 upload_element1.length()); | |
272 request_body->AppendFileRange( | |
273 upload_element2.path(), | |
274 upload_element2.offset(), | |
275 upload_element2.length(), | |
276 upload_element2.expected_modification_time()); | |
277 | |
278 upload = UploadDataStreamBuilder::Build( | |
279 request_body.get(), &blob_storage_context, NULL, | |
280 base::ThreadTaskRunnerHandle::Get().get()); | |
281 ASSERT_TRUE(upload->GetElementReaders()); | |
282 ASSERT_EQ(4U, upload->GetElementReaders()->size()); | |
283 EXPECT_TRUE(AreElementsEqual( | |
284 *(*upload->GetElementReaders())[0], blob_element1)); | |
285 EXPECT_TRUE(AreElementsEqual( | |
286 *(*upload->GetElementReaders())[1], blob_element2)); | |
287 EXPECT_TRUE(AreElementsEqual( | |
288 *(*upload->GetElementReaders())[2], upload_element1)); | |
289 EXPECT_TRUE(AreElementsEqual( | |
290 *(*upload->GetElementReaders())[3], upload_element2)); | |
291 | |
292 // Test having one blob reference at the end. | |
293 request_body = new ResourceRequestBody(); | |
294 request_body->AppendBytes( | |
295 upload_element1.bytes(), | |
296 upload_element1.length()); | |
297 request_body->AppendFileRange( | |
298 upload_element2.path(), | |
299 upload_element2.offset(), | |
300 upload_element2.length(), | |
301 upload_element2.expected_modification_time()); | |
302 request_body->AppendBlob(blob_id1); | |
303 | |
304 upload = UploadDataStreamBuilder::Build( | |
305 request_body.get(), &blob_storage_context, NULL, | |
306 base::ThreadTaskRunnerHandle::Get().get()); | |
307 ASSERT_TRUE(upload->GetElementReaders()); | |
308 ASSERT_EQ(4U, upload->GetElementReaders()->size()); | |
309 EXPECT_TRUE(AreElementsEqual( | |
310 *(*upload->GetElementReaders())[0], upload_element1)); | |
311 EXPECT_TRUE(AreElementsEqual( | |
312 *(*upload->GetElementReaders())[1], upload_element2)); | |
313 EXPECT_TRUE(AreElementsEqual( | |
314 *(*upload->GetElementReaders())[2], blob_element1)); | |
315 EXPECT_TRUE(AreElementsEqual( | |
316 *(*upload->GetElementReaders())[3], blob_element2)); | |
317 | |
318 // Test having one blob reference in the middle. | |
319 request_body = new ResourceRequestBody(); | |
320 request_body->AppendBytes( | |
321 upload_element1.bytes(), | |
322 upload_element1.length()); | |
323 request_body->AppendBlob(blob_id1); | |
324 request_body->AppendFileRange( | |
325 upload_element2.path(), | |
326 upload_element2.offset(), | |
327 upload_element2.length(), | |
328 upload_element2.expected_modification_time()); | |
329 | |
330 upload = UploadDataStreamBuilder::Build( | |
331 request_body.get(), &blob_storage_context, NULL, | |
332 base::ThreadTaskRunnerHandle::Get().get()); | |
333 ASSERT_TRUE(upload->GetElementReaders()); | |
334 ASSERT_EQ(4U, upload->GetElementReaders()->size()); | |
335 EXPECT_TRUE(AreElementsEqual( | |
336 *(*upload->GetElementReaders())[0], upload_element1)); | |
337 EXPECT_TRUE(AreElementsEqual( | |
338 *(*upload->GetElementReaders())[1], blob_element1)); | |
339 EXPECT_TRUE(AreElementsEqual( | |
340 *(*upload->GetElementReaders())[2], blob_element2)); | |
341 EXPECT_TRUE(AreElementsEqual( | |
342 *(*upload->GetElementReaders())[3], upload_element2)); | |
343 | |
344 // Test having multiple blob references. | |
345 request_body = new ResourceRequestBody(); | |
346 request_body->AppendBlob(blob_id1); | |
347 request_body->AppendBytes( | |
348 upload_element1.bytes(), | |
349 upload_element1.length()); | |
350 request_body->AppendBlob(blob_id1); | |
351 request_body->AppendBlob(blob_id1); | |
352 request_body->AppendFileRange( | |
353 upload_element2.path(), | |
354 upload_element2.offset(), | |
355 upload_element2.length(), | |
356 upload_element2.expected_modification_time()); | |
357 | |
358 upload = UploadDataStreamBuilder::Build( | |
359 request_body.get(), &blob_storage_context, NULL, | |
360 base::ThreadTaskRunnerHandle::Get().get()); | |
361 ASSERT_TRUE(upload->GetElementReaders()); | |
362 ASSERT_EQ(8U, upload->GetElementReaders()->size()); | |
363 EXPECT_TRUE(AreElementsEqual( | |
364 *(*upload->GetElementReaders())[0], blob_element1)); | |
365 EXPECT_TRUE(AreElementsEqual( | |
366 *(*upload->GetElementReaders())[1], blob_element2)); | |
367 EXPECT_TRUE(AreElementsEqual( | |
368 *(*upload->GetElementReaders())[2], upload_element1)); | |
369 EXPECT_TRUE(AreElementsEqual( | |
370 *(*upload->GetElementReaders())[3], blob_element1)); | |
371 EXPECT_TRUE(AreElementsEqual( | |
372 *(*upload->GetElementReaders())[4], blob_element2)); | |
373 EXPECT_TRUE(AreElementsEqual( | |
374 *(*upload->GetElementReaders())[5], blob_element1)); | |
375 EXPECT_TRUE(AreElementsEqual( | |
376 *(*upload->GetElementReaders())[6], blob_element2)); | |
377 EXPECT_TRUE(AreElementsEqual( | |
378 *(*upload->GetElementReaders())[7], upload_element2)); | |
379 } | 87 } |
380 // Clean up for ASAN. | 88 // Clean up for ASAN. |
381 base::RunLoop().RunUntilIdle(); | 89 base::RunLoop().RunUntilIdle(); |
382 } | 90 } |
383 | 91 |
384 TEST(UploadDataStreamBuilderTest, | 92 TEST(UploadDataStreamBuilderTest, |
385 WriteUploadDataStreamWithEmptyFileBackedBlob) { | 93 WriteUploadDataStreamWithEmptyFileBackedBlob) { |
386 base::MessageLoopForIO message_loop; | 94 base::MessageLoopForIO message_loop; |
387 { | 95 { |
388 base::FilePath test_blob_path; | 96 base::FilePath test_blob_path; |
389 ASSERT_TRUE(base::CreateTemporaryFile(&test_blob_path)); | 97 ASSERT_TRUE(base::CreateTemporaryFile(&test_blob_path)); |
390 | 98 |
391 const uint64_t kZeroLength = 0; | 99 const uint64_t kZeroLength = 0; |
392 base::Time blob_time; | 100 base::Time blob_time; |
393 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &blob_time); | 101 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &blob_time); |
394 ASSERT_TRUE(base::TouchFile(test_blob_path, blob_time, blob_time)); | 102 ASSERT_TRUE(base::TouchFile(test_blob_path, blob_time, blob_time)); |
395 | 103 |
396 BlobStorageContext blob_storage_context; | 104 BlobStorageContext blob_storage_context; |
397 | 105 |
398 // A blob created from an empty file added several times. | 106 // A blob created from an empty file added several times. |
399 const std::string blob_id("id-0"); | 107 const std::string blob_id("id-0"); |
400 scoped_ptr<BlobDataBuilder> blob_data_builder(new BlobDataBuilder(blob_id)); | 108 scoped_ptr<BlobDataBuilder> blob_data_builder(new BlobDataBuilder(blob_id)); |
401 blob_data_builder->AppendFile(test_blob_path, 0, kZeroLength, blob_time); | 109 blob_data_builder->AppendFile(test_blob_path, 0, kZeroLength, blob_time); |
402 scoped_ptr<BlobDataHandle> handle = | 110 scoped_ptr<BlobDataHandle> handle = |
403 blob_storage_context.AddFinishedBlob(blob_data_builder.get()); | 111 blob_storage_context.AddFinishedBlob(blob_data_builder.get()); |
404 | 112 |
405 ResourceRequestBody::Element blob_element; | |
406 blob_element.SetToFilePathRange(test_blob_path, 0, kZeroLength, blob_time); | |
407 | |
408 scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody()); | 113 scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody()); |
409 scoped_ptr<net::UploadDataStream> upload(UploadDataStreamBuilder::Build( | 114 scoped_ptr<net::UploadDataStream> upload(UploadDataStreamBuilder::Build( |
410 request_body.get(), &blob_storage_context, NULL, | 115 request_body.get(), &blob_storage_context, NULL, |
411 base::ThreadTaskRunnerHandle::Get().get())); | 116 base::ThreadTaskRunnerHandle::Get().get())); |
412 | 117 |
413 request_body = new ResourceRequestBody(); | 118 request_body = new ResourceRequestBody(); |
414 request_body->AppendBlob(blob_id); | 119 request_body->AppendBlob(blob_id); |
415 request_body->AppendBlob(blob_id); | 120 request_body->AppendBlob(blob_id); |
416 request_body->AppendBlob(blob_id); | 121 request_body->AppendBlob(blob_id); |
417 | 122 |
418 upload = UploadDataStreamBuilder::Build( | 123 upload = UploadDataStreamBuilder::Build( |
419 request_body.get(), &blob_storage_context, NULL, | 124 request_body.get(), &blob_storage_context, NULL, |
420 base::ThreadTaskRunnerHandle::Get().get()); | 125 base::ThreadTaskRunnerHandle::Get().get()); |
421 ASSERT_TRUE(upload->GetElementReaders()); | 126 ASSERT_TRUE(upload->GetElementReaders()); |
422 const auto& readers = *upload->GetElementReaders(); | 127 const auto& readers = *upload->GetElementReaders(); |
423 ASSERT_EQ(3U, readers.size()); | 128 ASSERT_EQ(3U, readers.size()); |
424 EXPECT_TRUE(AreElementsEqual(*readers[0], blob_element)); | |
425 EXPECT_TRUE(AreElementsEqual(*readers[1], blob_element)); | |
426 EXPECT_TRUE(AreElementsEqual(*readers[2], blob_element)); | |
427 | 129 |
428 net::TestCompletionCallback init_callback; | 130 net::TestCompletionCallback init_callback; |
429 ASSERT_EQ(net::ERR_IO_PENDING, upload->Init(init_callback.callback())); | 131 ASSERT_EQ(net::ERR_IO_PENDING, upload->Init(init_callback.callback())); |
430 EXPECT_EQ(net::OK, init_callback.WaitForResult()); | 132 EXPECT_EQ(net::OK, init_callback.WaitForResult()); |
431 | 133 |
432 EXPECT_EQ(kZeroLength, upload->size()); | 134 EXPECT_EQ(kZeroLength, upload->size()); |
433 | 135 |
434 // Purposely (try to) read more than what is in the stream. If we try to | 136 // Purposely (try to) read more than what is in the stream. If we try to |
435 // read zero bytes then UploadDataStream::Read will fail a DCHECK. | 137 // read zero bytes then UploadDataStream::Read will fail a DCHECK. |
436 int kBufferLength = kZeroLength + 1; | 138 int kBufferLength = kZeroLength + 1; |
437 scoped_ptr<char[]> buffer(new char[kBufferLength]); | 139 scoped_ptr<char[]> buffer(new char[kBufferLength]); |
438 scoped_refptr<net::IOBuffer> io_buffer = | 140 scoped_refptr<net::IOBuffer> io_buffer = |
439 new net::WrappedIOBuffer(buffer.get()); | 141 new net::WrappedIOBuffer(buffer.get()); |
440 net::TestCompletionCallback read_callback; | 142 net::TestCompletionCallback read_callback; |
441 int result = | 143 int result = |
442 upload->Read(io_buffer.get(), kBufferLength, read_callback.callback()); | 144 upload->Read(io_buffer.get(), kBufferLength, read_callback.callback()); |
443 EXPECT_EQ(static_cast<int>(kZeroLength), read_callback.GetResult(result)); | 145 EXPECT_EQ(static_cast<int>(kZeroLength), read_callback.GetResult(result)); |
444 | 146 |
445 base::DeleteFile(test_blob_path, false); | 147 base::DeleteFile(test_blob_path, false); |
446 } | 148 } |
447 // Clean up for ASAN. | 149 // Clean up for ASAN. |
448 base::RunLoop().RunUntilIdle(); | 150 base::RunLoop().RunUntilIdle(); |
449 } | 151 } |
450 } // namespace content | 152 } // namespace content |
OLD | NEW |