Add ICU message format support
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_context_unittest.cc
blobd299a2e3ba82856595694b2d966906b4f964bd19
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.
5 #include "content/public/browser/service_worker_context.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h"
10 #include "content/browser/browser_thread_impl.h"
11 #include "content/browser/service_worker/embedded_worker_registry.h"
12 #include "content/browser/service_worker/embedded_worker_test_helper.h"
13 #include "content/browser/service_worker/service_worker_context_core.h"
14 #include "content/browser/service_worker/service_worker_context_observer.h"
15 #include "content/browser/service_worker/service_worker_context_wrapper.h"
16 #include "content/browser/service_worker/service_worker_provider_host.h"
17 #include "content/browser/service_worker/service_worker_registration.h"
18 #include "content/browser/service_worker/service_worker_storage.h"
19 #include "content/common/service_worker/embedded_worker_messages.h"
20 #include "content/common/service_worker/service_worker_messages.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "content/public/test/test_utils.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 namespace content {
27 namespace {
29 void SaveResponseCallback(bool* called,
30 int64* store_registration_id,
31 ServiceWorkerStatusCode status,
32 const std::string& status_message,
33 int64 registration_id) {
34 EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
35 *called = true;
36 *store_registration_id = registration_id;
39 ServiceWorkerContextCore::RegistrationCallback MakeRegisteredCallback(
40 bool* called,
41 int64* store_registration_id) {
42 return base::Bind(&SaveResponseCallback, called, store_registration_id);
45 void CallCompletedCallback(bool* called, ServiceWorkerStatusCode) {
46 *called = true;
49 ServiceWorkerContextCore::UnregistrationCallback MakeUnregisteredCallback(
50 bool* called) {
51 return base::Bind(&CallCompletedCallback, called);
54 void ExpectRegisteredWorkers(
55 ServiceWorkerStatusCode expect_status,
56 bool expect_waiting,
57 bool expect_active,
58 ServiceWorkerStatusCode status,
59 const scoped_refptr<ServiceWorkerRegistration>& registration) {
60 ASSERT_EQ(expect_status, status);
61 if (status != SERVICE_WORKER_OK) {
62 EXPECT_FALSE(registration.get());
63 return;
66 if (expect_waiting) {
67 EXPECT_TRUE(registration->waiting_version());
68 } else {
69 EXPECT_FALSE(registration->waiting_version());
72 if (expect_active) {
73 EXPECT_TRUE(registration->active_version());
74 } else {
75 EXPECT_FALSE(registration->active_version());
79 class RejectInstallTestHelper : public EmbeddedWorkerTestHelper {
80 public:
81 explicit RejectInstallTestHelper(int mock_render_process_id)
82 : EmbeddedWorkerTestHelper(base::FilePath(), mock_render_process_id) {}
84 void OnInstallEvent(int embedded_worker_id,
85 int request_id) override {
86 SimulateSend(
87 new ServiceWorkerHostMsg_InstallEventFinished(
88 embedded_worker_id, request_id,
89 blink::WebServiceWorkerEventResultRejected));
93 class RejectActivateTestHelper : public EmbeddedWorkerTestHelper {
94 public:
95 explicit RejectActivateTestHelper(int mock_render_process_id)
96 : EmbeddedWorkerTestHelper(base::FilePath(), mock_render_process_id) {}
98 void OnActivateEvent(int embedded_worker_id, int request_id) override {
99 SimulateSend(
100 new ServiceWorkerHostMsg_ActivateEventFinished(
101 embedded_worker_id, request_id,
102 blink::WebServiceWorkerEventResultRejected));
106 enum NotificationType {
107 REGISTRATION_STORED,
108 REGISTRATION_DELETED,
109 STORAGE_RECOVERED,
112 struct NotificationLog {
113 NotificationType type;
114 GURL pattern;
115 int64 registration_id;
118 } // namespace
120 class ServiceWorkerContextTest : public ServiceWorkerContextObserver,
121 public testing::Test {
122 public:
123 ServiceWorkerContextTest()
124 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
125 render_process_id_(99) {}
127 void SetUp() override {
128 helper_.reset(
129 new EmbeddedWorkerTestHelper(base::FilePath(), render_process_id_));
130 helper_->context_wrapper()->AddObserver(this);
133 void TearDown() override { helper_.reset(); }
135 // ServiceWorkerContextObserver overrides.
136 void OnRegistrationStored(int64 registration_id,
137 const GURL& pattern) override {
138 NotificationLog log;
139 log.type = REGISTRATION_STORED;
140 log.pattern = pattern;
141 log.registration_id = registration_id;
142 notifications_.push_back(log);
144 void OnRegistrationDeleted(int64 registration_id,
145 const GURL& pattern) override {
146 NotificationLog log;
147 log.type = REGISTRATION_DELETED;
148 log.pattern = pattern;
149 log.registration_id = registration_id;
150 notifications_.push_back(log);
152 void OnStorageWiped() override {
153 NotificationLog log;
154 log.type = STORAGE_RECOVERED;
155 notifications_.push_back(log);
158 ServiceWorkerContextCore* context() { return helper_->context(); }
160 protected:
161 TestBrowserThreadBundle browser_thread_bundle_;
162 scoped_ptr<EmbeddedWorkerTestHelper> helper_;
163 const int render_process_id_;
164 std::vector<NotificationLog> notifications_;
167 // Make sure basic registration is working.
168 TEST_F(ServiceWorkerContextTest, Register) {
169 GURL pattern("http://www.example.com/");
170 GURL script_url("http://www.example.com/service_worker.js");
172 int64 registration_id = kInvalidServiceWorkerRegistrationId;
173 bool called = false;
174 context()->RegisterServiceWorker(
175 pattern,
176 script_url,
177 NULL,
178 MakeRegisteredCallback(&called, &registration_id));
180 ASSERT_FALSE(called);
181 base::RunLoop().RunUntilIdle();
182 EXPECT_TRUE(called);
184 EXPECT_EQ(4UL, helper_->ipc_sink()->message_count());
185 EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
186 EmbeddedWorkerMsg_StartWorker::ID));
187 EXPECT_TRUE(helper_->inner_ipc_sink()->GetUniqueMessageMatching(
188 ServiceWorkerMsg_InstallEvent::ID));
189 EXPECT_TRUE(helper_->inner_ipc_sink()->GetUniqueMessageMatching(
190 ServiceWorkerMsg_ActivateEvent::ID));
191 EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
192 EmbeddedWorkerMsg_StopWorker::ID));
193 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id);
195 ASSERT_EQ(1u, notifications_.size());
196 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
197 EXPECT_EQ(pattern, notifications_[0].pattern);
198 EXPECT_EQ(registration_id, notifications_[0].registration_id);
200 context()->storage()->FindRegistrationForId(
201 registration_id,
202 pattern.GetOrigin(),
203 base::Bind(&ExpectRegisteredWorkers,
204 SERVICE_WORKER_OK,
205 false /* expect_waiting */,
206 true /* expect_active */));
207 base::RunLoop().RunUntilIdle();
210 // Test registration when the service worker rejects the install event. The
211 // registration callback should indicate success, but there should be no waiting
212 // or active worker in the registration.
213 TEST_F(ServiceWorkerContextTest, Register_RejectInstall) {
214 GURL pattern("http://www.example.com/");
215 GURL script_url("http://www.example.com/service_worker.js");
217 helper_.reset(); // Make sure the process lookups stay overridden.
218 helper_.reset(new RejectInstallTestHelper(render_process_id_));
219 helper_->context_wrapper()->AddObserver(this);
220 int64 registration_id = kInvalidServiceWorkerRegistrationId;
221 bool called = false;
222 context()->RegisterServiceWorker(
223 pattern,
224 script_url,
225 NULL,
226 MakeRegisteredCallback(&called, &registration_id));
228 ASSERT_FALSE(called);
229 base::RunLoop().RunUntilIdle();
230 EXPECT_TRUE(called);
232 EXPECT_EQ(3UL, helper_->ipc_sink()->message_count());
233 EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
234 EmbeddedWorkerMsg_StartWorker::ID));
235 EXPECT_TRUE(helper_->inner_ipc_sink()->GetUniqueMessageMatching(
236 ServiceWorkerMsg_InstallEvent::ID));
237 EXPECT_FALSE(helper_->inner_ipc_sink()->GetUniqueMessageMatching(
238 ServiceWorkerMsg_ActivateEvent::ID));
239 EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
240 EmbeddedWorkerMsg_StopWorker::ID));
241 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id);
243 ASSERT_EQ(1u, notifications_.size());
244 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
245 EXPECT_EQ(pattern, notifications_[0].pattern);
246 EXPECT_EQ(registration_id, notifications_[0].registration_id);
248 context()->storage()->FindRegistrationForId(
249 registration_id,
250 pattern.GetOrigin(),
251 base::Bind(&ExpectRegisteredWorkers,
252 SERVICE_WORKER_ERROR_NOT_FOUND,
253 false /* expect_waiting */,
254 false /* expect_active */));
255 base::RunLoop().RunUntilIdle();
258 // Test registration when the service worker rejects the activate event. The
259 // worker should be activated anyway.
260 TEST_F(ServiceWorkerContextTest, Register_RejectActivate) {
261 GURL pattern("http://www.example.com/");
262 GURL script_url("http://www.example.com/service_worker.js");
264 helper_.reset();
265 helper_.reset(new RejectActivateTestHelper(render_process_id_));
266 helper_->context_wrapper()->AddObserver(this);
267 int64 registration_id = kInvalidServiceWorkerRegistrationId;
268 bool called = false;
269 context()->RegisterServiceWorker(
270 pattern, script_url, NULL,
271 MakeRegisteredCallback(&called, &registration_id));
273 ASSERT_FALSE(called);
274 base::RunLoop().RunUntilIdle();
275 EXPECT_TRUE(called);
277 EXPECT_EQ(4UL, helper_->ipc_sink()->message_count());
278 EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
279 EmbeddedWorkerMsg_StartWorker::ID));
280 EXPECT_TRUE(helper_->inner_ipc_sink()->GetUniqueMessageMatching(
281 ServiceWorkerMsg_InstallEvent::ID));
282 EXPECT_TRUE(helper_->inner_ipc_sink()->GetUniqueMessageMatching(
283 ServiceWorkerMsg_ActivateEvent::ID));
284 EXPECT_TRUE(helper_->ipc_sink()->GetUniqueMessageMatching(
285 EmbeddedWorkerMsg_StopWorker::ID));
286 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id);
288 ASSERT_EQ(1u, notifications_.size());
289 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
290 EXPECT_EQ(pattern, notifications_[0].pattern);
291 EXPECT_EQ(registration_id, notifications_[0].registration_id);
293 context()->storage()->FindRegistrationForId(
294 registration_id, pattern.GetOrigin(),
295 base::Bind(&ExpectRegisteredWorkers, SERVICE_WORKER_OK,
296 false /* expect_waiting */, true /* expect_active */));
297 base::RunLoop().RunUntilIdle();
300 // Make sure registrations are cleaned up when they are unregistered.
301 TEST_F(ServiceWorkerContextTest, Unregister) {
302 GURL pattern("http://www.example.com/");
304 bool called = false;
305 int64 registration_id = kInvalidServiceWorkerRegistrationId;
306 context()->RegisterServiceWorker(
307 pattern,
308 GURL("http://www.example.com/service_worker.js"),
309 NULL,
310 MakeRegisteredCallback(&called, &registration_id));
312 ASSERT_FALSE(called);
313 base::RunLoop().RunUntilIdle();
314 ASSERT_TRUE(called);
315 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id);
317 called = false;
318 context()->UnregisterServiceWorker(pattern,
319 MakeUnregisteredCallback(&called));
321 ASSERT_FALSE(called);
322 base::RunLoop().RunUntilIdle();
323 ASSERT_TRUE(called);
325 context()->storage()->FindRegistrationForId(
326 registration_id,
327 pattern.GetOrigin(),
328 base::Bind(&ExpectRegisteredWorkers,
329 SERVICE_WORKER_ERROR_NOT_FOUND,
330 false /* expect_waiting */,
331 false /* expect_active */));
332 base::RunLoop().RunUntilIdle();
334 ASSERT_EQ(2u, notifications_.size());
335 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
336 EXPECT_EQ(pattern, notifications_[0].pattern);
337 EXPECT_EQ(registration_id, notifications_[0].registration_id);
338 EXPECT_EQ(REGISTRATION_DELETED, notifications_[1].type);
339 EXPECT_EQ(pattern, notifications_[1].pattern);
340 EXPECT_EQ(registration_id, notifications_[1].registration_id);
343 // Make sure registrations are cleaned up when they are unregistered in bulk.
344 TEST_F(ServiceWorkerContextTest, UnregisterMultiple) {
345 GURL origin1_p1("http://www.example.com/test");
346 GURL origin1_p2("http://www.example.com/hello");
347 GURL origin2_p1("http://www.example.com:8080/again");
348 GURL origin3_p1("http://www.other.com/");
350 bool called = false;
351 int64 registration_id1 = kInvalidServiceWorkerRegistrationId;
352 int64 registration_id2 = kInvalidServiceWorkerRegistrationId;
353 int64 registration_id3 = kInvalidServiceWorkerRegistrationId;
354 int64 registration_id4 = kInvalidServiceWorkerRegistrationId;
355 context()->RegisterServiceWorker(
356 origin1_p1,
357 GURL("http://www.example.com/service_worker.js"),
358 NULL,
359 MakeRegisteredCallback(&called, &registration_id1));
360 context()->RegisterServiceWorker(
361 origin1_p2,
362 GURL("http://www.example.com/service_worker2.js"),
363 NULL,
364 MakeRegisteredCallback(&called, &registration_id2));
365 context()->RegisterServiceWorker(
366 origin2_p1,
367 GURL("http://www.example.com:8080/service_worker3.js"),
368 NULL,
369 MakeRegisteredCallback(&called, &registration_id3));
370 context()->RegisterServiceWorker(
371 origin3_p1,
372 GURL("http://www.other.com/service_worker4.js"),
373 NULL,
374 MakeRegisteredCallback(&called, &registration_id4));
376 ASSERT_FALSE(called);
377 base::RunLoop().RunUntilIdle();
378 ASSERT_TRUE(called);
380 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id1);
381 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id2);
382 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id3);
383 EXPECT_NE(kInvalidServiceWorkerRegistrationId, registration_id4);
385 called = false;
386 context()->UnregisterServiceWorkers(origin1_p1.GetOrigin(),
387 MakeUnregisteredCallback(&called));
389 ASSERT_FALSE(called);
390 base::RunLoop().RunUntilIdle();
391 ASSERT_TRUE(called);
393 context()->storage()->FindRegistrationForId(
394 registration_id1,
395 origin1_p1.GetOrigin(),
396 base::Bind(&ExpectRegisteredWorkers,
397 SERVICE_WORKER_ERROR_NOT_FOUND,
398 false /* expect_waiting */,
399 false /* expect_active */));
400 context()->storage()->FindRegistrationForId(
401 registration_id2,
402 origin1_p2.GetOrigin(),
403 base::Bind(&ExpectRegisteredWorkers,
404 SERVICE_WORKER_ERROR_NOT_FOUND,
405 false /* expect_waiting */,
406 false /* expect_active */));
407 context()->storage()->FindRegistrationForId(
408 registration_id3,
409 origin2_p1.GetOrigin(),
410 base::Bind(&ExpectRegisteredWorkers,
411 SERVICE_WORKER_OK,
412 false /* expect_waiting */,
413 true /* expect_active */));
415 context()->storage()->FindRegistrationForId(
416 registration_id4,
417 origin3_p1.GetOrigin(),
418 base::Bind(&ExpectRegisteredWorkers,
419 SERVICE_WORKER_OK,
420 false /* expect_waiting */,
421 true /* expect_active */));
423 base::RunLoop().RunUntilIdle();
425 ASSERT_EQ(6u, notifications_.size());
426 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
427 EXPECT_EQ(registration_id1, notifications_[0].registration_id);
428 EXPECT_EQ(origin1_p1, notifications_[0].pattern);
429 EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
430 EXPECT_EQ(origin1_p2, notifications_[1].pattern);
431 EXPECT_EQ(registration_id2, notifications_[1].registration_id);
432 EXPECT_EQ(REGISTRATION_STORED, notifications_[2].type);
433 EXPECT_EQ(origin2_p1, notifications_[2].pattern);
434 EXPECT_EQ(registration_id3, notifications_[2].registration_id);
435 EXPECT_EQ(REGISTRATION_STORED, notifications_[3].type);
436 EXPECT_EQ(origin3_p1, notifications_[3].pattern);
437 EXPECT_EQ(registration_id4, notifications_[3].registration_id);
438 EXPECT_EQ(REGISTRATION_DELETED, notifications_[4].type);
439 EXPECT_EQ(origin1_p2, notifications_[4].pattern);
440 EXPECT_EQ(registration_id2, notifications_[4].registration_id);
441 EXPECT_EQ(REGISTRATION_DELETED, notifications_[5].type);
442 EXPECT_EQ(origin1_p1, notifications_[5].pattern);
443 EXPECT_EQ(registration_id1, notifications_[5].registration_id);
446 // Make sure registering a new script shares an existing registration.
447 TEST_F(ServiceWorkerContextTest, RegisterNewScript) {
448 GURL pattern("http://www.example.com/");
450 bool called = false;
451 int64 old_registration_id = kInvalidServiceWorkerRegistrationId;
452 context()->RegisterServiceWorker(
453 pattern,
454 GURL("http://www.example.com/service_worker.js"),
455 NULL,
456 MakeRegisteredCallback(&called, &old_registration_id));
458 ASSERT_FALSE(called);
459 base::RunLoop().RunUntilIdle();
460 ASSERT_TRUE(called);
461 EXPECT_NE(kInvalidServiceWorkerRegistrationId, old_registration_id);
463 called = false;
464 int64 new_registration_id = kInvalidServiceWorkerRegistrationId;
465 context()->RegisterServiceWorker(
466 pattern,
467 GURL("http://www.example.com/service_worker_new.js"),
468 NULL,
469 MakeRegisteredCallback(&called, &new_registration_id));
471 ASSERT_FALSE(called);
472 base::RunLoop().RunUntilIdle();
473 ASSERT_TRUE(called);
475 EXPECT_NE(kInvalidServiceWorkerRegistrationId, new_registration_id);
476 EXPECT_EQ(old_registration_id, new_registration_id);
478 ASSERT_EQ(2u, notifications_.size());
479 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
480 EXPECT_EQ(pattern, notifications_[0].pattern);
481 EXPECT_EQ(old_registration_id, notifications_[0].registration_id);
482 EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
483 EXPECT_EQ(pattern, notifications_[1].pattern);
484 EXPECT_EQ(new_registration_id, notifications_[1].registration_id);
487 // Make sure that when registering a duplicate pattern+script_url
488 // combination, that the same registration is used.
489 TEST_F(ServiceWorkerContextTest, RegisterDuplicateScript) {
490 GURL pattern("http://www.example.com/");
491 GURL script_url("http://www.example.com/service_worker.js");
493 bool called = false;
494 int64 old_registration_id = kInvalidServiceWorkerRegistrationId;
495 context()->RegisterServiceWorker(
496 pattern,
497 script_url,
498 NULL,
499 MakeRegisteredCallback(&called, &old_registration_id));
501 ASSERT_FALSE(called);
502 base::RunLoop().RunUntilIdle();
503 ASSERT_TRUE(called);
504 EXPECT_NE(kInvalidServiceWorkerRegistrationId, old_registration_id);
506 called = false;
507 int64 new_registration_id = kInvalidServiceWorkerRegistrationId;
508 context()->RegisterServiceWorker(
509 pattern,
510 script_url,
511 NULL,
512 MakeRegisteredCallback(&called, &new_registration_id));
514 ASSERT_FALSE(called);
515 base::RunLoop().RunUntilIdle();
516 ASSERT_TRUE(called);
517 EXPECT_EQ(old_registration_id, new_registration_id);
519 ASSERT_EQ(2u, notifications_.size());
520 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
521 EXPECT_EQ(pattern, notifications_[0].pattern);
522 EXPECT_EQ(old_registration_id, notifications_[0].registration_id);
523 EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
524 EXPECT_EQ(pattern, notifications_[1].pattern);
525 EXPECT_EQ(old_registration_id, notifications_[1].registration_id);
528 TEST_F(ServiceWorkerContextTest, ProviderHostIterator) {
529 const int kRenderProcessId1 = 1;
530 const int kRenderProcessId2 = 2;
531 const GURL kOrigin1 = GURL("http://www.example.com/");
532 const GURL kOrigin2 = GURL("https://www.example.com/");
533 int provider_id = 1;
535 // Host1 (provider_id=1): process_id=1, origin1.
536 ServiceWorkerProviderHost* host1(new ServiceWorkerProviderHost(
537 kRenderProcessId1, MSG_ROUTING_NONE, provider_id++,
538 SERVICE_WORKER_PROVIDER_FOR_WINDOW, context()->AsWeakPtr(), nullptr));
539 host1->SetDocumentUrl(kOrigin1);
541 // Host2 (provider_id=2): process_id=2, origin2.
542 ServiceWorkerProviderHost* host2(new ServiceWorkerProviderHost(
543 kRenderProcessId2, MSG_ROUTING_NONE, provider_id++,
544 SERVICE_WORKER_PROVIDER_FOR_WINDOW, context()->AsWeakPtr(), nullptr));
545 host2->SetDocumentUrl(kOrigin2);
547 // Host3 (provider_id=3): process_id=2, origin1.
548 ServiceWorkerProviderHost* host3(new ServiceWorkerProviderHost(
549 kRenderProcessId2, MSG_ROUTING_NONE, provider_id++,
550 SERVICE_WORKER_PROVIDER_FOR_WINDOW, context()->AsWeakPtr(), nullptr));
551 host3->SetDocumentUrl(kOrigin1);
553 // Host4 (provider_id=4): process_id=2, origin2, for ServiceWorker.
554 ServiceWorkerProviderHost* host4(new ServiceWorkerProviderHost(
555 kRenderProcessId2, MSG_ROUTING_NONE, provider_id++,
556 SERVICE_WORKER_PROVIDER_FOR_CONTROLLER, context()->AsWeakPtr(), nullptr));
557 host4->SetDocumentUrl(kOrigin2);
559 context()->AddProviderHost(make_scoped_ptr(host1));
560 context()->AddProviderHost(make_scoped_ptr(host2));
561 context()->AddProviderHost(make_scoped_ptr(host3));
562 context()->AddProviderHost(make_scoped_ptr(host4));
564 // Iterate over all provider hosts.
565 std::set<ServiceWorkerProviderHost*> results;
566 for (auto it = context()->GetProviderHostIterator(); !it->IsAtEnd();
567 it->Advance()) {
568 results.insert(it->GetProviderHost());
570 EXPECT_EQ(4u, results.size());
571 EXPECT_TRUE(ContainsKey(results, host1));
572 EXPECT_TRUE(ContainsKey(results, host2));
573 EXPECT_TRUE(ContainsKey(results, host3));
574 EXPECT_TRUE(ContainsKey(results, host4));
576 // Iterate over the client provider hosts that belong to kOrigin1.
577 results.clear();
578 for (auto it = context()->GetClientProviderHostIterator(kOrigin1);
579 !it->IsAtEnd(); it->Advance()) {
580 results.insert(it->GetProviderHost());
582 EXPECT_EQ(2u, results.size());
583 EXPECT_TRUE(ContainsKey(results, host1));
584 EXPECT_TRUE(ContainsKey(results, host3));
586 // Iterate over the provider hosts that belong to kOrigin2.
587 // (This should not include host4 as it's not for controllee.)
588 results.clear();
589 for (auto it = context()->GetClientProviderHostIterator(kOrigin2);
590 !it->IsAtEnd(); it->Advance()) {
591 results.insert(it->GetProviderHost());
593 EXPECT_EQ(1u, results.size());
594 EXPECT_TRUE(ContainsKey(results, host2));
596 context()->RemoveProviderHost(kRenderProcessId1, 1);
597 context()->RemoveProviderHost(kRenderProcessId2, 2);
598 context()->RemoveProviderHost(kRenderProcessId2, 3);
599 context()->RemoveProviderHost(kRenderProcessId2, 4);
602 class ServiceWorkerContextRecoveryTest
603 : public ServiceWorkerContextTest,
604 public testing::WithParamInterface<bool> {
605 public:
606 ServiceWorkerContextRecoveryTest() {}
607 virtual ~ServiceWorkerContextRecoveryTest() {}
610 INSTANTIATE_TEST_CASE_P(ServiceWorkerContextRecoveryTest,
611 ServiceWorkerContextRecoveryTest,
612 testing::Values(true, false));
614 TEST_P(ServiceWorkerContextRecoveryTest, DeleteAndStartOver) {
615 GURL pattern("http://www.example.com/");
616 GURL script_url("http://www.example.com/service_worker.js");
618 bool is_storage_on_disk = GetParam();
619 if (is_storage_on_disk) {
620 // Reinitialize the helper to test on-disk storage.
621 base::ScopedTempDir user_data_directory;
622 ASSERT_TRUE(user_data_directory.CreateUniqueTempDir());
623 helper_.reset(new EmbeddedWorkerTestHelper(user_data_directory.path(),
624 render_process_id_));
625 helper_->context_wrapper()->AddObserver(this);
628 int64 registration_id = kInvalidServiceWorkerRegistrationId;
629 bool called = false;
630 context()->RegisterServiceWorker(
631 pattern,
632 script_url,
633 NULL,
634 MakeRegisteredCallback(&called, &registration_id));
636 ASSERT_FALSE(called);
637 base::RunLoop().RunUntilIdle();
638 EXPECT_TRUE(called);
640 context()->storage()->FindRegistrationForId(
641 registration_id,
642 pattern.GetOrigin(),
643 base::Bind(&ExpectRegisteredWorkers,
644 SERVICE_WORKER_OK,
645 false /* expect_waiting */,
646 true /* expect_active */));
647 base::RunLoop().RunUntilIdle();
649 // Next handle ids should be 0 (the next call should return 1).
650 EXPECT_EQ(0, context()->GetNewServiceWorkerHandleId());
651 EXPECT_EQ(0, context()->GetNewRegistrationHandleId());
653 context()->ScheduleDeleteAndStartOver();
655 // The storage is disabled while the recovery process is running, so the
656 // operation should be failed.
657 context()->storage()->FindRegistrationForId(
658 registration_id,
659 pattern.GetOrigin(),
660 base::Bind(&ExpectRegisteredWorkers,
661 SERVICE_WORKER_ERROR_FAILED,
662 false /* expect_waiting */,
663 true /* expect_active */));
664 base::RunLoop().RunUntilIdle();
666 // The context started over and the storage was re-initialized, so the
667 // registration should not be found.
668 context()->storage()->FindRegistrationForId(
669 registration_id,
670 pattern.GetOrigin(),
671 base::Bind(&ExpectRegisteredWorkers,
672 SERVICE_WORKER_ERROR_NOT_FOUND,
673 false /* expect_waiting */,
674 true /* expect_active */));
675 base::RunLoop().RunUntilIdle();
677 called = false;
678 context()->RegisterServiceWorker(
679 pattern,
680 script_url,
681 NULL,
682 MakeRegisteredCallback(&called, &registration_id));
684 ASSERT_FALSE(called);
685 base::RunLoop().RunUntilIdle();
686 EXPECT_TRUE(called);
688 context()->storage()->FindRegistrationForId(
689 registration_id,
690 pattern.GetOrigin(),
691 base::Bind(&ExpectRegisteredWorkers,
692 SERVICE_WORKER_OK,
693 false /* expect_waiting */,
694 true /* expect_active */));
695 base::RunLoop().RunUntilIdle();
697 // The new context should take over next handle ids.
698 EXPECT_EQ(1, context()->GetNewServiceWorkerHandleId());
699 EXPECT_EQ(1, context()->GetNewRegistrationHandleId());
701 ASSERT_EQ(3u, notifications_.size());
702 EXPECT_EQ(REGISTRATION_STORED, notifications_[0].type);
703 EXPECT_EQ(pattern, notifications_[0].pattern);
704 EXPECT_EQ(registration_id, notifications_[0].registration_id);
705 EXPECT_EQ(STORAGE_RECOVERED, notifications_[1].type);
706 EXPECT_EQ(REGISTRATION_STORED, notifications_[2].type);
707 EXPECT_EQ(pattern, notifications_[2].pattern);
708 EXPECT_EQ(registration_id, notifications_[2].registration_id);
712 } // namespace content