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/message_loop/message_loop_proxy.h" | 9 #include "base/message_loop/message_loop_proxy.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 blink::WebServiceWorkerResponseTypeDefault, headers, "", 0, GURL()); | 245 blink::WebServiceWorkerResponseTypeDefault, headers, "", 0, GURL()); |
246 } | 246 } |
247 | 247 |
248 scoped_ptr<ServiceWorkerFetchRequest> CopyFetchRequest( | 248 scoped_ptr<ServiceWorkerFetchRequest> CopyFetchRequest( |
249 const ServiceWorkerFetchRequest& request) { | 249 const ServiceWorkerFetchRequest& request) { |
250 return make_scoped_ptr(new ServiceWorkerFetchRequest( | 250 return make_scoped_ptr(new ServiceWorkerFetchRequest( |
251 request.url, request.method, request.headers, request.referrer, | 251 request.url, request.method, request.headers, request.referrer, |
252 request.is_reload)); | 252 request.is_reload)); |
253 } | 253 } |
254 | 254 |
255 scoped_ptr<ServiceWorkerResponse> CopyFetchResponse( | 255 CacheStorageError BatchOperation( |
256 const ServiceWorkerResponse& response) { | 256 const std::vector<CacheStorageBatchOperation>& operations) { |
257 scoped_ptr<ServiceWorkerResponse> sw_response(new ServiceWorkerResponse( | |
258 response.url, response.status_code, response.status_text, | |
259 response.response_type, response.headers, response.blob_uuid, | |
260 response.blob_size, response.stream_url)); | |
261 return sw_response.Pass(); | |
262 } | |
263 | |
264 bool Put(const ServiceWorkerFetchRequest& request, | |
265 const ServiceWorkerResponse& response) { | |
266 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | 257 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
267 | 258 |
268 cache_->Put( | 259 cache_->BatchOperation( |
269 CopyFetchRequest(request), CopyFetchResponse(response), | 260 operations, |
270 base::Bind(&CacheStorageCacheTest::ErrorTypeCallback, | 261 base::Bind(&CacheStorageCacheTest::ErrorTypeCallback, |
271 base::Unretained(this), base::Unretained(loop.get()))); | 262 base::Unretained(this), base::Unretained(loop.get()))); |
272 // TODO(jkarlin): These functions should use base::RunLoop().RunUntilIdle() | 263 // TODO(jkarlin): These functions should use base::RunLoop().RunUntilIdle() |
273 // once the cache uses a passed in MessageLoopProxy instead of the CACHE | 264 // once the cache uses a passed in MessageLoopProxy instead of the CACHE |
274 // thread. | 265 // thread. |
275 loop->Run(); | 266 loop->Run(); |
276 | 267 |
277 return callback_error_ == CACHE_STORAGE_OK; | 268 return callback_error_; |
| 269 } |
| 270 |
| 271 bool Put(const ServiceWorkerFetchRequest& request, |
| 272 const ServiceWorkerResponse& response) { |
| 273 CacheStorageBatchOperation operation; |
| 274 operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| 275 operation.request = request; |
| 276 operation.response = response; |
| 277 |
| 278 CacheStorageError error = |
| 279 BatchOperation(std::vector<CacheStorageBatchOperation>(1, operation)); |
| 280 return error == CACHE_STORAGE_OK; |
278 } | 281 } |
279 | 282 |
280 bool Match(const ServiceWorkerFetchRequest& request) { | 283 bool Match(const ServiceWorkerFetchRequest& request) { |
281 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | 284 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
282 | 285 |
283 cache_->Match( | 286 cache_->Match( |
284 CopyFetchRequest(request), | 287 CopyFetchRequest(request), |
285 base::Bind(&CacheStorageCacheTest::ResponseAndErrorCallback, | 288 base::Bind(&CacheStorageCacheTest::ResponseAndErrorCallback, |
286 base::Unretained(this), base::Unretained(loop.get()))); | 289 base::Unretained(this), base::Unretained(loop.get()))); |
287 loop->Run(); | 290 loop->Run(); |
288 | 291 |
289 return callback_error_ == CACHE_STORAGE_OK; | 292 return callback_error_ == CACHE_STORAGE_OK; |
290 } | 293 } |
291 | 294 |
292 bool Delete(const ServiceWorkerFetchRequest& request) { | 295 bool Delete(const ServiceWorkerFetchRequest& request) { |
293 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | 296 CacheStorageBatchOperation operation; |
| 297 operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE; |
| 298 operation.request = request; |
294 | 299 |
295 cache_->Delete( | 300 CacheStorageError error = |
296 CopyFetchRequest(request), | 301 BatchOperation(std::vector<CacheStorageBatchOperation>(1, operation)); |
297 base::Bind(&CacheStorageCacheTest::ErrorTypeCallback, | 302 return error == CACHE_STORAGE_OK; |
298 base::Unretained(this), base::Unretained(loop.get()))); | |
299 loop->Run(); | |
300 | |
301 return callback_error_ == CACHE_STORAGE_OK; | |
302 } | 303 } |
303 | 304 |
304 bool Keys() { | 305 bool Keys() { |
305 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | 306 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
306 | 307 |
307 cache_->Keys(base::Bind(&CacheStorageCacheTest::RequestsCallback, | 308 cache_->Keys(base::Bind(&CacheStorageCacheTest::RequestsCallback, |
308 base::Unretained(this), | 309 base::Unretained(this), |
309 base::Unretained(loop.get()))); | 310 base::Unretained(loop.get()))); |
310 loop->Run(); | 311 loop->Run(); |
311 | 312 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 }; | 450 }; |
450 | 451 |
451 TEST_P(CacheStorageCacheTestP, PutNoBody) { | 452 TEST_P(CacheStorageCacheTestP, PutNoBody) { |
452 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); | 453 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); |
453 } | 454 } |
454 | 455 |
455 TEST_P(CacheStorageCacheTestP, PutBody) { | 456 TEST_P(CacheStorageCacheTestP, PutBody) { |
456 EXPECT_TRUE(Put(body_request_, body_response_)); | 457 EXPECT_TRUE(Put(body_request_, body_response_)); |
457 } | 458 } |
458 | 459 |
| 460 TEST_P(CacheStorageCacheTestP, PutBody_Multiple) { |
| 461 CacheStorageBatchOperation operation1; |
| 462 operation1.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| 463 operation1.request = body_request_; |
| 464 operation1.request.url = GURL("http://example.com/1"); |
| 465 operation1.response = body_response_; |
| 466 operation1.response.url = GURL("http://example.com/1"); |
| 467 |
| 468 CacheStorageBatchOperation operation2; |
| 469 operation2.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| 470 operation2.request = body_request_; |
| 471 operation2.request.url = GURL("http://example.com/2"); |
| 472 operation2.response = body_response_; |
| 473 operation2.response.url = GURL("http://example.com/2"); |
| 474 |
| 475 CacheStorageBatchOperation operation3; |
| 476 operation3.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| 477 operation3.request = body_request_; |
| 478 operation3.request.url = GURL("http://example.com/3"); |
| 479 operation3.response = body_response_; |
| 480 operation3.response.url = GURL("http://example.com/3"); |
| 481 |
| 482 std::vector<CacheStorageBatchOperation> operations; |
| 483 operations.push_back(operation1); |
| 484 operations.push_back(operation2); |
| 485 operations.push_back(operation3); |
| 486 |
| 487 EXPECT_EQ(CACHE_STORAGE_OK, BatchOperation(operations)); |
| 488 EXPECT_TRUE(Match(operation1.request)); |
| 489 EXPECT_TRUE(Match(operation2.request)); |
| 490 EXPECT_TRUE(Match(operation3.request)); |
| 491 } |
| 492 |
| 493 // TODO(nhiroki): Add a test for the case where one of PUT operations fails. |
| 494 // Currently there is no handy way to fail only one operation in a batch. |
| 495 // This could be easily achieved after adding some security checks in the |
| 496 // browser side (http://crbug.com/425505). |
| 497 |
459 TEST_P(CacheStorageCacheTestP, ResponseURLDiffersFromRequestURL) { | 498 TEST_P(CacheStorageCacheTestP, ResponseURLDiffersFromRequestURL) { |
460 no_body_response_.url = GURL("http://example.com/foobar"); | 499 no_body_response_.url = GURL("http://example.com/foobar"); |
461 EXPECT_STRNE("http://example.com/foobar", | 500 EXPECT_STRNE("http://example.com/foobar", |
462 no_body_request_.url.spec().c_str()); | 501 no_body_request_.url.spec().c_str()); |
463 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); | 502 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); |
464 EXPECT_TRUE(Match(no_body_request_)); | 503 EXPECT_TRUE(Match(no_body_request_)); |
465 EXPECT_STREQ("http://example.com/foobar", | 504 EXPECT_STREQ("http://example.com/foobar", |
466 callback_response_->url.spec().c_str()); | 505 callback_response_->url.spec().c_str()); |
467 } | 506 } |
468 | 507 |
469 TEST_P(CacheStorageCacheTestP, ResponseURLEmpty) { | 508 TEST_P(CacheStorageCacheTestP, ResponseURLEmpty) { |
470 no_body_response_.url = GURL(); | 509 no_body_response_.url = GURL(); |
471 EXPECT_STRNE("", no_body_request_.url.spec().c_str()); | 510 EXPECT_STRNE("", no_body_request_.url.spec().c_str()); |
472 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); | 511 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); |
473 EXPECT_TRUE(Match(no_body_request_)); | 512 EXPECT_TRUE(Match(no_body_request_)); |
474 EXPECT_STREQ("", callback_response_->url.spec().c_str()); | 513 EXPECT_STREQ("", callback_response_->url.spec().c_str()); |
475 } | 514 } |
476 | 515 |
477 TEST_F(CacheStorageCacheTest, PutBodyDropBlobRef) { | 516 TEST_F(CacheStorageCacheTest, PutBodyDropBlobRef) { |
| 517 CacheStorageBatchOperation operation; |
| 518 operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| 519 operation.request = body_request_; |
| 520 operation.response = body_response_; |
| 521 |
478 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); | 522 scoped_ptr<base::RunLoop> loop(new base::RunLoop()); |
479 cache_->Put(CopyFetchRequest(body_request_), | 523 cache_->BatchOperation( |
480 CopyFetchResponse(body_response_), | 524 std::vector<CacheStorageBatchOperation>(1, operation), |
481 base::Bind(&CacheStorageCacheTestP::ErrorTypeCallback, | 525 base::Bind(&CacheStorageCacheTestP::ErrorTypeCallback, |
482 base::Unretained(this), base::Unretained(loop.get()))); | 526 base::Unretained(this), base::Unretained(loop.get()))); |
483 // The handle should be held by the cache now so the deref here should be | 527 // The handle should be held by the cache now so the deref here should be |
484 // okay. | 528 // okay. |
485 blob_handle_.reset(); | 529 blob_handle_.reset(); |
486 loop->Run(); | 530 loop->Run(); |
487 | 531 |
488 EXPECT_EQ(CACHE_STORAGE_OK, callback_error_); | 532 EXPECT_EQ(CACHE_STORAGE_OK, callback_error_); |
489 } | 533 } |
490 | 534 |
491 TEST_P(CacheStorageCacheTestP, PutReplace) { | 535 TEST_P(CacheStorageCacheTestP, PutReplace) { |
492 EXPECT_TRUE(Put(body_request_, no_body_response_)); | 536 EXPECT_TRUE(Put(body_request_, no_body_response_)); |
493 EXPECT_TRUE(Match(body_request_)); | 537 EXPECT_TRUE(Match(body_request_)); |
494 EXPECT_FALSE(callback_response_data_); | 538 EXPECT_FALSE(callback_response_data_); |
495 | 539 |
496 EXPECT_TRUE(Put(body_request_, body_response_)); | 540 EXPECT_TRUE(Put(body_request_, body_response_)); |
497 EXPECT_TRUE(Match(body_request_)); | 541 EXPECT_TRUE(Match(body_request_)); |
498 EXPECT_TRUE(callback_response_data_); | 542 EXPECT_TRUE(callback_response_data_); |
499 | 543 |
500 EXPECT_TRUE(Put(body_request_, no_body_response_)); | 544 EXPECT_TRUE(Put(body_request_, no_body_response_)); |
501 EXPECT_TRUE(Match(body_request_)); | 545 EXPECT_TRUE(Match(body_request_)); |
502 EXPECT_FALSE(callback_response_data_); | 546 EXPECT_FALSE(callback_response_data_); |
503 } | 547 } |
504 | 548 |
| 549 TEST_P(CacheStorageCacheTestP, PutReplcaceInBatch) { |
| 550 CacheStorageBatchOperation operation1; |
| 551 operation1.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| 552 operation1.request = body_request_; |
| 553 operation1.response = no_body_response_; |
| 554 |
| 555 CacheStorageBatchOperation operation2; |
| 556 operation2.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| 557 operation2.request = body_request_; |
| 558 operation2.response = body_response_; |
| 559 |
| 560 std::vector<CacheStorageBatchOperation> operations; |
| 561 operations.push_back(operation1); |
| 562 operations.push_back(operation2); |
| 563 |
| 564 EXPECT_EQ(CACHE_STORAGE_OK, BatchOperation(operations)); |
| 565 |
| 566 // |operation2| should win. |
| 567 EXPECT_TRUE(Match(operation2.request)); |
| 568 EXPECT_TRUE(callback_response_data_); |
| 569 } |
| 570 |
505 TEST_P(CacheStorageCacheTestP, MatchNoBody) { | 571 TEST_P(CacheStorageCacheTestP, MatchNoBody) { |
506 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); | 572 EXPECT_TRUE(Put(no_body_request_, no_body_response_)); |
507 EXPECT_TRUE(Match(no_body_request_)); | 573 EXPECT_TRUE(Match(no_body_request_)); |
508 EXPECT_EQ(200, callback_response_->status_code); | 574 EXPECT_EQ(200, callback_response_->status_code); |
509 EXPECT_STREQ("OK", callback_response_->status_text.c_str()); | 575 EXPECT_STREQ("OK", callback_response_->status_text.c_str()); |
510 EXPECT_STREQ("http://example.com/no_body.html", | 576 EXPECT_STREQ("http://example.com/no_body.html", |
511 callback_response_->url.spec().c_str()); | 577 callback_response_->url.spec().c_str()); |
512 EXPECT_STREQ("", callback_response_->blob_uuid.c_str()); | 578 EXPECT_STREQ("", callback_response_->blob_uuid.c_str()); |
513 EXPECT_EQ(0u, callback_response_->blob_size); | 579 EXPECT_EQ(0u, callback_response_->blob_size); |
514 } | 580 } |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 | 820 |
755 TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) { | 821 TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) { |
756 // Start two operations, the first one is delayed but the second isn't. The | 822 // Start two operations, the first one is delayed but the second isn't. The |
757 // second should wait for the first. | 823 // second should wait for the first. |
758 EXPECT_TRUE(Keys()); // Opens the backend. | 824 EXPECT_TRUE(Keys()); // Opens the backend. |
759 DelayableBackend* delayable_backend = cache_->UseDelayableBackend(); | 825 DelayableBackend* delayable_backend = cache_->UseDelayableBackend(); |
760 delayable_backend->set_delay_open(true); | 826 delayable_backend->set_delay_open(true); |
761 | 827 |
762 int sequence_out = -1; | 828 int sequence_out = -1; |
763 | 829 |
764 scoped_ptr<ServiceWorkerResponse> response1 = | 830 CacheStorageBatchOperation operation1; |
765 CopyFetchResponse(body_response_); | 831 operation1.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| 832 operation1.request = body_request_; |
| 833 operation1.response = body_response_; |
| 834 |
766 scoped_ptr<base::RunLoop> close_loop1(new base::RunLoop()); | 835 scoped_ptr<base::RunLoop> close_loop1(new base::RunLoop()); |
767 cache_->Put( | 836 cache_->BatchOperation( |
768 CopyFetchRequest(body_request_), response1.Pass(), | 837 std::vector<CacheStorageBatchOperation>(1, operation1), |
769 base::Bind(&CacheStorageCacheTest::SequenceCallback, | 838 base::Bind(&CacheStorageCacheTest::SequenceCallback, |
770 base::Unretained(this), 1, &sequence_out, close_loop1.get())); | 839 base::Unretained(this), 1, &sequence_out, close_loop1.get())); |
771 | 840 |
772 // Blocks on opening the cache entry. | 841 // Blocks on opening the cache entry. |
773 base::RunLoop().RunUntilIdle(); | 842 base::RunLoop().RunUntilIdle(); |
774 | 843 |
| 844 CacheStorageBatchOperation operation2; |
| 845 operation2.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| 846 operation2.request = body_request_; |
| 847 operation2.response = body_response_; |
| 848 |
775 delayable_backend->set_delay_open(false); | 849 delayable_backend->set_delay_open(false); |
776 scoped_ptr<ServiceWorkerResponse> response2 = | |
777 CopyFetchResponse(body_response_); | |
778 scoped_ptr<base::RunLoop> close_loop2(new base::RunLoop()); | 850 scoped_ptr<base::RunLoop> close_loop2(new base::RunLoop()); |
779 cache_->Put( | 851 cache_->BatchOperation( |
780 CopyFetchRequest(body_request_), response2.Pass(), | 852 std::vector<CacheStorageBatchOperation>(1, operation2), |
781 base::Bind(&CacheStorageCacheTest::SequenceCallback, | 853 base::Bind(&CacheStorageCacheTest::SequenceCallback, |
782 base::Unretained(this), 2, &sequence_out, close_loop2.get())); | 854 base::Unretained(this), 2, &sequence_out, close_loop2.get())); |
783 | 855 |
784 // The second put operation should wait for the first to complete. | 856 // The second put operation should wait for the first to complete. |
785 base::RunLoop().RunUntilIdle(); | 857 base::RunLoop().RunUntilIdle(); |
786 EXPECT_FALSE(callback_response_); | 858 EXPECT_FALSE(callback_response_); |
787 | 859 |
788 delayable_backend->OpenEntryContinue(); | 860 delayable_backend->OpenEntryContinue(); |
789 close_loop1->Run(); | 861 close_loop1->Run(); |
790 EXPECT_EQ(1, sequence_out); | 862 EXPECT_EQ(1, sequence_out); |
791 close_loop2->Run(); | 863 close_loop2->Run(); |
792 EXPECT_EQ(2, sequence_out); | 864 EXPECT_EQ(2, sequence_out); |
793 } | 865 } |
794 | 866 |
795 INSTANTIATE_TEST_CASE_P(CacheStorageCacheTest, | 867 INSTANTIATE_TEST_CASE_P(CacheStorageCacheTest, |
796 CacheStorageCacheTestP, | 868 CacheStorageCacheTestP, |
797 ::testing::Values(false, true)); | 869 ::testing::Values(false, true)); |
798 | 870 |
799 } // namespace content | 871 } // namespace content |
OLD | NEW |