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 context_wrapper_ = new ServiceWorkerContextWrapper;
33 context_wrapper_->Init(base::FilePath(), NULL);
34 helper_.reset(new EmbeddedWorkerTestHelper(context(), kRenderProcessId));
37 virtual void TearDown() {
39 if (context_wrapper_) {
40 context_wrapper_->Shutdown();
41 context_wrapper_ = NULL;
45 ServiceWorkerContextCore* context() { return context_wrapper_->context(); }
47 TestBrowserThreadBundle browser_thread_bundle_;
48 scoped_refptr<ServiceWorkerContextWrapper> context_wrapper_;
49 scoped_ptr<EmbeddedWorkerTestHelper> helper_;
53 class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost {
55 TestingServiceWorkerDispatcherHost(
57 ServiceWorkerContextWrapper* context_wrapper,
58 EmbeddedWorkerTestHelper* helper)
59 : ServiceWorkerDispatcherHost(process_id),
60 bad_messages_received_count_(0),
62 Init(context_wrapper);
65 virtual bool Send(IPC::Message* message) OVERRIDE {
66 return helper_->Send(message);
69 IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); }
71 virtual void BadMessageReceived() OVERRIDE {
72 ++bad_messages_received_count_;
75 int bad_messages_received_count_;
78 EmbeddedWorkerTestHelper* helper_;
79 virtual ~TestingServiceWorkerDispatcherHost() {}
82 TEST_F(ServiceWorkerDispatcherHostTest, DisabledCausesError) {
83 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(
84 switches::kEnableServiceWorker));
86 scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host =
87 new TestingServiceWorkerDispatcherHost(
88 kRenderProcessId, context_wrapper_.get(), helper_.get());
91 dispatcher_host->OnMessageReceived(
92 ServiceWorkerHostMsg_RegisterServiceWorker(-1, -1, GURL(), GURL()),
96 // TODO(alecflett): Pump the message loop when this becomes async.
97 ASSERT_EQ(1UL, dispatcher_host->ipc_sink()->message_count());
98 EXPECT_TRUE(dispatcher_host->ipc_sink()->GetUniqueMessageMatching(
99 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID));
102 TEST_F(ServiceWorkerDispatcherHostTest, Enabled) {
103 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(
104 switches::kEnableServiceWorker));
105 CommandLine::ForCurrentProcess()->AppendSwitch(
106 switches::kEnableServiceWorker);
108 scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host =
109 new TestingServiceWorkerDispatcherHost(
110 kRenderProcessId, context_wrapper_.get(), helper_.get());
113 dispatcher_host->OnMessageReceived(
114 ServiceWorkerHostMsg_RegisterServiceWorker(-1, -1, GURL(), GURL()),
116 EXPECT_TRUE(handled);
117 base::RunLoop().RunUntilIdle();
119 // TODO(alecflett): Pump the message loop when this becomes async.
120 ASSERT_EQ(2UL, dispatcher_host->ipc_sink()->message_count());
121 EXPECT_TRUE(dispatcher_host->ipc_sink()->GetUniqueMessageMatching(
122 EmbeddedWorkerMsg_StartWorker::ID));
123 EXPECT_TRUE(dispatcher_host->ipc_sink()->GetUniqueMessageMatching(
124 ServiceWorkerMsg_ServiceWorkerRegistered::ID));
127 TEST_F(ServiceWorkerDispatcherHostTest, EarlyContextDeletion) {
128 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch(
129 switches::kEnableServiceWorker));
130 CommandLine::ForCurrentProcess()->AppendSwitch(
131 switches::kEnableServiceWorker);
133 scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host =
134 new TestingServiceWorkerDispatcherHost(
135 kRenderProcessId, context_wrapper_.get(), helper_.get());
137 context_wrapper_->Shutdown();
138 context_wrapper_ = NULL;
141 dispatcher_host->OnMessageReceived(
142 ServiceWorkerHostMsg_RegisterServiceWorker(-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_.get(), 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