| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/cache_storage/cache_storage_cache.h" | 5 #include "content/browser/cache_storage/cache_storage_cache.h" |
| 6 | 6 |
| 7 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" |
| 8 #include "base/files/scoped_temp_dir.h" | 8 #include "base/files/scoped_temp_dir.h" |
| 9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 int rv = backend_->OpenEntry(key, entry, callback); | 115 int rv = backend_->OpenEntry(key, entry, callback); |
| 116 if (rv != net::ERR_IO_PENDING) | 116 if (rv != net::ERR_IO_PENDING) |
| 117 callback.Run(rv); | 117 callback.Run(rv); |
| 118 } | 118 } |
| 119 | 119 |
| 120 scoped_ptr<disk_cache::Backend> backend_; | 120 scoped_ptr<disk_cache::Backend> backend_; |
| 121 bool delay_open_; | 121 bool delay_open_; |
| 122 base::Closure open_entry_callback_; | 122 base::Closure open_entry_callback_; |
| 123 }; | 123 }; |
| 124 | 124 |
| 125 void CopyBody(const storage::BlobDataHandle& blob_handle, std::string* output) { |
| 126 *output = std::string(); |
| 127 scoped_ptr<storage::BlobDataSnapshot> data = blob_handle.CreateSnapshot(); |
| 128 const auto& items = data->items(); |
| 129 for (const auto& item : items) { |
| 130 switch (item->type()) { |
| 131 case storage::DataElement::TYPE_BYTES: { |
| 132 output->append(item->bytes(), item->length()); |
| 133 break; |
| 134 } |
| 135 case storage::DataElement::TYPE_DISK_CACHE_ENTRY: { |
| 136 disk_cache::Entry* entry = item->disk_cache_entry(); |
| 137 int32 body_size = entry->GetDataSize(item->disk_cache_stream_index()); |
| 138 |
| 139 scoped_refptr<net::IOBuffer> io_buffer = new net::IOBuffer(body_size); |
| 140 net::TestCompletionCallback callback; |
| 141 int rv = |
| 142 entry->ReadData(item->disk_cache_stream_index(), 0, io_buffer.get(), |
| 143 body_size, callback.callback()); |
| 144 if (rv == net::ERR_IO_PENDING) |
| 145 rv = callback.WaitForResult(); |
| 146 EXPECT_EQ(body_size, rv); |
| 147 if (rv > 0) |
| 148 output->append(io_buffer->data(), rv); |
| 149 break; |
| 150 } |
| 151 default: { ADD_FAILURE() << "invalid response blob type"; } break; |
| 152 } |
| 153 } |
| 154 } |
| 155 |
| 156 bool ResponseMetadataEqual(const ServiceWorkerResponse& expected, |
| 157 const ServiceWorkerResponse& actual) { |
| 158 EXPECT_EQ(expected.status_code, actual.status_code); |
| 159 if (expected.status_code != actual.status_code) |
| 160 return false; |
| 161 EXPECT_EQ(expected.status_text, actual.status_text); |
| 162 if (expected.status_text != actual.status_text) |
| 163 return false; |
| 164 EXPECT_EQ(expected.url, actual.url); |
| 165 if (expected.url != actual.url) |
| 166 return false; |
| 167 EXPECT_EQ(expected.blob_size, actual.blob_size); |
| 168 if (expected.blob_size != actual.blob_size) |
| 169 return false; |
| 170 |
| 171 if (expected.blob_size == 0) { |
| 172 EXPECT_STREQ("", actual.blob_uuid.c_str()); |
| 173 if (!actual.blob_uuid.empty()) |
| 174 return false; |
| 175 } else { |
| 176 EXPECT_STRNE("", actual.blob_uuid.c_str()); |
| 177 if (actual.blob_uuid.empty()) |
| 178 return false; |
| 179 } |
| 180 |
| 181 return true; |
| 182 } |
| 183 |
| 184 bool ResponseBodiesEqual(const std::string& expected_body, |
| 185 const storage::BlobDataHandle& actual_body_handle) { |
| 186 std::string actual_body; |
| 187 CopyBody(actual_body_handle, &actual_body); |
| 188 return expected_body == actual_body; |
| 189 } |
| 190 |
| 125 } // namespace | 191 } // namespace |
| 126 | 192 |
| 127 // A CacheStorageCache that can optionally delay during backend creation. | 193 // A CacheStorageCache that can optionally delay during backend creation. |
| 128 class TestCacheStorageCache : public CacheStorageCache { | 194 class TestCacheStorageCache : public CacheStorageCache { |
| 129 public: | 195 public: |
| 130 TestCacheStorageCache( | 196 TestCacheStorageCache( |
| 131 const GURL& origin, | 197 const GURL& origin, |
| 132 const base::FilePath& path, | 198 const base::FilePath& path, |
| 133 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, | 199 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter, |
| 134 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, | 200 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 | 354 |
| 289 cache_->Match( | 355 cache_->Match( |
| 290 CopyFetchRequest(request), | 356 CopyFetchRequest(request), |
| 291 base::Bind(&CacheStorageCacheTest::ResponseAndErrorCallback, | 357 base::Bind(&CacheStorageCacheTest::ResponseAndErrorCallback, |
| 292 base::Unretained(this), base::Unretained(loop.get()))); | 358 base::Unretained(this), base::Unretained(loop.get()))); |
| 293 loop->Run(); | 359 loop->Run(); |
| 294 | 360 |
| 295 return callback_error_ == CACHE_STORAGE_OK; | 361 return callback_error_ == CACHE_STORAGE_OK; |
| 296 } | 362 } |
| 297 | 363 |
| 364 bool MatchAll(scoped_ptr<CacheStorageCache::Responses>* responses, |
| 365 scoped_ptr<CacheStorageCache::BlobDataHandles>* body_handles) { |
| 366 base::RunLoop loop; |
| 367 cache_->MatchAll(base::Bind( |
| 368 &CacheStorageCacheTest::ResponsesAndErrorCallback, |
| 369 base::Unretained(this), loop.QuitClosure(), responses, body_handles)); |
| 370 loop.Run(); |
| 371 return callback_error_ == CACHE_STORAGE_OK; |
| 372 } |
| 373 |
| 298 bool Delete(const ServiceWorkerFetchRequest& request) { | 374 bool Delete(const ServiceWorkerFetchRequest& request) { |
| 299 CacheStorageBatchOperation operation; | 375 CacheStorageBatchOperation operation; |
| 300 operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE; | 376 operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE; |
| 301 operation.request = request; | 377 operation.request = request; |
| 302 | 378 |
| 303 CacheStorageError error = | 379 CacheStorageError error = |
| 304 BatchOperation(std::vector<CacheStorageBatchOperation>(1, operation)); | 380 BatchOperation(std::vector<CacheStorageBatchOperation>(1, operation)); |
| 305 return error == CACHE_STORAGE_OK; | 381 return error == CACHE_STORAGE_OK; |
| 306 } | 382 } |
| 307 | 383 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 callback_error_ = error; | 439 callback_error_ = error; |
| 364 callback_response_ = response.Pass(); | 440 callback_response_ = response.Pass(); |
| 365 callback_response_data_.reset(); | 441 callback_response_data_.reset(); |
| 366 if (error == CACHE_STORAGE_OK && !callback_response_->blob_uuid.empty()) | 442 if (error == CACHE_STORAGE_OK && !callback_response_->blob_uuid.empty()) |
| 367 callback_response_data_ = body_handle.Pass(); | 443 callback_response_data_ = body_handle.Pass(); |
| 368 | 444 |
| 369 if (run_loop) | 445 if (run_loop) |
| 370 run_loop->Quit(); | 446 run_loop->Quit(); |
| 371 } | 447 } |
| 372 | 448 |
| 449 void ResponsesAndErrorCallback( |
| 450 const base::Closure& quit_closure, |
| 451 scoped_ptr<CacheStorageCache::Responses>* responses_out, |
| 452 scoped_ptr<CacheStorageCache::BlobDataHandles>* body_handles_out, |
| 453 CacheStorageError error, |
| 454 scoped_ptr<CacheStorageCache::Responses> responses, |
| 455 scoped_ptr<CacheStorageCache::BlobDataHandles> body_handles) { |
| 456 callback_error_ = error; |
| 457 responses_out->swap(responses); |
| 458 body_handles_out->swap(body_handles); |
| 459 quit_closure.Run(); |
| 460 } |
| 461 |
| 373 void CloseCallback(base::RunLoop* run_loop) { | 462 void CloseCallback(base::RunLoop* run_loop) { |
| 374 EXPECT_FALSE(callback_closed_); | 463 EXPECT_FALSE(callback_closed_); |
| 375 callback_closed_ = true; | 464 callback_closed_ = true; |
| 376 if (run_loop) | 465 if (run_loop) |
| 377 run_loop->Quit(); | 466 run_loop->Quit(); |
| 378 } | 467 } |
| 379 | 468 |
| 380 void CopyBody(storage::BlobDataHandle* blob_handle, std::string* output) { | |
| 381 *output = std::string(); | |
| 382 scoped_ptr<storage::BlobDataSnapshot> data = blob_handle->CreateSnapshot(); | |
| 383 const auto& items = data->items(); | |
| 384 for (const auto& item : items) { | |
| 385 switch (item->type()) { | |
| 386 case storage::DataElement::TYPE_BYTES: { | |
| 387 output->append(item->bytes(), item->length()); | |
| 388 break; | |
| 389 } | |
| 390 case storage::DataElement::TYPE_DISK_CACHE_ENTRY: { | |
| 391 disk_cache::Entry* entry = item->disk_cache_entry(); | |
| 392 int32 body_size = entry->GetDataSize(item->disk_cache_stream_index()); | |
| 393 | |
| 394 scoped_refptr<net::IOBuffer> io_buffer = new net::IOBuffer(body_size); | |
| 395 net::TestCompletionCallback callback; | |
| 396 int rv = | |
| 397 entry->ReadData(item->disk_cache_stream_index(), 0, | |
| 398 io_buffer.get(), body_size, callback.callback()); | |
| 399 if (rv == net::ERR_IO_PENDING) | |
| 400 rv = callback.WaitForResult(); | |
| 401 EXPECT_EQ(body_size, rv); | |
| 402 if (rv > 0) | |
| 403 output->append(io_buffer->data(), rv); | |
| 404 break; | |
| 405 } | |
| 406 default: { ADD_FAILURE() << "invalid response blob type"; } break; | |
| 407 } | |
| 408 } | |
| 409 } | |
| 410 | |
| 411 bool VerifyKeys(const std::vector<std::string>& expected_keys) { | 469 bool VerifyKeys(const std::vector<std::string>& expected_keys) { |
| 412 if (expected_keys.size() != callback_strings_.size()) | 470 if (expected_keys.size() != callback_strings_.size()) |
| 413 return false; | 471 return false; |
| 414 | 472 |
| 415 std::set<std::string> found_set; | 473 std::set<std::string> found_set; |
| 416 for (int i = 0, max = callback_strings_.size(); i < max; ++i) | 474 for (int i = 0, max = callback_strings_.size(); i < max; ++i) |
| 417 found_set.insert(callback_strings_[i]); | 475 found_set.insert(callback_strings_[i]); |
| 418 | 476 |
| 419 for (int i = 0, max = expected_keys.size(); i < max; ++i) { | 477 for (int i = 0, max = expected_keys.size(); i < max; ++i) { |
| 420 if (found_set.find(expected_keys[i]) == found_set.end()) | 478 if (found_set.find(expected_keys[i]) == found_set.end()) |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 EXPECT_EQ(CACHE_STORAGE_OK, BatchOperation(operations)); | 648 EXPECT_EQ(CACHE_STORAGE_OK, BatchOperation(operations)); |
| 591 | 649 |
| 592 // |operation2| should win. | 650 // |operation2| should win. |
| 593 EXPECT_TRUE(Match(operation2.request)); | 651 EXPECT_TRUE(Match(operation2.request)); |
| 594 EXPECT_TRUE(callback_response_data_); | 652 EXPECT_TRUE(callback_response_data_); |
| 595 } | 653 } |
| 596 | 654 |
| 597 TEST_P(CacheStorageCacheTestP, MatchNoBody) { | 655 TEST_P(CacheStorageCacheTestP, MatchNoBody) { |
| 598 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); | 656 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); |
| 599 EXPECT_TRUE(Match(no_body_request_)); | 657 EXPECT_TRUE(Match(no_body_request_)); |
| 600 EXPECT_EQ(200, callback_response_->status_code); | 658 EXPECT_TRUE(ResponseMetadataEqual(no_body_response_, *callback_response_)); |
| 601 EXPECT_STREQ("OK", callback_response_->status_text.c_str()); | 659 EXPECT_FALSE(callback_response_data_); |
| 602 EXPECT_STREQ("http://example.com/no_body.html", | |
| 603 callback_response_->url.spec().c_str()); | |
| 604 EXPECT_STREQ("", callback_response_->blob_uuid.c_str()); | |
| 605 EXPECT_EQ(0u, callback_response_->blob_size); | |
| 606 } | 660 } |
| 607 | 661 |
| 608 TEST_P(CacheStorageCacheTestP, MatchBody) { | 662 TEST_P(CacheStorageCacheTestP, MatchBody) { |
| 609 EXPECT_TRUE(Put(body_request_, body_response_)); | 663 EXPECT_TRUE(Put(body_request_, body_response_)); |
| 610 EXPECT_TRUE(Match(body_request_)); | 664 EXPECT_TRUE(Match(body_request_)); |
| 611 EXPECT_EQ(200, callback_response_->status_code); | 665 EXPECT_TRUE(ResponseMetadataEqual(body_response_, *callback_response_)); |
| 612 EXPECT_STREQ("OK", callback_response_->status_text.c_str()); | 666 EXPECT_TRUE( |
| 613 EXPECT_STREQ("http://example.com/body.html", | 667 ResponseBodiesEqual(expected_blob_data_, *callback_response_data_)); |
| 614 callback_response_->url.spec().c_str()); | 668 } |
| 615 EXPECT_STRNE("", callback_response_->blob_uuid.c_str()); | |
| 616 EXPECT_EQ(expected_blob_data_.size(), callback_response_->blob_size); | |
| 617 | 669 |
| 618 std::string response_body; | 670 TEST_P(CacheStorageCacheTestP, MatchAll_Empty) { |
| 619 CopyBody(callback_response_data_.get(), &response_body); | 671 scoped_ptr<CacheStorageCache::Responses> responses; |
| 620 EXPECT_STREQ(expected_blob_data_.c_str(), response_body.c_str()); | 672 scoped_ptr<CacheStorageCache::BlobDataHandles> body_handles; |
| 673 EXPECT_TRUE(MatchAll(&responses, &body_handles)); |
| 674 EXPECT_TRUE(responses->empty()); |
| 675 EXPECT_TRUE(body_handles->empty()); |
| 676 } |
| 677 |
| 678 TEST_P(CacheStorageCacheTestP, MatchAll_NoBody) { |
| 679 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); |
| 680 |
| 681 scoped_ptr<CacheStorageCache::Responses> responses; |
| 682 scoped_ptr<CacheStorageCache::BlobDataHandles> body_handles; |
| 683 EXPECT_TRUE(MatchAll(&responses, &body_handles)); |
| 684 |
| 685 ASSERT_EQ(1u, responses->size()); |
| 686 EXPECT_TRUE(ResponseMetadataEqual(no_body_response_, responses->at(0))); |
| 687 EXPECT_TRUE(body_handles->empty()); |
| 688 } |
| 689 |
| 690 TEST_P(CacheStorageCacheTestP, MatchAll_Body) { |
| 691 EXPECT_TRUE(Put(body_request_, body_response_)); |
| 692 |
| 693 scoped_ptr<CacheStorageCache::Responses> responses; |
| 694 scoped_ptr<CacheStorageCache::BlobDataHandles> body_handles; |
| 695 EXPECT_TRUE(MatchAll(&responses, &body_handles)); |
| 696 |
| 697 ASSERT_EQ(1u, responses->size()); |
| 698 ASSERT_EQ(1u, body_handles->size()); |
| 699 EXPECT_TRUE(ResponseMetadataEqual(body_response_, responses->at(0))); |
| 700 EXPECT_TRUE(ResponseBodiesEqual(expected_blob_data_, body_handles->at(0))); |
| 701 } |
| 702 |
| 703 TEST_P(CacheStorageCacheTestP, MatchAll_TwoResponsesThenOne) { |
| 704 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); |
| 705 EXPECT_TRUE(Put(body_request_, body_response_)); |
| 706 |
| 707 scoped_ptr<CacheStorageCache::Responses> responses; |
| 708 scoped_ptr<CacheStorageCache::BlobDataHandles> body_handles; |
| 709 EXPECT_TRUE(MatchAll(&responses, &body_handles)); |
| 710 ASSERT_EQ(2u, responses->size()); |
| 711 ASSERT_EQ(1u, body_handles->size()); |
| 712 |
| 713 // Order of returned responses is not guaranteed. |
| 714 std::set<std::string> matched_set; |
| 715 for (const ServiceWorkerResponse& response : *responses) { |
| 716 if (response.url.spec() == "http://example.com/no_body.html") { |
| 717 EXPECT_TRUE(ResponseMetadataEqual(no_body_response_, response)); |
| 718 matched_set.insert(response.url.spec()); |
| 719 } else if (response.url.spec() == "http://example.com/body.html") { |
| 720 EXPECT_TRUE(ResponseMetadataEqual(body_response_, response)); |
| 721 EXPECT_TRUE( |
| 722 ResponseBodiesEqual(expected_blob_data_, body_handles->at(0))); |
| 723 matched_set.insert(response.url.spec()); |
| 724 } |
| 725 } |
| 726 EXPECT_EQ(2u, matched_set.size()); |
| 727 |
| 728 responses->clear(); |
| 729 body_handles->clear(); |
| 730 |
| 731 EXPECT_TRUE(Delete(body_request_)); |
| 732 EXPECT_TRUE(MatchAll(&responses, &body_handles)); |
| 733 |
| 734 ASSERT_EQ(1u, responses->size()); |
| 735 EXPECT_TRUE(ResponseMetadataEqual(no_body_response_, responses->at(0))); |
| 736 EXPECT_TRUE(body_handles->empty()); |
| 621 } | 737 } |
| 622 | 738 |
| 623 TEST_P(CacheStorageCacheTestP, Vary) { | 739 TEST_P(CacheStorageCacheTestP, Vary) { |
| 624 body_request_.headers["vary_foo"] = "foo"; | 740 body_request_.headers["vary_foo"] = "foo"; |
| 625 body_response_.headers["vary"] = "vary_foo"; | 741 body_response_.headers["vary"] = "vary_foo"; |
| 626 EXPECT_TRUE(Put(body_request_, body_response_)); | 742 EXPECT_TRUE(Put(body_request_, body_response_)); |
| 627 EXPECT_TRUE(Match(body_request_)); | 743 EXPECT_TRUE(Match(body_request_)); |
| 628 | 744 |
| 629 body_request_.headers["vary_foo"] = "bar"; | 745 body_request_.headers["vary_foo"] = "bar"; |
| 630 EXPECT_FALSE(Match(body_request_)); | 746 EXPECT_FALSE(Match(body_request_)); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 EXPECT_EQ(1, sequence_out); | 1005 EXPECT_EQ(1, sequence_out); |
| 890 close_loop2->Run(); | 1006 close_loop2->Run(); |
| 891 EXPECT_EQ(2, sequence_out); | 1007 EXPECT_EQ(2, sequence_out); |
| 892 } | 1008 } |
| 893 | 1009 |
| 894 INSTANTIATE_TEST_CASE_P(CacheStorageCacheTest, | 1010 INSTANTIATE_TEST_CASE_P(CacheStorageCacheTest, |
| 895 CacheStorageCacheTestP, | 1011 CacheStorageCacheTestP, |
| 896 ::testing::Values(false, true)); | 1012 ::testing::Values(false, true)); |
| 897 | 1013 |
| 898 } // namespace content | 1014 } // namespace content |
| OLD | NEW |