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
3 // found in the LICENSE file.
5 #include "content/browser/service_worker/service_worker_dispatcher_host.h"
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/run_loop.h"
10 #include "content/browser/browser_thread_impl.h"
11 #include "content/browser/service_worker/embedded_worker_instance.h"
12 #include "content/browser/service_worker/embedded_worker_registry.h"
13 #include "content/browser/service_worker/embedded_worker_test_helper.h"
14 #include "content/browser/service_worker/service_worker_context_core.h"
15 #include "content/browser/service_worker/service_worker_context_wrapper.h"
16 #include "content/common/service_worker/embedded_worker_messages.h"
17 #include "content/common/service_worker/service_worker_messages.h"
18 #include "content/public/common/content_switches.h"
19 #include "content/public/test/mock_resource_context.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "content/test/test_content_browser_client.h"
22 #include "testing/gtest/include/gtest/gtest.h"
28 static void SaveStatusCallback(bool* called
,
29 ServiceWorkerStatusCode
* out
,
30 ServiceWorkerStatusCode status
) {
37 static const int kRenderProcessId
= 1;
38 static const int kRenderFrameId
= 1;
40 class TestingServiceWorkerDispatcherHost
: public ServiceWorkerDispatcherHost
{
42 TestingServiceWorkerDispatcherHost(
44 ServiceWorkerContextWrapper
* context_wrapper
,
45 ResourceContext
* resource_context
,
46 EmbeddedWorkerTestHelper
* helper
)
47 : ServiceWorkerDispatcherHost(process_id
, NULL
, resource_context
),
48 bad_messages_received_count_(0),
50 Init(context_wrapper
);
53 bool Send(IPC::Message
* message
) override
{ return helper_
->Send(message
); }
55 IPC::TestSink
* ipc_sink() { return helper_
->ipc_sink(); }
57 void ShutdownForBadMessage() override
{ ++bad_messages_received_count_
; }
59 int bad_messages_received_count_
;
62 EmbeddedWorkerTestHelper
* helper_
;
63 ~TestingServiceWorkerDispatcherHost() override
{}
66 class ServiceWorkerDispatcherHostTest
: public testing::Test
{
68 ServiceWorkerDispatcherHostTest()
69 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
) {}
71 void SetUp() override
{
73 new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId
));
74 dispatcher_host_
= new TestingServiceWorkerDispatcherHost(
75 kRenderProcessId
, context_wrapper(), &resource_context_
, helper_
.get());
78 void TearDown() override
{ helper_
.reset(); }
80 ServiceWorkerContextCore
* context() { return helper_
->context(); }
81 ServiceWorkerContextWrapper
* context_wrapper() {
82 return helper_
->context_wrapper();
85 void SendRegister(int64 provider_id
, GURL pattern
, GURL worker_url
) {
86 dispatcher_host_
->OnMessageReceived(
87 ServiceWorkerHostMsg_RegisterServiceWorker(
88 -1, -1, provider_id
, pattern
, worker_url
));
89 base::RunLoop().RunUntilIdle();
92 void Register(int64 provider_id
,
95 uint32 expected_message
) {
96 SendRegister(provider_id
, pattern
, worker_url
);
97 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
99 dispatcher_host_
->ipc_sink()->ClearMessages();
102 void SendUnregister(int64 provider_id
, GURL pattern
) {
103 dispatcher_host_
->OnMessageReceived(
104 ServiceWorkerHostMsg_UnregisterServiceWorker(
105 -1, -1, provider_id
, pattern
));
106 base::RunLoop().RunUntilIdle();
109 void Unregister(int64 provider_id
, GURL pattern
, uint32 expected_message
) {
110 SendUnregister(provider_id
, pattern
);
111 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
113 dispatcher_host_
->ipc_sink()->ClearMessages();
116 void SendGetRegistration(int64 provider_id
, GURL document_url
) {
117 dispatcher_host_
->OnMessageReceived(
118 ServiceWorkerHostMsg_GetRegistration(
119 -1, -1, provider_id
, document_url
));
120 base::RunLoop().RunUntilIdle();
123 void GetRegistration(int64 provider_id
,
125 uint32 expected_message
) {
126 SendGetRegistration(provider_id
, document_url
);
127 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
129 dispatcher_host_
->ipc_sink()->ClearMessages();
132 void SendGetRegistrations(int64 provider_id
) {
133 dispatcher_host_
->OnMessageReceived(
134 ServiceWorkerHostMsg_GetRegistrations(-1, -1, provider_id
));
135 base::RunLoop().RunUntilIdle();
138 void GetRegistrations(int64 provider_id
, uint32 expected_message
) {
139 SendGetRegistrations(provider_id
);
140 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
142 dispatcher_host_
->ipc_sink()->ClearMessages();
145 ServiceWorkerProviderHost
* CreateServiceWorkerProviderHost(int provider_id
) {
146 return new ServiceWorkerProviderHost(
147 kRenderProcessId
, kRenderFrameId
, provider_id
,
148 SERVICE_WORKER_PROVIDER_FOR_WINDOW
, context()->AsWeakPtr(),
149 dispatcher_host_
.get());
153 TestBrowserThreadBundle browser_thread_bundle_
;
154 content::MockResourceContext resource_context_
;
155 scoped_ptr
<EmbeddedWorkerTestHelper
> helper_
;
156 scoped_refptr
<TestingServiceWorkerDispatcherHost
> dispatcher_host_
;
159 class ServiceWorkerTestContentBrowserClient
: public TestContentBrowserClient
{
161 ServiceWorkerTestContentBrowserClient() {}
162 bool AllowServiceWorker(const GURL
& scope
,
163 const GURL
& first_party
,
164 content::ResourceContext
* context
,
165 int render_process_id
,
166 int render_frame_id
) override
{
171 TEST_F(ServiceWorkerDispatcherHostTest
,
172 Register_ContentSettingsDisallowsServiceWorker
) {
173 ServiceWorkerTestContentBrowserClient test_browser_client
;
174 ContentBrowserClient
* old_browser_client
=
175 SetBrowserClientForTesting(&test_browser_client
);
177 const int64 kProviderId
= 99; // Dummy value
178 scoped_ptr
<ServiceWorkerProviderHost
> host(
179 CreateServiceWorkerProviderHost(kProviderId
));
180 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
181 context()->AddProviderHost(host
.Pass());
183 Register(kProviderId
,
184 GURL("https://www.example.com/"),
185 GURL("https://www.example.com/bar"),
186 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
187 Unregister(kProviderId
,
188 GURL("https://www.example.com/"),
189 ServiceWorkerMsg_ServiceWorkerUnregistrationError::ID
);
190 GetRegistration(kProviderId
,
191 GURL("https://www.example.com/"),
192 ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID
);
193 GetRegistrations(kProviderId
,
194 ServiceWorkerMsg_ServiceWorkerGetRegistrationsError::ID
);
196 SetBrowserClientForTesting(old_browser_client
);
199 TEST_F(ServiceWorkerDispatcherHostTest
, Register_HTTPS
) {
200 const int64 kProviderId
= 99; // Dummy value
201 scoped_ptr
<ServiceWorkerProviderHost
> host(
202 CreateServiceWorkerProviderHost(kProviderId
));
203 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
204 context()->AddProviderHost(host
.Pass());
206 Register(kProviderId
,
207 GURL("https://www.example.com/"),
208 GURL("https://www.example.com/bar"),
209 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
212 TEST_F(ServiceWorkerDispatcherHostTest
, Register_NonSecureTransportLocalhost
) {
213 const int64 kProviderId
= 99; // Dummy value
214 scoped_ptr
<ServiceWorkerProviderHost
> host(
215 CreateServiceWorkerProviderHost(kProviderId
));
216 host
->SetDocumentUrl(GURL("http://127.0.0.3:81/foo"));
217 context()->AddProviderHost(host
.Pass());
219 Register(kProviderId
,
220 GURL("http://127.0.0.3:81/bar"),
221 GURL("http://127.0.0.3:81/baz"),
222 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
225 TEST_F(ServiceWorkerDispatcherHostTest
, Register_InvalidScopeShouldFail
) {
226 const int64 kProviderId
= 99; // Dummy value
227 scoped_ptr
<ServiceWorkerProviderHost
> host(
228 CreateServiceWorkerProviderHost(kProviderId
));
229 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
230 context()->AddProviderHost(host
.Pass());
232 SendRegister(kProviderId
, GURL(""),
233 GURL("https://www.example.com/bar/hoge.js"));
234 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
237 TEST_F(ServiceWorkerDispatcherHostTest
, Register_InvalidScriptShouldFail
) {
238 const int64 kProviderId
= 99; // Dummy value
239 scoped_ptr
<ServiceWorkerProviderHost
> host(
240 CreateServiceWorkerProviderHost(kProviderId
));
241 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
242 context()->AddProviderHost(host
.Pass());
244 SendRegister(kProviderId
, GURL("https://www.example.com/bar/"), GURL(""));
245 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
248 TEST_F(ServiceWorkerDispatcherHostTest
, Register_NonSecureOriginShouldFail
) {
249 const int64 kProviderId
= 99; // Dummy value
250 scoped_ptr
<ServiceWorkerProviderHost
> host(
251 CreateServiceWorkerProviderHost(kProviderId
));
252 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
253 context()->AddProviderHost(host
.Pass());
255 SendRegister(kProviderId
,
256 GURL("http://www.example.com/"),
257 GURL("http://www.example.com/bar"));
258 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
261 TEST_F(ServiceWorkerDispatcherHostTest
, Register_CrossOriginShouldFail
) {
262 const int64 kProviderId
= 99; // Dummy value
263 scoped_ptr
<ServiceWorkerProviderHost
> host(
264 CreateServiceWorkerProviderHost(kProviderId
));
265 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
266 context()->AddProviderHost(host
.Pass());
268 // Script has a different host
269 SendRegister(kProviderId
,
270 GURL("https://www.example.com/"),
271 GURL("https://foo.example.com/bar"));
272 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
274 // Scope has a different host
275 SendRegister(kProviderId
,
276 GURL("https://foo.example.com/"),
277 GURL("https://www.example.com/bar"));
278 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
280 // Script has a different port
281 SendRegister(kProviderId
,
282 GURL("https://www.example.com/"),
283 GURL("https://www.example.com:8080/bar"));
284 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
286 // Scope has a different transport
287 SendRegister(kProviderId
,
288 GURL("wss://www.example.com/"),
289 GURL("https://www.example.com/bar"));
290 EXPECT_EQ(4, dispatcher_host_
->bad_messages_received_count_
);
292 // Script and scope have a different host but match each other
293 SendRegister(kProviderId
,
294 GURL("https://foo.example.com/"),
295 GURL("https://foo.example.com/bar"));
296 EXPECT_EQ(5, dispatcher_host_
->bad_messages_received_count_
);
298 // Script and scope URLs are invalid
299 SendRegister(kProviderId
,
302 EXPECT_EQ(6, dispatcher_host_
->bad_messages_received_count_
);
305 TEST_F(ServiceWorkerDispatcherHostTest
,
306 Register_FileSystemDocumentShouldFail
) {
307 const int64 kProviderId
= 99; // Dummy value
308 scoped_ptr
<ServiceWorkerProviderHost
> host(
309 CreateServiceWorkerProviderHost(kProviderId
));
310 host
->SetDocumentUrl(GURL("filesystem:https://www.example.com/temporary/a"));
311 context()->AddProviderHost(host
.Pass());
313 SendRegister(kProviderId
,
314 GURL("filesystem:https://www.example.com/temporary/"),
315 GURL("https://www.example.com/temporary/bar"));
316 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
318 SendRegister(kProviderId
,
319 GURL("https://www.example.com/temporary/"),
320 GURL("filesystem:https://www.example.com/temporary/bar"));
321 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
323 SendRegister(kProviderId
,
324 GURL("filesystem:https://www.example.com/temporary/"),
325 GURL("filesystem:https://www.example.com/temporary/bar"));
326 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
329 TEST_F(ServiceWorkerDispatcherHostTest
,
330 Register_FileSystemScriptOrScopeShouldFail
) {
331 const int64 kProviderId
= 99; // Dummy value
332 scoped_ptr
<ServiceWorkerProviderHost
> host(
333 CreateServiceWorkerProviderHost(kProviderId
));
334 host
->SetDocumentUrl(GURL("https://www.example.com/temporary/"));
335 context()->AddProviderHost(host
.Pass());
337 SendRegister(kProviderId
,
338 GURL("filesystem:https://www.example.com/temporary/"),
339 GURL("https://www.example.com/temporary/bar"));
340 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
342 SendRegister(kProviderId
,
343 GURL("https://www.example.com/temporary/"),
344 GURL("filesystem:https://www.example.com/temporary/bar"));
345 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
347 SendRegister(kProviderId
,
348 GURL("filesystem:https://www.example.com/temporary/"),
349 GURL("filesystem:https://www.example.com/temporary/bar"));
350 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
353 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_HTTPS
) {
354 const int64 kProviderId
= 99; // Dummy value
355 scoped_ptr
<ServiceWorkerProviderHost
> host(
356 CreateServiceWorkerProviderHost(kProviderId
));
357 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
358 context()->AddProviderHost(host
.Pass());
360 Unregister(kProviderId
,
361 GURL("https://www.example.com/"),
362 ServiceWorkerMsg_ServiceWorkerUnregistered::ID
);
365 TEST_F(ServiceWorkerDispatcherHostTest
,
366 Unregister_NotSecureTransportLocalhost
) {
367 const int64 kProviderId
= 99; // Dummy value
368 scoped_ptr
<ServiceWorkerProviderHost
> host(
369 CreateServiceWorkerProviderHost(kProviderId
));
370 host
->SetDocumentUrl(GURL("http://localhost/foo"));
371 context()->AddProviderHost(host
.Pass());
373 Unregister(kProviderId
,
374 GURL("http://localhost/"),
375 ServiceWorkerMsg_ServiceWorkerUnregistered::ID
);
378 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_CrossOriginShouldFail
) {
379 const int64 kProviderId
= 99; // Dummy value
380 scoped_ptr
<ServiceWorkerProviderHost
> host(
381 CreateServiceWorkerProviderHost(kProviderId
));
382 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
383 context()->AddProviderHost(host
.Pass());
385 SendUnregister(kProviderId
, GURL("https://foo.example.com/"));
386 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
389 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_InvalidScopeShouldFail
) {
390 const int64 kProviderId
= 99; // Dummy value
391 scoped_ptr
<ServiceWorkerProviderHost
> host(
392 CreateServiceWorkerProviderHost(kProviderId
));
393 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
394 context()->AddProviderHost(host
.Pass());
396 SendUnregister(kProviderId
, GURL(""));
397 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
400 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_NonSecureOriginShouldFail
) {
401 const int64 kProviderId
= 99; // Dummy value
402 scoped_ptr
<ServiceWorkerProviderHost
> host(
403 CreateServiceWorkerProviderHost(kProviderId
));
404 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
405 context()->AddProviderHost(host
.Pass());
407 SendUnregister(kProviderId
, GURL("http://www.example.com/"));
408 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
411 TEST_F(ServiceWorkerDispatcherHostTest
, EarlyContextDeletion
) {
412 helper_
->ShutdownContext();
414 // Let the shutdown reach the simulated IO thread.
415 base::RunLoop().RunUntilIdle();
420 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
423 TEST_F(ServiceWorkerDispatcherHostTest
, ProviderCreatedAndDestroyed
) {
424 const int kProviderId
= 1001; // Test with a value != kRenderProcessId.
426 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
427 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
428 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
430 // Two with the same ID should be seen as a bad message.
431 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
432 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
433 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
435 dispatcher_host_
->OnMessageReceived(
436 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
437 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
439 // Destroying an ID that does not exist warrants a bad message.
440 dispatcher_host_
->OnMessageReceived(
441 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
442 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
444 // Deletion of the dispatcher_host should cause providers for that
445 // process to get deleted as well.
446 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
447 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
448 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
449 EXPECT_TRUE(dispatcher_host_
->HasOneRef());
450 dispatcher_host_
= NULL
;
451 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
454 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_SameOrigin
) {
455 const int64 kProviderId
= 99; // Dummy value
456 scoped_ptr
<ServiceWorkerProviderHost
> host(
457 CreateServiceWorkerProviderHost(kProviderId
));
458 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
459 context()->AddProviderHost(host
.Pass());
461 GetRegistration(kProviderId
,
462 GURL("https://www.example.com/"),
463 ServiceWorkerMsg_DidGetRegistration::ID
);
466 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_CrossOriginShouldFail
) {
467 const int64 kProviderId
= 99; // Dummy value
468 scoped_ptr
<ServiceWorkerProviderHost
> host(
469 CreateServiceWorkerProviderHost(kProviderId
));
470 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
471 context()->AddProviderHost(host
.Pass());
473 SendGetRegistration(kProviderId
, GURL("https://foo.example.com/"));
474 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
477 TEST_F(ServiceWorkerDispatcherHostTest
,
478 GetRegistration_InvalidScopeShouldFail
) {
479 const int64 kProviderId
= 99; // Dummy value
480 scoped_ptr
<ServiceWorkerProviderHost
> host(
481 CreateServiceWorkerProviderHost(kProviderId
));
482 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
483 context()->AddProviderHost(host
.Pass());
485 SendGetRegistration(kProviderId
, GURL(""));
486 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
489 TEST_F(ServiceWorkerDispatcherHostTest
,
490 GetRegistration_NonSecureOriginShouldFail
) {
491 const int64 kProviderId
= 99; // Dummy value
492 scoped_ptr
<ServiceWorkerProviderHost
> host(
493 CreateServiceWorkerProviderHost(kProviderId
));
494 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
495 context()->AddProviderHost(host
.Pass());
497 SendGetRegistration(kProviderId
, GURL("http://www.example.com/"));
498 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
501 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_EarlyContextDeletion
) {
502 helper_
->ShutdownContext();
504 // Let the shutdown reach the simulated IO thread.
505 base::RunLoop().RunUntilIdle();
509 ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID
);
512 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistrations_SecureOrigin
) {
513 const int64 kProviderId
= 99; // Dummy value
514 scoped_ptr
<ServiceWorkerProviderHost
> host(
515 CreateServiceWorkerProviderHost(kProviderId
));
516 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
517 context()->AddProviderHost(host
.Pass());
519 GetRegistrations(kProviderId
, ServiceWorkerMsg_DidGetRegistrations::ID
);
522 TEST_F(ServiceWorkerDispatcherHostTest
,
523 GetRegistrations_NonSecureOriginShouldFail
) {
524 const int64 kProviderId
= 99; // Dummy value
525 scoped_ptr
<ServiceWorkerProviderHost
> host(
526 CreateServiceWorkerProviderHost(kProviderId
));
527 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
528 context()->AddProviderHost(host
.Pass());
530 SendGetRegistrations(kProviderId
);
531 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
534 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistrations_EarlyContextDeletion
) {
535 helper_
->ShutdownContext();
537 // Let the shutdown reach the simulated IO thread.
538 base::RunLoop().RunUntilIdle();
540 GetRegistrations(-1, ServiceWorkerMsg_ServiceWorkerGetRegistrationsError::ID
);
543 TEST_F(ServiceWorkerDispatcherHostTest
, CleanupOnRendererCrash
) {
544 // Add a provider and worker.
545 const int64 kProviderId
= 99; // Dummy value
546 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
547 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
549 GURL pattern
= GURL("http://www.example.com/");
550 scoped_refptr
<ServiceWorkerRegistration
> registration(
551 new ServiceWorkerRegistration(pattern
,
553 helper_
->context()->AsWeakPtr()));
554 scoped_refptr
<ServiceWorkerVersion
> version(
555 new ServiceWorkerVersion(registration
.get(),
556 GURL("http://www.example.com/service_worker.js"),
558 helper_
->context()->AsWeakPtr()));
559 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records
;
561 ServiceWorkerDatabase::ResourceRecord(10, version
->script_url(), 100));
562 version
->script_cache_map()->SetResources(records
);
564 // Make the registration findable via storage functions.
565 helper_
->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing
));
566 base::RunLoop().RunUntilIdle();
568 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_ABORT
;
569 helper_
->context()->storage()->StoreRegistration(
572 base::Bind(&SaveStatusCallback
, &called
, &status
));
573 base::RunLoop().RunUntilIdle();
575 ASSERT_EQ(SERVICE_WORKER_OK
, status
);
577 helper_
->SimulateAddProcessToPattern(pattern
, kRenderProcessId
);
579 // Start up the worker.
580 status
= SERVICE_WORKER_ERROR_ABORT
;
581 version
->StartWorker(base::Bind(&SaveStatusCallback
, &called
, &status
));
582 base::RunLoop().RunUntilIdle();
585 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
587 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
588 EXPECT_EQ(ServiceWorkerVersion::RUNNING
, version
->running_status());
590 // Simulate the render process crashing.
591 dispatcher_host_
->OnFilterRemoved();
593 // The dispatcher host should clean up the state from the process.
594 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
595 EXPECT_EQ(ServiceWorkerVersion::STOPPED
, version
->running_status());
597 // We should be able to hook up a new dispatcher host although the old object
598 // is not yet destroyed. This is what the browser does when reusing a crashed
600 scoped_refptr
<TestingServiceWorkerDispatcherHost
> new_dispatcher_host(
601 new TestingServiceWorkerDispatcherHost(kRenderProcessId
,
606 // To show the new dispatcher can operate, simulate provider creation. Since
607 // the old dispatcher cleaned up the old provider host, the new one won't
609 new_dispatcher_host
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
610 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
611 EXPECT_EQ(0, new_dispatcher_host
->bad_messages_received_count_
);
614 } // namespace content