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(
134 kRenderProcessId
, kRenderFrameId
, provider_id
,
135 SERVICE_WORKER_PROVIDER_FOR_WINDOW
, context()->AsWeakPtr(),
136 dispatcher_host_
.get());
140 TestBrowserThreadBundle browser_thread_bundle_
;
141 content::MockResourceContext resource_context_
;
142 scoped_ptr
<EmbeddedWorkerTestHelper
> helper_
;
143 scoped_refptr
<TestingServiceWorkerDispatcherHost
> dispatcher_host_
;
146 class ServiceWorkerTestContentBrowserClient
: public TestContentBrowserClient
{
148 ServiceWorkerTestContentBrowserClient() {}
149 bool AllowServiceWorker(const GURL
& scope
,
150 const GURL
& first_party
,
151 content::ResourceContext
* context
) override
{
156 TEST_F(ServiceWorkerDispatcherHostTest
,
157 Register_ContentSettingsDisallowsServiceWorker
) {
158 ServiceWorkerTestContentBrowserClient test_browser_client
;
159 ContentBrowserClient
* old_browser_client
=
160 SetBrowserClientForTesting(&test_browser_client
);
162 const int64 kProviderId
= 99; // Dummy value
163 scoped_ptr
<ServiceWorkerProviderHost
> host(
164 CreateServiceWorkerProviderHost(kProviderId
));
165 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
166 context()->AddProviderHost(host
.Pass());
168 Register(kProviderId
,
169 GURL("https://www.example.com/"),
170 GURL("https://www.example.com/bar"),
171 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
172 Unregister(kProviderId
,
173 GURL("https://www.example.com/"),
174 ServiceWorkerMsg_ServiceWorkerUnregistrationError::ID
);
175 GetRegistration(kProviderId
,
176 GURL("https://www.example.com/"),
177 ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID
);
179 SetBrowserClientForTesting(old_browser_client
);
182 TEST_F(ServiceWorkerDispatcherHostTest
, Register_HTTPS
) {
183 const int64 kProviderId
= 99; // Dummy value
184 scoped_ptr
<ServiceWorkerProviderHost
> host(
185 CreateServiceWorkerProviderHost(kProviderId
));
186 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
187 context()->AddProviderHost(host
.Pass());
189 Register(kProviderId
,
190 GURL("https://www.example.com/"),
191 GURL("https://www.example.com/bar"),
192 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
195 TEST_F(ServiceWorkerDispatcherHostTest
, Register_NonSecureTransportLocalhost
) {
196 const int64 kProviderId
= 99; // Dummy value
197 scoped_ptr
<ServiceWorkerProviderHost
> host(
198 CreateServiceWorkerProviderHost(kProviderId
));
199 host
->SetDocumentUrl(GURL("http://127.0.0.3:81/foo"));
200 context()->AddProviderHost(host
.Pass());
202 Register(kProviderId
,
203 GURL("http://127.0.0.3:81/bar"),
204 GURL("http://127.0.0.3:81/baz"),
205 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
208 TEST_F(ServiceWorkerDispatcherHostTest
, Register_InvalidScopeShouldFail
) {
209 const int64 kProviderId
= 99; // Dummy value
210 scoped_ptr
<ServiceWorkerProviderHost
> host(
211 CreateServiceWorkerProviderHost(kProviderId
));
212 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
213 context()->AddProviderHost(host
.Pass());
215 SendRegister(kProviderId
, GURL(""),
216 GURL("https://www.example.com/bar/hoge.js"));
217 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
220 TEST_F(ServiceWorkerDispatcherHostTest
, Register_InvalidScriptShouldFail
) {
221 const int64 kProviderId
= 99; // Dummy value
222 scoped_ptr
<ServiceWorkerProviderHost
> host(
223 CreateServiceWorkerProviderHost(kProviderId
));
224 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
225 context()->AddProviderHost(host
.Pass());
227 SendRegister(kProviderId
, GURL("https://www.example.com/bar/"), GURL(""));
228 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
231 TEST_F(ServiceWorkerDispatcherHostTest
, Register_NonSecureOriginShouldFail
) {
232 const int64 kProviderId
= 99; // Dummy value
233 scoped_ptr
<ServiceWorkerProviderHost
> host(
234 CreateServiceWorkerProviderHost(kProviderId
));
235 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
236 context()->AddProviderHost(host
.Pass());
238 SendRegister(kProviderId
,
239 GURL("http://www.example.com/"),
240 GURL("http://www.example.com/bar"));
241 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
244 TEST_F(ServiceWorkerDispatcherHostTest
, Register_CrossOriginShouldFail
) {
245 const int64 kProviderId
= 99; // Dummy value
246 scoped_ptr
<ServiceWorkerProviderHost
> host(
247 CreateServiceWorkerProviderHost(kProviderId
));
248 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
249 context()->AddProviderHost(host
.Pass());
251 // Script has a different host
252 SendRegister(kProviderId
,
253 GURL("https://www.example.com/"),
254 GURL("https://foo.example.com/bar"));
255 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
257 // Scope has a different host
258 SendRegister(kProviderId
,
259 GURL("https://foo.example.com/"),
260 GURL("https://www.example.com/bar"));
261 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
263 // Script has a different port
264 SendRegister(kProviderId
,
265 GURL("https://www.example.com/"),
266 GURL("https://www.example.com:8080/bar"));
267 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
269 // Scope has a different transport
270 SendRegister(kProviderId
,
271 GURL("wss://www.example.com/"),
272 GURL("https://www.example.com/bar"));
273 EXPECT_EQ(4, dispatcher_host_
->bad_messages_received_count_
);
275 // Script and scope have a different host but match each other
276 SendRegister(kProviderId
,
277 GURL("https://foo.example.com/"),
278 GURL("https://foo.example.com/bar"));
279 EXPECT_EQ(5, dispatcher_host_
->bad_messages_received_count_
);
281 // Script and scope URLs are invalid
282 SendRegister(kProviderId
,
285 EXPECT_EQ(6, dispatcher_host_
->bad_messages_received_count_
);
288 TEST_F(ServiceWorkerDispatcherHostTest
,
289 Register_FileSystemDocumentShouldFail
) {
290 const int64 kProviderId
= 99; // Dummy value
291 scoped_ptr
<ServiceWorkerProviderHost
> host(
292 CreateServiceWorkerProviderHost(kProviderId
));
293 host
->SetDocumentUrl(GURL("filesystem:https://www.example.com/temporary/a"));
294 context()->AddProviderHost(host
.Pass());
296 SendRegister(kProviderId
,
297 GURL("filesystem:https://www.example.com/temporary/"),
298 GURL("https://www.example.com/temporary/bar"));
299 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
301 SendRegister(kProviderId
,
302 GURL("https://www.example.com/temporary/"),
303 GURL("filesystem:https://www.example.com/temporary/bar"));
304 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
306 SendRegister(kProviderId
,
307 GURL("filesystem:https://www.example.com/temporary/"),
308 GURL("filesystem:https://www.example.com/temporary/bar"));
309 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
312 TEST_F(ServiceWorkerDispatcherHostTest
,
313 Register_FileSystemScriptOrScopeShouldFail
) {
314 const int64 kProviderId
= 99; // Dummy value
315 scoped_ptr
<ServiceWorkerProviderHost
> host(
316 CreateServiceWorkerProviderHost(kProviderId
));
317 host
->SetDocumentUrl(GURL("https://www.example.com/temporary/"));
318 context()->AddProviderHost(host
.Pass());
320 SendRegister(kProviderId
,
321 GURL("filesystem:https://www.example.com/temporary/"),
322 GURL("https://www.example.com/temporary/bar"));
323 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
325 SendRegister(kProviderId
,
326 GURL("https://www.example.com/temporary/"),
327 GURL("filesystem:https://www.example.com/temporary/bar"));
328 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
330 SendRegister(kProviderId
,
331 GURL("filesystem:https://www.example.com/temporary/"),
332 GURL("filesystem:https://www.example.com/temporary/bar"));
333 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
336 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_HTTPS
) {
337 const int64 kProviderId
= 99; // Dummy value
338 scoped_ptr
<ServiceWorkerProviderHost
> host(
339 CreateServiceWorkerProviderHost(kProviderId
));
340 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
341 context()->AddProviderHost(host
.Pass());
343 Unregister(kProviderId
,
344 GURL("https://www.example.com/"),
345 ServiceWorkerMsg_ServiceWorkerUnregistered::ID
);
348 TEST_F(ServiceWorkerDispatcherHostTest
,
349 Unregister_NotSecureTransportLocalhost
) {
350 const int64 kProviderId
= 99; // Dummy value
351 scoped_ptr
<ServiceWorkerProviderHost
> host(
352 CreateServiceWorkerProviderHost(kProviderId
));
353 host
->SetDocumentUrl(GURL("http://localhost/foo"));
354 context()->AddProviderHost(host
.Pass());
356 Unregister(kProviderId
,
357 GURL("http://localhost/"),
358 ServiceWorkerMsg_ServiceWorkerUnregistered::ID
);
361 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_CrossOriginShouldFail
) {
362 const int64 kProviderId
= 99; // Dummy value
363 scoped_ptr
<ServiceWorkerProviderHost
> host(
364 CreateServiceWorkerProviderHost(kProviderId
));
365 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
366 context()->AddProviderHost(host
.Pass());
368 SendUnregister(kProviderId
, GURL("https://foo.example.com/"));
369 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
372 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_InvalidScopeShouldFail
) {
373 const int64 kProviderId
= 99; // Dummy value
374 scoped_ptr
<ServiceWorkerProviderHost
> host(
375 CreateServiceWorkerProviderHost(kProviderId
));
376 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
377 context()->AddProviderHost(host
.Pass());
379 SendUnregister(kProviderId
, GURL(""));
380 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
383 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_NonSecureOriginShouldFail
) {
384 const int64 kProviderId
= 99; // Dummy value
385 scoped_ptr
<ServiceWorkerProviderHost
> host(
386 CreateServiceWorkerProviderHost(kProviderId
));
387 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
388 context()->AddProviderHost(host
.Pass());
390 SendUnregister(kProviderId
, GURL("http://www.example.com/"));
391 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
394 TEST_F(ServiceWorkerDispatcherHostTest
, EarlyContextDeletion
) {
395 helper_
->ShutdownContext();
397 // Let the shutdown reach the simulated IO thread.
398 base::RunLoop().RunUntilIdle();
403 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
406 TEST_F(ServiceWorkerDispatcherHostTest
, ProviderCreatedAndDestroyed
) {
407 const int kProviderId
= 1001; // Test with a value != kRenderProcessId.
409 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
410 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
411 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
413 // Two with the same ID should be seen as a bad message.
414 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
415 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
416 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
418 dispatcher_host_
->OnMessageReceived(
419 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
420 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
422 // Destroying an ID that does not exist warrants a bad message.
423 dispatcher_host_
->OnMessageReceived(
424 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
425 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
427 // Deletion of the dispatcher_host should cause providers for that
428 // process to get deleted as well.
429 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
430 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
431 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
432 EXPECT_TRUE(dispatcher_host_
->HasOneRef());
433 dispatcher_host_
= NULL
;
434 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
437 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_SameOrigin
) {
438 const int64 kProviderId
= 99; // Dummy value
439 scoped_ptr
<ServiceWorkerProviderHost
> host(
440 CreateServiceWorkerProviderHost(kProviderId
));
441 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
442 context()->AddProviderHost(host
.Pass());
444 GetRegistration(kProviderId
,
445 GURL("https://www.example.com/"),
446 ServiceWorkerMsg_DidGetRegistration::ID
);
449 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_CrossOriginShouldFail
) {
450 const int64 kProviderId
= 99; // Dummy value
451 scoped_ptr
<ServiceWorkerProviderHost
> host(
452 CreateServiceWorkerProviderHost(kProviderId
));
453 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
454 context()->AddProviderHost(host
.Pass());
456 SendGetRegistration(kProviderId
, GURL("https://foo.example.com/"));
457 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
460 TEST_F(ServiceWorkerDispatcherHostTest
,
461 GetRegistration_InvalidScopeShouldFail
) {
462 const int64 kProviderId
= 99; // Dummy value
463 scoped_ptr
<ServiceWorkerProviderHost
> host(
464 CreateServiceWorkerProviderHost(kProviderId
));
465 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
466 context()->AddProviderHost(host
.Pass());
468 SendGetRegistration(kProviderId
, GURL(""));
469 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
472 TEST_F(ServiceWorkerDispatcherHostTest
,
473 GetRegistration_NonSecureOriginShouldFail
) {
474 const int64 kProviderId
= 99; // Dummy value
475 scoped_ptr
<ServiceWorkerProviderHost
> host(
476 CreateServiceWorkerProviderHost(kProviderId
));
477 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
478 context()->AddProviderHost(host
.Pass());
480 SendGetRegistration(kProviderId
, GURL("http://www.example.com/"));
481 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
484 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_EarlyContextDeletion
) {
485 helper_
->ShutdownContext();
487 // Let the shutdown reach the simulated IO thread.
488 base::RunLoop().RunUntilIdle();
492 ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID
);
495 TEST_F(ServiceWorkerDispatcherHostTest
, CleanupOnRendererCrash
) {
496 // Add a provider and worker.
497 const int64 kProviderId
= 99; // Dummy value
498 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
499 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
501 GURL pattern
= GURL("http://www.example.com/");
502 scoped_refptr
<ServiceWorkerRegistration
> registration(
503 new ServiceWorkerRegistration(pattern
,
505 helper_
->context()->AsWeakPtr()));
506 scoped_refptr
<ServiceWorkerVersion
> version(
507 new ServiceWorkerVersion(registration
.get(),
508 GURL("http://www.example.com/service_worker.js"),
510 helper_
->context()->AsWeakPtr()));
512 // Make the registration findable via storage functions.
513 helper_
->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing
));
514 base::RunLoop().RunUntilIdle();
516 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_ABORT
;
517 helper_
->context()->storage()->StoreRegistration(
520 base::Bind(&SaveStatusCallback
, &called
, &status
));
521 base::RunLoop().RunUntilIdle();
523 ASSERT_EQ(SERVICE_WORKER_OK
, status
);
525 helper_
->SimulateAddProcessToPattern(pattern
, kRenderProcessId
);
527 // Start up the worker.
528 status
= SERVICE_WORKER_ERROR_ABORT
;
529 version
->StartWorker(base::Bind(&SaveStatusCallback
, &called
, &status
));
530 base::RunLoop().RunUntilIdle();
533 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
535 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
536 EXPECT_EQ(ServiceWorkerVersion::RUNNING
, version
->running_status());
538 // Simulate the render process crashing.
539 dispatcher_host_
->OnFilterRemoved();
541 // The dispatcher host should clean up the state from the process.
542 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
543 EXPECT_EQ(ServiceWorkerVersion::STOPPED
, version
->running_status());
545 // We should be able to hook up a new dispatcher host although the old object
546 // is not yet destroyed. This is what the browser does when reusing a crashed
548 scoped_refptr
<TestingServiceWorkerDispatcherHost
> new_dispatcher_host(
549 new TestingServiceWorkerDispatcherHost(kRenderProcessId
,
554 // To show the new dispatcher can operate, simulate provider creation. Since
555 // the old dispatcher cleaned up the old provider host, the new one won't
557 new_dispatcher_host
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
558 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
559 EXPECT_EQ(0, new_dispatcher_host
->bad_messages_received_count_
);
562 } // namespace content