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_storage_context.h" | 25 #include "storage/browser/blob/blob_storage_context.h" |
24 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
25 #include "url/gurl.h" | 27 #include "url/gurl.h" |
26 | 28 |
27 using storage::BlobDataBuilder; | 29 using storage::BlobDataBuilder; |
28 using storage::BlobDataHandle; | 30 using storage::BlobDataHandle; |
29 using storage::BlobStorageContext; | 31 using storage::BlobStorageContext; |
30 | 32 |
31 namespace content { | 33 namespace content { |
32 namespace { | 34 namespace { |
33 | 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 cb; | |
48 int rv = disk_cache::CreateCacheBackend(net::MEMORY_CACHE, | |
49 net::CACHE_BACKEND_DEFAULT, | |
50 base::FilePath(), 0, | |
51 false, NULL, NULL, &cache, | |
52 cb.callback()); | |
53 EXPECT_EQ(net::OK, cb.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* tmp_entry = nullptr; | |
62 net::TestCompletionCallback cb; | |
63 int rv = cache->CreateEntry(key, &tmp_entry, cb.callback()); | |
64 if (cb.GetResult(rv) != net::OK) | |
65 return nullptr; | |
66 disk_cache::ScopedEntryPtr entry(tmp_entry); | |
67 | |
68 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data); | |
69 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(), | |
70 iobuffer->size(), cb.callback(), false); | |
71 EXPECT_EQ(static_cast<int>(data.size()), cb.GetResult(rv)); | |
72 return entry.Pass(); | |
73 } | |
74 | |
34 bool AreElementsEqual(const net::UploadElementReader& reader, | 75 bool AreElementsEqual(const net::UploadElementReader& reader, |
35 const ResourceRequestBody::Element& element) { | 76 const ResourceRequestBody::Element& element) { |
36 switch(element.type()) { | 77 switch(element.type()) { |
37 case ResourceRequestBody::Element::TYPE_BYTES: { | 78 case ResourceRequestBody::Element::TYPE_BYTES: { |
38 const net::UploadBytesElementReader* bytes_reader = | 79 const net::UploadBytesElementReader* bytes_reader = |
39 reader.AsBytesReader(); | 80 reader.AsBytesReader(); |
40 return bytes_reader && | 81 return bytes_reader && |
41 element.length() == bytes_reader->length() && | 82 element.length() == bytes_reader->length() && |
42 std::equal(element.bytes(), element.bytes() + element.length(), | 83 std::equal(element.bytes(), element.bytes() + element.length(), |
43 bytes_reader->bytes()); | 84 bytes_reader->bytes()); |
44 } | 85 } |
45 case ResourceRequestBody::Element::TYPE_FILE: { | 86 case ResourceRequestBody::Element::TYPE_FILE: { |
46 const net::UploadFileElementReader* file_reader = reader.AsFileReader(); | 87 const net::UploadFileElementReader* file_reader = reader.AsFileReader(); |
47 return file_reader && | 88 return file_reader && |
48 file_reader->path() == element.path() && | 89 file_reader->path() == element.path() && |
49 file_reader->range_offset() == element.offset() && | 90 file_reader->range_offset() == element.offset() && |
50 file_reader->range_length() == element.length() && | 91 file_reader->range_length() == element.length() && |
51 file_reader->expected_modification_time() == | 92 file_reader->expected_modification_time() == |
52 element.expected_modification_time(); | 93 element.expected_modification_time(); |
53 break; | 94 break; |
54 } | 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 } | |
55 default: | 109 default: |
56 NOTREACHED(); | 110 NOTREACHED(); |
57 } | 111 } |
58 return false; | 112 return false; |
59 } | 113 } |
60 | 114 |
61 } // namespace | 115 } // namespace |
62 | 116 |
63 TEST(UploadDataStreamBuilderTest, CreateUploadDataStreamWithoutBlob) { | 117 TEST(UploadDataStreamBuilderTest, CreateUploadDataStreamWithoutBlob) { |
64 base::MessageLoop message_loop; | 118 base::MessageLoop message_loop; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
117 | 171 |
118 const std::string blob_id1("id-1"); | 172 const std::string blob_id1("id-1"); |
119 const std::string kBlobData = "BlobData"; | 173 const std::string kBlobData = "BlobData"; |
120 blob_data_builder.reset(new BlobDataBuilder(blob_id1)); | 174 blob_data_builder.reset(new BlobDataBuilder(blob_id1)); |
121 blob_data_builder->AppendData(kBlobData); | 175 blob_data_builder->AppendData(kBlobData); |
122 blob_data_builder->AppendFile( | 176 blob_data_builder->AppendFile( |
123 base::FilePath(FILE_PATH_LITERAL("BlobFile.txt")), 0, 20, time1); | 177 base::FilePath(FILE_PATH_LITERAL("BlobFile.txt")), 0, 20, time1); |
124 scoped_ptr<BlobDataHandle> handle2 = | 178 scoped_ptr<BlobDataHandle> handle2 = |
125 blob_storage_context.AddFinishedBlob(blob_data_builder.get()); | 179 blob_storage_context.AddFinishedBlob(blob_data_builder.get()); |
126 | 180 |
181 const std::string blob_id2("id-2"); | |
michaeln
2015/06/17 00:57:37
nit: should two adjacent lines be consistent with
gavinp
2015/06/17 15:14:21
Awkwardly, this usage is cut and paste from line 1
| |
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 | |
127 // Setup upload data elements for comparison. | 196 // Setup upload data elements for comparison. |
128 ResourceRequestBody::Element blob_element1, blob_element2; | 197 ResourceRequestBody::Element blob_element1, blob_element2, blob_element3; |
129 blob_element1.SetToBytes(kBlobData.c_str(), kBlobData.size()); | 198 blob_element1.SetToBytes(kBlobData.c_str(), kBlobData.size()); |
130 blob_element2.SetToFilePathRange( | 199 blob_element2.SetToFilePathRange( |
131 base::FilePath(FILE_PATH_LITERAL("BlobFile.txt")), 0, 20, time1); | 200 base::FilePath(FILE_PATH_LITERAL("BlobFile.txt")), 0, 20, time1); |
201 blob_element3.SetToDiskCacheEntryRange(0, kDiskCacheData.size()); | |
132 | 202 |
133 ResourceRequestBody::Element upload_element1, upload_element2; | 203 ResourceRequestBody::Element upload_element1, upload_element2; |
134 upload_element1.SetToBytes("Hello", 5); | 204 upload_element1.SetToBytes("Hello", 5); |
135 upload_element2.SetToFilePathRange( | 205 upload_element2.SetToFilePathRange( |
136 base::FilePath(FILE_PATH_LITERAL("foo1.txt")), 0, 20, time2); | 206 base::FilePath(FILE_PATH_LITERAL("foo1.txt")), 0, 20, time2); |
137 | 207 |
138 // Test no blob reference. | 208 // Test no blob reference. |
139 scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody()); | 209 scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody()); |
140 request_body->AppendBytes( | 210 request_body->AppendBytes( |
141 upload_element1.bytes(), | 211 upload_element1.bytes(), |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
174 upload = UploadDataStreamBuilder::Build( | 244 upload = UploadDataStreamBuilder::Build( |
175 request_body.get(), &blob_storage_context, NULL, | 245 request_body.get(), &blob_storage_context, NULL, |
176 base::ThreadTaskRunnerHandle::Get().get()); | 246 base::ThreadTaskRunnerHandle::Get().get()); |
177 ASSERT_TRUE(upload->GetElementReaders()); | 247 ASSERT_TRUE(upload->GetElementReaders()); |
178 ASSERT_EQ(2U, upload->GetElementReaders()->size()); | 248 ASSERT_EQ(2U, upload->GetElementReaders()->size()); |
179 EXPECT_TRUE(AreElementsEqual( | 249 EXPECT_TRUE(AreElementsEqual( |
180 *(*upload->GetElementReaders())[0], blob_element1)); | 250 *(*upload->GetElementReaders())[0], blob_element1)); |
181 EXPECT_TRUE(AreElementsEqual( | 251 EXPECT_TRUE(AreElementsEqual( |
182 *(*upload->GetElementReaders())[1], blob_element2)); | 252 *(*upload->GetElementReaders())[1], blob_element2)); |
183 | 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, NULL, | |
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 | |
184 // Test having one blob reference at the beginning. | 266 // Test having one blob reference at the beginning. |
185 request_body = new ResourceRequestBody(); | 267 request_body = new ResourceRequestBody(); |
186 request_body->AppendBlob(blob_id1); | 268 request_body->AppendBlob(blob_id1); |
187 request_body->AppendBytes( | 269 request_body->AppendBytes( |
188 upload_element1.bytes(), | 270 upload_element1.bytes(), |
189 upload_element1.length()); | 271 upload_element1.length()); |
190 request_body->AppendFileRange( | 272 request_body->AppendFileRange( |
191 upload_element2.path(), | 273 upload_element2.path(), |
192 upload_element2.offset(), | 274 upload_element2.offset(), |
193 upload_element2.length(), | 275 upload_element2.length(), |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
359 int result = | 441 int result = |
360 upload->Read(io_buffer.get(), kBufferLength, read_callback.callback()); | 442 upload->Read(io_buffer.get(), kBufferLength, read_callback.callback()); |
361 EXPECT_EQ(static_cast<int>(kZeroLength), read_callback.GetResult(result)); | 443 EXPECT_EQ(static_cast<int>(kZeroLength), read_callback.GetResult(result)); |
362 | 444 |
363 base::DeleteFile(test_blob_path, false); | 445 base::DeleteFile(test_blob_path, false); |
364 } | 446 } |
365 // Clean up for ASAN. | 447 // Clean up for ASAN. |
366 base::RunLoop().RunUntilIdle(); | 448 base::RunLoop().RunUntilIdle(); |
367 } | 449 } |
368 } // namespace content | 450 } // namespace content |
OLD | NEW |