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

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

Issue 2916533002: Introduce chrome://flags/#network-prediction-options-for-service-worker
Patch Set: use StartServiceWorkerForNavigationHint Created 3 years, 5 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
« no previous file with comments | « chrome/browser/about_flags.cc ('k') | chrome/browser/flag_descriptions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <tuple>
9
8 #include "base/bind.h" 10 #include "base/bind.h"
9 #include "base/command_line.h" 11 #include "base/command_line.h"
10 #include "base/files/scoped_temp_dir.h" 12 #include "base/files/scoped_temp_dir.h"
11 #include "base/numerics/safe_conversions.h" 13 #include "base/numerics/safe_conversions.h"
12 #include "base/run_loop.h" 14 #include "base/run_loop.h"
13 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
15 #include "base/test/histogram_tester.h" 17 #include "base/test/histogram_tester.h"
16 #include "base/threading/thread_restrictions.h" 18 #include "base/threading/thread_restrictions.h"
17 #include "build/build_config.h" 19 #include "build/build_config.h"
18 #include "chrome/browser/chrome_notification_types.h" 20 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 21 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
20 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 22 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
23 #include "chrome/browser/net/prediction_options.h"
24 #include "chrome/browser/net/predictor.h"
21 #include "chrome/browser/profiles/profile.h" 25 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/ui/browser.h" 26 #include "chrome/browser/ui/browser.h"
23 #include "chrome/browser/ui/browser_window.h" 27 #include "chrome/browser/ui/browser_window.h"
24 #include "chrome/browser/ui/tabs/tab_strip_model.h" 28 #include "chrome/browser/ui/tabs/tab_strip_model.h"
25 #include "chrome/common/chrome_switches.h" 29 #include "chrome/common/chrome_switches.h"
26 #include "chrome/test/base/in_process_browser_test.h" 30 #include "chrome/test/base/in_process_browser_test.h"
27 #include "chrome/test/base/ui_test_utils.h" 31 #include "chrome/test/base/ui_test_utils.h"
28 #include "components/content_settings/core/browser/host_content_settings_map.h" 32 #include "components/content_settings/core/browser/host_content_settings_map.h"
29 #include "content/public/browser/browser_context.h" 33 #include "content/public/browser/browser_context.h"
30 #include "content/public/browser/render_frame_host.h" 34 #include "content/public/browser/render_frame_host.h"
31 #include "content/public/browser/service_worker_context.h" 35 #include "content/public/browser/service_worker_context.h"
32 #include "content/public/browser/storage_partition.h" 36 #include "content/public/browser/storage_partition.h"
33 #include "content/public/browser/web_contents.h" 37 #include "content/public/browser/web_contents.h"
38 #include "content/public/common/content_switches.h"
34 #include "content/public/test/browser_test_utils.h" 39 #include "content/public/test/browser_test_utils.h"
35 #include "net/test/embedded_test_server/embedded_test_server.h" 40 #include "net/test/embedded_test_server/embedded_test_server.h"
41 #include "net/test/embedded_test_server/embedded_test_server_connection_listener .h"
36 #include "ppapi/shared_impl/ppapi_switches.h" 42 #include "ppapi/shared_impl/ppapi_switches.h"
37 43
38 namespace { 44 namespace {
39 45
40 const std::string kInstallAndWaitForActivatedPage = 46 const std::string kInstallAndWaitForActivatedPage =
41 "<script>" 47 "<script>"
42 "navigator.serviceWorker.register('./sw.js', {scope: './scope/'})" 48 "navigator.serviceWorker.register('./sw.js', {scope: './scope/'})"
43 " .then(function(reg) {" 49 " .then(function(reg) {"
44 " reg.addEventListener('updatefound', function() {" 50 " reg.addEventListener('updatefound', function() {"
45 " var worker = reg.installing;" 51 " var worker = reg.installing;"
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 InitializeServer(); 699 InitializeServer();
694 NavigateToPageAndWaitForReadyTitle("/test.html"); 700 NavigateToPageAndWaitForReadyTitle("/test.html");
695 GetServiceWorkerContext()->StopAllServiceWorkersForOrigin( 701 GetServiceWorkerContext()->StopAllServiceWorkersForOrigin(
696 embedded_test_server()->base_url()); 702 embedded_test_server()->base_url());
697 RunNavigationHintTest( 703 RunNavigationHintTest(
698 "/scope/", 704 "/scope/",
699 content::StartServiceWorkerForNavigationHintResult::NO_FETCH_HANDLER, 705 content::StartServiceWorkerForNavigationHintResult::NO_FETCH_HANDLER,
700 false); 706 false);
701 } 707 }
702 708
709 class ConnectionListener
710 : public net::test_server::EmbeddedTestServerConnectionListener {
711 public:
712 ConnectionListener() : task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
713 ~ConnectionListener() override {}
714
715 void AcceptedSocket(const net::StreamSocket& connection) override {
716 base::AutoLock lock(lock_);
717 socket_accepted_ = true;
718 if (wait_accept_loop_)
719 task_runner_->PostTask(FROM_HERE, wait_accept_loop_->QuitClosure());
720 }
721 void ReadFromSocket(const net::StreamSocket& socket, int rv) override {}
722
723 void ResetSocketAcceptedFlag() {
724 base::AutoLock lock(lock_);
725 socket_accepted_ = false;
726 }
727
728 bool GetSocketAcceptedFlag() const {
729 base::AutoLock lock(lock_);
730 return socket_accepted_;
731 }
732
733 void WaitForSocketAcceptedOnUI() {
734 {
735 base::AutoLock lock(lock_);
736 if (socket_accepted_)
737 return;
738 wait_accept_loop_.reset(new base::RunLoop());
739 }
740 wait_accept_loop_->Run();
741 }
742
743 private:
744 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
745
746 // This lock protects the members below, which each are used on both the
747 // IO and UI thread. Members declared after the lock are protected by it.
748 mutable base::Lock lock_;
749 bool socket_accepted_ = false;
750 std::unique_ptr<base::RunLoop> wait_accept_loop_;
751
752 DISALLOW_COPY_AND_ASSIGN(ConnectionListener);
753 };
754
755 class ChromeServiceWorkerPredictionOptionsTest
756 : public ChromeServiceWorkerTest,
757 public ::testing::WithParamInterface<std::tuple<
758 bool,
759 chrome_browser_net::NetworkPredictionOptionsForServiceWorker>> {
760 protected:
761 ChromeServiceWorkerPredictionOptionsTest()
762 : cross_site_test_server_(new net::EmbeddedTestServer()) {}
763 ~ChromeServiceWorkerPredictionOptionsTest() override {}
764
765 void SetUpCommandLine(base::CommandLine* command_line) override {
766 ChromeServiceWorkerTest::SetUpCommandLine(command_line);
767 if (std::get<0>(GetParam()))
768 command_line->AppendSwitch(switches::kEnableBrowserSideNavigation);
769 switch (Options()) {
770 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
771 PRECONNECT_ONLY:
772 command_line->AppendSwitchASCII(
773 switches::kNetworkPredictionOptionsForServiceWorker,
774 chrome_browser_net::kPreconnectOnly);
775 break;
776 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
777 START_SERVICE_WORKER_AND_PRECONNECT:
778 command_line->AppendSwitchASCII(
779 switches::kNetworkPredictionOptionsForServiceWorker,
780 chrome_browser_net::kStartServiceWorkerAndPreconnect);
781 break;
782 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
783 START_SERVICE_WORKER_AND_DEFER_PRECONNECT:
784 command_line->AppendSwitchASCII(
785 switches::kNetworkPredictionOptionsForServiceWorker,
786 chrome_browser_net::kStartServiceWorkerAndDeferPreconnect);
787 break;
788 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
789 START_SERVICE_WORKER_ONLY:
790 command_line->AppendSwitchASCII(
791 switches::kNetworkPredictionOptionsForServiceWorker,
792 chrome_browser_net::kStartServiceWorkerOnly);
793 break;
794 }
795 }
796
797 void SetUpOnMainThread() override {
798 WriteServiceWorkerPredictionOptionsTestFiles();
799
800 embedded_test_server()->ServeFilesFromDirectory(
801 service_worker_dir_.GetPath());
802 ASSERT_TRUE(embedded_test_server()->Start());
803
804 cross_site_test_server()->ServeFilesFromDirectory(
805 service_worker_dir_.GetPath());
806 cross_site_connection_listener_.reset(new ConnectionListener());
807 cross_site_test_server()->SetConnectionListener(
808 cross_site_connection_listener_.get());
809 ASSERT_TRUE(cross_site_test_server()->Start());
810
811 browser()->profile()->GetNetworkPredictor()->SetPredictorEnabledForTest(
812 true);
813 }
814
815 void InitializeServiceWorkerTest() {
816 base::HistogramTester histogram_tester;
817 const base::string16 expected_title = base::ASCIIToUTF16("READY");
818 content::TitleWatcher title_watcher(
819 browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
820 ui_test_utils::NavigateToURL(
821 browser(), embedded_test_server()->GetURL(
822 "/sw_test_page.html?" +
823 cross_site_test_server()->GetURL("/test.js").spec()));
824 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
825 histogram_tester.ExpectTotalCount("ServiceWorker.StartNewWorker.Status", 1);
826 histogram_tester.ExpectBucketCount("ServiceWorker.StartNewWorker.Status",
827 0 /* SERVICE_WORKER_OK */, 1);
828
829 // Stop the service worker.
830 content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
831 ->GetServiceWorkerContext()
832 ->StopAllServiceWorkersForOrigin(embedded_test_server()->base_url());
833
834 // Disconnect the connection.
835 cross_site_test_server()->FlushAllSocketsAndConnectionsOnUIThread();
836 EXPECT_TRUE(cross_site_connection_listener()->GetSocketAcceptedFlag());
837 cross_site_connection_listener()->ResetSocketAcceptedFlag();
838 }
839
840 void NavigateToServiceWorkerTestPage() {
841 const base::string16 expected_title = base::ASCIIToUTF16("SW");
842 content::TitleWatcher title_watcher(
843 browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
844 ui_test_utils::NavigateToURL(browser(),
845 embedded_test_server()->GetURL("/dummy.html"));
846 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
847 }
848
849 void InitializeNoServiceWorkerTest() {
850 const base::string16 expected_title = base::ASCIIToUTF16("READY");
851 content::TitleWatcher title_watcher(
852 browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
853 ui_test_utils::NavigateToURL(
854 browser(), embedded_test_server()->GetURL(
855 "/no_sw_test_page.html?" +
856 cross_site_test_server()->GetURL("/test.js").spec()));
857
858 // Disconnect the connection.
859 cross_site_test_server()->FlushAllSocketsAndConnectionsOnUIThread();
860 EXPECT_TRUE(cross_site_connection_listener()->GetSocketAcceptedFlag());
861 cross_site_connection_listener()->ResetSocketAcceptedFlag();
862 }
863
864 void NavigateToNoServiceWorkerTestPage() {
865 const base::string16 expected_title = base::ASCIIToUTF16("READY");
866 content::TitleWatcher title_watcher(
867 browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
868 ui_test_utils::NavigateToURL(
869 browser(), embedded_test_server()->GetURL("/no_sw_test_page.html"));
870 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
871 }
872
873 chrome_browser_net::NetworkPredictionOptionsForServiceWorker Options() const {
874 return std::get<1>(GetParam());
875 }
876
877 net::EmbeddedTestServer* cross_site_test_server() {
878 return cross_site_test_server_.get();
879 }
880
881 ConnectionListener* cross_site_connection_listener() {
882 return cross_site_connection_listener_.get();
883 }
884
885 private:
886 void WriteServiceWorkerPredictionOptionsTestFiles() {
887 WriteFile(FILE_PATH_LITERAL("test.js"), "document.title = 'READY';");
888 WriteFile(FILE_PATH_LITERAL("sw.js"),
889 "this.onfetch = function(event) {"
890 " event.respondWith(new Response("
891 " '<title>SW</title>', "
892 " {headers: {'Content-Type': 'text/html'}}));"
893 "};");
894 WriteFile(FILE_PATH_LITERAL("sw_test_page.html"),
895 "<body><script>"
896 "navigator.serviceWorker.register('./sw.js', {scope: './'})"
897 " .then(reg => {"
898 " reg.addEventListener('updatefound', _ => {"
899 " var worker = reg.installing;"
900 " worker.addEventListener('statechange', _ => {"
901 " if (worker.state != 'activated')"
902 " return;"
903 " var script = document.createElement('script');"
904 " script.src = window.location.search.substring(1);"
905 " document.body.appendChild(script);"
906 " });"
907 " });"
908 " });"
909 "</script></body>");
910 WriteFile(FILE_PATH_LITERAL("no_sw_test_page.html"),
911 "<body><script>"
912 "if (window.location.search != '') {"
913 " var script = document.createElement('script');"
914 " script.src = window.location.search.substring(1);"
915 " document.body.appendChild(script);"
916 "} else {"
917 " document.title = 'READY';"
918 "}"
919 "</script></body>");
920 }
921
922 std::unique_ptr<net::EmbeddedTestServer> cross_site_test_server_;
923 std::unique_ptr<ConnectionListener> cross_site_connection_listener_;
924
925 DISALLOW_COPY_AND_ASSIGN(ChromeServiceWorkerPredictionOptionsTest);
926 };
927
928 IN_PROC_BROWSER_TEST_P(ChromeServiceWorkerPredictionOptionsTest,
929 ServiceWorkerTest) {
930 InitializeServiceWorkerTest();
931 base::HistogramTester histogram_tester;
932 NavigateToServiceWorkerTestPage();
933 histogram_tester.ExpectTotalCount("ServiceWorker.StartWorker.Purpose", 1);
934
935 switch (Options()) {
936 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
937 PRECONNECT_ONLY:
938 histogram_tester.ExpectBucketCount(
939 "ServiceWorker.StartWorker.Purpose",
940 10 /* ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME */, 1);
941 break;
942 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
943 START_SERVICE_WORKER_AND_PRECONNECT:
944 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
945 START_SERVICE_WORKER_AND_DEFER_PRECONNECT:
946 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
947 START_SERVICE_WORKER_ONLY:
948 histogram_tester.ExpectBucketCount(
949 "ServiceWorker.StartWorker.Purpose",
950 27 /* ServiceWorkerMetrics::EventType::NAVIGATION_HINT */, 1);
951 break;
952 }
953
954 // Note: Wrting a chrome browset test which checks that the preconnection is
955 // defered until the service worker startup is too complex. So we only check
956 // that the preconnection is accutualy executed.
957 switch (Options()) {
958 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
959 PRECONNECT_ONLY:
960 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
961 START_SERVICE_WORKER_AND_PRECONNECT:
962 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
963 START_SERVICE_WORKER_AND_DEFER_PRECONNECT:
964 cross_site_connection_listener()->WaitForSocketAcceptedOnUI();
965 break;
966 case chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
967 START_SERVICE_WORKER_ONLY:
968 EXPECT_FALSE(cross_site_connection_listener()->GetSocketAcceptedFlag());
969 break;
970 }
971 }
972
973 IN_PROC_BROWSER_TEST_P(ChromeServiceWorkerPredictionOptionsTest,
974 NoServiceWorkerTest) {
975 InitializeNoServiceWorkerTest();
976 base::HistogramTester histogram_tester;
977 NavigateToNoServiceWorkerTestPage();
978 // If there is no service workers, the preconnection must be executed
979 // regardless of the options.
980 cross_site_connection_listener()->WaitForSocketAcceptedOnUI();
981 }
982
983 INSTANTIATE_TEST_CASE_P(
984 /* no prefix */,
985 ChromeServiceWorkerPredictionOptionsTest,
986 ::testing::Combine(
987 ::testing::Values(false, true),
988
989 ::testing::Values(
990 chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
991 PRECONNECT_ONLY,
992 chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
993 START_SERVICE_WORKER_AND_PRECONNECT,
994 chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
995 START_SERVICE_WORKER_AND_DEFER_PRECONNECT,
996 chrome_browser_net::NetworkPredictionOptionsForServiceWorker::
997 START_SERVICE_WORKER_ONLY)));
998
703 } // namespace 999 } // namespace
OLDNEW
« no previous file with comments | « chrome/browser/about_flags.cc ('k') | chrome/browser/flag_descriptions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698