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/test_browser_thread_bundle.h"
20 #include "testing/gtest/include/gtest/gtest.h"
24 static const int kRenderProcessId
= 1;
26 class TestingServiceWorkerDispatcherHost
: public ServiceWorkerDispatcherHost
{
28 TestingServiceWorkerDispatcherHost(
30 ServiceWorkerContextWrapper
* context_wrapper
,
31 EmbeddedWorkerTestHelper
* helper
)
32 : ServiceWorkerDispatcherHost(process_id
, NULL
),
33 bad_messages_received_count_(0),
35 Init(context_wrapper
);
38 virtual bool Send(IPC::Message
* message
) OVERRIDE
{
39 return helper_
->Send(message
);
42 IPC::TestSink
* ipc_sink() { return helper_
->ipc_sink(); }
44 virtual void BadMessageReceived() OVERRIDE
{
45 ++bad_messages_received_count_
;
48 int bad_messages_received_count_
;
51 EmbeddedWorkerTestHelper
* helper_
;
52 virtual ~TestingServiceWorkerDispatcherHost() {}
55 class ServiceWorkerDispatcherHostTest
: public testing::Test
{
57 ServiceWorkerDispatcherHostTest()
58 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
) {}
60 virtual void SetUp() {
61 helper_
.reset(new EmbeddedWorkerTestHelper(kRenderProcessId
));
62 dispatcher_host_
= new TestingServiceWorkerDispatcherHost(
63 kRenderProcessId
, context_wrapper(), helper_
.get());
66 virtual void TearDown() {
70 ServiceWorkerContextCore
* context() { return helper_
->context(); }
71 ServiceWorkerContextWrapper
* context_wrapper() {
72 return helper_
->context_wrapper();
75 void SendRegister(int64 provider_id
, GURL pattern
, GURL worker_url
) {
76 dispatcher_host_
->OnMessageReceived(
77 ServiceWorkerHostMsg_RegisterServiceWorker(
78 -1, -1, provider_id
, pattern
, worker_url
));
79 base::RunLoop().RunUntilIdle();
82 void Register(int64 provider_id
,
85 uint32 expected_message
) {
86 SendRegister(provider_id
, pattern
, worker_url
);
87 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
89 dispatcher_host_
->ipc_sink()->ClearMessages();
92 void SendUnregister(int64 provider_id
, GURL pattern
) {
93 dispatcher_host_
->OnMessageReceived(
94 ServiceWorkerHostMsg_UnregisterServiceWorker(
95 -1, -1, provider_id
, pattern
));
96 base::RunLoop().RunUntilIdle();
99 void Unregister(int64 provider_id
, GURL pattern
, uint32 expected_message
) {
100 SendUnregister(provider_id
, pattern
);
101 EXPECT_TRUE(dispatcher_host_
->ipc_sink()->GetUniqueMessageMatching(
103 dispatcher_host_
->ipc_sink()->ClearMessages();
106 TestBrowserThreadBundle browser_thread_bundle_
;
107 scoped_ptr
<EmbeddedWorkerTestHelper
> helper_
;
108 scoped_refptr
<TestingServiceWorkerDispatcherHost
> dispatcher_host_
;
111 TEST_F(ServiceWorkerDispatcherHostTest
, Register_SameOrigin
) {
112 const int64 kProviderId
= 99; // Dummy value
113 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
114 kRenderProcessId
, kProviderId
, context()->AsWeakPtr(), NULL
));
115 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
116 base::WeakPtr
<ServiceWorkerProviderHost
> provider_host
= host
->AsWeakPtr();
117 context()->AddProviderHost(host
.Pass());
119 Register(kProviderId
,
120 GURL("https://www.example.com/"),
121 GURL("https://www.example.com/bar"),
122 ServiceWorkerMsg_ServiceWorkerRegistered::ID
);
125 TEST_F(ServiceWorkerDispatcherHostTest
, Register_CrossOrigin
) {
126 const int64 kProviderId
= 99; // Dummy value
127 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
128 kRenderProcessId
, kProviderId
, context()->AsWeakPtr(), NULL
));
129 host
->SetDocumentUrl(GURL("https://www.example.com/foo"));
130 base::WeakPtr
<ServiceWorkerProviderHost
> provider_host
= host
->AsWeakPtr();
131 context()->AddProviderHost(host
.Pass());
133 // Script has a different host
134 SendRegister(kProviderId
,
135 GURL("https://www.example.com/"),
136 GURL("https://foo.example.com/bar"));
137 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
139 // Scope has a different host
140 SendRegister(kProviderId
,
141 GURL("https://foo.example.com/"),
142 GURL("https://www.example.com/bar"));
143 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
145 // Script has a different port
146 SendRegister(kProviderId
,
147 GURL("https://www.example.com/"),
148 GURL("https://www.example.com:8080/bar"));
149 EXPECT_EQ(3, dispatcher_host_
->bad_messages_received_count_
);
151 // Scope has a different transport
152 SendRegister(kProviderId
,
153 GURL("wss://www.example.com/"),
154 GURL("https://www.example.com/bar"));
155 EXPECT_EQ(4, dispatcher_host_
->bad_messages_received_count_
);
157 // Script and scope have different hosts
158 SendRegister(kProviderId
,
159 GURL("https://foo.example.com/"),
160 GURL("https://foo.example.com/bar"));
161 EXPECT_EQ(5, dispatcher_host_
->bad_messages_received_count_
);
163 // Script and scope URLs are invalid
164 SendRegister(kProviderId
,
167 EXPECT_EQ(6, dispatcher_host_
->bad_messages_received_count_
);
170 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_SameOrigin
) {
171 const int64 kProviderId
= 99; // Dummy value
172 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
173 kRenderProcessId
, kProviderId
, context()->AsWeakPtr(), NULL
));
174 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
175 base::WeakPtr
<ServiceWorkerProviderHost
> provider_host
= host
->AsWeakPtr();
176 context()->AddProviderHost(host
.Pass());
178 Unregister(kProviderId
,
179 GURL("http://www.example.com/"),
180 ServiceWorkerMsg_ServiceWorkerUnregistered::ID
);
183 TEST_F(ServiceWorkerDispatcherHostTest
, Unregister_CrossOrigin
) {
184 const int64 kProviderId
= 99; // Dummy value
185 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
186 kRenderProcessId
, kProviderId
, context()->AsWeakPtr(), NULL
));
187 host
->SetDocumentUrl(GURL("http://www.example.com/foo"));
188 base::WeakPtr
<ServiceWorkerProviderHost
> provider_host
= host
->AsWeakPtr();
189 context()->AddProviderHost(host
.Pass());
191 SendUnregister(kProviderId
, GURL("http://foo.example.com/"));
192 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
195 TEST_F(ServiceWorkerDispatcherHostTest
, EarlyContextDeletion
) {
196 helper_
->ShutdownContext();
198 // Let the shutdown reach the simulated IO thread.
199 base::RunLoop().RunUntilIdle();
204 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
);
207 TEST_F(ServiceWorkerDispatcherHostTest
, ProviderCreatedAndDestroyed
) {
208 const int kProviderId
= 1001; // Test with a value != kRenderProcessId.
210 dispatcher_host_
->OnMessageReceived(
211 ServiceWorkerHostMsg_ProviderCreated(kProviderId
));
212 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
214 // Two with the same ID should be seen as a bad message.
215 dispatcher_host_
->OnMessageReceived(
216 ServiceWorkerHostMsg_ProviderCreated(kProviderId
));
217 EXPECT_EQ(1, dispatcher_host_
->bad_messages_received_count_
);
219 dispatcher_host_
->OnMessageReceived(
220 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
221 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
223 // Destroying an ID that does not exist warrants a bad message.
224 dispatcher_host_
->OnMessageReceived(
225 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
));
226 EXPECT_EQ(2, dispatcher_host_
->bad_messages_received_count_
);
228 // Deletion of the dispatcher_host should cause providers for that
229 // process to get deleted as well.
230 dispatcher_host_
->OnMessageReceived(
231 ServiceWorkerHostMsg_ProviderCreated(kProviderId
));
232 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
233 EXPECT_TRUE(dispatcher_host_
->HasOneRef());
234 dispatcher_host_
= NULL
;
235 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
238 } // namespace content