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 <stdint.h> | 7 #include <stdint.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
13 #include "content/browser/browser_thread_impl.h" | 13 #include "content/browser/browser_thread_impl.h" |
| 14 #include "content/browser/message_port_service.h" |
14 #include "content/browser/service_worker/embedded_worker_instance.h" | 15 #include "content/browser/service_worker/embedded_worker_instance.h" |
15 #include "content/browser/service_worker/embedded_worker_registry.h" | 16 #include "content/browser/service_worker/embedded_worker_registry.h" |
16 #include "content/browser/service_worker/embedded_worker_test_helper.h" | 17 #include "content/browser/service_worker/embedded_worker_test_helper.h" |
17 #include "content/browser/service_worker/service_worker_context_core.h" | 18 #include "content/browser/service_worker/service_worker_context_core.h" |
18 #include "content/browser/service_worker/service_worker_context_wrapper.h" | 19 #include "content/browser/service_worker/service_worker_context_wrapper.h" |
| 20 #include "content/browser/service_worker/service_worker_handle.h" |
19 #include "content/common/service_worker/embedded_worker_messages.h" | 21 #include "content/common/service_worker/embedded_worker_messages.h" |
20 #include "content/common/service_worker/service_worker_messages.h" | 22 #include "content/common/service_worker/service_worker_messages.h" |
21 #include "content/public/common/content_switches.h" | 23 #include "content/public/common/content_switches.h" |
22 #include "content/public/test/mock_resource_context.h" | 24 #include "content/public/test/mock_resource_context.h" |
23 #include "content/public/test/test_browser_thread_bundle.h" | 25 #include "content/public/test/test_browser_thread_bundle.h" |
24 #include "content/test/test_content_browser_client.h" | 26 #include "content/test/test_content_browser_client.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
26 | 28 |
27 namespace content { | 29 namespace content { |
28 | 30 |
29 namespace { | 31 namespace { |
30 | 32 |
31 static void SaveStatusCallback(bool* called, | 33 static void SaveStatusCallback(bool* called, |
32 ServiceWorkerStatusCode* out, | 34 ServiceWorkerStatusCode* out, |
33 ServiceWorkerStatusCode status) { | 35 ServiceWorkerStatusCode status) { |
34 *called = true; | 36 *called = true; |
35 *out = status; | 37 *out = status; |
36 } | 38 } |
37 | 39 |
| 40 void SetUpDummyMessagePort(std::vector<TransferredMessagePort>* ports) { |
| 41 int port_id = -1; |
| 42 MessagePortService::GetInstance()->Create(MSG_ROUTING_NONE, nullptr, |
| 43 &port_id); |
| 44 TransferredMessagePort dummy_port; |
| 45 dummy_port.id = port_id; |
| 46 ports->push_back(dummy_port); |
38 } | 47 } |
39 | 48 |
| 49 } // namespace |
| 50 |
40 static const int kRenderFrameId = 1; | 51 static const int kRenderFrameId = 1; |
41 | 52 |
42 class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost { | 53 class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost { |
43 public: | 54 public: |
44 TestingServiceWorkerDispatcherHost( | 55 TestingServiceWorkerDispatcherHost( |
45 int process_id, | 56 int process_id, |
46 ServiceWorkerContextWrapper* context_wrapper, | 57 ServiceWorkerContextWrapper* context_wrapper, |
47 ResourceContext* resource_context, | 58 ResourceContext* resource_context, |
48 EmbeddedWorkerTestHelper* helper) | 59 EmbeddedWorkerTestHelper* helper) |
49 : ServiceWorkerDispatcherHost(process_id, NULL, resource_context), | 60 : ServiceWorkerDispatcherHost(process_id, NULL, resource_context), |
50 bad_messages_received_count_(0), | 61 bad_messages_received_count_(0), |
51 helper_(helper) { | 62 helper_(helper) { |
52 Init(context_wrapper); | 63 Init(context_wrapper); |
53 } | 64 } |
54 | 65 |
55 bool Send(IPC::Message* message) override { return helper_->Send(message); } | 66 bool Send(IPC::Message* message) override { return helper_->Send(message); } |
56 | 67 |
57 IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); } | 68 IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); } |
58 | 69 |
59 void ShutdownForBadMessage() override { ++bad_messages_received_count_; } | 70 void ShutdownForBadMessage() override { ++bad_messages_received_count_; } |
60 | 71 |
61 int bad_messages_received_count_; | 72 int bad_messages_received_count_; |
62 | 73 |
63 protected: | 74 protected: |
64 EmbeddedWorkerTestHelper* helper_; | 75 EmbeddedWorkerTestHelper* helper_; |
65 ~TestingServiceWorkerDispatcherHost() override {} | 76 ~TestingServiceWorkerDispatcherHost() override {} |
66 }; | 77 }; |
67 | 78 |
| 79 class FailToStartWorkerTestHelper : public EmbeddedWorkerTestHelper { |
| 80 public: |
| 81 FailToStartWorkerTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {} |
| 82 |
| 83 void OnStartWorker(int embedded_worker_id, |
| 84 int64_t service_worker_version_id, |
| 85 const GURL& scope, |
| 86 const GURL& script_url, |
| 87 bool pause_after_download) override { |
| 88 EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id); |
| 89 registry()->OnWorkerStopped(worker->process_id(), embedded_worker_id); |
| 90 } |
| 91 }; |
| 92 |
68 class ServiceWorkerDispatcherHostTest : public testing::Test { | 93 class ServiceWorkerDispatcherHostTest : public testing::Test { |
69 protected: | 94 protected: |
70 ServiceWorkerDispatcherHostTest() | 95 ServiceWorkerDispatcherHostTest() |
71 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} | 96 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} |
72 | 97 |
73 void SetUp() override { | 98 void SetUp() override { |
74 helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath())); | 99 Initialize(make_scoped_ptr(new EmbeddedWorkerTestHelper(base::FilePath()))); |
75 dispatcher_host_ = new TestingServiceWorkerDispatcherHost( | |
76 helper_->mock_render_process_id(), context_wrapper(), | |
77 &resource_context_, helper_.get()); | |
78 } | 100 } |
79 | 101 |
80 void TearDown() override { helper_.reset(); } | 102 void TearDown() override { |
| 103 version_ = nullptr; |
| 104 registration_ = nullptr; |
| 105 helper_.reset(); |
| 106 } |
81 | 107 |
82 ServiceWorkerContextCore* context() { return helper_->context(); } | 108 ServiceWorkerContextCore* context() { return helper_->context(); } |
83 ServiceWorkerContextWrapper* context_wrapper() { | 109 ServiceWorkerContextWrapper* context_wrapper() { |
84 return helper_->context_wrapper(); | 110 return helper_->context_wrapper(); |
85 } | 111 } |
86 | 112 |
| 113 void Initialize(scoped_ptr<EmbeddedWorkerTestHelper> helper) { |
| 114 helper_.reset(helper.release()); |
| 115 dispatcher_host_ = new TestingServiceWorkerDispatcherHost( |
| 116 helper_->mock_render_process_id(), context_wrapper(), |
| 117 &resource_context_, helper_.get()); |
| 118 } |
| 119 |
| 120 void SetUpRegistration(const GURL& scope, const GURL& script_url) { |
| 121 registration_ = new ServiceWorkerRegistration( |
| 122 scope, 1L, helper_->context()->AsWeakPtr()); |
| 123 version_ = new ServiceWorkerVersion(registration_.get(), script_url, 1L, |
| 124 helper_->context()->AsWeakPtr()); |
| 125 std::vector<ServiceWorkerDatabase::ResourceRecord> records; |
| 126 records.push_back( |
| 127 ServiceWorkerDatabase::ResourceRecord(10, version_->script_url(), 100)); |
| 128 version_->script_cache_map()->SetResources(records); |
| 129 |
| 130 // Make the registration findable via storage functions. |
| 131 helper_->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing)); |
| 132 base::RunLoop().RunUntilIdle(); |
| 133 bool called = false; |
| 134 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; |
| 135 helper_->context()->storage()->StoreRegistration( |
| 136 registration_.get(), version_.get(), |
| 137 base::Bind(&SaveStatusCallback, &called, &status)); |
| 138 base::RunLoop().RunUntilIdle(); |
| 139 EXPECT_TRUE(called); |
| 140 EXPECT_EQ(SERVICE_WORKER_OK, status); |
| 141 } |
| 142 |
| 143 void SendProviderCreated(ServiceWorkerProviderType type, |
| 144 const GURL& pattern) { |
| 145 const int64_t kProviderId = 99; |
| 146 dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated( |
| 147 kProviderId, MSG_ROUTING_NONE, type)); |
| 148 helper_->SimulateAddProcessToPattern(pattern, |
| 149 helper_->mock_render_process_id()); |
| 150 provider_host_ = context()->GetProviderHost( |
| 151 helper_->mock_render_process_id(), kProviderId); |
| 152 } |
| 153 |
87 void SendRegister(int64_t provider_id, GURL pattern, GURL worker_url) { | 154 void SendRegister(int64_t provider_id, GURL pattern, GURL worker_url) { |
88 dispatcher_host_->OnMessageReceived( | 155 dispatcher_host_->OnMessageReceived( |
89 ServiceWorkerHostMsg_RegisterServiceWorker( | 156 ServiceWorkerHostMsg_RegisterServiceWorker( |
90 -1, -1, provider_id, pattern, worker_url)); | 157 -1, -1, provider_id, pattern, worker_url)); |
91 base::RunLoop().RunUntilIdle(); | 158 base::RunLoop().RunUntilIdle(); |
92 } | 159 } |
93 | 160 |
94 void Register(int64_t provider_id, | 161 void Register(int64_t provider_id, |
95 GURL pattern, | 162 GURL pattern, |
96 GURL worker_url, | 163 GURL worker_url, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 base::RunLoop().RunUntilIdle(); | 206 base::RunLoop().RunUntilIdle(); |
140 } | 207 } |
141 | 208 |
142 void GetRegistrations(int64_t provider_id, uint32_t expected_message) { | 209 void GetRegistrations(int64_t provider_id, uint32_t expected_message) { |
143 SendGetRegistrations(provider_id); | 210 SendGetRegistrations(provider_id); |
144 EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( | 211 EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( |
145 expected_message)); | 212 expected_message)); |
146 dispatcher_host_->ipc_sink()->ClearMessages(); | 213 dispatcher_host_->ipc_sink()->ClearMessages(); |
147 } | 214 } |
148 | 215 |
| 216 void DispatchExtendableMessageEvent( |
| 217 scoped_refptr<ServiceWorkerVersion> worker, |
| 218 const base::string16& message, |
| 219 const url::Origin& source_origin, |
| 220 const std::vector<TransferredMessagePort>& sent_message_ports, |
| 221 ServiceWorkerProviderHost* sender_provider_host, |
| 222 const ServiceWorkerDispatcherHost::StatusCallback& callback) { |
| 223 dispatcher_host_->DispatchExtendableMessageEvent( |
| 224 std::move(worker), message, source_origin, sent_message_ports, |
| 225 sender_provider_host, callback); |
| 226 } |
| 227 |
149 ServiceWorkerProviderHost* CreateServiceWorkerProviderHost(int provider_id) { | 228 ServiceWorkerProviderHost* CreateServiceWorkerProviderHost(int provider_id) { |
150 return new ServiceWorkerProviderHost( | 229 return new ServiceWorkerProviderHost( |
151 helper_->mock_render_process_id(), kRenderFrameId, provider_id, | 230 helper_->mock_render_process_id(), kRenderFrameId, provider_id, |
152 SERVICE_WORKER_PROVIDER_FOR_WINDOW, context()->AsWeakPtr(), | 231 SERVICE_WORKER_PROVIDER_FOR_WINDOW, context()->AsWeakPtr(), |
153 dispatcher_host_.get()); | 232 dispatcher_host_.get()); |
154 } | 233 } |
155 | 234 |
156 | |
157 TestBrowserThreadBundle browser_thread_bundle_; | 235 TestBrowserThreadBundle browser_thread_bundle_; |
158 content::MockResourceContext resource_context_; | 236 content::MockResourceContext resource_context_; |
159 scoped_ptr<EmbeddedWorkerTestHelper> helper_; | 237 scoped_ptr<EmbeddedWorkerTestHelper> helper_; |
160 scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host_; | 238 scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host_; |
| 239 scoped_refptr<ServiceWorkerRegistration> registration_; |
| 240 scoped_refptr<ServiceWorkerVersion> version_; |
| 241 ServiceWorkerProviderHost* provider_host_; |
161 }; | 242 }; |
162 | 243 |
163 class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient { | 244 class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient { |
164 public: | 245 public: |
165 ServiceWorkerTestContentBrowserClient() {} | 246 ServiceWorkerTestContentBrowserClient() {} |
166 bool AllowServiceWorker(const GURL& scope, | 247 bool AllowServiceWorker(const GURL& scope, |
167 const GURL& first_party, | 248 const GURL& first_party, |
168 content::ResourceContext* context, | 249 content::ResourceContext* context, |
169 int render_process_id, | 250 int render_process_id, |
170 int render_frame_id) override { | 251 int render_frame_id) override { |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 TEST_F(ServiceWorkerDispatcherHostTest, GetRegistrations_EarlyContextDeletion) { | 600 TEST_F(ServiceWorkerDispatcherHostTest, GetRegistrations_EarlyContextDeletion) { |
520 helper_->ShutdownContext(); | 601 helper_->ShutdownContext(); |
521 | 602 |
522 // Let the shutdown reach the simulated IO thread. | 603 // Let the shutdown reach the simulated IO thread. |
523 base::RunLoop().RunUntilIdle(); | 604 base::RunLoop().RunUntilIdle(); |
524 | 605 |
525 GetRegistrations(-1, ServiceWorkerMsg_ServiceWorkerGetRegistrationsError::ID); | 606 GetRegistrations(-1, ServiceWorkerMsg_ServiceWorkerGetRegistrationsError::ID); |
526 } | 607 } |
527 | 608 |
528 TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) { | 609 TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) { |
| 610 GURL pattern = GURL("http://www.example.com/"); |
| 611 GURL script_url = GURL("http://www.example.com/service_worker.js"); |
529 int process_id = helper_->mock_render_process_id(); | 612 int process_id = helper_->mock_render_process_id(); |
530 | 613 |
531 // Add a provider and worker. | 614 SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_WINDOW, pattern); |
532 const int64_t kProviderId = 99; // Dummy value | 615 SetUpRegistration(pattern, script_url); |
533 dispatcher_host_->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated( | 616 int64_t provider_id = provider_host_->provider_id(); |
534 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW)); | |
535 | 617 |
536 GURL pattern = GURL("http://www.example.com/"); | 618 // Start up the worker. |
537 scoped_refptr<ServiceWorkerRegistration> registration( | |
538 new ServiceWorkerRegistration(pattern, | |
539 1L, | |
540 helper_->context()->AsWeakPtr())); | |
541 scoped_refptr<ServiceWorkerVersion> version( | |
542 new ServiceWorkerVersion(registration.get(), | |
543 GURL("http://www.example.com/service_worker.js"), | |
544 1L, | |
545 helper_->context()->AsWeakPtr())); | |
546 std::vector<ServiceWorkerDatabase::ResourceRecord> records; | |
547 records.push_back( | |
548 ServiceWorkerDatabase::ResourceRecord(10, version->script_url(), 100)); | |
549 version->script_cache_map()->SetResources(records); | |
550 | |
551 // Make the registration findable via storage functions. | |
552 helper_->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing)); | |
553 base::RunLoop().RunUntilIdle(); | |
554 bool called = false; | 619 bool called = false; |
555 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_ABORT; | 620 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_ABORT; |
556 helper_->context()->storage()->StoreRegistration( | 621 version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN, |
557 registration.get(), | 622 base::Bind(&SaveStatusCallback, &called, &status)); |
558 version.get(), | |
559 base::Bind(&SaveStatusCallback, &called, &status)); | |
560 base::RunLoop().RunUntilIdle(); | |
561 EXPECT_TRUE(called); | |
562 ASSERT_EQ(SERVICE_WORKER_OK, status); | |
563 | |
564 helper_->SimulateAddProcessToPattern(pattern, process_id); | |
565 | |
566 // Start up the worker. | |
567 status = SERVICE_WORKER_ERROR_ABORT; | |
568 version->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN, | |
569 base::Bind(&SaveStatusCallback, &called, &status)); | |
570 base::RunLoop().RunUntilIdle(); | 623 base::RunLoop().RunUntilIdle(); |
571 | 624 |
572 EXPECT_TRUE(called); | 625 EXPECT_TRUE(called); |
573 EXPECT_EQ(SERVICE_WORKER_OK, status); | 626 EXPECT_EQ(SERVICE_WORKER_OK, status); |
574 | 627 |
575 EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId)); | 628 EXPECT_TRUE(context()->GetProviderHost(process_id, provider_id)); |
576 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version->running_status()); | 629 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); |
577 | 630 |
578 // Simulate the render process crashing. | 631 // Simulate the render process crashing. |
579 dispatcher_host_->OnFilterRemoved(); | 632 dispatcher_host_->OnFilterRemoved(); |
580 | 633 |
581 // The dispatcher host should clean up the state from the process. | 634 // The dispatcher host should clean up the state from the process. |
582 EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId)); | 635 EXPECT_FALSE(context()->GetProviderHost(process_id, provider_id)); |
583 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version->running_status()); | 636 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status()); |
584 | 637 |
585 // We should be able to hook up a new dispatcher host although the old object | 638 // We should be able to hook up a new dispatcher host although the old object |
586 // is not yet destroyed. This is what the browser does when reusing a crashed | 639 // is not yet destroyed. This is what the browser does when reusing a crashed |
587 // render process. | 640 // render process. |
588 scoped_refptr<TestingServiceWorkerDispatcherHost> new_dispatcher_host( | 641 scoped_refptr<TestingServiceWorkerDispatcherHost> new_dispatcher_host( |
589 new TestingServiceWorkerDispatcherHost( | 642 new TestingServiceWorkerDispatcherHost( |
590 process_id, context_wrapper(), &resource_context_, helper_.get())); | 643 process_id, context_wrapper(), &resource_context_, helper_.get())); |
591 | 644 |
592 // To show the new dispatcher can operate, simulate provider creation. Since | 645 // To show the new dispatcher can operate, simulate provider creation. Since |
593 // the old dispatcher cleaned up the old provider host, the new one won't | 646 // the old dispatcher cleaned up the old provider host, the new one won't |
594 // complain. | 647 // complain. |
595 new_dispatcher_host->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated( | 648 new_dispatcher_host->OnMessageReceived(ServiceWorkerHostMsg_ProviderCreated( |
596 kProviderId, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW)); | 649 provider_id, MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_WINDOW)); |
597 EXPECT_EQ(0, new_dispatcher_host->bad_messages_received_count_); | 650 EXPECT_EQ(0, new_dispatcher_host->bad_messages_received_count_); |
598 } | 651 } |
599 | 652 |
| 653 TEST_F(ServiceWorkerDispatcherHostTest, DispatchExtendableMessageEvent) { |
| 654 GURL pattern = GURL("http://www.example.com/"); |
| 655 GURL script_url = GURL("http://www.example.com/service_worker.js"); |
| 656 |
| 657 SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, pattern); |
| 658 SetUpRegistration(pattern, script_url); |
| 659 |
| 660 // Set the running hosted version so that we can retrieve a valid service |
| 661 // worker object information for the source attribute of the message event. |
| 662 provider_host_->running_hosted_version_ = version_; |
| 663 |
| 664 // Set aside the initial refcount of the worker handle. |
| 665 provider_host_->GetOrCreateServiceWorkerHandle(version_.get()); |
| 666 ServiceWorkerHandle* sender_worker_handle = |
| 667 dispatcher_host_->FindServiceWorkerHandle(provider_host_->provider_id(), |
| 668 version_->version_id()); |
| 669 const int ref_count = sender_worker_handle->ref_count(); |
| 670 |
| 671 // Dispatch ExtendableMessageEvent. |
| 672 std::vector<TransferredMessagePort> ports; |
| 673 SetUpDummyMessagePort(&ports); |
| 674 bool called = false; |
| 675 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; |
| 676 DispatchExtendableMessageEvent( |
| 677 version_, base::string16(), url::Origin(version_->scope().GetOrigin()), |
| 678 ports, provider_host_, base::Bind(&SaveStatusCallback, &called, &status)); |
| 679 for (TransferredMessagePort port : ports) |
| 680 EXPECT_TRUE(MessagePortService::GetInstance()->AreMessagesHeld(port.id)); |
| 681 EXPECT_EQ(ref_count + 1, sender_worker_handle->ref_count()); |
| 682 base::RunLoop().RunUntilIdle(); |
| 683 EXPECT_TRUE(called); |
| 684 EXPECT_EQ(SERVICE_WORKER_OK, status); |
| 685 |
| 686 // Messages should be held until ports are created at the destination. |
| 687 for (TransferredMessagePort port : ports) |
| 688 EXPECT_TRUE(MessagePortService::GetInstance()->AreMessagesHeld(port.id)); |
| 689 |
| 690 EXPECT_EQ(ref_count + 1, sender_worker_handle->ref_count()); |
| 691 } |
| 692 |
| 693 TEST_F(ServiceWorkerDispatcherHostTest, DispatchExtendableMessageEvent_Fail) { |
| 694 GURL pattern = GURL("http://www.example.com/"); |
| 695 GURL script_url = GURL("http://www.example.com/service_worker.js"); |
| 696 |
| 697 Initialize(make_scoped_ptr(new FailToStartWorkerTestHelper)); |
| 698 SendProviderCreated(SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, pattern); |
| 699 SetUpRegistration(pattern, script_url); |
| 700 |
| 701 // Set the running hosted version so that we can retrieve a valid service |
| 702 // worker object information for the source attribute of the message event. |
| 703 provider_host_->running_hosted_version_ = version_; |
| 704 |
| 705 // Set aside the initial refcount of the worker handle. |
| 706 provider_host_->GetOrCreateServiceWorkerHandle(version_.get()); |
| 707 ServiceWorkerHandle* sender_worker_handle = |
| 708 dispatcher_host_->FindServiceWorkerHandle(provider_host_->provider_id(), |
| 709 version_->version_id()); |
| 710 const int ref_count = sender_worker_handle->ref_count(); |
| 711 |
| 712 // Try to dispatch ExtendableMessageEvent. This should fail to start the |
| 713 // worker and to dispatch the event. |
| 714 std::vector<TransferredMessagePort> ports; |
| 715 SetUpDummyMessagePort(&ports); |
| 716 bool called = false; |
| 717 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; |
| 718 DispatchExtendableMessageEvent( |
| 719 version_, base::string16(), url::Origin(version_->scope().GetOrigin()), |
| 720 ports, provider_host_, base::Bind(&SaveStatusCallback, &called, &status)); |
| 721 for (TransferredMessagePort port : ports) |
| 722 EXPECT_TRUE(MessagePortService::GetInstance()->AreMessagesHeld(port.id)); |
| 723 EXPECT_EQ(ref_count + 1, sender_worker_handle->ref_count()); |
| 724 base::RunLoop().RunUntilIdle(); |
| 725 EXPECT_TRUE(called); |
| 726 EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status); |
| 727 |
| 728 // The error callback should clean up the ports and handle. |
| 729 for (TransferredMessagePort port : ports) |
| 730 EXPECT_FALSE(MessagePortService::GetInstance()->AreMessagesHeld(port.id)); |
| 731 EXPECT_EQ(ref_count, sender_worker_handle->ref_count()); |
| 732 } |
| 733 |
600 } // namespace content | 734 } // namespace content |
OLD | NEW |