1 // Copyright 2014 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 "base/basictypes.h"
6 #include "base/run_loop.h"
7 #include "content/browser/service_worker/embedded_worker_registry.h"
8 #include "content/browser/service_worker/embedded_worker_test_helper.h"
9 #include "content/browser/service_worker/service_worker_context_core.h"
10 #include "content/browser/service_worker/service_worker_dispatcher_host.h"
11 #include "content/browser/service_worker/service_worker_handle.h"
12 #include "content/browser/service_worker/service_worker_registration.h"
13 #include "content/browser/service_worker/service_worker_test_utils.h"
14 #include "content/browser/service_worker/service_worker_version.h"
15 #include "content/common/service_worker/embedded_worker_messages.h"
16 #include "content/common/service_worker/service_worker_messages.h"
17 #include "content/public/test/mock_resource_context.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "ipc/ipc_message.h"
20 #include "ipc/ipc_test_sink.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "third_party/WebKit/public/platform/WebServiceWorkerState.h"
28 const int kRenderProcessId
= 88; // A dummy ID for testing.
29 const int kRenderFrameId
= 44; // A dummy ID for testing.
31 void VerifyStateChangedMessage(int expected_handle_id
,
32 blink::WebServiceWorkerState expected_state
,
33 const IPC::Message
* message
) {
34 ASSERT_TRUE(message
!= NULL
);
35 ServiceWorkerMsg_ServiceWorkerStateChanged::Param param
;
36 ASSERT_TRUE(ServiceWorkerMsg_ServiceWorkerStateChanged::Read(
38 EXPECT_EQ(expected_handle_id
, base::get
<1>(param
));
39 EXPECT_EQ(expected_state
, base::get
<2>(param
));
44 class TestingServiceWorkerDispatcherHost
: public ServiceWorkerDispatcherHost
{
46 TestingServiceWorkerDispatcherHost(
48 ServiceWorkerContextWrapper
* context_wrapper
,
49 ResourceContext
* resource_context
,
50 EmbeddedWorkerTestHelper
* helper
)
51 : ServiceWorkerDispatcherHost(process_id
, nullptr, resource_context
),
52 bad_message_received_count_(0),
54 Init(context_wrapper
);
57 bool Send(IPC::Message
* message
) override
{ return helper_
->Send(message
); }
59 void BadMessageReceived() override
{ ++bad_message_received_count_
; }
61 int bad_message_received_count_
;
64 EmbeddedWorkerTestHelper
* helper_
;
65 ~TestingServiceWorkerDispatcherHost() override
{}
68 class ServiceWorkerHandleTest
: public testing::Test
{
70 ServiceWorkerHandleTest()
71 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
) {}
73 void SetUp() override
{
75 new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId
));
77 dispatcher_host_
= new TestingServiceWorkerDispatcherHost(
78 kRenderProcessId
, helper_
->context_wrapper(),
79 &resource_context_
, helper_
.get());
81 const GURL
pattern("http://www.example.com/");
82 registration_
= new ServiceWorkerRegistration(
85 helper_
->context()->AsWeakPtr());
86 version_
= new ServiceWorkerVersion(
88 GURL("http://www.example.com/service_worker.js"),
90 helper_
->context()->AsWeakPtr());
91 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records
;
93 ServiceWorkerDatabase::ResourceRecord(10, version_
->script_url(), 100));
94 version_
->script_cache_map()->SetResources(records
);
96 // Make the registration findable via storage functions.
97 helper_
->context()->storage()->LazyInitialize(base::Bind(&base::DoNothing
));
98 base::RunLoop().RunUntilIdle();
99 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
100 helper_
->context()->storage()->StoreRegistration(
103 CreateReceiverOnCurrentThread(&status
));
104 base::RunLoop().RunUntilIdle();
105 ASSERT_EQ(SERVICE_WORKER_OK
, status
);
107 provider_host_
.reset(new ServiceWorkerProviderHost(
108 kRenderProcessId
, kRenderFrameId
, 1, SERVICE_WORKER_PROVIDER_FOR_WINDOW
,
109 helper_
->context()->AsWeakPtr(), dispatcher_host_
.get()));
111 helper_
->SimulateAddProcessToPattern(pattern
, kRenderProcessId
);
114 void TearDown() override
{
115 dispatcher_host_
= NULL
;
116 registration_
= NULL
;
118 provider_host_
.reset();
122 IPC::TestSink
* ipc_sink() { return helper_
->ipc_sink(); }
124 TestBrowserThreadBundle browser_thread_bundle_
;
125 MockResourceContext resource_context_
;
127 scoped_ptr
<EmbeddedWorkerTestHelper
> helper_
;
128 scoped_ptr
<ServiceWorkerProviderHost
> provider_host_
;
129 scoped_refptr
<ServiceWorkerRegistration
> registration_
;
130 scoped_refptr
<ServiceWorkerVersion
> version_
;
131 scoped_refptr
<TestingServiceWorkerDispatcherHost
> dispatcher_host_
;
134 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHandleTest
);
137 TEST_F(ServiceWorkerHandleTest
, OnVersionStateChanged
) {
138 scoped_ptr
<ServiceWorkerHandle
> handle
=
139 ServiceWorkerHandle::Create(helper_
->context()->AsWeakPtr(),
140 provider_host_
->AsWeakPtr(),
143 // Start the worker, and then...
144 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
145 version_
->StartWorker(CreateReceiverOnCurrentThread(&status
));
146 base::RunLoop().RunUntilIdle();
147 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
149 // ...dispatch install event.
150 status
= SERVICE_WORKER_ERROR_FAILED
;
151 version_
->SetStatus(ServiceWorkerVersion::INSTALLING
);
152 version_
->DispatchInstallEvent(CreateReceiverOnCurrentThread(&status
));
153 base::RunLoop().RunUntilIdle();
154 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
156 version_
->SetStatus(ServiceWorkerVersion::INSTALLED
);
158 ASSERT_EQ(4UL, ipc_sink()->message_count());
159 ASSERT_EQ(0L, dispatcher_host_
->bad_message_received_count_
);
161 // We should be sending 1. StartWorker,
162 EXPECT_EQ(EmbeddedWorkerMsg_StartWorker::ID
,
163 ipc_sink()->GetMessageAt(0)->type());
164 // 2. StateChanged (state == Installing),
165 VerifyStateChangedMessage(handle
->handle_id(),
166 blink::WebServiceWorkerStateInstalling
,
167 ipc_sink()->GetMessageAt(1));
168 // 3. SendMessageToWorker (to send InstallEvent), and
169 EXPECT_EQ(EmbeddedWorkerContextMsg_MessageToWorker::ID
,
170 ipc_sink()->GetMessageAt(2)->type());
171 // 4. StateChanged (state == Installed).
172 VerifyStateChangedMessage(handle
->handle_id(),
173 blink::WebServiceWorkerStateInstalled
,
174 ipc_sink()->GetMessageAt(3));
177 } // namespace content