service_worker_dispatcher_host_unittest.cc revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
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. 4 5#include "content/browser/service_worker/service_worker_dispatcher_host.h" 6 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" 21 22namespace content { 23 24static const int kRenderProcessId = 1; 25 26class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost { 27 public: 28 TestingServiceWorkerDispatcherHost( 29 int process_id, 30 ServiceWorkerContextWrapper* context_wrapper, 31 EmbeddedWorkerTestHelper* helper) 32 : ServiceWorkerDispatcherHost(process_id, NULL), 33 bad_messages_received_count_(0), 34 helper_(helper) { 35 Init(context_wrapper); 36 } 37 38 virtual bool Send(IPC::Message* message) OVERRIDE { 39 return helper_->Send(message); 40 } 41 42 IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); } 43 44 virtual void BadMessageReceived() OVERRIDE { 45 ++bad_messages_received_count_; 46 } 47 48 int bad_messages_received_count_; 49 50 protected: 51 EmbeddedWorkerTestHelper* helper_; 52 virtual ~TestingServiceWorkerDispatcherHost() {} 53}; 54 55class ServiceWorkerDispatcherHostTest : public testing::Test { 56 protected: 57 ServiceWorkerDispatcherHostTest() 58 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} 59 60 virtual void SetUp() { 61 helper_.reset(new EmbeddedWorkerTestHelper(kRenderProcessId)); 62 dispatcher_host_ = new TestingServiceWorkerDispatcherHost( 63 kRenderProcessId, context_wrapper(), helper_.get()); 64 } 65 66 virtual void TearDown() { 67 helper_.reset(); 68 } 69 70 ServiceWorkerContextCore* context() { return helper_->context(); } 71 ServiceWorkerContextWrapper* context_wrapper() { 72 return helper_->context_wrapper(); 73 } 74 75 void Register(int64 provider_id, 76 GURL pattern, 77 GURL worker_url, 78 uint32 expected_message) { 79 dispatcher_host_->OnMessageReceived( 80 ServiceWorkerHostMsg_RegisterServiceWorker( 81 -1, -1, provider_id, pattern, worker_url)); 82 base::RunLoop().RunUntilIdle(); 83 EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( 84 expected_message)); 85 dispatcher_host_->ipc_sink()->ClearMessages(); 86 } 87 88 void Unregister(int64 provider_id, GURL pattern, uint32 expected_message) { 89 dispatcher_host_->OnMessageReceived( 90 ServiceWorkerHostMsg_UnregisterServiceWorker( 91 -1, -1, provider_id, pattern)); 92 base::RunLoop().RunUntilIdle(); 93 EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( 94 expected_message)); 95 dispatcher_host_->ipc_sink()->ClearMessages(); 96 } 97 98 TestBrowserThreadBundle browser_thread_bundle_; 99 scoped_ptr<EmbeddedWorkerTestHelper> helper_; 100 scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host_; 101}; 102 103TEST_F(ServiceWorkerDispatcherHostTest, DisabledCausesError) { 104 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch( 105 switches::kEnableServiceWorker)); 106 107 dispatcher_host_->OnMessageReceived( 108 ServiceWorkerHostMsg_RegisterServiceWorker(-1, -1, -1, GURL(), GURL())); 109 110 // TODO(alecflett): Pump the message loop when this becomes async. 111 ASSERT_EQ(1UL, dispatcher_host_->ipc_sink()->message_count()); 112 EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( 113 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID)); 114} 115 116// TODO(falken): Enable this test when we remove the 117// --enable-service-worker-flag (see crbug.com/352581) 118TEST_F(ServiceWorkerDispatcherHostTest, DISABLED_RegisterSameOrigin) { 119 const int64 kProviderId = 99; // Dummy value 120 scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost( 121 kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL)); 122 host->SetDocumentUrl(GURL("http://www.example.com/foo")); 123 base::WeakPtr<ServiceWorkerProviderHost> provider_host = host->AsWeakPtr(); 124 context()->AddProviderHost(host.Pass()); 125 126 Register(kProviderId, 127 GURL("http://www.example.com/*"), 128 GURL("http://foo.example.com/bar"), 129 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); 130 Register(kProviderId, 131 GURL("http://foo.example.com/*"), 132 GURL("http://www.example.com/bar"), 133 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); 134 Register(kProviderId, 135 GURL("http://foo.example.com/*"), 136 GURL("http://foo.example.com/bar"), 137 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); 138 Register(kProviderId, 139 GURL("http://www.example.com/*"), 140 GURL("http://www.example.com/bar"), 141 ServiceWorkerMsg_ServiceWorkerRegistered::ID); 142} 143 144// TODO(falken): Enable this test when we remove the 145// --enable-service-worker-flag (see crbug.com/352581) 146TEST_F(ServiceWorkerDispatcherHostTest, DISABLED_UnregisterSameOrigin) { 147 const int64 kProviderId = 99; // Dummy value 148 scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost( 149 kRenderProcessId, kProviderId, context()->AsWeakPtr(), NULL)); 150 host->SetDocumentUrl(GURL("http://www.example.com/foo")); 151 base::WeakPtr<ServiceWorkerProviderHost> provider_host = host->AsWeakPtr(); 152 context()->AddProviderHost(host.Pass()); 153 154 Unregister(kProviderId, 155 GURL("http://foo.example.com/*"), 156 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID); 157 Unregister(kProviderId, 158 GURL("http://www.example.com/*"), 159 ServiceWorkerMsg_ServiceWorkerUnregistered::ID); 160} 161 162// Disable this since now we cache command-line switch in 163// ServiceWorkerUtils::IsFeatureEnabled() and this could be flaky depending 164// on testing order. (crbug.com/352581) 165// TODO(kinuko): Just remove DisabledCausesError test above and enable 166// this test when we remove the --enable-service-worker flag. 167TEST_F(ServiceWorkerDispatcherHostTest, DISABLED_Enabled) { 168 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch( 169 switches::kEnableServiceWorker)); 170 CommandLine::ForCurrentProcess()->AppendSwitch( 171 switches::kEnableServiceWorker); 172 173 dispatcher_host_->OnMessageReceived( 174 ServiceWorkerHostMsg_RegisterServiceWorker(-1, -1, -1, GURL(), GURL())); 175 base::RunLoop().RunUntilIdle(); 176 177 // TODO(alecflett): Pump the message loop when this becomes async. 178 ASSERT_EQ(2UL, dispatcher_host_->ipc_sink()->message_count()); 179 EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( 180 EmbeddedWorkerMsg_StartWorker::ID)); 181 EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( 182 ServiceWorkerMsg_ServiceWorkerRegistered::ID)); 183} 184 185TEST_F(ServiceWorkerDispatcherHostTest, EarlyContextDeletion) { 186 DCHECK(!CommandLine::ForCurrentProcess()->HasSwitch( 187 switches::kEnableServiceWorker)); 188 CommandLine::ForCurrentProcess()->AppendSwitch( 189 switches::kEnableServiceWorker); 190 191 helper_->ShutdownContext(); 192 193 // Let the shutdown reach the simulated IO thread. 194 base::RunLoop().RunUntilIdle(); 195 196 dispatcher_host_->OnMessageReceived( 197 ServiceWorkerHostMsg_RegisterServiceWorker(-1, -1, -1, GURL(), GURL())); 198 199 // TODO(alecflett): Pump the message loop when this becomes async. 200 ASSERT_EQ(1UL, dispatcher_host_->ipc_sink()->message_count()); 201 EXPECT_TRUE(dispatcher_host_->ipc_sink()->GetUniqueMessageMatching( 202 ServiceWorkerMsg_ServiceWorkerRegistrationError::ID)); 203} 204 205TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) { 206 const int kProviderId = 1001; // Test with a value != kRenderProcessId. 207 208 dispatcher_host_->OnMessageReceived( 209 ServiceWorkerHostMsg_ProviderCreated(kProviderId)); 210 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId, kProviderId)); 211 212 // Two with the same ID should be seen as a bad message. 213 dispatcher_host_->OnMessageReceived( 214 ServiceWorkerHostMsg_ProviderCreated(kProviderId)); 215 EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_); 216 217 dispatcher_host_->OnMessageReceived( 218 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId)); 219 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId, kProviderId)); 220 221 // Destroying an ID that does not exist warrants a bad message. 222 dispatcher_host_->OnMessageReceived( 223 ServiceWorkerHostMsg_ProviderDestroyed(kProviderId)); 224 EXPECT_EQ(2, dispatcher_host_->bad_messages_received_count_); 225 226 // Deletion of the dispatcher_host should cause providers for that 227 // process to get deleted as well. 228 dispatcher_host_->OnMessageReceived( 229 ServiceWorkerHostMsg_ProviderCreated(kProviderId)); 230 EXPECT_TRUE(context()->GetProviderHost(kRenderProcessId, kProviderId)); 231 EXPECT_TRUE(dispatcher_host_->HasOneRef()); 232 dispatcher_host_ = NULL; 233 EXPECT_FALSE(context()->GetProviderHost(kRenderProcessId, kProviderId)); 234} 235 236} // namespace content 237