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 ServiceWorkerDispatcherHostTest
: public testing::Test
{
28 ServiceWorkerDispatcherHostTest()
29 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
) {}
31 virtual void SetUp() {
32 helper_
.reset(new EmbeddedWorkerTestHelper(kRenderProcessId
));
35 virtual void TearDown() {
39 ServiceWorkerContextCore
* context() { return helper_
->context(); }
40 ServiceWorkerContextWrapper
* context_wrapper() {
41 return helper_
->context_wrapper();
44 TestBrowserThreadBundle browser_thread_bundle_
;
45 scoped_ptr
<EmbeddedWorkerTestHelper
> helper_
;
49 class TestingServiceWorkerDispatcherHost
: public ServiceWorkerDispatcherHost
{
51 TestingServiceWorkerDispatcherHost(
53 ServiceWorkerContextWrapper
* context_wrapper
,
54 EmbeddedWorkerTestHelper
* helper
)
55 : ServiceWorkerDispatcherHost(process_id
, NULL
),
56 bad_messages_received_count_(0),
58 Init(context_wrapper
);
61 virtual bool Send(IPC::Message
* message
) OVERRIDE
{
62 return helper_
->Send(message
);
65 IPC::TestSink
* ipc_sink() { return helper_
->ipc_sink(); }
67 virtual void BadMessageReceived() OVERRIDE
{
68 ++bad_messages_received_count_
;
71 int bad_messages_received_count_
;
74 EmbeddedWorkerTestHelper
* helper_
;
75 virtual ~TestingServiceWorkerDispatcherHost() {}
78 TEST_F(ServiceWorkerDispatcherHostTest
, DisabledCausesError
) {
79 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(
80 switches::kEnableServiceWorker
));
82 scoped_refptr
<TestingServiceWorkerDispatcherHost
> dispatcher_host
=
83 new TestingServiceWorkerDispatcherHost(
84 kRenderProcessId
, context_wrapper(), helper_
.get());
87 dispatcher_host
->OnMessageReceived(
88 ServiceWorkerHostMsg_RegisterServiceWorker(-1, -1, -1, GURL(), GURL()),
92 // TODO(alecflett): Pump the message loop when this becomes async.
93 ASSERT_EQ(1UL, dispatcher_host
->ipc_sink()->message_count());
94 EXPECT_TRUE(dispatcher_host
->ipc_sink()->GetUniqueMessageMatching(
95 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
));
98 // Disable this since now we cache command-line switch in
99 // ServiceWorkerUtils::IsFeatureEnabled() and this could be flaky depending
100 // on testing order. (crbug.com/352581)
101 // TODO(kinuko): Just remove DisabledCausesError test above and enable
102 // this test when we remove the --enable-service-worker flag.
103 TEST_F(ServiceWorkerDispatcherHostTest
, DISABLED_Enabled
) {
104 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(
105 switches::kEnableServiceWorker
));
106 CommandLine::ForCurrentProcess()->AppendSwitch(
107 switches::kEnableServiceWorker
);
109 scoped_refptr
<TestingServiceWorkerDispatcherHost
> dispatcher_host
=
110 new TestingServiceWorkerDispatcherHost(
111 kRenderProcessId
, context_wrapper(), helper_
.get());
114 dispatcher_host
->OnMessageReceived(
115 ServiceWorkerHostMsg_RegisterServiceWorker(-1, -1, -1, GURL(), GURL()),
117 EXPECT_TRUE(handled
);
118 base::RunLoop().RunUntilIdle();
120 // TODO(alecflett): Pump the message loop when this becomes async.
121 ASSERT_EQ(2UL, dispatcher_host
->ipc_sink()->message_count());
122 EXPECT_TRUE(dispatcher_host
->ipc_sink()->GetUniqueMessageMatching(
123 EmbeddedWorkerMsg_StartWorker::ID
));
124 EXPECT_TRUE(dispatcher_host
->ipc_sink()->GetUniqueMessageMatching(
125 ServiceWorkerMsg_ServiceWorkerRegistered::ID
));
128 TEST_F(ServiceWorkerDispatcherHostTest
, EarlyContextDeletion
) {
129 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(
130 switches::kEnableServiceWorker
));
131 CommandLine::ForCurrentProcess()->AppendSwitch(
132 switches::kEnableServiceWorker
);
134 scoped_refptr
<TestingServiceWorkerDispatcherHost
> dispatcher_host
=
135 new TestingServiceWorkerDispatcherHost(
136 kRenderProcessId
, context_wrapper(), helper_
.get());
138 helper_
->ShutdownContext();
141 dispatcher_host
->OnMessageReceived(
142 ServiceWorkerHostMsg_RegisterServiceWorker(-1, -1, -1, GURL(), GURL()),
144 EXPECT_TRUE(handled
);
146 // TODO(alecflett): Pump the message loop when this becomes async.
147 ASSERT_EQ(1UL, dispatcher_host
->ipc_sink()->message_count());
148 EXPECT_TRUE(dispatcher_host
->ipc_sink()->GetUniqueMessageMatching(
149 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID
));
152 TEST_F(ServiceWorkerDispatcherHostTest
, ProviderCreatedAndDestroyed
) {
153 scoped_refptr
<TestingServiceWorkerDispatcherHost
> dispatcher_host
=
154 new TestingServiceWorkerDispatcherHost(
155 kRenderProcessId
, context_wrapper(), helper_
.get());
157 const int kProviderId
= 1001; // Test with a value != kRenderProcessId.
159 bool handled
= false;
160 dispatcher_host
->OnMessageReceived(
161 ServiceWorkerHostMsg_ProviderCreated(kProviderId
),
163 EXPECT_TRUE(handled
);
164 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
166 // Two with the same ID should be seen as a bad message.
168 dispatcher_host
->OnMessageReceived(
169 ServiceWorkerHostMsg_ProviderCreated(kProviderId
),
171 EXPECT_TRUE(handled
);
172 EXPECT_EQ(1, dispatcher_host
->bad_messages_received_count_
);
175 dispatcher_host
->OnMessageReceived(
176 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
),
178 EXPECT_TRUE(handled
);
179 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
181 // Destroying an ID that does not exist warrants a bad message.
183 dispatcher_host
->OnMessageReceived(
184 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId
),
186 EXPECT_TRUE(handled
);
187 EXPECT_EQ(2, dispatcher_host
->bad_messages_received_count_
);
189 // Deletion of the dispatcher_host should cause providers for that
190 // process to get deleted as well.
191 dispatcher_host
->OnMessageReceived(
192 ServiceWorkerHostMsg_ProviderCreated(kProviderId
),
194 EXPECT_TRUE(handled
);
195 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
196 EXPECT_TRUE(dispatcher_host
->HasOneRef());
197 dispatcher_host
= NULL
;
198 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId
, kProviderId
));
201 } // namespace content