OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/service_worker/service_worker_dispatcher_host.h" | 5 #include "content/browser/service_worker/service_worker_dispatcher_host.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "content/browser/browser_thread_impl.h" | 10 #include "content/browser/browser_thread_impl.h" |
11 #include "content/browser/service_worker/embedded_worker_instance.h" | 11 #include "content/browser/service_worker/embedded_worker_instance.h" |
12 #include "content/browser/service_worker/embedded_worker_registry.h" | 12 #include "content/browser/service_worker/embedded_worker_registry.h" |
13 #include "content/browser/service_worker/embedded_worker_test_helper.h" | 13 #include "content/browser/service_worker/embedded_worker_test_helper.h" |
14 #include "content/browser/service_worker/service_worker_context_core.h" | 14 #include "content/browser/service_worker/service_worker_context_core.h" |
15 #include "content/browser/service_worker/service_worker_context_wrapper.h" | 15 #include "content/browser/service_worker/service_worker_context_wrapper.h" |
| 16 #include "content/browser/service_worker/service_worker_test_utils.h" |
16 #include "content/common/service_worker/embedded_worker_messages.h" | 17 #include "content/common/service_worker/embedded_worker_messages.h" |
17 #include "content/common/service_worker/service_worker_messages.h" | 18 #include "content/common/service_worker/service_worker_messages.h" |
18 #include "content/public/common/content_switches.h" | 19 #include "content/public/common/content_switches.h" |
19 #include "content/public/test/mock_resource_context.h" | 20 #include "content/public/test/mock_resource_context.h" |
20 #include "content/public/test/test_browser_thread_bundle.h" | 21 #include "content/public/test/test_browser_thread_bundle.h" |
| 22 #include "content/public/test/test_utils.h" |
21 #include "content/test/test_content_browser_client.h" | 23 #include "content/test/test_content_browser_client.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
23 | 25 |
24 namespace content { | 26 namespace content { |
25 | 27 |
26 namespace { | 28 namespace { |
27 | 29 |
28 static void SaveStatusCallback(bool* called, | 30 static void SaveStatusCallback(bool* called, |
29 ServiceWorkerStatusCode* out, | 31 ServiceWorkerStatusCode* out, |
30 ServiceWorkerStatusCode status) { | 32 ServiceWorkerStatusCode status) { |
31 *called = true; | 33 *called = true; |
32 *out = status; | 34 *out = status; |
33 } | 35 } |
34 | 36 |
| 37 class IPCWaiter : public IPC::Listener { |
| 38 public: |
| 39 explicit IPCWaiter(uint32 expected_message) |
| 40 : expected_message_(expected_message), runner_(new MessageLoopRunner) {} |
| 41 |
| 42 void Wait() { runner_->Run(); } |
| 43 |
| 44 bool OnMessageReceived(const IPC::Message& message) override { |
| 45 if (message.type() == expected_message_) |
| 46 runner_->Quit(); |
| 47 return false; |
| 48 } |
| 49 |
| 50 private: |
| 51 uint32 expected_message_; |
| 52 scoped_refptr<MessageLoopRunner> runner_; |
| 53 }; |
35 } | 54 } |
36 | 55 |
37 static const int kRenderProcessId = 1; | |
38 static const int kRenderFrameId = 1; | 56 static const int kRenderFrameId = 1; |
39 | 57 |
40 class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost { | 58 class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost { |
41 public: | 59 public: |
42 TestingServiceWorkerDispatcherHost( | 60 TestingServiceWorkerDispatcherHost( |
43 int process_id, | 61 int process_id, |
44 ServiceWorkerContextWrapper* context_wrapper, | 62 ServiceWorkerContextWrapper* context_wrapper, |
45 ResourceContext* resource_context, | 63 ResourceContext* resource_context, |
46 EmbeddedWorkerTestHelper* helper) | 64 EmbeddedWorkerTestHelper* helper) |
47 : ServiceWorkerDispatcherHost(process_id, NULL, resource_context), | 65 : ServiceWorkerDispatcherHost(process_id, NULL, resource_context), |
(...skipping 14 matching lines...) Expand all Loading... |
62 EmbeddedWorkerTestHelper* helper_; | 80 EmbeddedWorkerTestHelper* helper_; |
63 ~TestingServiceWorkerDispatcherHost() override {} | 81 ~TestingServiceWorkerDispatcherHost() override {} |
64 }; | 82 }; |
65 | 83 |
66 class ServiceWorkerDispatcherHostTest : public testing::Test { | 84 class ServiceWorkerDispatcherHostTest : public testing::Test { |
67 protected: | 85 protected: |
68 ServiceWorkerDispatcherHostTest() | 86 ServiceWorkerDispatcherHostTest() |
69 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} | 87 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} |
70 | 88 |
71 void SetUp() override { | 89 void SetUp() override { |
72 helper_.reset( | 90 helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath())); |
73 new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId)); | |
74 dispatcher_host_ = new TestingServiceWorkerDispatcherHost( | 91 dispatcher_host_ = new TestingServiceWorkerDispatcherHost( |
75 kRenderProcessId, context_wrapper(), &resource_context_, helper_.get()); | 92 helper_->mock_render_process_id(), context_wrapper(), |
| 93 &resource_context_, helper_.get()); |
76 } | 94 } |
77 | 95 |
78 void TearDown() override { helper_.reset(); } | 96 void TearDown() override { helper_.reset(); } |
79 | 97 |
80 ServiceWorkerContextCore* context() { return helper_->context(); } | 98 ServiceWorkerContextCore* context() { return helper_->context(); } |
81 ServiceWorkerContextWrapper* context_wrapper() { | 99 ServiceWorkerContextWrapper* context_wrapper() { |
82 return helper_->context_wrapper(); | 100 return helper_->context_wrapper(); |
83 } | 101 } |
84 | 102 |
85 void SendRegister(int64 provider_id, GURL pattern, GURL worker_url) { | 103 void SendRegister(int64 provider_id, GURL pattern, GURL worker_url) { |
86 dispatcher_host_->OnMessageReceived( | 104 dispatcher_host_->OnMessageReceived( |
87 ServiceWorkerHostMsg_RegisterServiceWorker( | 105 ServiceWorkerHostMsg_RegisterServiceWorker( |
88 -1, -1, provider_id, pattern, worker_url)); | 106 -1, -1, provider_id, pattern, worker_url)); |
89 base::RunLoop().RunUntilIdle(); | 107 base::RunLoop().RunUntilIdle(); |
90 } | 108 } |
91 | 109 |
92 void Register(int64 provider_id, | 110 void Register(int64 provider_id, |
93 GURL pattern, | 111 GURL pattern, |
94 GURL worker_url, | 112 GURL worker_url, |
95 uint32 expected_message) { | 113 uint32 expected_message) { |
| 114 IPCWaiter waiter(expected_message); |
| 115 dispatcher_host_->ipc_sink()->AddFilter(&waiter); |
96 SendRegister(provider_id, pattern, worker_url); | 116 SendRegister(provider_id, pattern, worker_url); |
| 117 waiter.Wait(); |
97 EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( | 118 EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( |
98 expected_message)); | 119 expected_message)); |
99 dispatcher_host_->ipc_sink()->ClearMessages(); | 120 dispatcher_host_->ipc_sink()->ClearMessages(); |
| 121 dispatcher_host_->ipc_sink()->RemoveFilter(&waiter); |
100 } | 122 } |
101 | 123 |
102 void SendUnregister(int64 provider_id, int64 registration_id) { | 124 void SendUnregister(int64 provider_id, int64 registration_id) { |
103 dispatcher_host_->OnMessageReceived( | 125 dispatcher_host_->OnMessageReceived( |
104 ServiceWorkerHostMsg_UnregisterServiceWorker(-1, -1, provider_id, | 126 ServiceWorkerHostMsg_UnregisterServiceWorker(-1, -1, provider_id, |
105 registration_id)); | 127 registration_id)); |
106 base::RunLoop().RunUntilIdle(); | 128 base::RunLoop().RunUntilIdle(); |
107 } | 129 } |
108 | 130 |
109 void Unregister(int64 provider_id, | 131 void Unregister(int64 provider_id, |
(...skipping 29 matching lines...) Expand all Loading... |
139 | 161 |
140 void GetRegistrations(int64 provider_id, uint32 expected_message) { | 162 void GetRegistrations(int64 provider_id, uint32 expected_message) { |
141 SendGetRegistrations(provider_id); | 163 SendGetRegistrations(provider_id); |
142 EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( | 164 EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( |
143 expected_message)); | 165 expected_message)); |
144 dispatcher_host_->ipc_sink()->ClearMessages(); | 166 dispatcher_host_->ipc_sink()->ClearMessages(); |
145 } | 167 } |
146 | 168 |
147 ServiceWorkerProviderHost* CreateServiceWorkerProviderHost(int provider_id) { | 169 ServiceWorkerProviderHost* CreateServiceWorkerProviderHost(int provider_id) { |
148 return new ServiceWorkerProviderHost( | 170 return new ServiceWorkerProviderHost( |
149 kRenderProcessId, kRenderFrameId, provider_id, | 171 helper_->mock_render_process_id(), kRenderFrameId, provider_id, |
150 SERVICE_WORKER_PROVIDER_FOR_WINDOW, context()->AsWeakPtr(), | 172 SERVICE_WORKER_PROVIDER_FOR_WINDOW, context()->AsWeakPtr(), |
151 dispatcher_host_.get()); | 173 dispatcher_host_.get()); |
152 } | 174 } |
153 | 175 |
154 | 176 |
155 TestBrowserThreadBundle browser_thread_bundle_; | 177 TestBrowserThreadBundle browser_thread_bundle_; |
156 content::MockResourceContext resource_context_; | 178 content::MockResourceContext resource_context_; |
157 scoped_ptr<EmbeddedWorkerTestHelper> helper_; | 179 scoped_ptr<EmbeddedWorkerTestHelper> helper_; |
158 scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host_; | 180 scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host_; |
159 }; | 181 }; |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 GURL(), | 390 GURL(), |
369 GURL(), | 391 GURL(), |
370 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); | 392 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); |
371 } | 393 } |
372 | 394 |
373 TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) { | 395 TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) { |
374 const int kProviderId = 1001; // Test with a value != kRenderProcessId. | 396 const int kProviderId = 1001; // Test with a value != kRenderProcessId. |
375 | 397 |
376 dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated( | 398 dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated( |
377 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW)); | 399 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW)); |
378 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId, kProviderId)); | 400 EXPECT_TRUE(context()->GetProviderHost(helper_->mock_render_process_id(), |
| 401 kProviderId)); |
379 | 402 |
380 // Two with the same ID should be seen as a bad message. | 403 // Two with the same ID should be seen as a bad message. |
381 dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated( | 404 dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated( |
382 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW)); | 405 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW)); |
383 EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); | 406 EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); |
384 | 407 |
385 dispatcher_host_->OnMessageReceived( | 408 dispatcher_host_->OnMessageReceived( |
386 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId)); | 409 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId)); |
387 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId, kProviderId)); | 410 EXPECT_FALSE(context()->GetProviderHost(helper_->mock_render_process_id(), |
| 411 kProviderId)); |
388 | 412 |
389 // Destroying an ID that does not exist warrants a bad message. | 413 // Destroying an ID that does not exist warrants a bad message. |
390 dispatcher_host_->OnMessageReceived( | 414 dispatcher_host_->OnMessageReceived( |
391 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId)); | 415 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId)); |
392 EXPECT_EQ(2, dispatcher_host_->bad_messages_received_count_); | 416 EXPECT_EQ(2, dispatcher_host_->bad_messages_received_count_); |
393 | 417 |
394 // Deletion of the dispatcher_host should cause providers for that | 418 // Deletion of the dispatcher_host should cause providers for that |
395 // process to get deleted as well. | 419 // process to get deleted as well. |
396 dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated( | 420 dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated( |
397 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW)); | 421 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW)); |
398 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId, kProviderId)); | 422 EXPECT_TRUE(context()->GetProviderHost(helper_->mock_render_process_id(), |
| 423 kProviderId)); |
399 EXPECT_TRUE(dispatcher_host_->HasOneRef()); | 424 EXPECT_TRUE(dispatcher_host_->HasOneRef()); |
400 dispatcher_host_ = NULL; | 425 dispatcher_host_ = NULL; |
401 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId, kProviderId)); | 426 EXPECT_FALSE(context()->GetProviderHost(helper_->mock_render_process_id(), |
| 427 kProviderId)); |
402 } | 428 } |
403 | 429 |
404 TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_SameOrigin) { | 430 TEST_F(ServiceWorkerDispatcherHostTest, GetRegistration_SameOrigin) { |
405 const int64 kProviderId = 99; // Dummy value | 431 const int64 kProviderId = 99; // Dummy value |
406 scoped_ptr<ServiceWorkerProviderHost> host( | 432 scoped_ptr<ServiceWorkerProviderHost> host( |
407 CreateServiceWorkerProviderHost(kProviderId)); | 433 CreateServiceWorkerProviderHost(kProviderId)); |
408 host->SetDocumentUrl(GURL("https://www.example.com/foo")); | 434 host->SetDocumentUrl(GURL("https://www.example.com/foo")); |
409 context()->AddProviderHost(host.Pass()); | 435 context()->AddProviderHost(host.Pass()); |
410 | 436 |
411 GetRegistration(kProviderId, | 437 GetRegistration(kProviderId, |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 bool called = false; | 543 bool called = false; |
518 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_ABORT; | 544 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_ABORT; |
519 helper_->context()->storage()->StoreRegistration( | 545 helper_->context()->storage()->StoreRegistration( |
520 registration.get(), | 546 registration.get(), |
521 version.get(), | 547 version.get(), |
522 base::Bind(&SaveStatusCallback, &called, &status)); | 548 base::Bind(&SaveStatusCallback, &called, &status)); |
523 base::RunLoop().RunUntilIdle(); | 549 base::RunLoop().RunUntilIdle(); |
524 EXPECT_TRUE(called); | 550 EXPECT_TRUE(called); |
525 ASSERT_EQ(SERVICE_WORKER_OK, status); | 551 ASSERT_EQ(SERVICE_WORKER_OK, status); |
526 | 552 |
527 helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId); | 553 helper_->SimulateAddProcessToPattern(pattern, |
| 554 helper_->mock_render_process_id()); |
528 | 555 |
529 // Start up the worker. | 556 // Start up the worker. |
530 status = SERVICE_WORKER_ERROR_ABORT; | 557 status = SERVICE_WORKER_ERROR_ABORT; |
531 version->StartWorker(base::Bind(&SaveStatusCallback, &called, &status)); | 558 scoped_refptr<MessageLoopRunner> runner(new MessageLoopRunner); |
532 base::RunLoop().RunUntilIdle(); | 559 version->StartWorker( |
| 560 CreateReceiverOnCurrentThread(&status, runner->QuitClosure())); |
| 561 runner->Run(); |
533 | 562 |
534 EXPECT_TRUE(called); | |
535 EXPECT_EQ(SERVICE_WORKER_OK, status); | 563 EXPECT_EQ(SERVICE_WORKER_OK, status); |
536 | 564 |
537 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId, kProviderId)); | 565 EXPECT_TRUE(context()->GetProviderHost(helper_->mock_render_process_id(), |
| 566 kProviderId)); |
538 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version->running_status()); | 567 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version->running_status()); |
539 | 568 |
540 // Simulate the render process crashing. | 569 // Simulate the render process crashing. |
541 dispatcher_host_->OnFilterRemoved(); | 570 dispatcher_host_->OnFilterRemoved(); |
542 | 571 |
543 // The dispatcher host should clean up the state from the process. | 572 // The dispatcher host should clean up the state from the process. |
544 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId, kProviderId)); | 573 EXPECT_FALSE(context()->GetProviderHost(helper_->mock_render_process_id(), |
| 574 kProviderId)); |
545 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version->running_status()); | 575 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version->running_status()); |
546 | 576 |
547 // We should be able to hook up a new dispatcher host although the old object | 577 // We should be able to hook up a new dispatcher host although the old object |
548 // is not yet destroyed. This is what the browser does when reusing a crashed | 578 // is not yet destroyed. This is what the browser does when reusing a crashed |
549 // render process. | 579 // render process. |
550 scoped_refptr<TestingServiceWorkerDispatcherHost> new_dispatcher_host( | 580 scoped_refptr<TestingServiceWorkerDispatcherHost> new_dispatcher_host( |
551 new TestingServiceWorkerDispatcherHost(kRenderProcessId, | 581 new TestingServiceWorkerDispatcherHost( |
552 context_wrapper(), | 582 helper_->mock_render_process_id(), context_wrapper(), |
553 &resource_context_, | 583 &resource_context_, helper_.get())); |
554 helper_.get())); | |
555 | 584 |
556 // To show the new dispatcher can operate, simulate provider creation. Since | 585 // To show the new dispatcher can operate, simulate provider creation. Since |
557 // the old dispatcher cleaned up the old provider host, the new one won't | 586 // the old dispatcher cleaned up the old provider host, the new one won't |
558 // complain. | 587 // complain. |
559 new_dispatcher_host->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated( | 588 new_dispatcher_host->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated( |
560 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW)); | 589 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW)); |
561 EXPECT_EQ(0, new_dispatcher_host->bad_messages_received_count_); | 590 EXPECT_EQ(0, new_dispatcher_host->bad_messages_received_count_); |
562 } | 591 } |
563 | 592 |
564 } // namespace content | 593 } // namespace content |
OLD | NEW |