OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <deque> | 5 #include <deque> |
6 #include <vector> | 6 #include <vector> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 // |file| afterwards. | 698 // |file| afterwards. |
699 void CreateHangingFirstRequestProtocolHandlerOnIO(const GURL& url, | 699 void CreateHangingFirstRequestProtocolHandlerOnIO(const GURL& url, |
700 const base::FilePath& file) { | 700 const base::FilePath& file) { |
701 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 701 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
702 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> never_respond_handler( | 702 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> never_respond_handler( |
703 new HangingFirstRequestProtocolHandler(file)); | 703 new HangingFirstRequestProtocolHandler(file)); |
704 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler( | 704 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler( |
705 url, never_respond_handler.Pass()); | 705 url, never_respond_handler.Pass()); |
706 } | 706 } |
707 | 707 |
| 708 // Wrapper over URLRequestMockHTTPJob that exposes extra callbacks. |
| 709 class MockHTTPJob : public content::URLRequestMockHTTPJob { |
| 710 public: |
| 711 MockHTTPJob(net::URLRequest* request, |
| 712 net::NetworkDelegate* delegate, |
| 713 const base::FilePath& file) |
| 714 : content::URLRequestMockHTTPJob(request, delegate, file) { |
| 715 } |
| 716 |
| 717 void set_start_callback(const base::Closure& start_callback) { |
| 718 start_callback_ = start_callback; |
| 719 } |
| 720 |
| 721 virtual void Start() OVERRIDE { |
| 722 if (!start_callback_.is_null()) |
| 723 start_callback_.Run(); |
| 724 content::URLRequestMockHTTPJob::Start(); |
| 725 } |
| 726 |
| 727 private: |
| 728 base::Closure start_callback_; |
| 729 }; |
| 730 |
| 731 // Dummy counter class to live on the UI thread for counting requests. |
| 732 class RequestCounter : public base::SupportsWeakPtr<RequestCounter> { |
| 733 public: |
| 734 RequestCounter() : count_(0) {} |
| 735 int count() const { return count_; } |
| 736 void RequestStarted() { count_++; } |
| 737 private: |
| 738 int count_; |
| 739 }; |
| 740 |
| 741 // Protocol handler which counts the number of requests that start. |
| 742 class CountingProtocolHandler |
| 743 : public net::URLRequestJobFactory::ProtocolHandler { |
| 744 public: |
| 745 CountingProtocolHandler(const base::FilePath& file, |
| 746 const base::WeakPtr<RequestCounter>& counter) |
| 747 : file_(file), |
| 748 counter_(counter), |
| 749 weak_factory_(this) { |
| 750 } |
| 751 virtual ~CountingProtocolHandler() {} |
| 752 |
| 753 virtual net::URLRequestJob* MaybeCreateJob( |
| 754 net::URLRequest* request, |
| 755 net::NetworkDelegate* network_delegate) const OVERRIDE { |
| 756 MockHTTPJob* job = new MockHTTPJob(request, network_delegate, file_); |
| 757 job->set_start_callback(base::Bind(&CountingProtocolHandler::RequestStarted, |
| 758 weak_factory_.GetWeakPtr())); |
| 759 return job; |
| 760 } |
| 761 |
| 762 void RequestStarted() { |
| 763 BrowserThread::PostTask( |
| 764 BrowserThread::UI, FROM_HERE, |
| 765 base::Bind(&RequestCounter::RequestStarted, counter_)); |
| 766 } |
| 767 |
| 768 private: |
| 769 base::FilePath file_; |
| 770 base::WeakPtr<RequestCounter> counter_; |
| 771 mutable base::WeakPtrFactory<CountingProtocolHandler> weak_factory_; |
| 772 }; |
| 773 |
| 774 // Makes |url| respond to requests with the contents of |file|, counting the |
| 775 // number that start in |counter|. |
| 776 void CreateCountingProtocolHandlerOnIO( |
| 777 const GURL& url, |
| 778 const base::FilePath& file, |
| 779 const base::WeakPtr<RequestCounter>& counter) { |
| 780 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 781 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> protocol_handler( |
| 782 new CountingProtocolHandler(file, counter)); |
| 783 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler( |
| 784 url, protocol_handler.Pass()); |
| 785 } |
| 786 |
708 // Makes |url| respond to requests with the contents of |file|. | 787 // Makes |url| respond to requests with the contents of |file|. |
709 void CreateMockProtocolHandlerOnIO(const GURL& url, | 788 void CreateMockProtocolHandlerOnIO(const GURL& url, |
710 const base::FilePath& file) { | 789 const base::FilePath& file) { |
711 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 790 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
712 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler( | 791 net::URLRequestFilter::GetInstance()->AddUrlProtocolHandler( |
713 url, content::URLRequestMockHTTPJob::CreateProtocolHandlerForSingleFile( | 792 url, content::URLRequestMockHTTPJob::CreateProtocolHandlerForSingleFile( |
714 file)); | 793 file)); |
715 } | 794 } |
716 | 795 |
717 // A ContentBrowserClient that cancels all prerenderers on OpenURL. | 796 // A ContentBrowserClient that cancels all prerenderers on OpenURL. |
(...skipping 2739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3457 // prerendered page tries to make a second navigation entry. | 3536 // prerendered page tries to make a second navigation entry. |
3458 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNewNavigationEntry) { | 3537 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNewNavigationEntry) { |
3459 PrerenderTestURL("files/prerender/prerender_new_entry.html", | 3538 PrerenderTestURL("files/prerender/prerender_new_entry.html", |
3460 FINAL_STATUS_NEW_NAVIGATION_ENTRY, | 3539 FINAL_STATUS_NEW_NAVIGATION_ENTRY, |
3461 1); | 3540 1); |
3462 } | 3541 } |
3463 | 3542 |
3464 // Attempt a swap-in in a new tab, verifying that session storage namespace | 3543 // Attempt a swap-in in a new tab, verifying that session storage namespace |
3465 // merging works. | 3544 // merging works. |
3466 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTab) { | 3545 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTab) { |
3467 PrerenderTestURL("files/prerender/prerender_session_storage.html", | 3546 base::FilePath test_data_dir; |
3468 FINAL_STATUS_USED, 1); | 3547 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); |
| 3548 |
| 3549 // Mock out some URLs and count the number of requests to one of them. Both |
| 3550 // prerender_session_storage.html and init_session_storage.html need to be |
| 3551 // mocked so they are same-origin. |
| 3552 const GURL kInitURL("http://prerender.test/init_session_storage.html"); |
| 3553 base::FilePath init_file = test_data_dir.AppendASCII( |
| 3554 "prerender/init_session_storage.html"); |
| 3555 BrowserThread::PostTask( |
| 3556 BrowserThread::IO, FROM_HERE, |
| 3557 base::Bind(&CreateMockProtocolHandlerOnIO, kInitURL, init_file)); |
| 3558 |
| 3559 const GURL kTestURL("http://prerender.test/prerender_session_storage.html"); |
| 3560 base::FilePath test_file = test_data_dir.AppendASCII( |
| 3561 "prerender/prerender_session_storage.html"); |
| 3562 RequestCounter counter; |
| 3563 BrowserThread::PostTask( |
| 3564 BrowserThread::IO, FROM_HERE, |
| 3565 base::Bind(&CreateCountingProtocolHandlerOnIO, |
| 3566 kTestURL, test_file, counter.AsWeakPtr())); |
| 3567 |
| 3568 PrerenderTestURL(kTestURL, FINAL_STATUS_USED, 1); |
3469 | 3569 |
3470 // Open a new tab to navigate in. | 3570 // Open a new tab to navigate in. |
3471 ui_test_utils::NavigateToURLWithDisposition( | 3571 ui_test_utils::NavigateToURLWithDisposition( |
3472 current_browser(), | 3572 current_browser(), kInitURL, NEW_FOREGROUND_TAB, |
3473 test_server()->GetURL("files/prerender/init_session_storage.html"), | |
3474 NEW_FOREGROUND_TAB, | |
3475 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 3573 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
3476 | 3574 |
3477 // Now navigate in the new tab. Set expect_swap_to_succeed to false because | 3575 // Now navigate in the new tab. Set expect_swap_to_succeed to false because |
3478 // the swap does not occur synchronously. | 3576 // the swap does not occur synchronously. |
3479 // | 3577 // |
| 3578 // TODO(davidben): When all swaps become asynchronous, remove the OpenURL |
| 3579 // return value assertion and let this go through the usual successful-swap |
| 3580 // codepath. |
| 3581 NavigateToDestURLWithDisposition(CURRENT_TAB, false); |
| 3582 |
| 3583 // Verify DidDisplayPass manually since the previous call skipped it. |
| 3584 EXPECT_TRUE(DidDisplayPass( |
| 3585 current_browser()->tab_strip_model()->GetActiveWebContents())); |
| 3586 |
| 3587 // Only one request to the test URL started. |
| 3588 EXPECT_EQ(1, counter.count()); |
| 3589 } |
| 3590 |
| 3591 // Attempt a swap-in in a new tab, verifying that session storage namespace |
| 3592 // merging works. Unlike the above test, the swap is for a navigation that would |
| 3593 // normally be cross-process. |
| 3594 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTabCrossProcess) { |
| 3595 base::FilePath test_data_dir; |
| 3596 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)); |
| 3597 |
| 3598 // Mock out some URLs and count the number of requests to one of them. Both |
| 3599 // prerender_session_storage.html and init_session_storage.html need to be |
| 3600 // mocked so they are same-origin. |
| 3601 const GURL kInitURL("http://prerender.test/init_session_storage.html"); |
| 3602 base::FilePath init_file = test_data_dir.AppendASCII( |
| 3603 "prerender/init_session_storage.html"); |
| 3604 BrowserThread::PostTask( |
| 3605 BrowserThread::IO, FROM_HERE, |
| 3606 base::Bind(&CreateMockProtocolHandlerOnIO, kInitURL, init_file)); |
| 3607 |
| 3608 const GURL kTestURL("http://prerender.test/prerender_session_storage.html"); |
| 3609 base::FilePath test_file = test_data_dir.AppendASCII( |
| 3610 "prerender/prerender_session_storage.html"); |
| 3611 RequestCounter counter; |
| 3612 BrowserThread::PostTask( |
| 3613 BrowserThread::IO, FROM_HERE, |
| 3614 base::Bind(&CreateCountingProtocolHandlerOnIO, |
| 3615 kTestURL, test_file, counter.AsWeakPtr())); |
| 3616 |
| 3617 PrerenderTestURL(kTestURL, FINAL_STATUS_USED, 1); |
| 3618 |
| 3619 // Open a new tab to navigate in. |
| 3620 ui_test_utils::NavigateToURLWithDisposition( |
| 3621 current_browser(), kInitURL, NEW_FOREGROUND_TAB, |
| 3622 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
| 3623 |
| 3624 // Navigate to about:blank so the next navigation is cross-process. |
| 3625 ui_test_utils::NavigateToURL(current_browser(), |
| 3626 GURL(content::kAboutBlankURL)); |
| 3627 |
| 3628 // Now navigate in the new tab. Set expect_swap_to_succeed to false because |
| 3629 // the swap does not occur synchronously. |
| 3630 // |
3480 // TODO(davidben): When all swaps become asynchronous, remove the OpenURL | 3631 // TODO(davidben): When all swaps become asynchronous, remove the OpenURL |
3481 // return value assertion and let this go through the usual successful-swap | 3632 // return value assertion and let this go through the usual successful-swap |
3482 // codepath. | 3633 // codepath. |
3483 NavigateToDestURLWithDisposition(CURRENT_TAB, false); | 3634 NavigateToDestURLWithDisposition(CURRENT_TAB, false); |
3484 | 3635 |
3485 // Verify DidDisplayPass manually since the previous call skipped it. | 3636 // Verify DidDisplayPass manually since the previous call skipped it. |
3486 EXPECT_TRUE(DidDisplayPass( | 3637 EXPECT_TRUE(DidDisplayPass( |
3487 current_browser()->tab_strip_model()->GetActiveWebContents())); | 3638 current_browser()->tab_strip_model()->GetActiveWebContents())); |
| 3639 |
| 3640 // Only one request to the test URL started. |
| 3641 EXPECT_EQ(1, counter.count()); |
3488 } | 3642 } |
3489 | 3643 |
3490 // Verify that session storage conflicts don't merge. | 3644 // Verify that session storage conflicts don't merge. |
3491 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorageConflict) { | 3645 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorageConflict) { |
3492 PrerenderTestURL("files/prerender/prerender_session_storage_conflict.html", | 3646 PrerenderTestURL("files/prerender/prerender_session_storage_conflict.html", |
3493 FINAL_STATUS_APP_TERMINATING, 1); | 3647 FINAL_STATUS_APP_TERMINATING, 1); |
3494 | 3648 |
3495 // Open a new tab to navigate in. | 3649 // Open a new tab to navigate in. |
3496 ui_test_utils::NavigateToURLWithDisposition( | 3650 ui_test_utils::NavigateToURLWithDisposition( |
3497 current_browser(), | 3651 current_browser(), |
(...skipping 23 matching lines...) Expand all Loading... |
3521 const NavigationController& controller = web_contents->GetController(); | 3675 const NavigationController& controller = web_contents->GetController(); |
3522 // First entry is about:blank, second is prerender_page.html. | 3676 // First entry is about:blank, second is prerender_page.html. |
3523 EXPECT_TRUE(controller.GetPendingEntry() == NULL); | 3677 EXPECT_TRUE(controller.GetPendingEntry() == NULL); |
3524 EXPECT_EQ(2, controller.GetEntryCount()); | 3678 EXPECT_EQ(2, controller.GetEntryCount()); |
3525 EXPECT_EQ(GURL(content::kAboutBlankURL), | 3679 EXPECT_EQ(GURL(content::kAboutBlankURL), |
3526 controller.GetEntryAtIndex(0)->GetURL()); | 3680 controller.GetEntryAtIndex(0)->GetURL()); |
3527 EXPECT_EQ(dest_url(), controller.GetEntryAtIndex(1)->GetURL()); | 3681 EXPECT_EQ(dest_url(), controller.GetEntryAtIndex(1)->GetURL()); |
3528 } | 3682 } |
3529 | 3683 |
3530 } // namespace prerender | 3684 } // namespace prerender |
OLD | NEW |