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
, int64 registration_id
) {
103 dispatcher_host_
->OnMessageReceived(
104 ServiceWorkerHostMsg_UnregisterServiceWorker(-1, -1, provider_id
,
106 base::RunLoop().RunUntilIdle();
109 void Unregister(int64 provider_id
,
110 int64 registration_id
,
111 uint32 expected_message
) {
112 SendUnregister(provider_id
, registration_id
);
113 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
115 dispatcher_host_
->ipc_sink()->ClearMessages();
118 void SendGetRegistration(int64 provider_id
, GURL document_url
) {
119 dispatcher_host_
->OnMessageReceived(
120 ServiceWorkerHostMsg_GetRegistration(
121 -1, -1, provider_id
, document_url
));
122 base::RunLoop().RunUntilIdle();
125 void GetRegistration(int64 provider_id
,
127 uint32 expected_message
) {
128 SendGetRegistration(provider_id
, document_url
);
129 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
131 dispatcher_host_
->ipc_sink()->ClearMessages();
134 void SendGetRegistrations(int64 provider_id
) {
135 dispatcher_host_
->OnMessageReceived(
136 ServiceWorkerHostMsg_GetRegistrations(-1, -1, provider_id
));
137 base::RunLoop().RunUntilIdle();
140 void GetRegistrations(int64 provider_id
, uint32 expected_message
) {
141 SendGetRegistrations(provider_id
);
142 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
144 dispatcher_host_
->ipc_sink()->ClearMessages();
147 ServiceWorkerProviderHost
* CreateServiceWorkerProviderHost(int provider_id
) {
148 return new ServiceWorkerProviderHost(
149 kRenderProcessId
, kRenderFrameId
, provider_id
,
150 SERVICE_WORKER_PROVIDER_FOR_WINDOW
, context()->AsWeakPtr(),
151 dispatcher_host_
.get());
155 TestBrowserThreadBundle browser_thread_bundle_
;
156 content::MockResourceContext resource_context_
;
157 scoped_ptr
<EmbeddedWorkerTestHelper
> helper_
;
158 scoped_refptr
<TestingServiceWorkerDispatcherHost
> dispatcher_host_
;
161 class ServiceWorkerTestContentBrowserClient
: public TestContentBrowserClient
{
163 ServiceWorkerTestContentBrowserClient() {}
164 bool AllowServiceWorker(const GURL
& scope
,
165 const GURL
& first_party
,
166 content::ResourceContext
* context
,
167 int render_process_id
,
168 int render_frame_id
) override
{
173 TEST_F(ServiceWorkerDispatcherHostTest
,
174 Register_ContentSettingsDisallowsServiceWorker
) {
175 ServiceWorkerTestContentBrowserClient test_browser_client
;
176 ContentBrowserClient
* old_browser_client
=
177 SetBrowserClientForTesting(&test_browser_client
);
179 const int64 kProviderId
= 99; // Dummy value
180 scoped_ptr
<ServiceWorkerProviderHost
> host(
181 CreateServiceWorkerProviderHost(kProviderId
));
182 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
183 context()->AddProviderHost(host
.Pass());
185 Register(kProviderId
,
186 GURL("https://www.example.com/"),
187 GURL("https://www.example.com/bar"),
188 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
189 GetRegistration(kProviderId
,
190 GURL("https://www.example.com/"),
191 ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID
);
192 GetRegistrations(kProviderId
,
193 ServiceWorkerMsg_ServiceWorkerGetRegistrationsError::ID
);
195 // Add a registration into a live registration map so that Unregister() can
197 const int64 kRegistrationId
= 999; // Dummy value
198 scoped_refptr
<ServiceWorkerRegistration
> registration(
199 new ServiceWorkerRegistration(GURL("https://www.example.com/"),
200 kRegistrationId
, context()->AsWeakPtr()));
201 Unregister(kProviderId
, kRegistrationId
,
202 ServiceWorkerMsg_ServiceWorkerUnregistrationError::ID
);
204 SetBrowserClientForTesting(old_browser_client
);
207 TEST_F(ServiceWorkerDispatcherHostTest
, Register_HTTPS
) {
208 const int64 kProviderId
= 99; // Dummy value
209 scoped_ptr
<ServiceWorkerProviderHost
> host(
210 CreateServiceWorkerProviderHost(kProviderId
));
211 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
212 context()->AddProviderHost(host
.Pass());
214 Register(kProviderId
,
215 GURL("https://www.example.com/"),
216 GURL("https://www.example.com/bar"),
217 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
220 TEST_F(ServiceWorkerDispatcherHostTest
, Register_NonSecureTransportLocalhost
) {
221 const int64 kProviderId
= 99; // Dummy value
222 scoped_ptr
<ServiceWorkerProviderHost
> host(
223 CreateServiceWorkerProviderHost(kProviderId
));
224 host
->SetDocumentUrl(GURL("http://127.0.0.3:81/foo"));
225 context()->AddProviderHost(host
.Pass());
227 Register(kProviderId
,
228 GURL("http://127.0.0.3:81/bar"),
229 GURL("http://127.0.0.3:81/baz"),
230 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
233 TEST_F(ServiceWorkerDispatcherHostTest
, Register_InvalidScopeShouldFail
) {
234 const int64 kProviderId
= 99; // Dummy value
235 scoped_ptr
<ServiceWorkerProviderHost
> host(
236 CreateServiceWorkerProviderHost(kProviderId
));
237 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
238 context()->AddProviderHost(host
.Pass());
240 SendRegister(kProviderId
, GURL(""),
241 GURL("https://www.example.com/bar/hoge.js"));
242 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
245 TEST_F(ServiceWorkerDispatcherHostTest
, Register_InvalidScriptShouldFail
) {
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 SendRegister(kProviderId
, GURL("https://www.example.com/bar/"), GURL(""));
253 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
256 TEST_F(ServiceWorkerDispatcherHostTest
, Register_NonSecureOriginShouldFail
) {
257 const int64 kProviderId
= 99; // Dummy value
258 scoped_ptr
<ServiceWorkerProviderHost
> host(
259 CreateServiceWorkerProviderHost(kProviderId
));
260 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
261 context()->AddProviderHost(host
.Pass());
263 SendRegister(kProviderId
,
264 GURL("http://www.example.com/"),
265 GURL("http://www.example.com/bar"));
266 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
269 TEST_F(ServiceWorkerDispatcherHostTest
, Register_CrossOriginShouldFail
) {
270 const int64 kProviderId
= 99; // Dummy value
271 scoped_ptr
<ServiceWorkerProviderHost
> host(
272 CreateServiceWorkerProviderHost(kProviderId
));
273 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
274 context()->AddProviderHost(host
.Pass());
276 // Script has a different host
277 SendRegister(kProviderId
,
278 GURL("https://www.example.com/"),
279 GURL("https://foo.example.com/bar"));
280 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
282 // Scope has a different host
283 SendRegister(kProviderId
,
284 GURL("https://foo.example.com/"),
285 GURL("https://www.example.com/bar"));
286 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
288 // Script has a different port
289 SendRegister(kProviderId
,
290 GURL("https://www.example.com/"),
291 GURL("https://www.example.com:8080/bar"));
292 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
294 // Scope has a different transport
295 SendRegister(kProviderId
,
296 GURL("wss://www.example.com/"),
297 GURL("https://www.example.com/bar"));
298 EXPECT_EQ(4, dispatcher_host_
->bad_messages_received_count_
);
300 // Script and scope have a different host but match each other
301 SendRegister(kProviderId
,
302 GURL("https://foo.example.com/"),
303 GURL("https://foo.example.com/bar"));
304 EXPECT_EQ(5, dispatcher_host_
->bad_messages_received_count_
);
306 // Script and scope URLs are invalid
307 SendRegister(kProviderId
,
310 EXPECT_EQ(6, dispatcher_host_
->bad_messages_received_count_
);
313 TEST_F(ServiceWorkerDispatcherHostTest
, Register_BadCharactersShouldFail
) {
314 const int64 kProviderId
= 99; // Dummy value
315 scoped_ptr
<ServiceWorkerProviderHost
> host(
316 CreateServiceWorkerProviderHost(kProviderId
));
317 host
->SetDocumentUrl(GURL("https://www.example.com/"));
318 context()->AddProviderHost(host
.Pass());
320 SendRegister(kProviderId
, GURL("https://www.example.com/%2f"),
321 GURL("https://www.example.com/"));
322 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
324 SendRegister(kProviderId
, GURL("https://www.example.com/%2F"),
325 GURL("https://www.example.com/"));
326 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
328 SendRegister(kProviderId
, GURL("https://www.example.com/"),
329 GURL("https://www.example.com/%2f"));
330 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
332 SendRegister(kProviderId
, GURL("https://www.example.com/%5c"),
333 GURL("https://www.example.com/"));
334 EXPECT_EQ(4, dispatcher_host_
->bad_messages_received_count_
);
336 SendRegister(kProviderId
, GURL("https://www.example.com/"),
337 GURL("https://www.example.com/%5c"));
338 EXPECT_EQ(5, dispatcher_host_
->bad_messages_received_count_
);
340 SendRegister(kProviderId
, GURL("https://www.example.com/"),
341 GURL("https://www.example.com/%5C"));
342 EXPECT_EQ(6, dispatcher_host_
->bad_messages_received_count_
);
345 TEST_F(ServiceWorkerDispatcherHostTest
,
346 Register_FileSystemDocumentShouldFail
) {
347 const int64 kProviderId
= 99; // Dummy value
348 scoped_ptr
<ServiceWorkerProviderHost
> host(
349 CreateServiceWorkerProviderHost(kProviderId
));
350 host
->SetDocumentUrl(GURL("filesystem:https://www.example.com/temporary/a"));
351 context()->AddProviderHost(host
.Pass());
353 SendRegister(kProviderId
,
354 GURL("filesystem:https://www.example.com/temporary/"),
355 GURL("https://www.example.com/temporary/bar"));
356 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
358 SendRegister(kProviderId
,
359 GURL("https://www.example.com/temporary/"),
360 GURL("filesystem:https://www.example.com/temporary/bar"));
361 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
363 SendRegister(kProviderId
,
364 GURL("filesystem:https://www.example.com/temporary/"),
365 GURL("filesystem:https://www.example.com/temporary/bar"));
366 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
369 TEST_F(ServiceWorkerDispatcherHostTest
,
370 Register_FileSystemScriptOrScopeShouldFail
) {
371 const int64 kProviderId
= 99; // Dummy value
372 scoped_ptr
<ServiceWorkerProviderHost
> host(
373 CreateServiceWorkerProviderHost(kProviderId
));
374 host
->SetDocumentUrl(GURL("https://www.example.com/temporary/"));
375 context()->AddProviderHost(host
.Pass());
377 SendRegister(kProviderId
,
378 GURL("filesystem:https://www.example.com/temporary/"),
379 GURL("https://www.example.com/temporary/bar"));
380 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
382 SendRegister(kProviderId
,
383 GURL("https://www.example.com/temporary/"),
384 GURL("filesystem:https://www.example.com/temporary/bar"));
385 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
387 SendRegister(kProviderId
,
388 GURL("filesystem:https://www.example.com/temporary/"),
389 GURL("filesystem:https://www.example.com/temporary/bar"));
390 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
393 TEST_F(ServiceWorkerDispatcherHostTest
, EarlyContextDeletion
) {
394 helper_
->ShutdownContext();
396 // Let the shutdown reach the simulated IO thread.
397 base::RunLoop().RunUntilIdle();
402 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
405 TEST_F(ServiceWorkerDispatcherHostTest
, ProviderCreatedAndDestroyed
) {
406 const int kProviderId
= 1001; // Test with a value != kRenderProcessId.
408 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
409 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
410 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
412 // Two with the same ID should be seen as a bad message.
413 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
414 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
415 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
417 dispatcher_host_
->OnMessageReceived(
418 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
419 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
421 // Destroying an ID that does not exist warrants a bad message.
422 dispatcher_host_
->OnMessageReceived(
423 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
424 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
426 // Deletion of the dispatcher_host should cause providers for that
427 // process to get deleted as well.
428 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
429 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
430 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
431 EXPECT_TRUE(dispatcher_host_
->HasOneRef());
432 dispatcher_host_
= NULL
;
433 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
436 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_SameOrigin
) {
437 const int64 kProviderId
= 99; // Dummy value
438 scoped_ptr
<ServiceWorkerProviderHost
> host(
439 CreateServiceWorkerProviderHost(kProviderId
));
440 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
441 context()->AddProviderHost(host
.Pass());
443 GetRegistration(kProviderId
,
444 GURL("https://www.example.com/"),
445 ServiceWorkerMsg_DidGetRegistration::ID
);
448 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_CrossOriginShouldFail
) {
449 const int64 kProviderId
= 99; // Dummy value
450 scoped_ptr
<ServiceWorkerProviderHost
> host(
451 CreateServiceWorkerProviderHost(kProviderId
));
452 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
453 context()->AddProviderHost(host
.Pass());
455 SendGetRegistration(kProviderId
, GURL("https://foo.example.com/"));
456 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
459 TEST_F(ServiceWorkerDispatcherHostTest
,
460 GetRegistration_InvalidScopeShouldFail
) {
461 const int64 kProviderId
= 99; // Dummy value
462 scoped_ptr
<ServiceWorkerProviderHost
> host(
463 CreateServiceWorkerProviderHost(kProviderId
));
464 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
465 context()->AddProviderHost(host
.Pass());
467 SendGetRegistration(kProviderId
, GURL(""));
468 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
471 TEST_F(ServiceWorkerDispatcherHostTest
,
472 GetRegistration_NonSecureOriginShouldFail
) {
473 const int64 kProviderId
= 99; // Dummy value
474 scoped_ptr
<ServiceWorkerProviderHost
> host(
475 CreateServiceWorkerProviderHost(kProviderId
));
476 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
477 context()->AddProviderHost(host
.Pass());
479 SendGetRegistration(kProviderId
, GURL("http://www.example.com/"));
480 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
483 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistration_EarlyContextDeletion
) {
484 helper_
->ShutdownContext();
486 // Let the shutdown reach the simulated IO thread.
487 base::RunLoop().RunUntilIdle();
491 ServiceWorkerMsg_ServiceWorkerGetRegistrationError::ID
);
494 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistrations_SecureOrigin
) {
495 const int64 kProviderId
= 99; // Dummy value
496 scoped_ptr
<ServiceWorkerProviderHost
> host(
497 CreateServiceWorkerProviderHost(kProviderId
));
498 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
499 context()->AddProviderHost(host
.Pass());
501 GetRegistrations(kProviderId
, ServiceWorkerMsg_DidGetRegistrations::ID
);
504 TEST_F(ServiceWorkerDispatcherHostTest
,
505 GetRegistrations_NonSecureOriginShouldFail
) {
506 const int64 kProviderId
= 99; // Dummy value
507 scoped_ptr
<ServiceWorkerProviderHost
> host(
508 CreateServiceWorkerProviderHost(kProviderId
));
509 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
510 context()->AddProviderHost(host
.Pass());
512 SendGetRegistrations(kProviderId
);
513 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
516 TEST_F(ServiceWorkerDispatcherHostTest
, GetRegistrations_EarlyContextDeletion
) {
517 helper_
->ShutdownContext();
519 // Let the shutdown reach the simulated IO thread.
520 base::RunLoop().RunUntilIdle();
522 GetRegistrations(-1, ServiceWorkerMsg_ServiceWorkerGetRegistrationsError::ID
);
525 TEST_F(ServiceWorkerDispatcherHostTest
, CleanupOnRendererCrash
) {
526 // Add a provider and worker.
527 const int64 kProviderId
= 99; // Dummy value
528 dispatcher_host_
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
529 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
531 GURL pattern
= GURL("http://www.example.com/");
532 scoped_refptr
<ServiceWorkerRegistration
> registration(
533 new ServiceWorkerRegistration(pattern
,
535 helper_
->context()->AsWeakPtr()));
536 scoped_refptr
<ServiceWorkerVersion
> version(
537 new ServiceWorkerVersion(registration
.get(),
538 GURL("http://www.example.com/service_worker.js"),
540 helper_
->context()->AsWeakPtr()));
541 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records
;
543 ServiceWorkerDatabase::ResourceRecord(10, version
->script_url(), 100));
544 version
->script_cache_map()->SetResources(records
);
546 // Make the registration findable via storage functions.
547 helper_
->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing
));
548 base::RunLoop().RunUntilIdle();
550 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_ABORT
;
551 helper_
->context()->storage()->StoreRegistration(
554 base::Bind(&SaveStatusCallback
, &called
, &status
));
555 base::RunLoop().RunUntilIdle();
557 ASSERT_EQ(SERVICE_WORKER_OK
, status
);
559 helper_
->SimulateAddProcessToPattern(pattern
, kRenderProcessId
);
561 // Start up the worker.
562 status
= SERVICE_WORKER_ERROR_ABORT
;
563 version
->StartWorker(base::Bind(&SaveStatusCallback
, &called
, &status
));
564 base::RunLoop().RunUntilIdle();
567 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
569 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
570 EXPECT_EQ(ServiceWorkerVersion::RUNNING
, version
->running_status());
572 // Simulate the render process crashing.
573 dispatcher_host_
->OnFilterRemoved();
575 // The dispatcher host should clean up the state from the process.
576 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
577 EXPECT_EQ(ServiceWorkerVersion::STOPPED
, version
->running_status());
579 // We should be able to hook up a new dispatcher host although the old object
580 // is not yet destroyed. This is what the browser does when reusing a crashed
582 scoped_refptr
<TestingServiceWorkerDispatcherHost
> new_dispatcher_host(
583 new TestingServiceWorkerDispatcherHost(kRenderProcessId
,
588 // To show the new dispatcher can operate, simulate provider creation. Since
589 // the old dispatcher cleaned up the old provider host, the new one won't
591 new_dispatcher_host
->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated(
592 kProviderId
, MSG_ROUTING_NONE
, SERVICE_WORKER_PROVIDER_FOR_WINDOW
));
593 EXPECT_EQ(0, new_dispatcher_host
->bad_messages_received_count_
);
596 } // namespace content