Cast: Skip receiver log messages with time delta that can't be encoded.
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_job_unittest.cc
blob448e1e1ac1c2854cebfee91d7c980d89f13998ad
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/files/scoped_temp_dir.h"
6 #include "base/logging.h"
7 #include "base/run_loop.h"
8 #include "content/browser/browser_thread_impl.h"
9 #include "content/browser/service_worker/embedded_worker_registry.h"
10 #include "content/browser/service_worker/embedded_worker_test_helper.h"
11 #include "content/browser/service_worker/service_worker_context_core.h"
12 #include "content/browser/service_worker/service_worker_job_coordinator.h"
13 #include "content/browser/service_worker/service_worker_registration.h"
14 #include "content/browser/service_worker/service_worker_registration_status.h"
15 #include "content/public/test/test_browser_thread_bundle.h"
16 #include "ipc/ipc_test_sink.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 // Unit tests for testing all job registration tasks.
20 namespace content {
22 namespace {
24 void SaveRegistrationCallback(
25 ServiceWorkerStatusCode expected_status,
26 bool* called,
27 scoped_refptr<ServiceWorkerRegistration>* registration,
28 ServiceWorkerStatusCode status,
29 const scoped_refptr<ServiceWorkerRegistration>& result) {
30 EXPECT_EQ(expected_status, status);
31 *called = true;
32 *registration = result;
35 void SaveFoundRegistrationCallback(
36 ServiceWorkerStatusCode expected_status,
37 bool* called,
38 scoped_refptr<ServiceWorkerRegistration>* registration,
39 ServiceWorkerStatusCode status,
40 const scoped_refptr<ServiceWorkerRegistration>& result) {
41 EXPECT_EQ(expected_status, status);
42 *called = true;
43 *registration = result;
46 // Creates a callback which both keeps track of if it's been called,
47 // as well as the resulting registration. Whent the callback is fired,
48 // it ensures that the resulting status matches the expectation.
49 // 'called' is useful for making sure a sychronous callback is or
50 // isn't called.
51 ServiceWorkerRegisterJob::RegistrationCallback SaveRegistration(
52 ServiceWorkerStatusCode expected_status,
53 bool* called,
54 scoped_refptr<ServiceWorkerRegistration>* registration) {
55 *called = false;
56 return base::Bind(
57 &SaveRegistrationCallback, expected_status, called, registration);
60 ServiceWorkerStorage::FindRegistrationCallback SaveFoundRegistration(
61 ServiceWorkerStatusCode expected_status,
62 bool* called,
63 scoped_refptr<ServiceWorkerRegistration>* registration) {
64 *called = false;
65 return base::Bind(&SaveFoundRegistrationCallback,
66 expected_status,
67 called,
68 registration);
71 void SaveUnregistrationCallback(ServiceWorkerStatusCode expected_status,
72 bool* called,
73 ServiceWorkerStatusCode status) {
74 EXPECT_EQ(expected_status, status);
75 *called = true;
78 ServiceWorkerRegisterJob::UnregistrationCallback SaveUnregistration(
79 ServiceWorkerStatusCode expected_status,
80 bool* called) {
81 *called = false;
82 return base::Bind(&SaveUnregistrationCallback, expected_status, called);
85 } // namespace
87 class ServiceWorkerJobTest : public testing::Test {
88 public:
89 ServiceWorkerJobTest()
90 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
91 render_process_id_(88) {}
93 virtual void SetUp() OVERRIDE {
94 context_.reset(new ServiceWorkerContextCore(base::FilePath(), NULL));
95 helper_.reset(new EmbeddedWorkerTestHelper(context_.get(),
96 render_process_id_));
99 virtual void TearDown() OVERRIDE {
100 helper_.reset();
101 context_.reset();
104 ServiceWorkerJobCoordinator* job_coordinator() const {
105 return context_->job_coordinator();
107 ServiceWorkerStorage* storage() const { return context_->storage(); }
109 protected:
110 TestBrowserThreadBundle browser_thread_bundle_;
111 scoped_ptr<ServiceWorkerContextCore> context_;
112 scoped_ptr<EmbeddedWorkerTestHelper> helper_;
114 int render_process_id_;
117 TEST_F(ServiceWorkerJobTest, SameDocumentSameRegistration) {
118 scoped_refptr<ServiceWorkerRegistration> original_registration;
119 bool called;
120 job_coordinator()->Register(
121 GURL("http://www.example.com/*"),
122 GURL("http://www.example.com/service_worker.js"),
123 render_process_id_,
124 SaveRegistration(SERVICE_WORKER_OK, &called, &original_registration));
125 EXPECT_FALSE(called);
126 base::RunLoop().RunUntilIdle();
127 EXPECT_TRUE(called);
129 scoped_refptr<ServiceWorkerRegistration> registration1;
130 storage()->FindRegistrationForDocument(
131 GURL("http://www.example.com/"),
132 SaveFoundRegistration(SERVICE_WORKER_OK, &called, &registration1));
133 scoped_refptr<ServiceWorkerRegistration> registration2;
134 storage()->FindRegistrationForDocument(
135 GURL("http://www.example.com/"),
136 SaveFoundRegistration(SERVICE_WORKER_OK, &called, &registration2));
138 ServiceWorkerRegistration* null_registration(NULL);
139 ASSERT_EQ(null_registration, registration1);
140 ASSERT_EQ(null_registration, registration2);
141 EXPECT_FALSE(called);
142 base::RunLoop().RunUntilIdle();
143 EXPECT_TRUE(called);
144 ASSERT_NE(null_registration, registration1);
145 ASSERT_NE(null_registration, registration2);
147 ASSERT_EQ(registration1, registration2);
150 TEST_F(ServiceWorkerJobTest, SameMatchSameRegistration) {
151 bool called;
152 scoped_refptr<ServiceWorkerRegistration> original_registration;
153 job_coordinator()->Register(
154 GURL("http://www.example.com/*"),
155 GURL("http://www.example.com/service_worker.js"),
156 render_process_id_,
157 SaveRegistration(SERVICE_WORKER_OK, &called, &original_registration));
158 EXPECT_FALSE(called);
159 base::RunLoop().RunUntilIdle();
160 EXPECT_TRUE(called);
161 ASSERT_NE(static_cast<ServiceWorkerRegistration*>(NULL),
162 original_registration.get());
164 scoped_refptr<ServiceWorkerRegistration> registration1;
165 storage()->FindRegistrationForDocument(
166 GURL("http://www.example.com/one"),
167 SaveFoundRegistration(SERVICE_WORKER_OK, &called, &registration1));
169 EXPECT_FALSE(called);
170 base::RunLoop().RunUntilIdle();
171 EXPECT_TRUE(called);
173 scoped_refptr<ServiceWorkerRegistration> registration2;
174 storage()->FindRegistrationForDocument(
175 GURL("http://www.example.com/two"),
176 SaveFoundRegistration(SERVICE_WORKER_OK, &called, &registration2));
177 EXPECT_FALSE(called);
178 base::RunLoop().RunUntilIdle();
179 EXPECT_TRUE(called);
181 ASSERT_EQ(registration1, registration2);
184 TEST_F(ServiceWorkerJobTest, DifferentMatchDifferentRegistration) {
185 bool called1;
186 scoped_refptr<ServiceWorkerRegistration> original_registration1;
187 job_coordinator()->Register(
188 GURL("http://www.example.com/one/*"),
189 GURL("http://www.example.com/service_worker.js"),
190 render_process_id_,
191 SaveRegistration(SERVICE_WORKER_OK, &called1, &original_registration1));
193 bool called2;
194 scoped_refptr<ServiceWorkerRegistration> original_registration2;
195 job_coordinator()->Register(
196 GURL("http://www.example.com/two/*"),
197 GURL("http://www.example.com/service_worker.js"),
198 render_process_id_,
199 SaveRegistration(SERVICE_WORKER_OK, &called2, &original_registration2));
201 EXPECT_FALSE(called1);
202 EXPECT_FALSE(called2);
203 base::RunLoop().RunUntilIdle();
204 EXPECT_TRUE(called2);
205 EXPECT_TRUE(called1);
207 scoped_refptr<ServiceWorkerRegistration> registration1;
208 storage()->FindRegistrationForDocument(
209 GURL("http://www.example.com/one/"),
210 SaveFoundRegistration(SERVICE_WORKER_OK, &called1, &registration1));
211 scoped_refptr<ServiceWorkerRegistration> registration2;
212 storage()->FindRegistrationForDocument(
213 GURL("http://www.example.com/two/"),
214 SaveFoundRegistration(SERVICE_WORKER_OK, &called2, &registration2));
216 EXPECT_FALSE(called1);
217 EXPECT_FALSE(called2);
218 base::RunLoop().RunUntilIdle();
219 EXPECT_TRUE(called2);
220 EXPECT_TRUE(called1);
222 ASSERT_NE(registration1, registration2);
225 // Make sure basic registration is working.
226 TEST_F(ServiceWorkerJobTest, Register) {
227 bool called = false;
228 scoped_refptr<ServiceWorkerRegistration> registration;
229 job_coordinator()->Register(
230 GURL("http://www.example.com/*"),
231 GURL("http://www.example.com/service_worker.js"),
232 render_process_id_,
233 SaveRegistration(SERVICE_WORKER_OK, &called, &registration));
235 ASSERT_FALSE(called);
236 base::RunLoop().RunUntilIdle();
237 ASSERT_TRUE(called);
239 ASSERT_NE(scoped_refptr<ServiceWorkerRegistration>(NULL), registration);
242 // Make sure registrations are cleaned up when they are unregistered.
243 TEST_F(ServiceWorkerJobTest, Unregister) {
244 GURL pattern("http://www.example.com/*");
246 bool called;
247 scoped_refptr<ServiceWorkerRegistration> registration;
248 job_coordinator()->Register(
249 pattern,
250 GURL("http://www.example.com/service_worker.js"),
251 render_process_id_,
252 SaveRegistration(SERVICE_WORKER_OK, &called, &registration));
254 ASSERT_FALSE(called);
255 base::RunLoop().RunUntilIdle();
256 ASSERT_TRUE(called);
258 job_coordinator()->Unregister(pattern,
259 render_process_id_,
260 SaveUnregistration(SERVICE_WORKER_OK, &called));
262 ASSERT_FALSE(called);
263 base::RunLoop().RunUntilIdle();
264 ASSERT_TRUE(called);
266 ASSERT_TRUE(registration->HasOneRef());
268 storage()->FindRegistrationForPattern(
269 pattern,
270 SaveFoundRegistration(SERVICE_WORKER_ERROR_NOT_FOUND,
271 &called, &registration));
273 ASSERT_FALSE(called);
274 base::RunLoop().RunUntilIdle();
275 ASSERT_TRUE(called);
277 ASSERT_EQ(scoped_refptr<ServiceWorkerRegistration>(NULL), registration);
280 // Make sure that when a new registration replaces an existing
281 // registration, that the old one is cleaned up.
282 TEST_F(ServiceWorkerJobTest, RegisterNewScript) {
283 GURL pattern("http://www.example.com/*");
285 bool called;
286 scoped_refptr<ServiceWorkerRegistration> old_registration;
287 job_coordinator()->Register(
288 pattern,
289 GURL("http://www.example.com/service_worker.js"),
290 render_process_id_,
291 SaveRegistration(SERVICE_WORKER_OK, &called, &old_registration));
293 ASSERT_FALSE(called);
294 base::RunLoop().RunUntilIdle();
295 ASSERT_TRUE(called);
297 scoped_refptr<ServiceWorkerRegistration> old_registration_by_pattern;
298 storage()->FindRegistrationForPattern(
299 pattern,
300 SaveFoundRegistration(
301 SERVICE_WORKER_OK, &called, &old_registration_by_pattern));
303 ASSERT_FALSE(called);
304 base::RunLoop().RunUntilIdle();
305 ASSERT_TRUE(called);
307 ASSERT_EQ(old_registration, old_registration_by_pattern);
308 old_registration_by_pattern = NULL;
310 scoped_refptr<ServiceWorkerRegistration> new_registration;
311 job_coordinator()->Register(
312 pattern,
313 GURL("http://www.example.com/service_worker_new.js"),
314 render_process_id_,
315 SaveRegistration(SERVICE_WORKER_OK, &called, &new_registration));
317 ASSERT_FALSE(called);
318 base::RunLoop().RunUntilIdle();
319 ASSERT_TRUE(called);
321 ASSERT_TRUE(old_registration->HasOneRef());
323 ASSERT_NE(old_registration, new_registration);
325 scoped_refptr<ServiceWorkerRegistration> new_registration_by_pattern;
326 storage()->FindRegistrationForPattern(
327 pattern,
328 SaveFoundRegistration(
329 SERVICE_WORKER_OK, &called, &new_registration));
331 ASSERT_FALSE(called);
332 base::RunLoop().RunUntilIdle();
333 ASSERT_TRUE(called);
335 ASSERT_NE(new_registration_by_pattern, old_registration);
338 // Make sure that when registering a duplicate pattern+script_url
339 // combination, that the same registration is used.
340 TEST_F(ServiceWorkerJobTest, RegisterDuplicateScript) {
341 GURL pattern("http://www.example.com/*");
342 GURL script_url("http://www.example.com/service_worker.js");
344 bool called;
345 scoped_refptr<ServiceWorkerRegistration> old_registration;
346 job_coordinator()->Register(
347 pattern,
348 script_url,
349 render_process_id_,
350 SaveRegistration(SERVICE_WORKER_OK, &called, &old_registration));
352 ASSERT_FALSE(called);
353 base::RunLoop().RunUntilIdle();
354 ASSERT_TRUE(called);
356 scoped_refptr<ServiceWorkerRegistration> old_registration_by_pattern;
357 storage()->FindRegistrationForPattern(
358 pattern,
359 SaveFoundRegistration(
360 SERVICE_WORKER_OK, &called, &old_registration_by_pattern));
361 ASSERT_FALSE(called);
362 base::RunLoop().RunUntilIdle();
363 ASSERT_TRUE(called);
365 ASSERT_TRUE(old_registration_by_pattern);
367 scoped_refptr<ServiceWorkerRegistration> new_registration;
368 job_coordinator()->Register(
369 pattern,
370 script_url,
371 render_process_id_,
372 SaveRegistration(SERVICE_WORKER_OK, &called, &new_registration));
374 ASSERT_FALSE(called);
375 base::RunLoop().RunUntilIdle();
376 ASSERT_TRUE(called);
378 ASSERT_EQ(old_registration, new_registration);
380 ASSERT_FALSE(old_registration->HasOneRef());
382 scoped_refptr<ServiceWorkerRegistration> new_registration_by_pattern;
383 storage()->FindRegistrationForPattern(
384 pattern,
385 SaveFoundRegistration(
386 SERVICE_WORKER_OK, &called, &new_registration_by_pattern));
388 ASSERT_FALSE(called);
389 base::RunLoop().RunUntilIdle();
390 ASSERT_TRUE(called);
392 ASSERT_EQ(new_registration, old_registration);
395 // Register and then unregister the pattern, in parallel. Job coordinator should
396 // process jobs until the last job.
397 TEST_F(ServiceWorkerJobTest, ParallelRegUnreg) {
398 GURL pattern("http://www.example.com/*");
399 GURL script_url("http://www.example.com/service_worker.js");
401 bool registration_called = false;
402 scoped_refptr<ServiceWorkerRegistration> registration;
403 job_coordinator()->Register(
404 pattern,
405 script_url,
406 render_process_id_,
407 SaveRegistration(SERVICE_WORKER_OK, &registration_called, &registration));
409 bool unregistration_called = false;
410 job_coordinator()->Unregister(
411 pattern,
412 render_process_id_,
413 SaveUnregistration(SERVICE_WORKER_OK, &unregistration_called));
415 ASSERT_FALSE(registration_called);
416 ASSERT_FALSE(unregistration_called);
417 base::RunLoop().RunUntilIdle();
418 ASSERT_TRUE(registration_called);
419 ASSERT_TRUE(unregistration_called);
421 ASSERT_TRUE(registration->is_shutdown());
423 bool find_called = false;
424 storage()->FindRegistrationForPattern(
425 pattern,
426 SaveFoundRegistration(
427 SERVICE_WORKER_ERROR_NOT_FOUND, &find_called, &registration));
429 base::RunLoop().RunUntilIdle();
431 ASSERT_EQ(scoped_refptr<ServiceWorkerRegistration>(), registration);
434 // Register conflicting scripts for the same pattern. The most recent
435 // registration should win, and the old registration should have been
436 // shutdown.
437 TEST_F(ServiceWorkerJobTest, ParallelRegNewScript) {
438 GURL pattern("http://www.example.com/*");
440 GURL script_url1("http://www.example.com/service_worker1.js");
441 bool registration1_called = false;
442 scoped_refptr<ServiceWorkerRegistration> registration1;
443 job_coordinator()->Register(
444 pattern,
445 script_url1,
446 render_process_id_,
447 SaveRegistration(
448 SERVICE_WORKER_OK, &registration1_called, &registration1));
450 GURL script_url2("http://www.example.com/service_worker2.js");
451 bool registration2_called = false;
452 scoped_refptr<ServiceWorkerRegistration> registration2;
453 job_coordinator()->Register(
454 pattern,
455 script_url2,
456 render_process_id_,
457 SaveRegistration(
458 SERVICE_WORKER_OK, &registration2_called, &registration2));
460 ASSERT_FALSE(registration1_called);
461 ASSERT_FALSE(registration2_called);
462 base::RunLoop().RunUntilIdle();
463 ASSERT_TRUE(registration1_called);
464 ASSERT_TRUE(registration2_called);
466 scoped_refptr<ServiceWorkerRegistration> registration;
467 bool find_called = false;
468 storage()->FindRegistrationForPattern(
469 pattern,
470 SaveFoundRegistration(
471 SERVICE_WORKER_OK, &find_called, &registration));
473 base::RunLoop().RunUntilIdle();
475 EXPECT_TRUE(registration1->is_shutdown());
476 EXPECT_FALSE(registration2->is_shutdown());
477 ASSERT_EQ(registration2, registration);
480 // Register the exact same pattern + script. Requests should be
481 // coalesced such that both callers get the exact same registration
482 // object.
483 TEST_F(ServiceWorkerJobTest, ParallelRegSameScript) {
484 GURL pattern("http://www.example.com/*");
486 GURL script_url("http://www.example.com/service_worker1.js");
487 bool registration1_called = false;
488 scoped_refptr<ServiceWorkerRegistration> registration1;
489 job_coordinator()->Register(
490 pattern,
491 script_url,
492 render_process_id_,
493 SaveRegistration(
494 SERVICE_WORKER_OK, &registration1_called, &registration1));
496 bool registration2_called = false;
497 scoped_refptr<ServiceWorkerRegistration> registration2;
498 job_coordinator()->Register(
499 pattern,
500 script_url,
501 render_process_id_,
502 SaveRegistration(
503 SERVICE_WORKER_OK, &registration2_called, &registration2));
505 ASSERT_FALSE(registration1_called);
506 ASSERT_FALSE(registration2_called);
507 base::RunLoop().RunUntilIdle();
508 ASSERT_TRUE(registration1_called);
509 ASSERT_TRUE(registration2_called);
511 ASSERT_EQ(registration1, registration2);
513 scoped_refptr<ServiceWorkerRegistration> registration;
514 bool find_called = false;
515 storage()->FindRegistrationForPattern(
516 pattern,
517 SaveFoundRegistration(
518 SERVICE_WORKER_OK, &find_called, &registration));
520 base::RunLoop().RunUntilIdle();
521 ASSERT_EQ(registration, registration1);
524 // Call simulataneous unregister calls.
525 TEST_F(ServiceWorkerJobTest, ParallelUnreg) {
526 GURL pattern("http://www.example.com/*");
528 GURL script_url("http://www.example.com/service_worker.js");
529 bool unregistration1_called = false;
530 job_coordinator()->Unregister(
531 pattern,
532 render_process_id_,
533 SaveUnregistration(SERVICE_WORKER_OK, &unregistration1_called));
535 bool unregistration2_called = false;
536 job_coordinator()->Unregister(
537 pattern,
538 render_process_id_,
539 SaveUnregistration(SERVICE_WORKER_OK, &unregistration2_called));
541 ASSERT_FALSE(unregistration1_called);
542 ASSERT_FALSE(unregistration2_called);
543 base::RunLoop().RunUntilIdle();
544 ASSERT_TRUE(unregistration1_called);
545 ASSERT_TRUE(unregistration2_called);
547 // There isn't really a way to test that they are being coalesced,
548 // but we can make sure they can exist simultaneously without
549 // crashing.
550 scoped_refptr<ServiceWorkerRegistration> registration;
551 bool find_called = false;
552 storage()->FindRegistrationForPattern(
553 pattern,
554 SaveFoundRegistration(
555 SERVICE_WORKER_ERROR_NOT_FOUND, &find_called, &registration));
557 base::RunLoop().RunUntilIdle();
558 ASSERT_EQ(scoped_refptr<ServiceWorkerRegistration>(), registration);
561 } // namespace content