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" |
21 #include "net/base/upload_file_element_reader.h" | 22 #include "net/base/upload_file_element_reader.h" |
| 23 #include "net/disk_cache/disk_cache.h" |
22 #include "storage/browser/blob/blob_data_builder.h" | 24 #include "storage/browser/blob/blob_data_builder.h" |
23 #include "storage/browser/blob/blob_data_handle.h" | |
24 #include "storage/browser/blob/blob_storage_context.h" | 25 #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 | 34 namespace { |
35 TEST(UploadDataStreamBuilderTest, CreateUploadDataStream) { | 35 |
| 36 const int kTestDiskCacheStreamIndex = 0; |
| 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) { |
36 base::MessageLoop message_loop; | 157 base::MessageLoop message_loop; |
37 { | 158 { |
38 scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody; | 159 // Setup blob data for testing. |
39 | 160 base::Time time1, time2; |
40 const std::string kBlob = "blobuuid"; | 161 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1); |
41 const std::string kBlobData = "blobdata"; | 162 base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2); |
42 const char kData[] = "123"; | 163 |
43 const base::FilePath::StringType kFilePath = FILE_PATH_LITERAL("abc"); | 164 BlobStorageContext blob_storage_context; |
44 const uint64 kFileOffset = 10U; | 165 |
45 const uint64 kFileLength = 100U; | 166 const std::string blob_id0("id-0"); |
46 const base::Time kFileTime = base::Time::FromDoubleT(999); | 167 scoped_ptr<BlobDataBuilder> blob_data_builder( |
47 const int64 kIdentifier = 12345; | 168 new BlobDataBuilder(blob_id0)); |
48 | 169 scoped_ptr<BlobDataHandle> handle1 = |
49 BlobStorageContext context; | 170 blob_storage_context.AddFinishedBlob(blob_data_builder.get()); |
50 BlobDataBuilder builder(kBlob); | 171 |
51 builder.AppendData(kBlobData); | 172 const std::string blob_id1("id-1"); |
52 scoped_ptr<BlobDataHandle> handle = context.AddFinishedBlob(&builder); | 173 const std::string kBlobData = "BlobData"; |
53 | 174 blob_data_builder.reset(new BlobDataBuilder(blob_id1)); |
54 request_body->AppendBytes(kData, arraysize(kData) - 1); | 175 blob_data_builder->AppendData(kBlobData); |
55 request_body->AppendFileRange(base::FilePath(kFilePath), kFileOffset, | 176 blob_data_builder->AppendFile( |
56 kFileLength, kFileTime); | 177 base::FilePath(FILE_PATH_LITERAL("BlobFile.txt")), 0, 20, time1); |
57 request_body->AppendBlob(kBlob); | 178 scoped_ptr<BlobDataHandle> handle2 = |
58 request_body->set_identifier(kIdentifier); | 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()); |
59 | 218 |
60 scoped_ptr<net::UploadDataStream> upload(UploadDataStreamBuilder::Build( | 219 scoped_ptr<net::UploadDataStream> upload(UploadDataStreamBuilder::Build( |
61 request_body.get(), &context, NULL, | 220 request_body.get(), &blob_storage_context, NULL, |
62 base::ThreadTaskRunnerHandle::Get().get())); | 221 base::ThreadTaskRunnerHandle::Get().get())); |
63 | 222 |
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)); |
68 | 227 EXPECT_TRUE(AreElementsEqual( |
69 const net::UploadBytesElementReader* r1 = | 228 *(*upload->GetElementReaders())[1], upload_element2)); |
70 (*upload->GetElementReaders())[0]->AsBytesReader(); | 229 |
71 ASSERT_TRUE(r1); | 230 // Test having only one blob reference that refers to empty blob data. |
72 EXPECT_EQ(kData, std::string(r1->bytes(), r1->length())); | 231 request_body = new ResourceRequestBody(); |
73 | 232 request_body->AppendBlob(blob_id0); |
74 const net::UploadFileElementReader* r2 = | 233 |
75 (*upload->GetElementReaders())[1]->AsFileReader(); | 234 upload = UploadDataStreamBuilder::Build( |
76 ASSERT_TRUE(r2); | 235 request_body.get(), &blob_storage_context, NULL, |
77 EXPECT_EQ(kFilePath, r2->path().value()); | 236 base::ThreadTaskRunnerHandle::Get().get()); |
78 EXPECT_EQ(kFileOffset, r2->range_offset()); | 237 ASSERT_TRUE(upload->GetElementReaders()); |
79 EXPECT_EQ(kFileLength, r2->range_length()); | 238 ASSERT_EQ(0U, upload->GetElementReaders()->size()); |
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)); |
87 } | 379 } |
88 // Clean up for ASAN. | 380 // Clean up for ASAN. |
89 base::RunLoop().RunUntilIdle(); | 381 base::RunLoop().RunUntilIdle(); |
90 } | 382 } |
91 | 383 |
92 TEST(UploadDataStreamBuilderTest, | 384 TEST(UploadDataStreamBuilderTest, |
93 WriteUploadDataStreamWithEmptyFileBackedBlob) { | 385 WriteUploadDataStreamWithEmptyFileBackedBlob) { |
94 base::MessageLoopForIO message_loop; | 386 base::MessageLoopForIO message_loop; |
95 { | 387 { |
96 base::FilePath test_blob_path; | 388 base::FilePath test_blob_path; |
97 ASSERT_TRUE(base::CreateTemporaryFile(&test_blob_path)); | 389 ASSERT_TRUE(base::CreateTemporaryFile(&test_blob_path)); |
98 | 390 |
99 const uint64_t kZeroLength = 0; | 391 const uint64_t kZeroLength = 0; |
100 base::Time blob_time; | 392 base::Time blob_time; |
101 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &blob_time); | 393 base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &blob_time); |
102 ASSERT_TRUE(base::TouchFile(test_blob_path, blob_time, blob_time)); | 394 ASSERT_TRUE(base::TouchFile(test_blob_path, blob_time, blob_time)); |
103 | 395 |
104 BlobStorageContext blob_storage_context; | 396 BlobStorageContext blob_storage_context; |
105 | 397 |
106 // A blob created from an empty file added several times. | 398 // A blob created from an empty file added several times. |
107 const std::string blob_id("id-0"); | 399 const std::string blob_id("id-0"); |
108 scoped_ptr<BlobDataBuilder> blob_data_builder(new BlobDataBuilder(blob_id)); | 400 scoped_ptr<BlobDataBuilder> blob_data_builder(new BlobDataBuilder(blob_id)); |
109 blob_data_builder->AppendFile(test_blob_path, 0, kZeroLength, blob_time); | 401 blob_data_builder->AppendFile(test_blob_path, 0, kZeroLength, blob_time); |
110 scoped_ptr<BlobDataHandle> handle = | 402 scoped_ptr<BlobDataHandle> handle = |
111 blob_storage_context.AddFinishedBlob(blob_data_builder.get()); | 403 blob_storage_context.AddFinishedBlob(blob_data_builder.get()); |
112 | 404 |
| 405 ResourceRequestBody::Element blob_element; |
| 406 blob_element.SetToFilePathRange(test_blob_path, 0, kZeroLength, blob_time); |
| 407 |
113 scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody()); | 408 scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody()); |
114 scoped_ptr<net::UploadDataStream> upload(UploadDataStreamBuilder::Build( | 409 scoped_ptr<net::UploadDataStream> upload(UploadDataStreamBuilder::Build( |
115 request_body.get(), &blob_storage_context, NULL, | 410 request_body.get(), &blob_storage_context, NULL, |
116 base::ThreadTaskRunnerHandle::Get().get())); | 411 base::ThreadTaskRunnerHandle::Get().get())); |
117 | 412 |
118 request_body = new ResourceRequestBody(); | 413 request_body = new ResourceRequestBody(); |
119 request_body->AppendBlob(blob_id); | 414 request_body->AppendBlob(blob_id); |
120 request_body->AppendBlob(blob_id); | 415 request_body->AppendBlob(blob_id); |
121 request_body->AppendBlob(blob_id); | 416 request_body->AppendBlob(blob_id); |
122 | 417 |
123 upload = UploadDataStreamBuilder::Build( | 418 upload = UploadDataStreamBuilder::Build( |
124 request_body.get(), &blob_storage_context, NULL, | 419 request_body.get(), &blob_storage_context, NULL, |
125 base::ThreadTaskRunnerHandle::Get().get()); | 420 base::ThreadTaskRunnerHandle::Get().get()); |
126 ASSERT_TRUE(upload->GetElementReaders()); | 421 ASSERT_TRUE(upload->GetElementReaders()); |
127 const auto& readers = *upload->GetElementReaders(); | 422 const auto& readers = *upload->GetElementReaders(); |
128 ASSERT_EQ(3U, readers.size()); | 423 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)); |
129 | 427 |
130 net::TestCompletionCallback init_callback; | 428 net::TestCompletionCallback init_callback; |
131 ASSERT_EQ(net::ERR_IO_PENDING, upload->Init(init_callback.callback())); | 429 ASSERT_EQ(net::ERR_IO_PENDING, upload->Init(init_callback.callback())); |
132 EXPECT_EQ(net::OK, init_callback.WaitForResult()); | 430 EXPECT_EQ(net::OK, init_callback.WaitForResult()); |
133 | 431 |
134 EXPECT_EQ(kZeroLength, upload->size()); | 432 EXPECT_EQ(kZeroLength, upload->size()); |
135 | 433 |
136 // Purposely (try to) read more than what is in the stream. If we try to | 434 // Purposely (try to) read more than what is in the stream. If we try to |
137 // read zero bytes then UploadDataStream::Read will fail a DCHECK. | 435 // read zero bytes then UploadDataStream::Read will fail a DCHECK. |
138 int kBufferLength = kZeroLength + 1; | 436 int kBufferLength = kZeroLength + 1; |
139 scoped_ptr<char[]> buffer(new char[kBufferLength]); | 437 scoped_ptr<char[]> buffer(new char[kBufferLength]); |
140 scoped_refptr<net::IOBuffer> io_buffer = | 438 scoped_refptr<net::IOBuffer> io_buffer = |
141 new net::WrappedIOBuffer(buffer.get()); | 439 new net::WrappedIOBuffer(buffer.get()); |
142 net::TestCompletionCallback read_callback; | 440 net::TestCompletionCallback read_callback; |
143 int result = | 441 int result = |
144 upload->Read(io_buffer.get(), kBufferLength, read_callback.callback()); | 442 upload->Read(io_buffer.get(), kBufferLength, read_callback.callback()); |
145 EXPECT_EQ(static_cast<int>(kZeroLength), read_callback.GetResult(result)); | 443 EXPECT_EQ(static_cast<int>(kZeroLength), read_callback.GetResult(result)); |
146 | 444 |
147 base::DeleteFile(test_blob_path, false); | 445 base::DeleteFile(test_blob_path, false); |
148 } | 446 } |
149 // Clean up for ASAN. | 447 // Clean up for ASAN. |
150 base::RunLoop().RunUntilIdle(); | 448 base::RunLoop().RunUntilIdle(); |
151 } | 449 } |
152 } // namespace content | 450 } // namespace content |
OLD | NEW |