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

Side by Side Diff: content/browser/service_worker/service_worker_job_unittest.cc

Issue 380093002: Update installed ServiceWorkers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 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 | Annotate | Revision Log
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 #include "base/files/scoped_temp_dir.h" 5 #include "base/files/scoped_temp_dir.h"
6 #include "base/logging.h" 6 #include "base/logging.h"
7 #include "base/run_loop.h" 7 #include "base/run_loop.h"
8 #include "content/browser/browser_thread_impl.h" 8 #include "content/browser/browser_thread_impl.h"
9 #include "content/browser/service_worker/embedded_worker_registry.h" 9 #include "content/browser/service_worker/embedded_worker_registry.h"
10 #include "content/browser/service_worker/embedded_worker_test_helper.h" 10 #include "content/browser/service_worker/embedded_worker_test_helper.h"
11 #include "content/browser/service_worker/service_worker_context_core.h" 11 #include "content/browser/service_worker/service_worker_context_core.h"
12 #include "content/browser/service_worker/service_worker_disk_cache.h"
12 #include "content/browser/service_worker/service_worker_job_coordinator.h" 13 #include "content/browser/service_worker/service_worker_job_coordinator.h"
13 #include "content/browser/service_worker/service_worker_registration.h" 14 #include "content/browser/service_worker/service_worker_registration.h"
14 #include "content/browser/service_worker/service_worker_registration_status.h" 15 #include "content/browser/service_worker/service_worker_registration_status.h"
15 #include "content/browser/service_worker/service_worker_test_utils.h" 16 #include "content/browser/service_worker/service_worker_test_utils.h"
16 #include "content/public/test/test_browser_thread_bundle.h" 17 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "ipc/ipc_test_sink.h" 18 #include "ipc/ipc_test_sink.h"
19 #include "net/base/io_buffer.h"
20 #include "net/base/net_errors.h"
21 #include "net/base/test_completion_callback.h"
22 #include "net/http/http_response_headers.h"
18 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/gtest/include/gtest/gtest.h"
19 24
25 using net::IOBuffer;
26 using net::TestCompletionCallback;
27 using net::WrappedIOBuffer;
28
20 // Unit tests for testing all job registration tasks. 29 // Unit tests for testing all job registration tasks.
21 namespace content { 30 namespace content {
22 31
23 namespace { 32 namespace {
24 33
34 int kMockRenderProcessId = 88;
35
25 void SaveRegistrationCallback( 36 void SaveRegistrationCallback(
26 ServiceWorkerStatusCode expected_status, 37 ServiceWorkerStatusCode expected_status,
27 bool* called, 38 bool* called,
28 scoped_refptr<ServiceWorkerRegistration>* registration_out, 39 scoped_refptr<ServiceWorkerRegistration>* registration_out,
29 ServiceWorkerStatusCode status, 40 ServiceWorkerStatusCode status,
30 ServiceWorkerRegistration* registration, 41 ServiceWorkerRegistration* registration,
31 ServiceWorkerVersion* version) { 42 ServiceWorkerVersion* version) {
32 ASSERT_TRUE(!version || version->registration_id() == registration->id()) 43 ASSERT_TRUE(!version || version->registration_id() == registration->id())
33 << version << " " << registration; 44 << version << " " << registration;
34 EXPECT_EQ(expected_status, status); 45 EXPECT_EQ(expected_status, status);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 *called = false; 96 *called = false;
86 return base::Bind(&SaveUnregistrationCallback, expected_status, called); 97 return base::Bind(&SaveUnregistrationCallback, expected_status, called);
87 } 98 }
88 99
89 } // namespace 100 } // namespace
90 101
91 class ServiceWorkerJobTest : public testing::Test { 102 class ServiceWorkerJobTest : public testing::Test {
92 public: 103 public:
93 ServiceWorkerJobTest() 104 ServiceWorkerJobTest()
94 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), 105 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
95 render_process_id_(88) {} 106 render_process_id_(kMockRenderProcessId) {}
96 107
97 virtual void SetUp() OVERRIDE { 108 virtual void SetUp() OVERRIDE {
98 helper_.reset(new EmbeddedWorkerTestHelper(render_process_id_)); 109 helper_.reset(new EmbeddedWorkerTestHelper(render_process_id_));
99 } 110 }
100 111
101 virtual void TearDown() OVERRIDE { 112 virtual void TearDown() OVERRIDE {
102 helper_.reset(); 113 helper_.reset();
103 } 114 }
104 115
105 ServiceWorkerContextCore* context() const { return helper_->context(); } 116 ServiceWorkerContextCore* context() const { return helper_->context(); }
106 117
107 ServiceWorkerJobCoordinator* job_coordinator() const { 118 ServiceWorkerJobCoordinator* job_coordinator() const {
108 return context()->job_coordinator(); 119 return context()->job_coordinator();
109 } 120 }
110 ServiceWorkerStorage* storage() const { return context()->storage(); } 121 ServiceWorkerStorage* storage() const { return context()->storage(); }
111 122
112 protected: 123 protected:
113 TestBrowserThreadBundle browser_thread_bundle_; 124 TestBrowserThreadBundle browser_thread_bundle_;
114 scoped_ptr<EmbeddedWorkerTestHelper> helper_; 125 scoped_ptr<EmbeddedWorkerTestHelper> helper_;
115
116 int render_process_id_; 126 int render_process_id_;
117 }; 127 };
118 128
119 TEST_F(ServiceWorkerJobTest, SameDocumentSameRegistration) { 129 TEST_F(ServiceWorkerJobTest, SameDocumentSameRegistration) {
120 scoped_refptr<ServiceWorkerRegistration> original_registration; 130 scoped_refptr<ServiceWorkerRegistration> original_registration;
121 bool called; 131 bool called;
122 job_coordinator()->Register( 132 job_coordinator()->Register(
123 GURL("http://www.example.com/*"), 133 GURL("http://www.example.com/*"),
124 GURL("http://www.example.com/service_worker.js"), 134 GURL("http://www.example.com/service_worker.js"),
125 render_process_id_, 135 render_process_id_,
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 } 404 }
395 405
396 class FailToStartWorkerTestHelper : public EmbeddedWorkerTestHelper { 406 class FailToStartWorkerTestHelper : public EmbeddedWorkerTestHelper {
397 public: 407 public:
398 explicit FailToStartWorkerTestHelper(int mock_render_process_id) 408 explicit FailToStartWorkerTestHelper(int mock_render_process_id)
399 : EmbeddedWorkerTestHelper(mock_render_process_id) {} 409 : EmbeddedWorkerTestHelper(mock_render_process_id) {}
400 410
401 virtual void OnStartWorker(int embedded_worker_id, 411 virtual void OnStartWorker(int embedded_worker_id,
402 int64 service_worker_version_id, 412 int64 service_worker_version_id,
403 const GURL& scope, 413 const GURL& scope,
404 const GURL& script_url) OVERRIDE { 414 const GURL& script_url,
405 // Simulate failure by sending worker stopped instead of started. 415 bool pause_after_download) OVERRIDE {
406 EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id); 416 EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
407 registry()->OnWorkerStopped(worker->process_id(), embedded_worker_id); 417 registry()->OnWorkerStopped(worker->process_id(), embedded_worker_id);
408 } 418 }
409 }; 419 };
410 420
411 TEST_F(ServiceWorkerJobTest, Register_FailToStartWorker) { 421 TEST_F(ServiceWorkerJobTest, Register_FailToStartWorker) {
412 helper_.reset(new FailToStartWorkerTestHelper(render_process_id_)); 422 helper_.reset(new FailToStartWorkerTestHelper(render_process_id_));
413 423
414 bool called = false; 424 bool called = false;
415 scoped_refptr<ServiceWorkerRegistration> registration; 425 scoped_refptr<ServiceWorkerRegistration> registration;
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 EXPECT_EQ(ServiceWorkerVersion::ACTIVATED, version->status()); 818 EXPECT_EQ(ServiceWorkerVersion::ACTIVATED, version->status());
809 819
810 registration->active_version()->RemoveControllee(host.get()); 820 registration->active_version()->RemoveControllee(host.get());
811 base::RunLoop().RunUntilIdle(); 821 base::RunLoop().RunUntilIdle();
812 822
813 // The version should be stopped since there is no controllee. 823 // The version should be stopped since there is no controllee.
814 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version->running_status()); 824 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version->running_status());
815 EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, version->status()); 825 EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, version->status());
816 } 826 }
817 827
828 namespace { // Helpers for the update job tests.
829
830 const GURL kNoChangeOrigin("http://nochange/");
831 const GURL kNewVersionOrigin("http://newversion/");
832 const std::string kScope("scope/*");
833 const std::string kScript("script.js");
834
835 void RunNestedUntilIdle() {
836 base::MessageLoop::ScopedNestableTaskAllower allow(
837 base::MessageLoop::current());
838 base::MessageLoop::current()->RunUntilIdle();
839 }
840
841 void OnIOComplete(int* rv_out, int rv) {
842 *rv_out = rv;
843 }
844
845 void WriteResponse(
846 ServiceWorkerStorage* storage, int64 id,
847 const std::string& headers,
848 IOBuffer* body, int length) {
849 scoped_ptr<ServiceWorkerResponseWriter> writer =
850 storage->CreateResponseWriter(id);
851
852 scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo);
853 info->request_time = base::Time::Now();
854 info->response_time = base::Time::Now();
855 info->was_cached = false;
856 info->headers = new net::HttpResponseHeaders(headers);
857 scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
858 new HttpResponseInfoIOBuffer(info.release());
859
860 int rv = -1234;
861 writer->WriteInfo(info_buffer, base::Bind(&OnIOComplete, &rv));
862 RunNestedUntilIdle();
863 EXPECT_LT(0, rv);
864
865 rv = -1234;
866 writer->WriteData(body, length,
867 base::Bind(&OnIOComplete, &rv));
868 RunNestedUntilIdle();
869 EXPECT_EQ(length, rv);
870 }
871
872 void WriteStringResponse(
873 ServiceWorkerStorage* storage, int64 id,
874 const std::string& body) {
875 scoped_refptr<IOBuffer> body_buffer(new WrappedIOBuffer(body.data()));
876 const char kHttpHeaders[] = "HTTP/1.0 200 HONKYDORY\0\0";
877 std::string headers(kHttpHeaders, arraysize(kHttpHeaders));
878 WriteResponse(storage, id, headers, body_buffer, body.length());
879 }
880
881 class UpdateJobTestHelper
882 : public EmbeddedWorkerTestHelper,
883 public ServiceWorkerRegistration::Listener,
884 public ServiceWorkerVersion::Listener {
885 public:
886 struct AttributeChangeLogEntry {
887 int64 registration_id;
888 ChangedVersionAttributesMask mask;
889 ServiceWorkerRegistrationInfo info;
890 };
891
892 struct StateChangeLogEntry {
893 int64 version_id;
894 ServiceWorkerVersion::Status status;
895 };
896
897 UpdateJobTestHelper(int mock_render_process_id)
898 : EmbeddedWorkerTestHelper(mock_render_process_id) {}
899
900 ServiceWorkerStorage* storage() { return context()->storage(); }
901 ServiceWorkerJobCoordinator* job_coordinator() {
902 return context()->job_coordinator();
903 }
904
905 scoped_refptr<ServiceWorkerRegistration> SetupInitialRegistration(
906 const GURL& test_origin) {
907 scoped_refptr<ServiceWorkerRegistration> registration;
908 bool called = false;
909 job_coordinator()->Register(
910 test_origin.Resolve(kScope),
911 test_origin.Resolve(kScript),
912 mock_render_process_id(),
913 SaveRegistration(SERVICE_WORKER_OK, &called, &registration));
914 base::RunLoop().RunUntilIdle();
915 EXPECT_TRUE(called);
916 EXPECT_TRUE(registration);
917 EXPECT_TRUE(registration->active_version());
918 EXPECT_FALSE(registration->installing_version());
919 EXPECT_FALSE(registration->waiting_version());
920 return registration;
921 }
922
923 // EmbeddedWorkerTestHelper overrides
924 virtual void OnStartWorker(int embedded_worker_id,
925 int64 version_id,
926 const GURL& scope,
927 const GURL& script,
928 bool pause_after_download) OVERRIDE {
929 const std::string kMockScriptBody = "mock_script";
930 ServiceWorkerVersion* version = context()->GetLiveVersion(version_id);
931 ASSERT_TRUE(version);
932 version->AddListener(this);
933
934 if (!pause_after_download) {
935 // Spoof caching the script for the initial version.
936 int64 resource_id = storage()->NewResourceId();
937 version->script_cache_map()->NotifyStartedCaching(script, resource_id);
938 WriteStringResponse(storage(), resource_id, kMockScriptBody);
939 version->script_cache_map()->NotifyFinishedCaching(script, true);
940 } else {
941 // Spoof caching the script for the new version.
942 int64 resource_id = storage()->NewResourceId();
943 version->script_cache_map()->NotifyStartedCaching(script, resource_id);
944 if (script.GetOrigin() == kNoChangeOrigin)
945 WriteStringResponse(storage(), resource_id, kMockScriptBody);
946 else
947 WriteStringResponse(storage(), resource_id, "mock_different_script");
948 version->script_cache_map()->NotifyFinishedCaching(script, true);
949 }
950 EmbeddedWorkerTestHelper::OnStartWorker(
951 embedded_worker_id, version_id, scope, script, pause_after_download);
952 }
953
954 // ServiceWorkerRegistration::Listener overrides
955 virtual void OnVersionAttributesChanged(
956 ServiceWorkerRegistration* registration,
957 ChangedVersionAttributesMask changed_mask,
958 const ServiceWorkerRegistrationInfo& info) OVERRIDE {
959 AttributeChangeLogEntry entry;
960 entry.registration_id = registration->id();
961 entry.mask = changed_mask;
962 entry.info = info;
963 attribute_change_log_.push_back(entry);
964 }
965
966 // ServiceWorkerVersion::Listener overrides
967 virtual void OnVersionStateChanged(ServiceWorkerVersion* version) OVERRIDE {
968 StateChangeLogEntry entry;
969 entry.version_id = version->version_id();
970 entry.status = version->status();
971 state_change_log_.push_back(entry);
972 }
973
974 std::vector<AttributeChangeLogEntry> attribute_change_log_;
975 std::vector<StateChangeLogEntry> state_change_log_;
976 };
977
978 } // namespace
979
980 TEST_F(ServiceWorkerJobTest, Update_NoChange) {
981 UpdateJobTestHelper* update_helper =
982 new UpdateJobTestHelper(render_process_id_);
983 helper_.reset(update_helper);
984 scoped_refptr<ServiceWorkerRegistration> registration =
985 update_helper->SetupInitialRegistration(kNoChangeOrigin);
986 ASSERT_TRUE(registration);
987 ASSERT_EQ(4u, update_helper->state_change_log_.size());
988 EXPECT_EQ(ServiceWorkerVersion::INSTALLING,
989 update_helper->state_change_log_[0].status);
990 EXPECT_EQ(ServiceWorkerVersion::INSTALLED,
991 update_helper->state_change_log_[1].status);
992 EXPECT_EQ(ServiceWorkerVersion::ACTIVATING,
993 update_helper->state_change_log_[2].status);
994 EXPECT_EQ(ServiceWorkerVersion::ACTIVATED,
995 update_helper->state_change_log_[3].status);
996 update_helper->state_change_log_.clear();
997
998 // Run the update job.
999 registration->AddListener(update_helper);
1000 scoped_refptr<ServiceWorkerVersion> first_version =
1001 registration->active_version();
1002 first_version->StartUpdate();
1003 base::RunLoop().RunUntilIdle();
1004
1005 // Verify results.
1006 ASSERT_TRUE(registration->active_version());
1007 EXPECT_EQ(first_version.get(), registration->active_version());
1008 EXPECT_FALSE(registration->installing_version());
1009 EXPECT_FALSE(registration->waiting_version());
1010 EXPECT_TRUE(update_helper->attribute_change_log_.empty());
1011 ASSERT_EQ(1u, update_helper->state_change_log_.size());
1012 EXPECT_NE(registration->active_version()->version_id(),
1013 update_helper->state_change_log_[0].version_id);
1014 EXPECT_EQ(ServiceWorkerVersion::REDUNDANT,
1015 update_helper->state_change_log_[0].status);
1016 }
1017
1018 TEST_F(ServiceWorkerJobTest, Update_NewVersion) {
1019 UpdateJobTestHelper* update_helper =
1020 new UpdateJobTestHelper(render_process_id_);
1021 helper_.reset(update_helper);
1022 scoped_refptr<ServiceWorkerRegistration> registration =
1023 update_helper->SetupInitialRegistration(kNewVersionOrigin);
1024 ASSERT_TRUE(registration);
1025 update_helper->state_change_log_.clear();
1026
1027 // Run the update job.
1028 registration->AddListener(update_helper);
1029 scoped_refptr<ServiceWorkerVersion> first_version =
1030 registration->active_version();
1031 first_version->StartUpdate();
1032 base::RunLoop().RunUntilIdle();
1033
1034 // Verify results.
1035 ASSERT_TRUE(registration->active_version());
1036 EXPECT_NE(first_version.get(), registration->active_version());
1037 EXPECT_FALSE(registration->installing_version());
1038 EXPECT_FALSE(registration->waiting_version());
1039 ASSERT_EQ(3u, update_helper->attribute_change_log_.size());
1040
1041 UpdateJobTestHelper::AttributeChangeLogEntry entry;
1042 entry = update_helper->attribute_change_log_[0];
1043 EXPECT_TRUE(entry.mask.installing_changed());
1044 EXPECT_FALSE(entry.mask.waiting_changed());
1045 EXPECT_FALSE(entry.mask.active_changed());
1046 EXPECT_FALSE(entry.info.installing_version.is_null);
1047 EXPECT_TRUE(entry.info.waiting_version.is_null);
1048 EXPECT_FALSE(entry.info.active_version.is_null);
1049
1050 entry = update_helper->attribute_change_log_[1];
1051 EXPECT_TRUE(entry.mask.installing_changed());
1052 EXPECT_TRUE(entry.mask.waiting_changed());
1053 EXPECT_FALSE(entry.mask.active_changed());
1054 EXPECT_TRUE(entry.info.installing_version.is_null);
1055 EXPECT_FALSE(entry.info.waiting_version.is_null);
1056 EXPECT_FALSE(entry.info.active_version.is_null);
1057
1058 entry = update_helper->attribute_change_log_[2];
1059 EXPECT_FALSE(entry.mask.installing_changed());
1060 EXPECT_TRUE(entry.mask.waiting_changed());
1061 EXPECT_TRUE(entry.mask.active_changed());
1062 EXPECT_TRUE(entry.info.installing_version.is_null);
1063 EXPECT_TRUE(entry.info.waiting_version.is_null);
1064 EXPECT_FALSE(entry.info.active_version.is_null);
1065
1066 // expected version state transitions:
1067 // new.installing, new.installed,
1068 // old.redundant,
1069 // new.activating, new.activated
1070 ASSERT_EQ(5u, update_helper->state_change_log_.size());
1071
1072 EXPECT_EQ(registration->active_version()->version_id(),
1073 update_helper->state_change_log_[0].version_id);
1074 EXPECT_EQ(ServiceWorkerVersion::INSTALLING,
1075 update_helper->state_change_log_[0].status);
1076
1077 EXPECT_EQ(registration->active_version()->version_id(),
1078 update_helper->state_change_log_[1].version_id);
1079 EXPECT_EQ(ServiceWorkerVersion::INSTALLED,
1080 update_helper->state_change_log_[1].status);
1081
1082 EXPECT_EQ(first_version->version_id(),
1083 update_helper->state_change_log_[2].version_id);
1084 EXPECT_EQ(ServiceWorkerVersion::REDUNDANT,
1085 update_helper->state_change_log_[2].status);
1086
1087 EXPECT_EQ(registration->active_version()->version_id(),
1088 update_helper->state_change_log_[3].version_id);
1089 EXPECT_EQ(ServiceWorkerVersion::ACTIVATING,
1090 update_helper->state_change_log_[3].status);
1091
1092 EXPECT_EQ(registration->active_version()->version_id(),
1093 update_helper->state_change_log_[4].version_id);
1094 EXPECT_EQ(ServiceWorkerVersion::ACTIVATED,
1095 update_helper->state_change_log_[4].status);
1096 }
1097
818 } // namespace content 1098 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698