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 "content/browser/service_worker/embedded_worker_test_helper.h"
10 #include "base/atomic_sequence_num.h"
11 #include "base/bind.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "content/browser/message_port_message_filter.h"
15 #include "content/browser/service_worker/embedded_worker_instance.h"
16 #include "content/browser/service_worker/embedded_worker_registry.h"
17 #include "content/browser/service_worker/service_worker_context_core.h"
18 #include "content/browser/service_worker/service_worker_context_wrapper.h"
19 #include "content/common/service_worker/embedded_worker_messages.h"
20 #include "content/common/service_worker/service_worker_messages.h"
21 #include "testing/gtest/include/gtest/gtest.h"
25 class MockMessagePortMessageFilter
: public MessagePortMessageFilter
{
27 MockMessagePortMessageFilter()
28 : MessagePortMessageFilter(
29 base::Bind(&base::AtomicSequenceNumber::GetNext
,
30 base::Unretained(&next_routing_id_
))) {}
32 bool Send(IPC::Message
* message
) override
{
33 message_queue_
.push_back(message
);
38 ~MockMessagePortMessageFilter() override
{}
39 base::AtomicSequenceNumber next_routing_id_
;
40 ScopedVector
<IPC::Message
> message_queue_
;
43 EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
44 const base::FilePath
& user_data_directory
,
45 int mock_render_process_id
)
46 : wrapper_(new ServiceWorkerContextWrapper(NULL
)),
48 mock_render_process_id_(mock_render_process_id
),
50 scoped_ptr
<MockServiceWorkerDatabaseTaskManager
> database_task_manager(
51 new MockServiceWorkerDatabaseTaskManager(
52 base::ThreadTaskRunnerHandle::Get()));
53 wrapper_
->InitInternal(user_data_directory
,
54 database_task_manager
.Pass(),
55 base::ThreadTaskRunnerHandle::Get(),
58 wrapper_
->process_manager()->SetProcessIdForTest(mock_render_process_id
);
59 registry()->AddChildProcessSender(mock_render_process_id
, this,
60 NewMessagePortMessageFilter());
63 EmbeddedWorkerTestHelper::~EmbeddedWorkerTestHelper() {
68 void EmbeddedWorkerTestHelper::SimulateAddProcessToPattern(
71 registry()->AddChildProcessSender(process_id
, this,
72 NewMessagePortMessageFilter());
73 wrapper_
->process_manager()->AddProcessReferenceToPattern(
77 bool EmbeddedWorkerTestHelper::Send(IPC::Message
* message
) {
78 OnMessageReceived(*message
);
83 bool EmbeddedWorkerTestHelper::OnMessageReceived(const IPC::Message
& message
) {
85 IPC_BEGIN_MESSAGE_MAP(EmbeddedWorkerTestHelper
, message
)
86 IPC_MESSAGE_HANDLER(EmbeddedWorkerMsg_StartWorker
, OnStartWorkerStub
)
87 IPC_MESSAGE_HANDLER(EmbeddedWorkerMsg_StopWorker
, OnStopWorkerStub
)
88 IPC_MESSAGE_HANDLER(EmbeddedWorkerContextMsg_MessageToWorker
,
89 OnMessageToWorkerStub
)
90 IPC_MESSAGE_UNHANDLED(handled
= false)
93 // IPC::TestSink only records messages that are not handled by filters,
94 // so we just forward all messages to the separate sink.
95 sink_
.OnMessageReceived(message
);
100 ServiceWorkerContextCore
* EmbeddedWorkerTestHelper::context() {
101 return wrapper_
->context();
104 void EmbeddedWorkerTestHelper::ShutdownContext() {
105 wrapper_
->Shutdown();
109 void EmbeddedWorkerTestHelper::OnStartWorker(int embedded_worker_id
,
110 int64 service_worker_version_id
,
112 const GURL
& script_url
) {
113 embedded_worker_id_service_worker_version_id_map_
[embedded_worker_id
] =
114 service_worker_version_id
;
115 SimulateWorkerReadyForInspection(embedded_worker_id
);
116 SimulateWorkerScriptCached(embedded_worker_id
);
117 SimulateWorkerScriptLoaded(embedded_worker_id
);
118 SimulateWorkerThreadStarted(next_thread_id_
++, embedded_worker_id
);
119 SimulateWorkerScriptEvaluated(embedded_worker_id
);
120 SimulateWorkerStarted(embedded_worker_id
);
123 void EmbeddedWorkerTestHelper::OnStopWorker(int embedded_worker_id
) {
124 // By default just notify the sender that the worker is stopped.
125 SimulateWorkerStopped(embedded_worker_id
);
128 bool EmbeddedWorkerTestHelper::OnMessageToWorker(
130 int embedded_worker_id
,
131 const IPC::Message
& message
) {
133 current_embedded_worker_id_
= embedded_worker_id
;
134 IPC_BEGIN_MESSAGE_MAP(EmbeddedWorkerTestHelper
, message
)
135 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ActivateEvent
, OnActivateEventStub
)
136 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_InstallEvent
, OnInstallEventStub
)
137 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_FetchEvent
, OnFetchEventStub
)
138 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_PushEvent
, OnPushEventStub
)
139 IPC_MESSAGE_UNHANDLED(handled
= false)
140 IPC_END_MESSAGE_MAP()
141 // Record all messages directed to inner script context.
142 inner_sink_
.OnMessageReceived(message
);
146 void EmbeddedWorkerTestHelper::OnActivateEvent(int embedded_worker_id
,
149 new ServiceWorkerHostMsg_ActivateEventFinished(
150 embedded_worker_id
, request_id
,
151 blink::WebServiceWorkerEventResultCompleted
));
154 void EmbeddedWorkerTestHelper::OnInstallEvent(int embedded_worker_id
,
156 // The installing worker may have been doomed and terminated.
157 if (!registry()->GetWorker(embedded_worker_id
))
160 new ServiceWorkerHostMsg_InstallEventFinished(
161 embedded_worker_id
, request_id
,
162 blink::WebServiceWorkerEventResultCompleted
));
165 void EmbeddedWorkerTestHelper::OnFetchEvent(
166 int embedded_worker_id
,
168 const ServiceWorkerFetchRequest
& request
) {
169 SimulateSend(new ServiceWorkerHostMsg_FetchEventFinished(
170 embedded_worker_id
, request_id
,
171 SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE
,
172 ServiceWorkerResponse(GURL(), 200, "OK",
173 blink::WebServiceWorkerResponseTypeDefault
,
174 ServiceWorkerHeaderMap(), std::string(), 0, GURL(),
175 blink::WebServiceWorkerResponseErrorUnknown
)));
178 void EmbeddedWorkerTestHelper::OnPushEvent(int embedded_worker_id
,
180 const std::string
& data
) {
181 SimulateSend(new ServiceWorkerHostMsg_PushEventFinished(
182 embedded_worker_id
, request_id
,
183 blink::WebServiceWorkerEventResultCompleted
));
186 void EmbeddedWorkerTestHelper::SimulateWorkerReadyForInspection(
187 int embedded_worker_id
) {
188 EmbeddedWorkerInstance
* worker
= registry()->GetWorker(embedded_worker_id
);
189 ASSERT_TRUE(worker
!= NULL
);
190 registry()->OnWorkerReadyForInspection(worker
->process_id(),
194 void EmbeddedWorkerTestHelper::SimulateWorkerScriptCached(
195 int embedded_worker_id
) {
197 embedded_worker_id_service_worker_version_id_map_
[embedded_worker_id
];
198 ServiceWorkerVersion
* version
= context()->GetLiveVersion(version_id
);
199 if (!version
|| version
->script_cache_map()->size())
201 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records
;
202 // Add a dummy ResourceRecord for the main script to the script cache map of
203 // the ServiceWorkerVersion. We use embedded_worker_id for resource_id to
204 // avoid ID collision.
205 records
.push_back(ServiceWorkerDatabase::ResourceRecord(
206 embedded_worker_id
, version
->script_url(), 100));
207 version
->script_cache_map()->SetResources(records
);
210 void EmbeddedWorkerTestHelper::SimulateWorkerScriptLoaded(
211 int embedded_worker_id
) {
212 EmbeddedWorkerInstance
* worker
= registry()->GetWorker(embedded_worker_id
);
213 ASSERT_TRUE(worker
!= NULL
);
214 registry()->OnWorkerScriptLoaded(worker
->process_id(), embedded_worker_id
);
217 void EmbeddedWorkerTestHelper::SimulateWorkerThreadStarted(
219 int embedded_worker_id
) {
220 EmbeddedWorkerInstance
* worker
= registry()->GetWorker(embedded_worker_id
);
221 ASSERT_TRUE(worker
!= NULL
);
222 registry()->OnWorkerThreadStarted(worker
->process_id(), thread_id
,
226 void EmbeddedWorkerTestHelper::SimulateWorkerScriptEvaluated(
227 int embedded_worker_id
) {
228 EmbeddedWorkerInstance
* worker
= registry()->GetWorker(embedded_worker_id
);
229 ASSERT_TRUE(worker
!= NULL
);
230 registry()->OnWorkerScriptEvaluated(
231 worker
->process_id(), embedded_worker_id
, true /* success */);
234 void EmbeddedWorkerTestHelper::SimulateWorkerStarted(
235 int embedded_worker_id
) {
236 EmbeddedWorkerInstance
* worker
= registry()->GetWorker(embedded_worker_id
);
237 ASSERT_TRUE(worker
!= NULL
);
238 registry()->OnWorkerStarted(
239 worker
->process_id(),
243 void EmbeddedWorkerTestHelper::SimulateWorkerStopped(
244 int embedded_worker_id
) {
245 EmbeddedWorkerInstance
* worker
= registry()->GetWorker(embedded_worker_id
);
247 registry()->OnWorkerStopped(worker
->process_id(), embedded_worker_id
);
250 void EmbeddedWorkerTestHelper::SimulateSend(
251 IPC::Message
* message
) {
252 registry()->OnMessageReceived(*message
, mock_render_process_id_
);
256 void EmbeddedWorkerTestHelper::OnStartWorkerStub(
257 const EmbeddedWorkerMsg_StartWorker_Params
& params
) {
258 EmbeddedWorkerInstance
* worker
=
259 registry()->GetWorker(params
.embedded_worker_id
);
260 ASSERT_TRUE(worker
!= NULL
);
261 EXPECT_EQ(EmbeddedWorkerInstance::STARTING
, worker
->status());
262 base::ThreadTaskRunnerHandle::Get()->PostTask(
264 base::Bind(&EmbeddedWorkerTestHelper::OnStartWorker
,
265 weak_factory_
.GetWeakPtr(), params
.embedded_worker_id
,
266 params
.service_worker_version_id
, params
.scope
,
270 void EmbeddedWorkerTestHelper::OnStopWorkerStub(int embedded_worker_id
) {
271 EmbeddedWorkerInstance
* worker
= registry()->GetWorker(embedded_worker_id
);
272 ASSERT_TRUE(worker
!= NULL
);
273 base::ThreadTaskRunnerHandle::Get()->PostTask(
275 base::Bind(&EmbeddedWorkerTestHelper::OnStopWorker
,
276 weak_factory_
.GetWeakPtr(),
277 embedded_worker_id
));
280 void EmbeddedWorkerTestHelper::OnMessageToWorkerStub(
282 int embedded_worker_id
,
283 const IPC::Message
& message
) {
284 EmbeddedWorkerInstance
* worker
= registry()->GetWorker(embedded_worker_id
);
285 ASSERT_TRUE(worker
!= NULL
);
286 EXPECT_EQ(worker
->thread_id(), thread_id
);
287 base::ThreadTaskRunnerHandle::Get()->PostTask(
290 base::IgnoreResult(&EmbeddedWorkerTestHelper::OnMessageToWorker
),
291 weak_factory_
.GetWeakPtr(),
297 void EmbeddedWorkerTestHelper::OnActivateEventStub(int request_id
) {
298 base::ThreadTaskRunnerHandle::Get()->PostTask(
300 base::Bind(&EmbeddedWorkerTestHelper::OnActivateEvent
,
301 weak_factory_
.GetWeakPtr(),
302 current_embedded_worker_id_
,
306 void EmbeddedWorkerTestHelper::OnInstallEventStub(int request_id
) {
307 base::ThreadTaskRunnerHandle::Get()->PostTask(
309 base::Bind(&EmbeddedWorkerTestHelper::OnInstallEvent
,
310 weak_factory_
.GetWeakPtr(),
311 current_embedded_worker_id_
,
315 void EmbeddedWorkerTestHelper::OnFetchEventStub(
317 const ServiceWorkerFetchRequest
& request
) {
318 base::ThreadTaskRunnerHandle::Get()->PostTask(
320 base::Bind(&EmbeddedWorkerTestHelper::OnFetchEvent
,
321 weak_factory_
.GetWeakPtr(),
322 current_embedded_worker_id_
,
327 void EmbeddedWorkerTestHelper::OnPushEventStub(int request_id
,
328 const std::string
& data
) {
329 base::ThreadTaskRunnerHandle::Get()->PostTask(
330 FROM_HERE
, base::Bind(&EmbeddedWorkerTestHelper::OnPushEvent
,
331 weak_factory_
.GetWeakPtr(),
332 current_embedded_worker_id_
, request_id
, data
));
335 EmbeddedWorkerRegistry
* EmbeddedWorkerTestHelper::registry() {
337 return context()->embedded_worker_registry();
340 MessagePortMessageFilter
*
341 EmbeddedWorkerTestHelper::NewMessagePortMessageFilter() {
342 scoped_refptr
<MessagePortMessageFilter
> filter(
343 new MockMessagePortMessageFilter
);
344 message_port_message_filters_
.push_back(filter
);
348 } // namespace content