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 BadMessageReceived() 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 ServiceWorkerProviderHost
* CreateServiceWorkerProviderHost(int provider_id
) {
133 return new ServiceWorkerProviderHost(kRenderProcessId
,
136 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
,
137 context()->AsWeakPtr(),
138 dispatcher_host_
.get());
142 TestBrowserThreadBundle browser_thread_bundle_
;
143 content::MockResourceContext resource_context_
;
144 scoped_ptr
<EmbeddedWorkerTestHelper
> helper_
;
145 scoped_refptr
<TestingServiceWorkerDispatcherHost
> dispatcher_host_
;
148 class ServiceWorkerTestContentBrowserClient
: public TestContentBrowserClient
{
150 ServiceWorkerTestContentBrowserClient() {}
151 bool AllowServiceWorker(const GURL
& scope
,
152 const GURL
& first_party
,
153 content::ResourceContext
* context
) override
{
158 TEST_F(ServiceWorkerDispatcherHostTest
,
159 Register_ContentSettingsDisallowsServiceWorker
) {
160 ServiceWorkerTestContentBrowserClient test_browser_client
;
161 ContentBrowserClient
* old_browser_client
=
162 SetBrowserClientForTesting(&test_browser_client
);
164 const int64 kProviderId
= 99; // Dummy value
165 scoped_ptr
<ServiceWorkerProviderHost
> host(
166 CreateServiceWorkerProviderHost(kProviderId
));
167 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
168 context()->AddProviderHost(host
.Pass());
170 Register(kProviderId
,
171 GURL("https://www.example.com/"),
172 GURL("https://www.example.com/bar"),
173 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
174 Unregister(kProviderId
,
175 GURL("https://www.example.com/"),
176 ServiceWorkerMsg_ServiceWorkerUnregistrationError::ID
);
177 GetRegistration(kProviderId
,
178 GURL("https://www.example.com/"),
179 ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID
);
181 SetBrowserClientForTesting(old_browser_client
);
184 TEST_F(ServiceWorkerDispatcherHostTest
, Register_HTTPS
) {
185 const int64 kProviderId
= 99; // Dummy value
186 scoped_ptr
<ServiceWorkerProviderHost
> host(
187 CreateServiceWorkerProviderHost(kProviderId
));
188 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
189 context()->AddProviderHost(host
.Pass());
191 Register(kProviderId
,
192 GURL("https://www.example.com/"),
193 GURL("https://www.example.com/bar"),
194 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
197 TEST_F(ServiceWorkerDispatcherHostTest
, Register_NonSecureTransportLocalhost
) {
198 const int64 kProviderId
= 99; // Dummy value
199 scoped_ptr
<ServiceWorkerProviderHost
> host(
200 CreateServiceWorkerProviderHost(kProviderId
));
201 host
->SetDocumentUrl(GURL("http://127.0.0.3:81/foo"));
202 context()->AddProviderHost(host
.Pass());
204 Register(kProviderId
,
205 GURL("http://127.0.0.3:81/bar"),
206 GURL("http://127.0.0.3:81/baz"),
207 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
210 TEST_F(ServiceWorkerDispatcherHostTest
, Register_InvalidScopeShouldFail
) {
211 const int64 kProviderId
= 99; // Dummy value
212 scoped_ptr
<ServiceWorkerProviderHost
> host(
213 CreateServiceWorkerProviderHost(kProviderId
));
214 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
215 context()->AddProviderHost(host
.Pass());
217 SendRegister(kProviderId
, GURL(""),
218 GURL("https://www.example.com/bar/hoge.js"));
219 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
222 TEST_F(ServiceWorkerDispatcherHostTest
, Register_InvalidScriptShouldFail
) {
223 const int64 kProviderId
= 99; // Dummy value
224 scoped_ptr
<ServiceWorkerProviderHost
> host(
225 CreateServiceWorkerProviderHost(kProviderId
));
226 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
227 context()->AddProviderHost(host
.Pass());
229 SendRegister(kProviderId
, GURL("https://www.example.com/bar/"), GURL(""));
230 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
233 TEST_F(ServiceWorkerDispatcherHostTest
, Register_NonSecureOriginShouldFail
) {
234 const int64 kProviderId
= 99; // Dummy value
235 scoped_ptr
<ServiceWorkerProviderHost
> host(
236 CreateServiceWorkerProviderHost(kProviderId
));
237 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
238 context()->AddProviderHost(host
.Pass());
240 SendRegister(kProviderId
,
241 GURL("http://www.example.com/"),
242 GURL("http://www.example.com/bar"));
243 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
246 TEST_F(ServiceWorkerDispatcherHostTest
, Register_CrossOriginShouldFail
) {
247 const int64 kProviderId
= 99; // Dummy value
248 scoped_ptr
<ServiceWorkerProviderHost
> host(
249 CreateServiceWorkerProviderHost(kProviderId
));
250 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
251 context()->AddProviderHost(host
.Pass());
253 // Script has a different host
254 SendRegister(kProviderId
,
255 GURL("https://www.example.com/"),
256 GURL("https://foo.example.com/bar"));
257 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
259 // Scope has a different host
260 SendRegister(kProviderId
,
261 GURL("https://foo.example.com/"),
262 GURL("https://www.example.com/bar"));
263 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
265 // Script has a different port
266 SendRegister(kProviderId
,
267 GURL("https://www.example.com/"),
268 GURL("https://www.example.com:8080/bar"));
269 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
271 // Scope has a different transport
272 SendRegister(kProviderId
,
273 GURL("wss://www.example.com/"),
274 GURL("https://www.example.com/bar"));
275 EXPECT_EQ(4, dispatcher_host_
->bad_messages_received_count_
);
277 // Script and scope have a different host but match each other
278 SendRegister(kProviderId
,
279 GURL("https://foo.example.com/"),
280 GURL("https://foo.example.com/bar"));
281 EXPECT_EQ(5, dispatcher_host_
->bad_messages_received_count_
);
283 // Script and scope URLs are invalid
284 SendRegister(kProviderId
,
287 EXPECT_EQ(6, dispatcher_host_
->bad_messages_received_count_
);
290 TEST_F(ServiceWorkerDispatcherHostTest
,
291 Register_FileSystemDocumentShouldFail
) {
292 const int64 kProviderId
= 99; // Dummy value
293 scoped_ptr
<ServiceWorkerProviderHost
> host(
294 CreateServiceWorkerProviderHost(kProviderId
));
295 host
->SetDocumentUrl(GURL("filesystem:https://www.example.com/temporary/a"));
296 context()->AddProviderHost(host
.Pass());
298 SendRegister(kProviderId
,
299 GURL("filesystem:https://www.example.com/temporary/"),
300 GURL("https://www.example.com/temporary/bar"));
301 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
303 SendRegister(kProviderId
,
304 GURL("https://www.example.com/temporary/"),
305 GURL("filesystem:https://www.example.com/temporary/bar"));
306 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
308 SendRegister(kProviderId
,
309 GURL("filesystem:https://www.example.com/temporary/"),
310 GURL("filesystem:https://www.example.com/temporary/bar"));
311 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
314 TEST_F(ServiceWorkerDispatcherHostTest
,
315 Register_FileSystemScriptOrScopeShouldFail
) {
316 const int64 kProviderId
= 99; // Dummy value
317 scoped_ptr
<ServiceWorkerProviderHost
> host(
318 CreateServiceWorkerProviderHost(kProviderId
));
319 host
->SetDocumentUrl(GURL("https://www.example.com/temporary/"));
320 context()->AddProviderHost(host
.Pass());
322 SendRegister(kProviderId
,
323 GURL("filesystem:https://www.example.com/temporary/"),
324 GURL("https://www.example.com/temporary/bar"));
325 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
327 SendRegister(kProviderId
,
328 GURL("https://www.example.com/temporary/"),
329 GURL("filesystem:https://www.example.com/temporary/bar"));
330 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
332 SendRegister(kProviderId
,
333 GURL("filesystem:https://www.example.com/temporary/"),
334 GURL("filesystem:https://www.example.com/temporary/bar"));
335 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
338 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_HTTPS
) {
339 const int64 kProviderId
= 99; // Dummy value
340 scoped_ptr
<ServiceWorkerProviderHost
> host(
341 CreateServiceWorkerProviderHost(kProviderId
));
342 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
343 context()->AddProviderHost(host
.Pass());
345 Unregister(kProviderId
,
346 GURL("https://www.example.com/"),
347 ServiceWorkerMsg_ServiceWorkerUnregistered::ID
);
350 TEST_F(ServiceWorkerDispatcherHostTest
,
351 Unregister_NotSecureTransportLocalhost
) {
352 const int64 kProviderId
= 99; // Dummy value
353 scoped_ptr
<ServiceWorkerProviderHost
> host(
354 CreateServiceWorkerProviderHost(kProviderId
));
355 host
->SetDocumentUrl(GURL("http://localhost/foo"));
356 context()->AddProviderHost(host
.Pass());
358 Unregister(kProviderId
,
359 GURL("http://localhost/"),
360 ServiceWorkerMsg_ServiceWorkerUnregistered::ID
);
363 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_CrossOriginShouldFail
) {
364 const int64 kProviderId
= 99; // Dummy value
365 scoped_ptr
<ServiceWorkerProviderHost
> host(
366 CreateServiceWorkerProviderHost(kProviderId
));
367 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
368 context()->AddProviderHost(host
.Pass());
370 SendUnregister(kProviderId
, GURL("https://foo.example.com/"));
371 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
374 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_InvalidScopeShouldFail
) {
375 const int64 kProviderId
= 99; // Dummy value
376 scoped_ptr
<ServiceWorkerProviderHost
> host(
377 CreateServiceWorkerProviderHost(kProviderId
));
378 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
379 context()->AddProviderHost(host
.Pass());
381 SendUnregister(kProviderId
, GURL(""));
382 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
385 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_NonSecureOriginShouldFail
) {
386 const int64 kProviderId
= 99; // Dummy value
387 scoped_ptr
<ServiceWorkerProviderHost
> host(
388 CreateServiceWorkerProviderHost(kProviderId
));
389 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
390 context()->AddProviderHost(host
.Pass());
392 SendUnregister(kProviderId
, GURL("http://www.example.com/"));
393 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
396 TEST_F(ServiceWorkerDispatcherHostTest
, EarlyContextDeletion
) {
397 helper_
->ShutdownContext();
399 // Let the shutdown reach the simulated IO thread.
400 base::RunLoop().RunUntilIdle();
405 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
408 TEST_F(ServiceWorkerDispatcherHostTest
, ProviderCreatedAndDestroyed
) {
409 const int kProviderId
= 1001; // Test with a value != kRenderProcessId.
411 dispatcher_host_
->OnMessageReceived(
412 ServiceWorkerHostMsg_ProviderCreated(
413 kProviderId
, MSG_ROUTING_NONE
,
414 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
));
415 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
417 // Two with the same ID should be seen as a bad message.
418 dispatcher_host_
->OnMessageReceived(
419 ServiceWorkerHostMsg_ProviderCreated(
420 kProviderId
, MSG_ROUTING_NONE
,
421 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
));
422 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
424 dispatcher_host_
->OnMessageReceived(
425 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
426 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
428 // Destroying an ID that does not exist warrants a bad message.
429 dispatcher_host_
->OnMessageReceived(
430 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
431 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
433 // Deletion of the dispatcher_host should cause providers for that
434 // process to get deleted as well.
435 dispatcher_host_
->OnMessageReceived(
436 ServiceWorkerHostMsg_ProviderCreated(
437 kProviderId
, MSG_ROUTING_NONE
,
438 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
));
439 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
440 EXPECT_TRUE(dispatcher_host_
->HasOneRef());
441 dispatcher_host_
= NULL
;
442 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
445 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_SameOrigin
) {
446 const int64 kProviderId
= 99; // Dummy value
447 scoped_ptr
<ServiceWorkerProviderHost
> host(
448 CreateServiceWorkerProviderHost(kProviderId
));
449 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
450 context()->AddProviderHost(host
.Pass());
452 GetRegistration(kProviderId
,
453 GURL("https://www.example.com/"),
454 ServiceWorkerMsg_DidGetRegistration::ID
);
457 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_CrossOriginShouldFail
) {
458 const int64 kProviderId
= 99; // Dummy value
459 scoped_ptr
<ServiceWorkerProviderHost
> host(
460 CreateServiceWorkerProviderHost(kProviderId
));
461 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
462 context()->AddProviderHost(host
.Pass());
464 SendGetRegistration(kProviderId
, GURL("https://foo.example.com/"));
465 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
468 TEST_F(ServiceWorkerDispatcherHostTest
,
469 GetRegistration_InvalidScopeShouldFail
) {
470 const int64 kProviderId
= 99; // Dummy value
471 scoped_ptr
<ServiceWorkerProviderHost
> host(
472 CreateServiceWorkerProviderHost(kProviderId
));
473 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
474 context()->AddProviderHost(host
.Pass());
476 SendGetRegistration(kProviderId
, GURL(""));
477 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
480 TEST_F(ServiceWorkerDispatcherHostTest
,
481 GetRegistration_NonSecureOriginShouldFail
) {
482 const int64 kProviderId
= 99; // Dummy value
483 scoped_ptr
<ServiceWorkerProviderHost
> host(
484 CreateServiceWorkerProviderHost(kProviderId
));
485 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
486 context()->AddProviderHost(host
.Pass());
488 SendGetRegistration(kProviderId
, GURL("http://www.example.com/"));
489 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
492 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_EarlyContextDeletion
) {
493 helper_
->ShutdownContext();
495 // Let the shutdown reach the simulated IO thread.
496 base::RunLoop().RunUntilIdle();
500 ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID
);
503 TEST_F(ServiceWorkerDispatcherHostTest
, CleanupOnRendererCrash
) {
504 // Add a provider and worker.
505 const int64 kProviderId
= 99; // Dummy value
506 dispatcher_host_
->OnMessageReceived(
507 ServiceWorkerHostMsg_ProviderCreated(
508 kProviderId
, MSG_ROUTING_NONE
,
509 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
));
511 GURL pattern
= GURL("http://www.example.com/");
512 scoped_refptr
<ServiceWorkerRegistration
> registration(
513 new ServiceWorkerRegistration(pattern
,
515 helper_
->context()->AsWeakPtr()));
516 scoped_refptr
<ServiceWorkerVersion
> version(
517 new ServiceWorkerVersion(registration
.get(),
518 GURL("http://www.example.com/service_worker.js"),
520 helper_
->context()->AsWeakPtr()));
522 // Make the registration findable via storage functions.
523 helper_
->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing
));
524 base::RunLoop().RunUntilIdle();
526 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_ABORT
;
527 helper_
->context()->storage()->StoreRegistration(
530 base::Bind(&SaveStatusCallback
, &called
, &status
));
531 base::RunLoop().RunUntilIdle();
533 ASSERT_EQ(SERVICE_WORKER_OK
, status
);
535 helper_
->SimulateAddProcessToPattern(pattern
, kRenderProcessId
);
537 // Start up the worker.
538 status
= SERVICE_WORKER_ERROR_ABORT
;
539 version
->StartWorker(base::Bind(&SaveStatusCallback
, &called
, &status
));
540 base::RunLoop().RunUntilIdle();
543 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
545 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
546 EXPECT_EQ(ServiceWorkerVersion::RUNNING
, version
->running_status());
548 // Simulate the render process crashing.
549 dispatcher_host_
->OnFilterRemoved();
551 // The dispatcher host should clean up the state from the process.
552 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
553 EXPECT_EQ(ServiceWorkerVersion::STOPPED
, version
->running_status());
555 // We should be able to hook up a new dispatcher host although the old object
556 // is not yet destroyed. This is what the browser does when reusing a crashed
558 scoped_refptr
<TestingServiceWorkerDispatcherHost
> new_dispatcher_host(
559 new TestingServiceWorkerDispatcherHost(kRenderProcessId
,
564 // To show the new dispatcher can operate, simulate provider creation. Since
565 // the old dispatcher cleaned up the old provider host, the new one won't
567 new_dispatcher_host
->OnMessageReceived(
568 ServiceWorkerHostMsg_ProviderCreated(
569 kProviderId
, MSG_ROUTING_NONE
,
570 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
));
571 EXPECT_EQ(0, new_dispatcher_host
->bad_messages_received_count_
);
574 } // namespace content