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
{
72 helper_
.reset(new EmbeddedWorkerTestHelper(kRenderProcessId
));
73 dispatcher_host_
= new TestingServiceWorkerDispatcherHost(
74 kRenderProcessId
, context_wrapper(), &resource_context_
, helper_
.get());
77 void TearDown() override
{ helper_
.reset(); }
79 ServiceWorkerContextCore
* context() { return helper_
->context(); }
80 ServiceWorkerContextWrapper
* context_wrapper() {
81 return helper_
->context_wrapper();
84 void SendRegister(int64 provider_id
, GURL pattern
, GURL worker_url
) {
85 dispatcher_host_
->OnMessageReceived(
86 ServiceWorkerHostMsg_RegisterServiceWorker(
87 -1, -1, provider_id
, pattern
, worker_url
));
88 base::RunLoop().RunUntilIdle();
91 void Register(int64 provider_id
,
94 uint32 expected_message
) {
95 SendRegister(provider_id
, pattern
, worker_url
);
96 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
98 dispatcher_host_
->ipc_sink()->ClearMessages();
101 void SendUnregister(int64 provider_id
, GURL pattern
) {
102 dispatcher_host_
->OnMessageReceived(
103 ServiceWorkerHostMsg_UnregisterServiceWorker(
104 -1, -1, provider_id
, pattern
));
105 base::RunLoop().RunUntilIdle();
108 void Unregister(int64 provider_id
, GURL pattern
, uint32 expected_message
) {
109 SendUnregister(provider_id
, pattern
);
110 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
112 dispatcher_host_
->ipc_sink()->ClearMessages();
115 void SendGetRegistration(int64 provider_id
, GURL document_url
) {
116 dispatcher_host_
->OnMessageReceived(
117 ServiceWorkerHostMsg_GetRegistration(
118 -1, -1, provider_id
, document_url
));
119 base::RunLoop().RunUntilIdle();
122 void GetRegistration(int64 provider_id
,
124 uint32 expected_message
) {
125 SendGetRegistration(provider_id
, document_url
);
126 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
128 dispatcher_host_
->ipc_sink()->ClearMessages();
131 ServiceWorkerProviderHost
* CreateServiceWorkerProviderHost(int provider_id
) {
132 return new ServiceWorkerProviderHost(kRenderProcessId
,
135 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
,
136 context()->AsWeakPtr(),
137 dispatcher_host_
.get());
141 TestBrowserThreadBundle browser_thread_bundle_
;
142 content::MockResourceContext resource_context_
;
143 scoped_ptr
<EmbeddedWorkerTestHelper
> helper_
;
144 scoped_refptr
<TestingServiceWorkerDispatcherHost
> dispatcher_host_
;
147 class ServiceWorkerTestContentBrowserClient
: public TestContentBrowserClient
{
149 ServiceWorkerTestContentBrowserClient() {}
150 bool AllowServiceWorker(const GURL
& scope
,
151 const GURL
& first_party
,
152 content::ResourceContext
* context
) override
{
157 TEST_F(ServiceWorkerDispatcherHostTest
,
158 Register_ContentSettingsDisallowsServiceWorker
) {
159 ServiceWorkerTestContentBrowserClient test_browser_client
;
160 ContentBrowserClient
* old_browser_client
=
161 SetBrowserClientForTesting(&test_browser_client
);
163 const int64 kProviderId
= 99; // Dummy value
164 scoped_ptr
<ServiceWorkerProviderHost
> host(
165 CreateServiceWorkerProviderHost(kProviderId
));
166 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
167 context()->AddProviderHost(host
.Pass());
169 Register(kProviderId
,
170 GURL("https://www.example.com/"),
171 GURL("https://www.example.com/bar"),
172 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
173 Unregister(kProviderId
,
174 GURL("https://www.example.com/"),
175 ServiceWorkerMsg_ServiceWorkerUnregistrationError::ID
);
176 GetRegistration(kProviderId
,
177 GURL("https://www.example.com/"),
178 ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID
);
180 SetBrowserClientForTesting(old_browser_client
);
183 TEST_F(ServiceWorkerDispatcherHostTest
, Register_HTTPS
) {
184 const int64 kProviderId
= 99; // Dummy value
185 scoped_ptr
<ServiceWorkerProviderHost
> host(
186 CreateServiceWorkerProviderHost(kProviderId
));
187 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
188 context()->AddProviderHost(host
.Pass());
190 Register(kProviderId
,
191 GURL("https://www.example.com/"),
192 GURL("https://www.example.com/bar"),
193 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
196 TEST_F(ServiceWorkerDispatcherHostTest
, Register_NonSecureTransportLocalhost
) {
197 const int64 kProviderId
= 99; // Dummy value
198 scoped_ptr
<ServiceWorkerProviderHost
> host(
199 CreateServiceWorkerProviderHost(kProviderId
));
200 host
->SetDocumentUrl(GURL("http://127.0.0.3:81/foo"));
201 context()->AddProviderHost(host
.Pass());
203 Register(kProviderId
,
204 GURL("http://127.0.0.3:81/bar"),
205 GURL("http://127.0.0.3:81/baz"),
206 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
209 TEST_F(ServiceWorkerDispatcherHostTest
, Register_InvalidScopeShouldFail
) {
210 const int64 kProviderId
= 99; // Dummy value
211 scoped_ptr
<ServiceWorkerProviderHost
> host(
212 CreateServiceWorkerProviderHost(kProviderId
));
213 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
214 context()->AddProviderHost(host
.Pass());
216 SendRegister(kProviderId
, GURL(""),
217 GURL("https://www.example.com/bar/hoge.js"));
218 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
221 TEST_F(ServiceWorkerDispatcherHostTest
, Register_InvalidScriptShouldFail
) {
222 const int64 kProviderId
= 99; // Dummy value
223 scoped_ptr
<ServiceWorkerProviderHost
> host(
224 CreateServiceWorkerProviderHost(kProviderId
));
225 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
226 context()->AddProviderHost(host
.Pass());
228 SendRegister(kProviderId
, GURL("https://www.example.com/bar/"), GURL(""));
229 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
232 TEST_F(ServiceWorkerDispatcherHostTest
, Register_NonSecureOriginShouldFail
) {
233 const int64 kProviderId
= 99; // Dummy value
234 scoped_ptr
<ServiceWorkerProviderHost
> host(
235 CreateServiceWorkerProviderHost(kProviderId
));
236 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
237 context()->AddProviderHost(host
.Pass());
239 SendRegister(kProviderId
,
240 GURL("http://www.example.com/"),
241 GURL("http://www.example.com/bar"));
242 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
245 TEST_F(ServiceWorkerDispatcherHostTest
, Register_CrossOriginShouldFail
) {
246 const int64 kProviderId
= 99; // Dummy value
247 scoped_ptr
<ServiceWorkerProviderHost
> host(
248 CreateServiceWorkerProviderHost(kProviderId
));
249 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
250 context()->AddProviderHost(host
.Pass());
252 // Script has a different host
253 SendRegister(kProviderId
,
254 GURL("https://www.example.com/"),
255 GURL("https://foo.example.com/bar"));
256 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
258 // Scope has a different host
259 SendRegister(kProviderId
,
260 GURL("https://foo.example.com/"),
261 GURL("https://www.example.com/bar"));
262 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
264 // Script has a different port
265 SendRegister(kProviderId
,
266 GURL("https://www.example.com/"),
267 GURL("https://www.example.com:8080/bar"));
268 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
270 // Scope has a different transport
271 SendRegister(kProviderId
,
272 GURL("wss://www.example.com/"),
273 GURL("https://www.example.com/bar"));
274 EXPECT_EQ(4, dispatcher_host_
->bad_messages_received_count_
);
276 // Script and scope have a different host but match each other
277 SendRegister(kProviderId
,
278 GURL("https://foo.example.com/"),
279 GURL("https://foo.example.com/bar"));
280 EXPECT_EQ(5, dispatcher_host_
->bad_messages_received_count_
);
282 // Script and scope URLs are invalid
283 SendRegister(kProviderId
,
286 EXPECT_EQ(6, dispatcher_host_
->bad_messages_received_count_
);
289 TEST_F(ServiceWorkerDispatcherHostTest
,
290 Register_FileSystemDocumentShouldFail
) {
291 const int64 kProviderId
= 99; // Dummy value
292 scoped_ptr
<ServiceWorkerProviderHost
> host(
293 CreateServiceWorkerProviderHost(kProviderId
));
294 host
->SetDocumentUrl(GURL("filesystem:https://www.example.com/temporary/a"));
295 context()->AddProviderHost(host
.Pass());
297 SendRegister(kProviderId
,
298 GURL("filesystem:https://www.example.com/temporary/"),
299 GURL("https://www.example.com/temporary/bar"));
300 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
302 SendRegister(kProviderId
,
303 GURL("https://www.example.com/temporary/"),
304 GURL("filesystem:https://www.example.com/temporary/bar"));
305 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
307 SendRegister(kProviderId
,
308 GURL("filesystem:https://www.example.com/temporary/"),
309 GURL("filesystem:https://www.example.com/temporary/bar"));
310 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
313 TEST_F(ServiceWorkerDispatcherHostTest
,
314 Register_FileSystemScriptOrScopeShouldFail
) {
315 const int64 kProviderId
= 99; // Dummy value
316 scoped_ptr
<ServiceWorkerProviderHost
> host(
317 CreateServiceWorkerProviderHost(kProviderId
));
318 host
->SetDocumentUrl(GURL("https://www.example.com/temporary/"));
319 context()->AddProviderHost(host
.Pass());
321 SendRegister(kProviderId
,
322 GURL("filesystem:https://www.example.com/temporary/"),
323 GURL("https://www.example.com/temporary/bar"));
324 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
326 SendRegister(kProviderId
,
327 GURL("https://www.example.com/temporary/"),
328 GURL("filesystem:https://www.example.com/temporary/bar"));
329 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
331 SendRegister(kProviderId
,
332 GURL("filesystem:https://www.example.com/temporary/"),
333 GURL("filesystem:https://www.example.com/temporary/bar"));
334 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
337 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_HTTPS
) {
338 const int64 kProviderId
= 99; // Dummy value
339 scoped_ptr
<ServiceWorkerProviderHost
> host(
340 CreateServiceWorkerProviderHost(kProviderId
));
341 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
342 context()->AddProviderHost(host
.Pass());
344 Unregister(kProviderId
,
345 GURL("https://www.example.com/"),
346 ServiceWorkerMsg_ServiceWorkerUnregistered::ID
);
349 TEST_F(ServiceWorkerDispatcherHostTest
,
350 Unregister_NotSecureTransportLocalhost
) {
351 const int64 kProviderId
= 99; // Dummy value
352 scoped_ptr
<ServiceWorkerProviderHost
> host(
353 CreateServiceWorkerProviderHost(kProviderId
));
354 host
->SetDocumentUrl(GURL("http://localhost/foo"));
355 context()->AddProviderHost(host
.Pass());
357 Unregister(kProviderId
,
358 GURL("http://localhost/"),
359 ServiceWorkerMsg_ServiceWorkerUnregistered::ID
);
362 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_CrossOriginShouldFail
) {
363 const int64 kProviderId
= 99; // Dummy value
364 scoped_ptr
<ServiceWorkerProviderHost
> host(
365 CreateServiceWorkerProviderHost(kProviderId
));
366 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
367 context()->AddProviderHost(host
.Pass());
369 SendUnregister(kProviderId
, GURL("https://foo.example.com/"));
370 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
373 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_InvalidScopeShouldFail
) {
374 const int64 kProviderId
= 99; // Dummy value
375 scoped_ptr
<ServiceWorkerProviderHost
> host(
376 CreateServiceWorkerProviderHost(kProviderId
));
377 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
378 context()->AddProviderHost(host
.Pass());
380 SendUnregister(kProviderId
, GURL(""));
381 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
384 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_NonSecureOriginShouldFail
) {
385 const int64 kProviderId
= 99; // Dummy value
386 scoped_ptr
<ServiceWorkerProviderHost
> host(
387 CreateServiceWorkerProviderHost(kProviderId
));
388 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
389 context()->AddProviderHost(host
.Pass());
391 SendUnregister(kProviderId
, GURL("http://www.example.com/"));
392 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
395 TEST_F(ServiceWorkerDispatcherHostTest
, EarlyContextDeletion
) {
396 helper_
->ShutdownContext();
398 // Let the shutdown reach the simulated IO thread.
399 base::RunLoop().RunUntilIdle();
404 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
407 TEST_F(ServiceWorkerDispatcherHostTest
, ProviderCreatedAndDestroyed
) {
408 const int kProviderId
= 1001; // Test with a value != kRenderProcessId.
410 dispatcher_host_
->OnMessageReceived(
411 ServiceWorkerHostMsg_ProviderCreated(
412 kProviderId
, MSG_ROUTING_NONE
,
413 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
));
414 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
416 // Two with the same ID should be seen as a bad message.
417 dispatcher_host_
->OnMessageReceived(
418 ServiceWorkerHostMsg_ProviderCreated(
419 kProviderId
, MSG_ROUTING_NONE
,
420 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
));
421 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
423 dispatcher_host_
->OnMessageReceived(
424 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
425 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
427 // Destroying an ID that does not exist warrants a bad message.
428 dispatcher_host_
->OnMessageReceived(
429 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
430 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
432 // Deletion of the dispatcher_host should cause providers for that
433 // process to get deleted as well.
434 dispatcher_host_
->OnMessageReceived(
435 ServiceWorkerHostMsg_ProviderCreated(
436 kProviderId
, MSG_ROUTING_NONE
,
437 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
));
438 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
439 EXPECT_TRUE(dispatcher_host_
->HasOneRef());
440 dispatcher_host_
= NULL
;
441 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
444 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_SameOrigin
) {
445 const int64 kProviderId
= 99; // Dummy value
446 scoped_ptr
<ServiceWorkerProviderHost
> host(
447 CreateServiceWorkerProviderHost(kProviderId
));
448 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
449 context()->AddProviderHost(host
.Pass());
451 GetRegistration(kProviderId
,
452 GURL("https://www.example.com/"),
453 ServiceWorkerMsg_DidGetRegistration::ID
);
456 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_CrossOriginShouldFail
) {
457 const int64 kProviderId
= 99; // Dummy value
458 scoped_ptr
<ServiceWorkerProviderHost
> host(
459 CreateServiceWorkerProviderHost(kProviderId
));
460 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
461 context()->AddProviderHost(host
.Pass());
463 SendGetRegistration(kProviderId
, GURL("https://foo.example.com/"));
464 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
467 TEST_F(ServiceWorkerDispatcherHostTest
,
468 GetRegistration_InvalidScopeShouldFail
) {
469 const int64 kProviderId
= 99; // Dummy value
470 scoped_ptr
<ServiceWorkerProviderHost
> host(
471 CreateServiceWorkerProviderHost(kProviderId
));
472 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
473 context()->AddProviderHost(host
.Pass());
475 SendGetRegistration(kProviderId
, GURL(""));
476 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
479 TEST_F(ServiceWorkerDispatcherHostTest
,
480 GetRegistration_NonSecureOriginShouldFail
) {
481 const int64 kProviderId
= 99; // Dummy value
482 scoped_ptr
<ServiceWorkerProviderHost
> host(
483 CreateServiceWorkerProviderHost(kProviderId
));
484 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
485 context()->AddProviderHost(host
.Pass());
487 SendGetRegistration(kProviderId
, GURL("http://www.example.com/"));
488 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
491 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_EarlyContextDeletion
) {
492 helper_
->ShutdownContext();
494 // Let the shutdown reach the simulated IO thread.
495 base::RunLoop().RunUntilIdle();
499 ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID
);
502 TEST_F(ServiceWorkerDispatcherHostTest
, CleanupOnRendererCrash
) {
503 // Add a provider and worker.
504 const int64 kProviderId
= 99; // Dummy value
505 dispatcher_host_
->OnMessageReceived(
506 ServiceWorkerHostMsg_ProviderCreated(
507 kProviderId
, MSG_ROUTING_NONE
,
508 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
));
510 GURL pattern
= GURL("http://www.example.com/");
511 scoped_refptr
<ServiceWorkerRegistration
> registration(
512 new ServiceWorkerRegistration(pattern
,
514 helper_
->context()->AsWeakPtr()));
515 scoped_refptr
<ServiceWorkerVersion
> version(
516 new ServiceWorkerVersion(registration
.get(),
517 GURL("http://www.example.com/service_worker.js"),
519 helper_
->context()->AsWeakPtr()));
520 helper_
->SimulateAddProcessToPattern(pattern
, kRenderProcessId
);
522 // Start up the worker.
524 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_ABORT
;
525 version
->StartWorker(base::Bind(&SaveStatusCallback
, &called
, &status
));
526 base::RunLoop().RunUntilIdle();
529 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
531 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
532 EXPECT_EQ(ServiceWorkerVersion::RUNNING
, version
->running_status());
534 // Simulate the render process crashing.
535 dispatcher_host_
->OnFilterRemoved();
537 // The dispatcher host should clean up the state from the process.
538 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
539 EXPECT_EQ(ServiceWorkerVersion::STOPPED
, version
->running_status());
541 // We should be able to hook up a new dispatcher host although the old object
542 // is not yet destroyed. This is what the browser does when reusing a crashed
544 scoped_refptr
<TestingServiceWorkerDispatcherHost
> new_dispatcher_host(
545 new TestingServiceWorkerDispatcherHost(kRenderProcessId
,
550 // To show the new dispatcher can operate, simulate provider creation. Since
551 // the old dispatcher cleaned up the old provider host, the new one won't
553 new_dispatcher_host
->OnMessageReceived(
554 ServiceWorkerHostMsg_ProviderCreated(
555 kProviderId
, MSG_ROUTING_NONE
,
556 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
));
557 EXPECT_EQ(0, new_dispatcher_host
->bad_messages_received_count_
);
560 } // namespace content