ServiceWorkerVersion: remove unused parameter in DispatchInstallEvent
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_version_unittest.cc
blob2b3739db96f90fa58a1d709367d61b2450d23d1e
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_registration.h"
11 #include "content/browser/service_worker/service_worker_test_utils.h"
12 #include "content/browser/service_worker/service_worker_version.h"
13 #include "content/public/test/test_browser_thread_bundle.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 // IPC messages for testing ---------------------------------------------------
18 #define IPC_MESSAGE_IMPL
19 #include "ipc/ipc_message_macros.h"
21 #define IPC_MESSAGE_START TestMsgStart
23 IPC_MESSAGE_CONTROL0(TestMsg_Message);
24 IPC_MESSAGE_ROUTED1(TestMsg_MessageFromWorker, int);
26 // ---------------------------------------------------------------------------
28 namespace content {
30 namespace {
32 static const int kRenderProcessId = 1;
34 class MessageReceiver : public EmbeddedWorkerTestHelper {
35 public:
36 MessageReceiver()
37 : EmbeddedWorkerTestHelper(kRenderProcessId),
38 current_embedded_worker_id_(0) {}
39 ~MessageReceiver() override {}
41 bool OnMessageToWorker(int thread_id,
42 int embedded_worker_id,
43 const IPC::Message& message) override {
44 if (EmbeddedWorkerTestHelper::OnMessageToWorker(
45 thread_id, embedded_worker_id, message)) {
46 return true;
48 current_embedded_worker_id_ = embedded_worker_id;
49 bool handled = true;
50 IPC_BEGIN_MESSAGE_MAP(MessageReceiver, message)
51 IPC_MESSAGE_HANDLER(TestMsg_Message, OnMessage)
52 IPC_MESSAGE_UNHANDLED(handled = false)
53 IPC_END_MESSAGE_MAP()
54 return handled;
57 void SimulateSendValueToBrowser(int embedded_worker_id, int value) {
58 SimulateSend(new TestMsg_MessageFromWorker(embedded_worker_id, value));
61 private:
62 void OnMessage() {
63 // Do nothing.
66 int current_embedded_worker_id_;
67 DISALLOW_COPY_AND_ASSIGN(MessageReceiver);
70 void VerifyCalled(bool* called) {
71 *called = true;
74 void ObserveStatusChanges(ServiceWorkerVersion* version,
75 std::vector<ServiceWorkerVersion::Status>* statuses) {
76 statuses->push_back(version->status());
77 version->RegisterStatusChangeCallback(
78 base::Bind(&ObserveStatusChanges, base::Unretained(version), statuses));
81 // A specialized listener class to receive test messages from a worker.
82 class MessageReceiverFromWorker : public EmbeddedWorkerInstance::Listener {
83 public:
84 explicit MessageReceiverFromWorker(EmbeddedWorkerInstance* instance)
85 : instance_(instance) {
86 instance_->AddListener(this);
88 ~MessageReceiverFromWorker() override { instance_->RemoveListener(this); }
90 void OnStarted() override { NOTREACHED(); }
91 void OnStopped(EmbeddedWorkerInstance::Status old_status) override {
92 NOTREACHED();
94 bool OnMessageReceived(const IPC::Message& message) override {
95 bool handled = true;
96 IPC_BEGIN_MESSAGE_MAP(MessageReceiverFromWorker, message)
97 IPC_MESSAGE_HANDLER(TestMsg_MessageFromWorker, OnMessageFromWorker)
98 IPC_MESSAGE_UNHANDLED(handled = false)
99 IPC_END_MESSAGE_MAP()
100 return handled;
103 void OnMessageFromWorker(int value) { received_values_.push_back(value); }
104 const std::vector<int>& received_values() const { return received_values_; }
106 private:
107 EmbeddedWorkerInstance* instance_;
108 std::vector<int> received_values_;
109 DISALLOW_COPY_AND_ASSIGN(MessageReceiverFromWorker);
112 } // namespace
114 class ServiceWorkerVersionTest : public testing::Test {
115 protected:
116 ServiceWorkerVersionTest()
117 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
119 void SetUp() override {
120 helper_ = GetMessageReceiver();
122 pattern_ = GURL("http://www.example.com/");
123 registration_ = new ServiceWorkerRegistration(
124 pattern_,
126 helper_->context()->AsWeakPtr());
127 version_ = new ServiceWorkerVersion(
128 registration_.get(),
129 GURL("http://www.example.com/service_worker.js"),
131 helper_->context()->AsWeakPtr());
133 // Simulate adding one process to the pattern.
134 helper_->SimulateAddProcessToPattern(pattern_, kRenderProcessId);
135 ASSERT_TRUE(helper_->context()->process_manager()
136 ->PatternHasProcessToRun(pattern_));
139 virtual scoped_ptr<MessageReceiver> GetMessageReceiver() {
140 return make_scoped_ptr(new MessageReceiver());
143 void TearDown() override {
144 version_ = 0;
145 registration_ = 0;
146 helper_.reset();
149 TestBrowserThreadBundle thread_bundle_;
150 scoped_ptr<MessageReceiver> helper_;
151 scoped_refptr<ServiceWorkerRegistration> registration_;
152 scoped_refptr<ServiceWorkerVersion> version_;
153 GURL pattern_;
155 private:
156 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionTest);
159 class MessageReceiverDisallowStart : public MessageReceiver {
160 public:
161 MessageReceiverDisallowStart()
162 : MessageReceiver() {}
163 ~MessageReceiverDisallowStart() override {}
165 void OnStartWorker(int embedded_worker_id,
166 int64 service_worker_version_id,
167 const GURL& scope,
168 const GURL& script_url,
169 bool pause_after_download) override {
170 // Do nothing.
173 private:
174 DISALLOW_COPY_AND_ASSIGN(MessageReceiverDisallowStart);
177 class ServiceWorkerFailToStartTest : public ServiceWorkerVersionTest {
178 protected:
179 ServiceWorkerFailToStartTest()
180 : ServiceWorkerVersionTest() {}
182 scoped_ptr<MessageReceiver> GetMessageReceiver() override {
183 return make_scoped_ptr(new MessageReceiverDisallowStart());
186 private:
187 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerFailToStartTest);
190 TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) {
191 // Call StartWorker() multiple times.
192 ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED;
193 ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED;
194 ServiceWorkerStatusCode status3 = SERVICE_WORKER_ERROR_FAILED;
195 version_->StartWorker(CreateReceiverOnCurrentThread(&status1));
196 version_->StartWorker(CreateReceiverOnCurrentThread(&status2));
198 EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status());
199 base::RunLoop().RunUntilIdle();
200 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
202 // Call StartWorker() after it's started.
203 version_->StartWorker(CreateReceiverOnCurrentThread(&status3));
204 base::RunLoop().RunUntilIdle();
206 // All should just succeed.
207 EXPECT_EQ(SERVICE_WORKER_OK, status1);
208 EXPECT_EQ(SERVICE_WORKER_OK, status2);
209 EXPECT_EQ(SERVICE_WORKER_OK, status3);
211 // Call StopWorker() multiple times.
212 status1 = SERVICE_WORKER_ERROR_FAILED;
213 status2 = SERVICE_WORKER_ERROR_FAILED;
214 version_->StopWorker(CreateReceiverOnCurrentThread(&status1));
215 version_->StopWorker(CreateReceiverOnCurrentThread(&status2));
217 EXPECT_EQ(ServiceWorkerVersion::STOPPING, version_->running_status());
218 base::RunLoop().RunUntilIdle();
219 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
221 // All StopWorker should just succeed.
222 EXPECT_EQ(SERVICE_WORKER_OK, status1);
223 EXPECT_EQ(SERVICE_WORKER_OK, status2);
225 // Start worker again.
226 status1 = SERVICE_WORKER_ERROR_FAILED;
227 status2 = SERVICE_WORKER_ERROR_FAILED;
228 status3 = SERVICE_WORKER_ERROR_FAILED;
230 version_->StartWorker(CreateReceiverOnCurrentThread(&status1));
232 EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status());
233 base::RunLoop().RunUntilIdle();
234 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
236 // Call StopWorker()
237 status2 = SERVICE_WORKER_ERROR_FAILED;
238 version_->StopWorker(CreateReceiverOnCurrentThread(&status2));
240 // And try calling StartWorker while StopWorker is in queue.
241 version_->StartWorker(CreateReceiverOnCurrentThread(&status3));
243 EXPECT_EQ(ServiceWorkerVersion::STOPPING, version_->running_status());
244 base::RunLoop().RunUntilIdle();
245 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
247 // All should just succeed.
248 EXPECT_EQ(SERVICE_WORKER_OK, status1);
249 EXPECT_EQ(SERVICE_WORKER_OK, status2);
250 EXPECT_EQ(SERVICE_WORKER_OK, status3);
253 TEST_F(ServiceWorkerVersionTest, DispatchEventToStoppedWorker) {
254 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
256 // Dispatch an event without starting the worker.
257 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
258 version_->SetStatus(ServiceWorkerVersion::INSTALLING);
259 version_->DispatchInstallEvent(CreateReceiverOnCurrentThread(&status));
260 base::RunLoop().RunUntilIdle();
261 EXPECT_EQ(SERVICE_WORKER_OK, status);
263 // The worker should be now started.
264 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
266 // Stop the worker, and then dispatch an event immediately after that.
267 status = SERVICE_WORKER_ERROR_FAILED;
268 ServiceWorkerStatusCode stop_status = SERVICE_WORKER_ERROR_FAILED;
269 version_->StopWorker(CreateReceiverOnCurrentThread(&stop_status));
270 version_->DispatchInstallEvent(CreateReceiverOnCurrentThread(&status));
271 base::RunLoop().RunUntilIdle();
272 EXPECT_EQ(SERVICE_WORKER_OK, stop_status);
274 // Dispatch an event should return SERVICE_WORKER_OK since the worker
275 // should have been restarted to dispatch the event.
276 EXPECT_EQ(SERVICE_WORKER_OK, status);
278 // The worker should be now started again.
279 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
282 TEST_F(ServiceWorkerVersionTest, ReceiveMessageFromWorker) {
283 // Start worker.
284 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
285 version_->StartWorker(CreateReceiverOnCurrentThread(&status));
286 EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status());
287 base::RunLoop().RunUntilIdle();
288 EXPECT_EQ(SERVICE_WORKER_OK, status);
289 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
291 MessageReceiverFromWorker receiver(version_->embedded_worker());
293 // Simulate sending some dummy values from the worker.
294 helper_->SimulateSendValueToBrowser(
295 version_->embedded_worker()->embedded_worker_id(), 555);
296 helper_->SimulateSendValueToBrowser(
297 version_->embedded_worker()->embedded_worker_id(), 777);
299 // Verify the receiver received the values.
300 ASSERT_EQ(2U, receiver.received_values().size());
301 EXPECT_EQ(555, receiver.received_values()[0]);
302 EXPECT_EQ(777, receiver.received_values()[1]);
305 TEST_F(ServiceWorkerVersionTest, InstallAndWaitCompletion) {
306 version_->SetStatus(ServiceWorkerVersion::INSTALLING);
308 // Dispatch an install event.
309 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
310 version_->DispatchInstallEvent(CreateReceiverOnCurrentThread(&status));
312 // Wait for the completion.
313 bool status_change_called = false;
314 version_->RegisterStatusChangeCallback(
315 base::Bind(&VerifyCalled, &status_change_called));
317 base::RunLoop().RunUntilIdle();
319 // Version's status must not have changed during installation.
320 EXPECT_EQ(SERVICE_WORKER_OK, status);
321 EXPECT_FALSE(status_change_called);
322 EXPECT_EQ(ServiceWorkerVersion::INSTALLING, version_->status());
325 TEST_F(ServiceWorkerVersionTest, ActivateAndWaitCompletion) {
326 version_->SetStatus(ServiceWorkerVersion::ACTIVATING);
328 // Dispatch an activate event.
329 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
330 version_->DispatchActivateEvent(CreateReceiverOnCurrentThread(&status));
332 // Wait for the completion.
333 bool status_change_called = false;
334 version_->RegisterStatusChangeCallback(
335 base::Bind(&VerifyCalled, &status_change_called));
337 base::RunLoop().RunUntilIdle();
339 // Version's status must not have changed during activation.
340 EXPECT_EQ(SERVICE_WORKER_OK, status);
341 EXPECT_FALSE(status_change_called);
342 EXPECT_EQ(ServiceWorkerVersion::ACTIVATING, version_->status());
345 TEST_F(ServiceWorkerVersionTest, RepeatedlyObserveStatusChanges) {
346 EXPECT_EQ(ServiceWorkerVersion::NEW, version_->status());
348 // Repeatedly observe status changes (the callback re-registers itself).
349 std::vector<ServiceWorkerVersion::Status> statuses;
350 version_->RegisterStatusChangeCallback(
351 base::Bind(&ObserveStatusChanges, version_, &statuses));
353 version_->SetStatus(ServiceWorkerVersion::INSTALLING);
354 version_->SetStatus(ServiceWorkerVersion::INSTALLED);
355 version_->SetStatus(ServiceWorkerVersion::ACTIVATING);
356 version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
357 version_->SetStatus(ServiceWorkerVersion::REDUNDANT);
359 // Verify that we could successfully observe repeated status changes.
360 ASSERT_EQ(5U, statuses.size());
361 ASSERT_EQ(ServiceWorkerVersion::INSTALLING, statuses[0]);
362 ASSERT_EQ(ServiceWorkerVersion::INSTALLED, statuses[1]);
363 ASSERT_EQ(ServiceWorkerVersion::ACTIVATING, statuses[2]);
364 ASSERT_EQ(ServiceWorkerVersion::ACTIVATED, statuses[3]);
365 ASSERT_EQ(ServiceWorkerVersion::REDUNDANT, statuses[4]);
368 TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) {
369 // Verify the timer is not running when version initializes its status.
370 version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
371 EXPECT_FALSE(version_->stop_worker_timer_.IsRunning());
373 // Verify the timer is running after the worker is started.
374 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
375 version_->StartWorker(CreateReceiverOnCurrentThread(&status));
376 base::RunLoop().RunUntilIdle();
377 EXPECT_EQ(SERVICE_WORKER_OK, status);
378 EXPECT_TRUE(version_->stop_worker_timer_.IsRunning());
380 // The timer should be running if the worker is restarted without controllee.
381 status = SERVICE_WORKER_ERROR_FAILED;
382 version_->StopWorker(CreateReceiverOnCurrentThread(&status));
383 base::RunLoop().RunUntilIdle();
384 EXPECT_EQ(SERVICE_WORKER_OK, status);
385 status = SERVICE_WORKER_ERROR_FAILED;
386 version_->StartWorker(CreateReceiverOnCurrentThread(&status));
387 base::RunLoop().RunUntilIdle();
388 EXPECT_EQ(SERVICE_WORKER_OK, status);
389 EXPECT_TRUE(version_->stop_worker_timer_.IsRunning());
391 // Adding controllee doesn't stop the stop-worker-timer.
392 scoped_ptr<ServiceWorkerProviderHost> host(
393 new ServiceWorkerProviderHost(33 /* dummy render process id */,
394 MSG_ROUTING_NONE /* render_frame_id */,
395 1 /* dummy provider_id */,
396 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE,
397 helper_->context()->AsWeakPtr(),
398 NULL));
399 version_->AddControllee(host.get());
400 EXPECT_TRUE(version_->stop_worker_timer_.IsRunning());
403 TEST_F(ServiceWorkerVersionTest, ListenerAvailability) {
404 // Initially the worker is not running. There should be no cache_listener_.
405 EXPECT_FALSE(version_->cache_listener_.get());
407 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
408 version_->StartWorker(
409 CreateReceiverOnCurrentThread(&status));
410 base::RunLoop().RunUntilIdle();
412 // A new cache listener should be available once the worker starts.
413 EXPECT_TRUE(version_->cache_listener_.get());
415 version_->StopWorker(
416 CreateReceiverOnCurrentThread(&status));
417 base::RunLoop().RunUntilIdle();
419 // Should be destroyed when the worker stops.
420 EXPECT_FALSE(version_->cache_listener_.get());
422 version_->StartWorker(
423 CreateReceiverOnCurrentThread(&status));
424 base::RunLoop().RunUntilIdle();
426 // Recreated when the worker starts again.
427 EXPECT_TRUE(version_->cache_listener_.get());
430 TEST_F(ServiceWorkerFailToStartTest, RendererCrash) {
431 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
432 version_->StartWorker(
433 CreateReceiverOnCurrentThread(&status));
434 base::RunLoop().RunUntilIdle();
436 // Callback has not completed yet.
437 EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, status);
438 EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status());
440 // Simulate renderer crash: do what
441 // ServiceWorkerDispatcherHost::OnFilterRemoved does.
442 int process_id = helper_->mock_render_process_id();
443 helper_->context()->RemoveAllProviderHostsForProcess(process_id);
444 helper_->context()->embedded_worker_registry()->RemoveChildProcessSender(
445 process_id);
446 base::RunLoop().RunUntilIdle();
448 // Callback completed.
449 EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status);
450 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
453 } // namespace content