Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Side by Side Diff: chrome/browser/chrome_service_worker_browsertest.cc

Issue 2916533002: Introduce chrome://flags/#network-prediction-options-for-service-worker
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 // This file tests that Service Workers (a Content feature) work in the Chromium 5 // This file tests that Service Workers (a Content feature) work in the Chromium
6 // embedder. 6 // embedder.
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/scoped_temp_dir.h" 10 #include "base/files/scoped_temp_dir.h"
11 #include "base/numerics/safe_conversions.h" 11 #include "base/numerics/safe_conversions.h"
12 #include "base/run_loop.h" 12 #include "base/run_loop.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "base/test/histogram_tester.h"
15 #include "base/threading/thread_restrictions.h" 16 #include "base/threading/thread_restrictions.h"
16 #include "build/build_config.h" 17 #include "build/build_config.h"
17 #include "chrome/browser/chrome_notification_types.h" 18 #include "chrome/browser/chrome_notification_types.h"
18 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 19 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
19 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 20 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
21 #include "chrome/browser/net/prediction_options.h"
22 #include "chrome/browser/net/predictor.h"
20 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/browser.h" 24 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_window.h" 25 #include "chrome/browser/ui/browser_window.h"
23 #include "chrome/browser/ui/tabs/tab_strip_model.h" 26 #include "chrome/browser/ui/tabs/tab_strip_model.h"
24 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
25 #include "chrome/test/base/in_process_browser_test.h" 28 #include "chrome/test/base/in_process_browser_test.h"
26 #include "chrome/test/base/ui_test_utils.h" 29 #include "chrome/test/base/ui_test_utils.h"
27 #include "components/content_settings/core/browser/host_content_settings_map.h" 30 #include "components/content_settings/core/browser/host_content_settings_map.h"
28 #include "content/public/browser/browser_context.h" 31 #include "content/public/browser/browser_context.h"
29 #include "content/public/browser/render_frame_host.h" 32 #include "content/public/browser/render_frame_host.h"
30 #include "content/public/browser/service_worker_context.h" 33 #include "content/public/browser/service_worker_context.h"
31 #include "content/public/browser/storage_partition.h" 34 #include "content/public/browser/storage_partition.h"
32 #include "content/public/browser/web_contents.h" 35 #include "content/public/browser/web_contents.h"
33 #include "content/public/test/browser_test_utils.h" 36 #include "content/public/test/browser_test_utils.h"
34 #include "net/test/embedded_test_server/embedded_test_server.h" 37 #include "net/test/embedded_test_server/embedded_test_server.h"
38 #include "net/test/embedded_test_server/embedded_test_server_connection_listener .h"
35 #include "ppapi/shared_impl/ppapi_switches.h" 39 #include "ppapi/shared_impl/ppapi_switches.h"
36 40
37 namespace { 41 namespace {
38 42
39 class ChromeServiceWorkerTest : public InProcessBrowserTest { 43 class ChromeServiceWorkerTest : public InProcessBrowserTest {
40 protected: 44 protected:
41 ChromeServiceWorkerTest() { 45 ChromeServiceWorkerTest() {
42 EXPECT_TRUE(service_worker_dir_.CreateUniqueTempDir()); 46 EXPECT_TRUE(service_worker_dir_.CreateUniqueTempDir());
43 EXPECT_TRUE(base::CreateDirectoryAndGetError( 47 EXPECT_TRUE(base::CreateDirectoryAndGetError(
44 service_worker_dir_.GetPath().Append( 48 service_worker_dir_.GetPath().Append(
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 EXPECT_EQ(GetRequestStringForPNACL("#OtherCredentials"), 608 EXPECT_EQ(GetRequestStringForPNACL("#OtherCredentials"),
605 ExecutePNACLUrlLoaderTest("OtherCredentials")); 609 ExecutePNACLUrlLoaderTest("OtherCredentials"));
606 } 610 }
607 611
608 IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPIPrivateTest, 612 IN_PROC_BROWSER_TEST_F(ChromeServiceWorkerFetchPPAPIPrivateTest,
609 OtherOriginCORSCredentials) { 613 OtherOriginCORSCredentials) {
610 EXPECT_EQ(GetRequestStringForPNACL("#OtherCORSCredentials"), 614 EXPECT_EQ(GetRequestStringForPNACL("#OtherCORSCredentials"),
611 ExecutePNACLUrlLoaderTest("OtherCORSCredentials")); 615 ExecutePNACLUrlLoaderTest("OtherCORSCredentials"));
612 } 616 }
613 617
618 class ConnectionListener
619 : public net::test_server::EmbeddedTestServerConnectionListener {
620 public:
621 ConnectionListener() : task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
622 ~ConnectionListener() override {}
623
624 void AcceptedSocket(const net::StreamSocket& connection) override {
625 base::AutoLock lock(lock_);
626 socket_accepted_ = true;
627 if (wait_accept_loop_)
628 task_runner_->PostTask(FROM_HERE, wait_accept_loop_->QuitClosure());
629 }
630 void ReadFromSocket(const net::StreamSocket& socket, int rv) override {}
631
632 void ResetSocketAcceptedFlag() {
633 base::AutoLock lock(lock_);
634 socket_accepted_ = false;
635 }
636
637 bool GetSocketAcceptedFlag() const {
638 base::AutoLock lock(lock_);
639 return socket_accepted_;
640 }
641
642 void WaitForSocketAcceptedOnUI() {
643 {
644 base::AutoLock lock(lock_);
645 if (socket_accepted_)
646 return;
647 wait_accept_loop_.reset(new base::RunLoop());
648 }
649 wait_accept_loop_->Run();
650 }
651
652 private:
653 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
654
655 // This lock protects the members below, which each are used on both the
656 // IO and UI thread. Members declared after the lock are protected by it.
657 mutable base::Lock lock_;
658 bool socket_accepted_ = false;
659 std::unique_ptr<base::RunLoop> wait_accept_loop_;
660
661 DISALLOW_COPY_AND_ASSIGN(ConnectionListener);
662 };
663
664 class ChromeServiceWorkerPredictionOptionsTest
665 : public ChromeServiceWorkerTest,
666 public ::testing::WithParamInterface<
667 chrome_browser_net::NetworkPredictionOptionsForServiceWorker> {
668 protected:
669 ChromeServiceWorkerPredictionOptionsTest()
670 : cross_site_test_server_(new net::EmbeddedTestServer()) {}
671 ~ChromeServiceWorkerPredictionOptionsTest() override {}
672
673 void SetUpCommandLine(base::CommandLine* command_line) override {
674 ChromeServiceWorkerTest::SetUpCommandLine(command_line);
675 switch (GetParam()) {
676 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
677 PRECONNECT_ONLY:
678 command_line->AppendSwitchASCII(
679 switches::kNetworkPredictionOptionsForServiceWorker,
680 chrome_browser_net::kPreconnectOnly);
681 break;
682 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
683 START_SERVICE_WORKER_AND_PRECONNECT:
684 command_line->AppendSwitchASCII(
685 switches::kNetworkPredictionOptionsForServiceWorker,
686 chrome_browser_net::kStartServiceWorkerAndPreconnect);
687 break;
688 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
689 START_SERVICE_WORKER_AND_DEFER_PRECONNECT:
690 command_line->AppendSwitchASCII(
691 switches::kNetworkPredictionOptionsForServiceWorker,
692 chrome_browser_net::kStartServiceWorkerAndDeferPreconnect);
693 break;
694 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
695 START_SERVICE_WORKER_ONLY:
696 command_line->AppendSwitchASCII(
697 switches::kNetworkPredictionOptionsForServiceWorker,
698 chrome_browser_net::kStartServiceWorkerOnly);
699 break;
700 }
701 }
702
703 void SetUpOnMainThread() override {
704 WriteServiceWorkerPredictionOptionsTestFiles();
705
706 embedded_test_server()->ServeFilesFromDirectory(
707 service_worker_dir_.GetPath());
708 ASSERT_TRUE(embedded_test_server()->Start());
709
710 cross_site_test_server()->ServeFilesFromDirectory(
711 service_worker_dir_.GetPath());
712 cross_site_connection_listener_.reset(new ConnectionListener());
713 cross_site_test_server()->SetConnectionListener(
714 cross_site_connection_listener_.get());
715 ASSERT_TRUE(cross_site_test_server()->Start());
716
717 browser()->profile()->GetNetworkPredictor()->SetPredictorEnabledForTest(
718 true);
719 }
720
721 void InitializeServiceWorkerTest() {
722 base::HistogramTester histogram_tester;
723 const base::string16 expected_title = base::ASCIIToUTF16("READY");
724 content::TitleWatcher title_watcher(
725 browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
726 ui_test_utils::NavigateToURL(
727 browser(), embedded_test_server()->GetURL(
728 "/sw_test_page.html?" +
729 cross_site_test_server()->GetURL("/test.js").spec()));
730 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
731 histogram_tester.ExpectTotalCount("ServiceWorker.StartNewWorker.Status", 1);
732 histogram_tester.ExpectBucketCount("ServiceWorker.StartNewWorker.Status",
733 0 /* SERVICE_WORKER_OK */, 1);
734
735 // Stop the service worker.
736 content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
737 ->GetServiceWorkerContext()
738 ->StopAllServiceWorkersForOrigin(embedded_test_server()->base_url());
739
740 // Disconnect the connection.
741 cross_site_test_server()->FlushAllSocketsAndConnectionsOnUIThread();
742 EXPECT_TRUE(cross_site_connection_listener()->GetSocketAcceptedFlag());
743 cross_site_connection_listener()->ResetSocketAcceptedFlag();
744 }
745
746 void NavigateToServiceWorkerTestPage() {
747 const base::string16 expected_title = base::ASCIIToUTF16("SW");
748 content::TitleWatcher title_watcher(
749 browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
750 ui_test_utils::NavigateToURL(browser(),
751 embedded_test_server()->GetURL("/dummy.html"));
752 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
753 }
754
755 void InitializeNoServiceWorkerTest() {
756 const base::string16 expected_title = base::ASCIIToUTF16("READY");
757 content::TitleWatcher title_watcher(
758 browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
759 ui_test_utils::NavigateToURL(
760 browser(), embedded_test_server()->GetURL(
761 "/no_sw_test_page.html?" +
762 cross_site_test_server()->GetURL("/test.js").spec()));
763
764 // Disconnect the connection.
765 cross_site_test_server()->FlushAllSocketsAndConnectionsOnUIThread();
766 EXPECT_TRUE(cross_site_connection_listener()->GetSocketAcceptedFlag());
767 cross_site_connection_listener()->ResetSocketAcceptedFlag();
768 }
769
770 void NavigateToNoServiceWorkerTestPage() {
771 const base::string16 expected_title = base::ASCIIToUTF16("READY");
772 content::TitleWatcher title_watcher(
773 browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
774 ui_test_utils::NavigateToURL(
775 browser(), embedded_test_server()->GetURL("/no_sw_test_page.html"));
776 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
777 }
778
779 net::EmbeddedTestServer* cross_site_test_server() {
780 return cross_site_test_server_.get();
781 }
782
783 ConnectionListener* cross_site_connection_listener() {
784 return cross_site_connection_listener_.get();
785 }
786
787 private:
788 void WriteServiceWorkerPredictionOptionsTestFiles() {
789 WriteFile(FILE_PATH_LITERAL("test.js"), "document.title = 'READY';");
790 WriteFile(FILE_PATH_LITERAL("sw.js"),
791 "this.onfetch = function(event) {"
792 " event.respondWith(new Response("
793 " '<title>SW</title>', "
794 " {headers: {'Content-Type': 'text/html'}}));"
795 "};");
796 WriteFile(FILE_PATH_LITERAL("sw_test_page.html"),
797 "<body><script>"
798 "navigator.serviceWorker.register('./sw.js', {scope: './'})"
799 " .then(reg => {"
800 " reg.addEventListener('updatefound', _ => {"
801 " var worker = reg.installing;"
802 " worker.addEventListener('statechange', _ => {"
803 " if (worker.state != 'activated')"
804 " return;"
805 " var script = document.createElement('script');"
806 " script.src = window.location.search.substring(1);"
807 " document.body.appendChild(script);"
808 " });"
809 " });"
810 " });"
811 "</script></body>");
812 WriteFile(FILE_PATH_LITERAL("no_sw_test_page.html"),
813 "<body><script>"
814 "if (window.location.search != '') {"
815 " var script = document.createElement('script');"
816 " script.src = window.location.search.substring(1);"
817 " document.body.appendChild(script);"
818 "} else {"
819 " document.title = 'READY';"
820 "}"
821 "</script></body>");
822 }
823
824 std::unique_ptr<net::EmbeddedTestServer> cross_site_test_server_;
825 std::unique_ptr<ConnectionListener> cross_site_connection_listener_;
826
827 DISALLOW_COPY_AND_ASSIGN(ChromeServiceWorkerPredictionOptionsTest);
828 };
829
830 IN_PROC_BROWSER_TEST_P(ChromeServiceWorkerPredictionOptionsTest,
831 ServiceWorkerTest) {
832 InitializeServiceWorkerTest();
833 base::HistogramTester histogram_tester;
834 NavigateToServiceWorkerTestPage();
835 histogram_tester.ExpectTotalCount("ServiceWorker.StartWorker.Purpose", 1);
836
837 switch (GetParam()) {
838 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
839 PRECONNECT_ONLY:
840 histogram_tester.ExpectBucketCount(
841 "ServiceWorker.StartWorker.Purpose",
842 10 /* ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME */, 1);
843 break;
844 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
845 START_SERVICE_WORKER_AND_PRECONNECT:
846 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
847 START_SERVICE_WORKER_AND_DEFER_PRECONNECT:
848 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
849 START_SERVICE_WORKER_ONLY:
850 histogram_tester.ExpectBucketCount(
851 "ServiceWorker.StartWorker.Purpose",
852 27 /* ServiceWorkerMetrics::EventType::PRECONNECT */, 1);
853 break;
854 }
855
856 // Note: Wrting a chrome browset test which checks that the preconnection is
857 // defered until the service worker startup is too complex. So we only check
858 // that the preconnection is accutualy executed.
859 switch (GetParam()) {
860 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
861 PRECONNECT_ONLY:
862 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
863 START_SERVICE_WORKER_AND_PRECONNECT:
864 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
865 START_SERVICE_WORKER_AND_DEFER_PRECONNECT:
866 cross_site_connection_listener()->WaitForSocketAcceptedOnUI();
867 break;
868 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
869 START_SERVICE_WORKER_ONLY:
870 EXPECT_FALSE(cross_site_connection_listener()->GetSocketAcceptedFlag());
871 break;
872 }
873 }
874
875 IN_PROC_BROWSER_TEST_P(ChromeServiceWorkerPredictionOptionsTest,
876 NoServiceWorkerTest) {
877 InitializeNoServiceWorkerTest();
878 base::HistogramTester histogram_tester;
879 NavigateToNoServiceWorkerTestPage();
880 // If there is no service workers, the preconnection must be executed
881 // regardless of the options.
882 cross_site_connection_listener()->WaitForSocketAcceptedOnUI();
883 }
884
885 INSTANTIATE_TEST_CASE_P(
886 /* no prefix */,
887 ChromeServiceWorkerPredictionOptionsTest,
888 ::testing::Values(
889 chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
890 PRECONNECT_ONLY,
891 chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
892 START_SERVICE_WORKER_AND_PRECONNECT,
893 chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
894 START_SERVICE_WORKER_AND_DEFER_PRECONNECT,
895 chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
896 START_SERVICE_WORKER_ONLY));
897
614 } // namespace 898 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698