| 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 "base/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "base/bind.h" | 6 #include "base/bind.h" |
| 7 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" |
| 8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 9 #include "base/files/scoped_temp_dir.h" | 9 #include "base/files/scoped_temp_dir.h" |
| 10 #include "base/macros.h" |
| 10 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
| 11 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/numerics/safe_conversions.h" | 13 #include "base/numerics/safe_conversions.h" |
| 13 #include "base/run_loop.h" | 14 #include "base/run_loop.h" |
| 14 #include "base/thread_task_runner_handle.h" | 15 #include "base/thread_task_runner_handle.h" |
| 15 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 16 #include "content/browser/fileapi/mock_url_request_delegate.h" | 17 #include "content/browser/fileapi/mock_url_request_delegate.h" |
| 17 #include "content/public/test/async_file_test_helper.h" | 18 #include "content/public/test/async_file_test_helper.h" |
| 18 #include "content/public/test/test_file_system_context.h" | 19 #include "content/public/test/test_file_system_context.h" |
| 20 #include "net/base/net_errors.h" |
| 19 #include "net/base/request_priority.h" | 21 #include "net/base/request_priority.h" |
| 22 #include "net/base/test_completion_callback.h" |
| 23 #include "net/disk_cache/disk_cache.h" |
| 20 #include "net/http/http_byte_range.h" | 24 #include "net/http/http_byte_range.h" |
| 21 #include "net/http/http_request_headers.h" | 25 #include "net/http/http_request_headers.h" |
| 22 #include "net/http/http_response_headers.h" | 26 #include "net/http/http_response_headers.h" |
| 23 #include "net/url_request/url_request.h" | 27 #include "net/url_request/url_request.h" |
| 24 #include "net/url_request/url_request_context.h" | 28 #include "net/url_request/url_request_context.h" |
| 25 #include "net/url_request/url_request_job_factory_impl.h" | 29 #include "net/url_request/url_request_job_factory_impl.h" |
| 26 #include "storage/browser/blob/blob_data_builder.h" | 30 #include "storage/browser/blob/blob_data_builder.h" |
| 27 #include "storage/browser/blob/blob_data_handle.h" | 31 #include "storage/browser/blob/blob_data_handle.h" |
| 28 #include "storage/browser/blob/blob_data_snapshot.h" | 32 #include "storage/browser/blob/blob_data_snapshot.h" |
| 29 #include "storage/browser/blob/blob_storage_context.h" | 33 #include "storage/browser/blob/blob_storage_context.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 41 | 45 |
| 42 namespace { | 46 namespace { |
| 43 | 47 |
| 44 const int kBufferSize = 1024; | 48 const int kBufferSize = 1024; |
| 45 const char kTestData1[] = "Hello"; | 49 const char kTestData1[] = "Hello"; |
| 46 const char kTestData2[] = "Here it is data."; | 50 const char kTestData2[] = "Here it is data."; |
| 47 const char kTestFileData1[] = "0123456789"; | 51 const char kTestFileData1[] = "0123456789"; |
| 48 const char kTestFileData2[] = "This is sample file."; | 52 const char kTestFileData2[] = "This is sample file."; |
| 49 const char kTestFileSystemFileData1[] = "abcdefghijklmnop"; | 53 const char kTestFileSystemFileData1[] = "abcdefghijklmnop"; |
| 50 const char kTestFileSystemFileData2[] = "File system file test data."; | 54 const char kTestFileSystemFileData2[] = "File system file test data."; |
| 55 const char kTestDiskCacheKey[] = "pipe"; |
| 56 const char kTestDiskCacheData[] = "Ceci n'est pas un pamplemousse."; |
| 51 const char kTestContentType[] = "foo/bar"; | 57 const char kTestContentType[] = "foo/bar"; |
| 52 const char kTestContentDisposition[] = "attachment; filename=foo.txt"; | 58 const char kTestContentDisposition[] = "attachment; filename=foo.txt"; |
| 53 | 59 |
| 54 const char kFileSystemURLOrigin[] = "http://remote"; | 60 const char kFileSystemURLOrigin[] = "http://remote"; |
| 55 const storage::FileSystemType kFileSystemType = | 61 const storage::FileSystemType kFileSystemType = |
| 56 storage::kFileSystemTypeTemporary; | 62 storage::kFileSystemTypeTemporary; |
| 57 | 63 |
| 64 const int kTestDiskCacheStreamIndex = 0; |
| 65 |
| 66 // Our disk cache tests don't need a real data handle since the tests themselves |
| 67 // scope the disk cache and entries. |
| 68 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle { |
| 69 private: |
| 70 ~EmptyDataHandle() override {} |
| 71 }; |
| 72 |
| 73 scoped_ptr<disk_cache::Backend> CreateInMemoryDiskCache() { |
| 74 scoped_ptr<disk_cache::Backend> cache; |
| 75 net::TestCompletionCallback callback; |
| 76 int rv = disk_cache::CreateCacheBackend(net::MEMORY_CACHE, |
| 77 net::CACHE_BACKEND_DEFAULT, |
| 78 base::FilePath(), 0, |
| 79 false, nullptr, nullptr, &cache, |
| 80 callback.callback()); |
| 81 EXPECT_EQ(net::OK, callback.GetResult(rv)); |
| 82 |
| 83 return cache.Pass(); |
| 84 } |
| 85 |
| 86 disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache, |
| 87 const char* key, |
| 88 const std::string& data) { |
| 89 disk_cache::Entry* temp_entry = nullptr; |
| 90 net::TestCompletionCallback callback; |
| 91 int rv = cache->CreateEntry(key, &temp_entry, callback.callback()); |
| 92 if (callback.GetResult(rv) != net::OK) |
| 93 return nullptr; |
| 94 disk_cache::ScopedEntryPtr entry(temp_entry); |
| 95 |
| 96 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data); |
| 97 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(), |
| 98 iobuffer->size(), callback.callback(), false); |
| 99 EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv)); |
| 100 return entry.Pass(); |
| 101 } |
| 102 |
| 58 } // namespace | 103 } // namespace |
| 59 | 104 |
| 60 class BlobURLRequestJobTest : public testing::Test { | 105 class BlobURLRequestJobTest : public testing::Test { |
| 61 public: | 106 public: |
| 62 // A simple ProtocolHandler implementation to create BlobURLRequestJob. | 107 // A simple ProtocolHandler implementation to create BlobURLRequestJob. |
| 63 class MockProtocolHandler : | 108 class MockProtocolHandler : |
| 64 public net::URLRequestJobFactory::ProtocolHandler { | 109 public net::URLRequestJobFactory::ProtocolHandler { |
| 65 public: | 110 public: |
| 66 MockProtocolHandler(BlobURLRequestJobTest* test) : test_(test) {} | 111 MockProtocolHandler(BlobURLRequestJobTest* test) : test_(test) {} |
| 67 | 112 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 94 temp_file_modification_time1_ = file_info1.last_modified; | 139 temp_file_modification_time1_ = file_info1.last_modified; |
| 95 | 140 |
| 96 temp_file2_ = temp_dir_.path().AppendASCII("BlobFile2.dat"); | 141 temp_file2_ = temp_dir_.path().AppendASCII("BlobFile2.dat"); |
| 97 ASSERT_EQ(static_cast<int>(arraysize(kTestFileData2) - 1), | 142 ASSERT_EQ(static_cast<int>(arraysize(kTestFileData2) - 1), |
| 98 base::WriteFile(temp_file2_, kTestFileData2, | 143 base::WriteFile(temp_file2_, kTestFileData2, |
| 99 arraysize(kTestFileData2) - 1)); | 144 arraysize(kTestFileData2) - 1)); |
| 100 base::File::Info file_info2; | 145 base::File::Info file_info2; |
| 101 base::GetFileInfo(temp_file2_, &file_info2); | 146 base::GetFileInfo(temp_file2_, &file_info2); |
| 102 temp_file_modification_time2_ = file_info2.last_modified; | 147 temp_file_modification_time2_ = file_info2.last_modified; |
| 103 | 148 |
| 149 disk_cache_backend_ = CreateInMemoryDiskCache(); |
| 150 disk_cache_entry_ = CreateDiskCacheEntry( |
| 151 disk_cache_backend_.get(), kTestDiskCacheKey, kTestDiskCacheData); |
| 152 |
| 104 url_request_job_factory_.SetProtocolHandler("blob", | 153 url_request_job_factory_.SetProtocolHandler("blob", |
| 105 new MockProtocolHandler(this)); | 154 new MockProtocolHandler(this)); |
| 106 url_request_context_.set_job_factory(&url_request_job_factory_); | 155 url_request_context_.set_job_factory(&url_request_job_factory_); |
| 107 } | 156 } |
| 108 | 157 |
| 109 void TearDown() override { | 158 void TearDown() override { |
| 110 blob_handle_.reset(); | 159 blob_handle_.reset(); |
| 111 // Clean up for ASAN | 160 // Clean up for ASAN |
| 112 base::RunLoop run_loop; | 161 base::RunLoop run_loop; |
| 113 run_loop.RunUntilIdle(); | 162 run_loop.RunUntilIdle(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 | 250 |
| 202 // Verify response. | 251 // Verify response. |
| 203 EXPECT_TRUE(request_->status().is_success()); | 252 EXPECT_TRUE(request_->status().is_success()); |
| 204 EXPECT_EQ(expected_status_code_, | 253 EXPECT_EQ(expected_status_code_, |
| 205 request_->response_headers()->response_code()); | 254 request_->response_headers()->response_code()); |
| 206 EXPECT_EQ(expected_response_, url_request_delegate_.response_data()); | 255 EXPECT_EQ(expected_response_, url_request_delegate_.response_data()); |
| 207 } | 256 } |
| 208 | 257 |
| 209 void BuildComplicatedData(std::string* expected_result) { | 258 void BuildComplicatedData(std::string* expected_result) { |
| 210 blob_data_->AppendData(kTestData1 + 1, 2); | 259 blob_data_->AppendData(kTestData1 + 1, 2); |
| 260 *expected_result = std::string(kTestData1 + 1, 2); |
| 261 |
| 211 blob_data_->AppendFile(temp_file1_, 2, 3, temp_file_modification_time1_); | 262 blob_data_->AppendFile(temp_file1_, 2, 3, temp_file_modification_time1_); |
| 263 *expected_result += std::string(kTestFileData1 + 2, 3); |
| 264 |
| 265 blob_data_->AppendDiskCacheEntry(new EmptyDataHandle(), |
| 266 disk_cache_entry_.get(), |
| 267 kTestDiskCacheStreamIndex); |
| 268 *expected_result += std::string(kTestDiskCacheData); |
| 269 |
| 212 blob_data_->AppendFileSystemFile(temp_file_system_file1_, 3, 4, | 270 blob_data_->AppendFileSystemFile(temp_file_system_file1_, 3, 4, |
| 213 temp_file_system_file_modification_time1_); | 271 temp_file_system_file_modification_time1_); |
| 272 *expected_result += std::string(kTestFileSystemFileData1 + 3, 4); |
| 273 |
| 214 blob_data_->AppendData(kTestData2 + 4, 5); | 274 blob_data_->AppendData(kTestData2 + 4, 5); |
| 275 *expected_result += std::string(kTestData2 + 4, 5); |
| 276 |
| 215 blob_data_->AppendFile(temp_file2_, 5, 6, temp_file_modification_time2_); | 277 blob_data_->AppendFile(temp_file2_, 5, 6, temp_file_modification_time2_); |
| 278 *expected_result += std::string(kTestFileData2 + 5, 6); |
| 279 |
| 216 blob_data_->AppendFileSystemFile(temp_file_system_file2_, 6, 7, | 280 blob_data_->AppendFileSystemFile(temp_file_system_file2_, 6, 7, |
| 217 temp_file_system_file_modification_time2_); | 281 temp_file_system_file_modification_time2_); |
| 218 *expected_result = std::string(kTestData1 + 1, 2); | |
| 219 *expected_result += std::string(kTestFileData1 + 2, 3); | |
| 220 *expected_result += std::string(kTestFileSystemFileData1 + 3, 4); | |
| 221 *expected_result += std::string(kTestData2 + 4, 5); | |
| 222 *expected_result += std::string(kTestFileData2 + 5, 6); | |
| 223 *expected_result += std::string(kTestFileSystemFileData2 + 6, 7); | 282 *expected_result += std::string(kTestFileSystemFileData2 + 6, 7); |
| 224 } | 283 } |
| 225 | 284 |
| 226 scoped_ptr<BlobDataSnapshot> GetSnapshotFromBuilder() { | 285 scoped_ptr<BlobDataSnapshot> GetSnapshotFromBuilder() { |
| 227 if (!blob_handle_) { | 286 if (!blob_handle_) { |
| 228 blob_handle_ = blob_context_.AddFinishedBlob(blob_data_.get()).Pass(); | 287 blob_handle_ = blob_context_.AddFinishedBlob(blob_data_.get()).Pass(); |
| 229 } | 288 } |
| 230 return blob_handle_->CreateSnapshot().Pass(); | 289 return blob_handle_->CreateSnapshot().Pass(); |
| 231 } | 290 } |
| 232 | 291 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 249 base::FilePath temp_file1_; | 308 base::FilePath temp_file1_; |
| 250 base::FilePath temp_file2_; | 309 base::FilePath temp_file2_; |
| 251 base::Time temp_file_modification_time1_; | 310 base::Time temp_file_modification_time1_; |
| 252 base::Time temp_file_modification_time2_; | 311 base::Time temp_file_modification_time2_; |
| 253 GURL file_system_root_url_; | 312 GURL file_system_root_url_; |
| 254 GURL temp_file_system_file1_; | 313 GURL temp_file_system_file1_; |
| 255 GURL temp_file_system_file2_; | 314 GURL temp_file_system_file2_; |
| 256 base::Time temp_file_system_file_modification_time1_; | 315 base::Time temp_file_system_file_modification_time1_; |
| 257 base::Time temp_file_system_file_modification_time2_; | 316 base::Time temp_file_system_file_modification_time2_; |
| 258 | 317 |
| 318 scoped_ptr<disk_cache::Backend> disk_cache_backend_; |
| 319 disk_cache::ScopedEntryPtr disk_cache_entry_; |
| 320 |
| 259 base::MessageLoopForIO message_loop_; | 321 base::MessageLoopForIO message_loop_; |
| 260 scoped_refptr<storage::FileSystemContext> file_system_context_; | 322 scoped_refptr<storage::FileSystemContext> file_system_context_; |
| 261 | 323 |
| 262 storage::BlobStorageContext blob_context_; | 324 storage::BlobStorageContext blob_context_; |
| 263 scoped_ptr<storage::BlobDataHandle> blob_handle_; | 325 scoped_ptr<storage::BlobDataHandle> blob_handle_; |
| 264 scoped_ptr<BlobDataBuilder> blob_data_; | 326 scoped_ptr<BlobDataBuilder> blob_data_; |
| 265 scoped_ptr<BlobDataSnapshot> blob_data_snapshot_; | 327 scoped_ptr<BlobDataSnapshot> blob_data_snapshot_; |
| 266 net::URLRequestJobFactoryImpl url_request_job_factory_; | 328 net::URLRequestJobFactoryImpl url_request_job_factory_; |
| 267 net::URLRequestContext url_request_context_; | 329 net::URLRequestContext url_request_context_; |
| 268 MockURLRequestDelegate url_request_delegate_; | 330 MockURLRequestDelegate url_request_delegate_; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 284 | 346 |
| 285 TEST_F(BlobURLRequestJobTest, TestGetLargeFileRequest) { | 347 TEST_F(BlobURLRequestJobTest, TestGetLargeFileRequest) { |
| 286 base::FilePath large_temp_file = | 348 base::FilePath large_temp_file = |
| 287 temp_dir_.path().AppendASCII("LargeBlob.dat"); | 349 temp_dir_.path().AppendASCII("LargeBlob.dat"); |
| 288 std::string large_data; | 350 std::string large_data; |
| 289 large_data.reserve(kBufferSize * 5); | 351 large_data.reserve(kBufferSize * 5); |
| 290 for (int i = 0; i < kBufferSize * 5; ++i) | 352 for (int i = 0; i < kBufferSize * 5; ++i) |
| 291 large_data.append(1, static_cast<char>(i % 256)); | 353 large_data.append(1, static_cast<char>(i % 256)); |
| 292 ASSERT_EQ(static_cast<int>(large_data.size()), | 354 ASSERT_EQ(static_cast<int>(large_data.size()), |
| 293 base::WriteFile(large_temp_file, large_data.data(), | 355 base::WriteFile(large_temp_file, large_data.data(), |
| 294 large_data.size())); | 356 large_data.size())); |
| 295 blob_data_->AppendFile(large_temp_file, 0, kuint64max, base::Time()); | 357 blob_data_->AppendFile(large_temp_file, 0, kuint64max, base::Time()); |
| 296 TestSuccessNonrangeRequest(large_data, large_data.size()); | 358 TestSuccessNonrangeRequest(large_data, large_data.size()); |
| 297 } | 359 } |
| 298 | 360 |
| 299 TEST_F(BlobURLRequestJobTest, TestGetNonExistentFileRequest) { | 361 TEST_F(BlobURLRequestJobTest, TestGetNonExistentFileRequest) { |
| 300 base::FilePath non_existent_file = | 362 base::FilePath non_existent_file = |
| 301 temp_file1_.InsertBeforeExtension(FILE_PATH_LITERAL("-na")); | 363 temp_file1_.InsertBeforeExtension(FILE_PATH_LITERAL("-na")); |
| 302 blob_data_->AppendFile(non_existent_file, 0, kuint64max, base::Time()); | 364 blob_data_->AppendFile(non_existent_file, 0, kuint64max, base::Time()); |
| 303 TestErrorRequest(404); | 365 TestErrorRequest(404); |
| 304 } | 366 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 } | 426 } |
| 365 | 427 |
| 366 TEST_F(BlobURLRequestJobTest, TestGetSlicedFileSystemFileRequest) { | 428 TEST_F(BlobURLRequestJobTest, TestGetSlicedFileSystemFileRequest) { |
| 367 SetUpFileSystem(); | 429 SetUpFileSystem(); |
| 368 blob_data_->AppendFileSystemFile(temp_file_system_file1_, 2, 4, | 430 blob_data_->AppendFileSystemFile(temp_file_system_file1_, 2, 4, |
| 369 temp_file_system_file_modification_time1_); | 431 temp_file_system_file_modification_time1_); |
| 370 std::string result(kTestFileSystemFileData1 + 2, 4); | 432 std::string result(kTestFileSystemFileData1 + 2, 4); |
| 371 TestSuccessNonrangeRequest(result, 4); | 433 TestSuccessNonrangeRequest(result, 4); |
| 372 } | 434 } |
| 373 | 435 |
| 374 TEST_F(BlobURLRequestJobTest, TestGetComplicatedDataAndFileRequest) { | 436 TEST_F(BlobURLRequestJobTest, TestGetSimpleDiskCacheRequest) { |
| 437 blob_data_->AppendDiskCacheEntry(new EmptyDataHandle(), |
| 438 disk_cache_entry_.get(), |
| 439 kTestDiskCacheStreamIndex); |
| 440 TestSuccessNonrangeRequest(kTestDiskCacheData, |
| 441 arraysize(kTestDiskCacheData) - 1); |
| 442 } |
| 443 |
| 444 TEST_F(BlobURLRequestJobTest, TestGetComplicatedDataFileAndDiskCacheRequest) { |
| 375 SetUpFileSystem(); | 445 SetUpFileSystem(); |
| 376 std::string result; | 446 std::string result; |
| 377 BuildComplicatedData(&result); | 447 BuildComplicatedData(&result); |
| 378 TestSuccessNonrangeRequest(result, GetTotalBlobLength()); | 448 TestSuccessNonrangeRequest(result, GetTotalBlobLength()); |
| 379 } | 449 } |
| 380 | 450 |
| 381 TEST_F(BlobURLRequestJobTest, TestGetRangeRequest1) { | 451 TEST_F(BlobURLRequestJobTest, TestGetRangeRequest1) { |
| 382 SetUpFileSystem(); | 452 SetUpFileSystem(); |
| 383 std::string result; | 453 std::string result; |
| 384 BuildComplicatedData(&result); | 454 BuildComplicatedData(&result); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 EXPECT_TRUE(request_->response_headers()->GetMimeType(&content_type)); | 503 EXPECT_TRUE(request_->response_headers()->GetMimeType(&content_type)); |
| 434 EXPECT_EQ(kTestContentType, content_type); | 504 EXPECT_EQ(kTestContentType, content_type); |
| 435 void* iter = NULL; | 505 void* iter = NULL; |
| 436 std::string content_disposition; | 506 std::string content_disposition; |
| 437 EXPECT_TRUE(request_->response_headers()->EnumerateHeader( | 507 EXPECT_TRUE(request_->response_headers()->EnumerateHeader( |
| 438 &iter, "Content-Disposition", &content_disposition)); | 508 &iter, "Content-Disposition", &content_disposition)); |
| 439 EXPECT_EQ(kTestContentDisposition, content_disposition); | 509 EXPECT_EQ(kTestContentDisposition, content_disposition); |
| 440 } | 510 } |
| 441 | 511 |
| 442 } // namespace content | 512 } // namespace content |
| OLD | NEW |