OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/service_worker/service_worker_dispatcher_host.h" | 5 #include "content/browser/service_worker/service_worker_dispatcher_host.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 base::RunLoop().RunUntilIdle(); | 92 base::RunLoop().RunUntilIdle(); |
93 return navigation_handle_core; | 93 return navigation_handle_core; |
94 } | 94 } |
95 | 95 |
96 } // namespace | 96 } // namespace |
97 | 97 |
98 static const int kRenderFrameId = 1; | 98 static const int kRenderFrameId = 1; |
99 | 99 |
100 class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost { | 100 class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost { |
101 public: | 101 public: |
102 TestingServiceWorkerDispatcherHost( | 102 TestingServiceWorkerDispatcherHost(int process_id, |
103 int process_id, | 103 ResourceContext* resource_context, |
104 ServiceWorkerContextWrapper* context_wrapper, | 104 EmbeddedWorkerTestHelper* helper) |
105 ResourceContext* resource_context, | |
106 EmbeddedWorkerTestHelper* helper) | |
107 : ServiceWorkerDispatcherHost(process_id, resource_context), | 105 : ServiceWorkerDispatcherHost(process_id, resource_context), |
108 bad_messages_received_count_(0), | 106 bad_messages_received_count_(0), |
109 helper_(helper) { | 107 helper_(helper) {} |
110 Init(context_wrapper); | |
111 } | |
112 | 108 |
113 bool Send(IPC::Message* message) override { return helper_->Send(message); } | 109 bool Send(IPC::Message* message) override { return helper_->Send(message); } |
114 | 110 |
115 IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); } | 111 IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); } |
116 | 112 |
117 void ShutdownForBadMessage() override { ++bad_messages_received_count_; } | 113 void ShutdownForBadMessage() override { ++bad_messages_received_count_; } |
118 | 114 |
119 int bad_messages_received_count_; | 115 int bad_messages_received_count_; |
120 | 116 |
121 protected: | 117 protected: |
122 EmbeddedWorkerTestHelper* helper_; | 118 EmbeddedWorkerTestHelper* helper_; |
123 ~TestingServiceWorkerDispatcherHost() override {} | 119 ~TestingServiceWorkerDispatcherHost() override {} |
124 }; | 120 }; |
125 | 121 |
126 class FailToStartWorkerTestHelper : public EmbeddedWorkerTestHelper { | 122 class FailToStartWorkerTestHelper : public EmbeddedWorkerTestHelper { |
127 public: | 123 public: |
128 FailToStartWorkerTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {} | 124 FailToStartWorkerTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {} |
129 | 125 |
130 void OnStartWorker(int embedded_worker_id, | 126 void OnStartWorker( |
131 int64_t service_worker_version_id, | 127 int embedded_worker_id, |
132 const GURL& scope, | 128 int64_t service_worker_version_id, |
133 const GURL& script_url, | 129 const GURL& scope, |
134 bool pause_after_download, | 130 const GURL& script_url, |
135 mojom::ServiceWorkerEventDispatcherRequest request, | 131 bool pause_after_download, |
136 mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo | 132 mojom::ServiceWorkerEventDispatcherRequest request, |
137 instance_host) override { | 133 mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host, |
| 134 mojom::ServiceWorkerProviderClientInfoPtr provider_client_info) override { |
138 mojom::EmbeddedWorkerInstanceHostAssociatedPtr instance_host_ptr; | 135 mojom::EmbeddedWorkerInstanceHostAssociatedPtr instance_host_ptr; |
139 instance_host_ptr.Bind(std::move(instance_host)); | 136 instance_host_ptr.Bind(std::move(instance_host)); |
140 instance_host_ptr->OnStopped(); | 137 instance_host_ptr->OnStopped(); |
141 base::RunLoop().RunUntilIdle(); | 138 base::RunLoop().RunUntilIdle(); |
142 } | 139 } |
143 }; | 140 }; |
144 | 141 |
145 class ServiceWorkerDispatcherHostTest : public testing::Test { | 142 class ServiceWorkerDispatcherHostTest : public testing::Test { |
146 protected: | 143 protected: |
147 ServiceWorkerDispatcherHostTest() | 144 ServiceWorkerDispatcherHostTest() |
(...skipping 11 matching lines...) Expand all Loading... |
159 | 156 |
160 ServiceWorkerContextCore* context() { return helper_->context(); } | 157 ServiceWorkerContextCore* context() { return helper_->context(); } |
161 ServiceWorkerContextWrapper* context_wrapper() { | 158 ServiceWorkerContextWrapper* context_wrapper() { |
162 return helper_->context_wrapper(); | 159 return helper_->context_wrapper(); |
163 } | 160 } |
164 | 161 |
165 void Initialize(std::unique_ptr<EmbeddedWorkerTestHelper> helper) { | 162 void Initialize(std::unique_ptr<EmbeddedWorkerTestHelper> helper) { |
166 helper_.reset(helper.release()); | 163 helper_.reset(helper.release()); |
167 // Replace the default dispatcher host. | 164 // Replace the default dispatcher host. |
168 int process_id = helper_->mock_render_process_id(); | 165 int process_id = helper_->mock_render_process_id(); |
169 context()->RemoveDispatcherHost(process_id); | |
170 dispatcher_host_ = new TestingServiceWorkerDispatcherHost( | 166 dispatcher_host_ = new TestingServiceWorkerDispatcherHost( |
171 process_id, context_wrapper(), &resource_context_, helper_.get()); | 167 process_id, &resource_context_, helper_.get()); |
| 168 helper_->RegisterMockDispatcherHost(process_id, nullptr); |
| 169 dispatcher_host_->Init(context_wrapper()); |
172 } | 170 } |
173 | 171 |
174 void SetUpRegistration(const GURL& scope, const GURL& script_url) { | 172 void SetUpRegistration(const GURL& scope, const GURL& script_url) { |
175 registration_ = new ServiceWorkerRegistration( | 173 registration_ = new ServiceWorkerRegistration( |
176 scope, 1L, helper_->context()->AsWeakPtr()); | 174 scope, 1L, helper_->context()->AsWeakPtr()); |
177 version_ = new ServiceWorkerVersion(registration_.get(), script_url, 1L, | 175 version_ = new ServiceWorkerVersion(registration_.get(), script_url, 1L, |
178 helper_->context()->AsWeakPtr()); | 176 helper_->context()->AsWeakPtr()); |
179 std::vector<ServiceWorkerDatabase::ResourceRecord> records; | 177 std::vector<ServiceWorkerDatabase::ResourceRecord> records; |
180 records.push_back( | 178 records.push_back( |
181 ServiceWorkerDatabase::ResourceRecord(10, version_->script_url(), 100)); | 179 ServiceWorkerDatabase::ResourceRecord(10, version_->script_url(), 100)); |
(...skipping 10 matching lines...) Expand all Loading... |
192 bool called = false; | 190 bool called = false; |
193 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; | 191 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; |
194 helper_->context()->storage()->StoreRegistration( | 192 helper_->context()->storage()->StoreRegistration( |
195 registration_.get(), version_.get(), | 193 registration_.get(), version_.get(), |
196 base::Bind(&SaveStatusCallback, &called, &status)); | 194 base::Bind(&SaveStatusCallback, &called, &status)); |
197 base::RunLoop().RunUntilIdle(); | 195 base::RunLoop().RunUntilIdle(); |
198 EXPECT_TRUE(called); | 196 EXPECT_TRUE(called); |
199 EXPECT_EQ(SERVICE_WORKER_OK, status); | 197 EXPECT_EQ(SERVICE_WORKER_OK, status); |
200 } | 198 } |
201 | 199 |
202 void SendSetHostedVersionId(int provider_id, | |
203 int64_t version_id, | |
204 int embedded_worker_id) { | |
205 dispatcher_host_->OnSetHostedVersionId(provider_id, version_id, | |
206 embedded_worker_id); | |
207 } | |
208 | |
209 void SendProviderCreated(ServiceWorkerProviderType type, | 200 void SendProviderCreated(ServiceWorkerProviderType type, |
210 const GURL& pattern) { | 201 const GURL& pattern) { |
211 const int64_t kProviderId = 99; | 202 const int64_t kProviderId = 99; |
212 ServiceWorkerProviderHostInfo info(kProviderId, MSG_ROUTING_NONE, type, | 203 ServiceWorkerProviderHostInfo info(kProviderId, MSG_ROUTING_NONE, type, |
213 true /* is_parent_frame_secure */); | 204 true /* is_parent_frame_secure */); |
214 remote_endpoint_.BindWithProviderHostInfo(&info); | 205 remote_endpoint_.BindWithProviderHostInfo(&info); |
215 | 206 |
216 dispatcher_host_->OnProviderCreated(std::move(info)); | 207 dispatcher_host_->OnProviderCreated(std::move(info)); |
217 helper_->SimulateAddProcessToPattern(pattern, | 208 helper_->SimulateAddProcessToPattern(pattern, |
218 helper_->mock_render_process_id()); | 209 helper_->mock_render_process_id()); |
219 provider_host_ = context()->GetProviderHost( | 210 provider_host_ = context()->GetProviderHost( |
220 helper_->mock_render_process_id(), kProviderId); | 211 helper_->mock_render_process_id(), kProviderId); |
221 } | 212 } |
222 | 213 |
| 214 void PrepareProviderForServiceWorkerContext(ServiceWorkerVersion* version, |
| 215 const GURL& pattern) { |
| 216 std::unique_ptr<ServiceWorkerProviderHost> host = |
| 217 CreateProviderHostForServiceWorkerContext( |
| 218 dispatcher_host_->render_process_id_, |
| 219 true /* is_parent_frame_secure */, version, |
| 220 helper_->context()->AsWeakPtr(), &remote_endpoint_); |
| 221 provider_host_ = host.get(); |
| 222 helper_->SimulateAddProcessToPattern(pattern, |
| 223 helper_->mock_render_process_id()); |
| 224 context()->AddProviderHost(std::move(host)); |
| 225 } |
| 226 |
223 void SendRegister(int64_t provider_id, GURL pattern, GURL worker_url) { | 227 void SendRegister(int64_t provider_id, GURL pattern, GURL worker_url) { |
224 dispatcher_host_->OnMessageReceived( | 228 dispatcher_host_->OnMessageReceived( |
225 ServiceWorkerHostMsg_RegisterServiceWorker( | 229 ServiceWorkerHostMsg_RegisterServiceWorker( |
226 -1, -1, provider_id, pattern, worker_url)); | 230 -1, -1, provider_id, pattern, worker_url)); |
227 base::RunLoop().RunUntilIdle(); | 231 base::RunLoop().RunUntilIdle(); |
228 } | 232 } |
229 | 233 |
230 void Register(int64_t provider_id, | 234 void Register(int64_t provider_id, |
231 GURL pattern, | 235 GURL pattern, |
232 GURL worker_url, | 236 GURL worker_url, |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 dispatcher_host_->OnFilterRemoved(); | 740 dispatcher_host_->OnFilterRemoved(); |
737 | 741 |
738 // The dispatcher host should clean up the state from the process. | 742 // The dispatcher host should clean up the state from the process. |
739 EXPECT_FALSE(context()->GetProviderHost(process_id, provider_id)); | 743 EXPECT_FALSE(context()->GetProviderHost(process_id, provider_id)); |
740 EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status()); | 744 EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status()); |
741 | 745 |
742 // We should be able to hook up a new dispatcher host although the old object | 746 // We should be able to hook up a new dispatcher host although the old object |
743 // is not yet destroyed. This is what the browser does when reusing a crashed | 747 // is not yet destroyed. This is what the browser does when reusing a crashed |
744 // render process. | 748 // render process. |
745 scoped_refptr<TestingServiceWorkerDispatcherHost> new_dispatcher_host( | 749 scoped_refptr<TestingServiceWorkerDispatcherHost> new_dispatcher_host( |
746 new TestingServiceWorkerDispatcherHost( | 750 new TestingServiceWorkerDispatcherHost(process_id, &resource_context_, |
747 process_id, context_wrapper(), &resource_context_, helper_.get())); | 751 helper_.get())); |
| 752 new_dispatcher_host->Init(context_wrapper()); |
748 | 753 |
749 // To show the new dispatcher can operate, simulate provider creation. Since | 754 // To show the new dispatcher can operate, simulate provider creation. Since |
750 // the old dispatcher cleaned up the old provider host, the new one won't | 755 // the old dispatcher cleaned up the old provider host, the new one won't |
751 // complain. | 756 // complain. |
752 ServiceWorkerProviderHostInfo host_info(provider_id, MSG_ROUTING_NONE, | 757 ServiceWorkerProviderHostInfo host_info(provider_id, MSG_ROUTING_NONE, |
753 SERVICE_WORKER_PROVIDER_FOR_WINDOW, | 758 SERVICE_WORKER_PROVIDER_FOR_WINDOW, |
754 true /* is_parent_frame_secure */); | 759 true /* is_parent_frame_secure */); |
755 ServiceWorkerRemoteProviderEndpoint remote_endpoint; | 760 ServiceWorkerRemoteProviderEndpoint remote_endpoint; |
756 remote_endpoint.BindWithProviderHostInfo(&host_info); | 761 remote_endpoint.BindWithProviderHostInfo(&host_info); |
757 new_dispatcher_host->OnProviderCreated(std::move(host_info)); | 762 new_dispatcher_host->OnProviderCreated(std::move(host_info)); |
758 EXPECT_EQ(0, new_dispatcher_host->bad_messages_received_count_); | 763 EXPECT_EQ(0, new_dispatcher_host->bad_messages_received_count_); |
759 } | 764 } |
760 | 765 |
761 TEST_F(ServiceWorkerDispatcherHostTest, DispatchExtendableMessageEvent) { | 766 TEST_F(ServiceWorkerDispatcherHostTest, DispatchExtendableMessageEvent) { |
762 GURL pattern = GURL("http://www.example.com/"); | 767 GURL pattern = GURL("http://www.example.com/"); |
763 GURL script_url = GURL("http://www.example.com/service_worker.js"); | 768 GURL script_url = GURL("http://www.example.com/service_worker.js"); |
764 | 769 |
765 SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, pattern); | |
766 SetUpRegistration(pattern, script_url); | 770 SetUpRegistration(pattern, script_url); |
| 771 PrepareProviderForServiceWorkerContext(version_.get(), pattern); |
767 | 772 |
768 // Set the running hosted version so that we can retrieve a valid service | 773 // Set the running hosted version so that we can retrieve a valid service |
769 // worker object information for the source attribute of the message event. | 774 // worker object information for the source attribute of the message event. |
770 provider_host_->running_hosted_version_ = version_; | 775 provider_host_->running_hosted_version_ = version_; |
771 | 776 |
772 // Set aside the initial refcount of the worker handle. | 777 // Set aside the initial refcount of the worker handle. |
773 provider_host_->GetOrCreateServiceWorkerHandle(version_.get()); | 778 provider_host_->GetOrCreateServiceWorkerHandle(version_.get()); |
774 ServiceWorkerHandle* sender_worker_handle = | 779 ServiceWorkerHandle* sender_worker_handle = |
775 dispatcher_host_->FindServiceWorkerHandle(provider_host_->provider_id(), | 780 dispatcher_host_->FindServiceWorkerHandle(provider_host_->provider_id(), |
776 version_->version_id()); | 781 version_->version_id()); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 // worker and to dispatch the event. | 835 // worker and to dispatch the event. |
831 std::vector<MessagePort> ports; | 836 std::vector<MessagePort> ports; |
832 SetUpDummyMessagePort(&ports); | 837 SetUpDummyMessagePort(&ports); |
833 bool called = false; | 838 bool called = false; |
834 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; | 839 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; |
835 DispatchExtendableMessageEvent( | 840 DispatchExtendableMessageEvent( |
836 version_, base::string16(), url::Origin(version_->scope().GetOrigin()), | 841 version_, base::string16(), url::Origin(version_->scope().GetOrigin()), |
837 ports, provider_host_, base::Bind(&SaveStatusCallback, &called, &status)); | 842 ports, provider_host_, base::Bind(&SaveStatusCallback, &called, &status)); |
838 base::RunLoop().RunUntilIdle(); | 843 base::RunLoop().RunUntilIdle(); |
839 EXPECT_TRUE(called); | 844 EXPECT_TRUE(called); |
| 845 EXPECT_NE(SERVICE_WORKER_ERROR_TIMEOUT, status); |
840 EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status); | 846 EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status); |
841 } | 847 } |
842 | 848 |
843 TEST_F(ServiceWorkerDispatcherHostTest, OnSetHostedVersionId) { | |
844 GURL pattern = GURL("http://www.example.com/"); | |
845 GURL script_url = GURL("http://www.example.com/service_worker.js"); | |
846 | |
847 Initialize(base::WrapUnique(new FailToStartWorkerTestHelper)); | |
848 SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, pattern); | |
849 SetUpRegistration(pattern, script_url); | |
850 | |
851 const int64_t kProviderId = 99; // Dummy value | |
852 bool called; | |
853 ServiceWorkerStatusCode status; | |
854 // StartWorker puts the worker in STARTING state but it will have no | |
855 // process id yet. | |
856 version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN, | |
857 base::Bind(&SaveStatusCallback, &called, &status)); | |
858 EXPECT_NE(version_->embedded_worker()->process_id(), | |
859 provider_host_->process_id()); | |
860 // SendSetHostedVersionId should reject because the provider host process id | |
861 // is different. It should call BadMessageReceived because it's not an | |
862 // expected error state. | |
863 SendSetHostedVersionId(kProviderId, version_->version_id(), | |
864 version_->embedded_worker()->embedded_worker_id()); | |
865 base::RunLoop().RunUntilIdle(); | |
866 EXPECT_FALSE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( | |
867 ServiceWorkerMsg_AssociateRegistration::ID)); | |
868 EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); | |
869 } | |
870 | |
871 TEST_F(ServiceWorkerDispatcherHostTest, OnSetHostedVersionId_DetachedWorker) { | |
872 GURL pattern = GURL("http://www.example.com/"); | |
873 GURL script_url = GURL("http://www.example.com/service_worker.js"); | |
874 | |
875 Initialize(base::WrapUnique(new FailToStartWorkerTestHelper)); | |
876 SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, pattern); | |
877 SetUpRegistration(pattern, script_url); | |
878 | |
879 const int64_t kProviderId = 99; // Dummy value | |
880 bool called; | |
881 ServiceWorkerStatusCode status; | |
882 // StartWorker puts the worker in STARTING state. | |
883 version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN, | |
884 base::Bind(&SaveStatusCallback, &called, &status)); | |
885 | |
886 // SendSetHostedVersionId should bail because the embedded worker is | |
887 // different. It shouldn't call BadMessageReceived because receiving a message | |
888 // for a detached worker is a legitimite possibility. | |
889 int bad_embedded_worker_id = | |
890 version_->embedded_worker()->embedded_worker_id() + 1; | |
891 SendSetHostedVersionId(kProviderId, version_->version_id(), | |
892 bad_embedded_worker_id); | |
893 base::RunLoop().RunUntilIdle(); | |
894 EXPECT_FALSE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( | |
895 ServiceWorkerMsg_AssociateRegistration::ID)); | |
896 EXPECT_EQ(0, dispatcher_host_->bad_messages_received_count_); | |
897 } | |
898 | |
899 TEST_F(ServiceWorkerDispatcherHostTest, ReceivedTimedOutRequestResponse) { | 849 TEST_F(ServiceWorkerDispatcherHostTest, ReceivedTimedOutRequestResponse) { |
900 GURL pattern = GURL("https://www.example.com/"); | 850 GURL pattern = GURL("https://www.example.com/"); |
901 GURL script_url = GURL("https://www.example.com/service_worker.js"); | 851 GURL script_url = GURL("https://www.example.com/service_worker.js"); |
902 | 852 |
903 SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_WINDOW, pattern); | 853 SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_WINDOW, pattern); |
904 SetUpRegistration(pattern, script_url); | 854 SetUpRegistration(pattern, script_url); |
905 | 855 |
906 version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN, | 856 version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN, |
907 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 857 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
908 base::RunLoop().RunUntilIdle(); | 858 base::RunLoop().RunUntilIdle(); |
909 | 859 |
910 // Set the worker status to STOPPING. | 860 // Set the worker status to STOPPING. |
911 version_->embedded_worker()->Stop(); | 861 version_->embedded_worker()->Stop(); |
912 EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, version_->running_status()); | 862 EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, version_->running_status()); |
913 | 863 |
914 // Receive a response for a timed out request. The bad message count should | 864 // Receive a response for a timed out request. The bad message count should |
915 // not increase. | 865 // not increase. |
916 const int kFetchEventId = 91; // Dummy value | 866 const int kFetchEventId = 91; // Dummy value |
917 dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_FetchEventResponse( | 867 dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_FetchEventResponse( |
918 version_->embedded_worker()->embedded_worker_id(), kFetchEventId, | 868 version_->embedded_worker()->embedded_worker_id(), kFetchEventId, |
919 ServiceWorkerResponse(), base::Time::Now())); | 869 ServiceWorkerResponse(), base::Time::Now())); |
920 | 870 |
921 base::RunLoop().RunUntilIdle(); | 871 base::RunLoop().RunUntilIdle(); |
922 EXPECT_EQ(0, dispatcher_host_->bad_messages_received_count_); | 872 EXPECT_EQ(0, dispatcher_host_->bad_messages_received_count_); |
923 } | 873 } |
924 | 874 |
925 } // namespace content | 875 } // namespace content |
OLD | NEW |