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.
4 
5 #include "content/public/browser/service_worker_context.h"
6 
7 #include <stdint.h>
8 
9 #include "base/bind.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/logging.h"
12 #include "base/run_loop.h"
13 #include "base/scoped_observer.h"
14 #include "base/time/time.h"
15 #include "content/browser/service_worker/embedded_worker_test_helper.h"
16 #include "content/browser/service_worker/fake_embedded_worker_instance_client.h"
17 #include "content/browser/service_worker/service_worker_container_host.h"
18 #include "content/browser/service_worker/service_worker_context_core.h"
19 #include "content/browser/service_worker/service_worker_context_core_observer.h"
20 #include "content/browser/service_worker/service_worker_context_wrapper.h"
21 #include "content/browser/service_worker/service_worker_metrics.h"
22 #include "content/browser/service_worker/service_worker_provider_host.h"
23 #include "content/browser/service_worker/service_worker_registration.h"
24 #include "content/browser/service_worker/service_worker_storage.h"
25 #include "content/browser/service_worker/service_worker_test_utils.h"
26 #include "content/browser/service_worker/service_worker_version.h"
27 #include "content/public/browser/service_worker_context_observer.h"
28 #include "content/public/test/browser_task_environment.h"
29 #include "content/public/test/test_utils.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "third_party/blink/public/common/service_worker/service_worker_types.h"
32 #include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
33 #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
34 
35 namespace content {
36 
37 namespace {
38 
SaveResponseCallback(bool * called,int64_t * store_registration_id,blink::ServiceWorkerStatusCode status,const std::string & status_message,int64_t registration_id)39 void SaveResponseCallback(bool* called,
40                           int64_t* store_registration_id,
41                           blink::ServiceWorkerStatusCode status,
42                           const std::string& status_message,
43                           int64_t registration_id) {
44   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
45       << blink::ServiceWorkerStatusToString(status);
46   *called = true;
47   *store_registration_id = registration_id;
48 }
49 
MakeRegisteredCallback(bool * called,int64_t * store_registration_id)50 ServiceWorkerContextCore::RegistrationCallback MakeRegisteredCallback(
51     bool* called,
52     int64_t* store_registration_id) {
53   return base::BindOnce(&SaveResponseCallback, called, store_registration_id);
54 }
55 
RegisteredCallback(base::OnceClosure quit_closure,blink::ServiceWorkerStatusCode status,const std::string & status_message,int64_t registration_id)56 void RegisteredCallback(base::OnceClosure quit_closure,
57                         blink::ServiceWorkerStatusCode status,
58                         const std::string& status_message,
59                         int64_t registration_id) {
60   std::move(quit_closure).Run();
61 }
62 
CallCompletedCallback(bool * called,blink::ServiceWorkerStatusCode)63 void CallCompletedCallback(bool* called, blink::ServiceWorkerStatusCode) {
64   *called = true;
65 }
66 
MakeUnregisteredCallback(bool * called)67 ServiceWorkerContextCore::UnregistrationCallback MakeUnregisteredCallback(
68     bool* called) {
69   return base::BindOnce(&CallCompletedCallback, called);
70 }
71 
ExpectRegisteredWorkers(blink::ServiceWorkerStatusCode expect_status,bool expect_waiting,bool expect_active,blink::ServiceWorkerStatusCode status,scoped_refptr<ServiceWorkerRegistration> registration)72 void ExpectRegisteredWorkers(
73     blink::ServiceWorkerStatusCode expect_status,
74     bool expect_waiting,
75     bool expect_active,
76     blink::ServiceWorkerStatusCode status,
77     scoped_refptr<ServiceWorkerRegistration> registration) {
78   ASSERT_EQ(expect_status, status);
79   if (status != blink::ServiceWorkerStatusCode::kOk) {
80     EXPECT_FALSE(registration.get());
81     return;
82   }
83 
84   if (expect_waiting) {
85     EXPECT_TRUE(registration->waiting_version());
86   } else {
87     EXPECT_FALSE(registration->waiting_version());
88   }
89 
90   if (expect_active) {
91     EXPECT_TRUE(registration->active_version());
92   } else {
93     EXPECT_FALSE(registration->active_version());
94   }
95 
96   EXPECT_EQ(blink::mojom::ServiceWorkerUpdateViaCache::kImports,
97             registration->update_via_cache());
98 }
99 
100 class InstallActivateWorker : public FakeServiceWorker {
101  public:
InstallActivateWorker(EmbeddedWorkerTestHelper * helper)102   explicit InstallActivateWorker(EmbeddedWorkerTestHelper* helper)
103       : FakeServiceWorker(helper) {}
104   ~InstallActivateWorker() override = default;
105 
events() const106   const std::vector<ServiceWorkerMetrics::EventType>& events() const {
107     return events_;
108   }
109 
SetToRejectInstall()110   void SetToRejectInstall() { reject_install_ = true; }
111 
SetToRejectActivate()112   void SetToRejectActivate() { reject_activate_ = true; }
113 
DispatchInstallEvent(blink::mojom::ServiceWorker::DispatchInstallEventCallback callback)114   void DispatchInstallEvent(
115       blink::mojom::ServiceWorker::DispatchInstallEventCallback callback)
116       override {
117     events_.emplace_back(ServiceWorkerMetrics::EventType::INSTALL);
118     std::move(callback).Run(
119         reject_install_ ? blink::mojom::ServiceWorkerEventStatus::REJECTED
120                         : blink::mojom::ServiceWorkerEventStatus::COMPLETED);
121   }
122 
DispatchActivateEvent(blink::mojom::ServiceWorker::DispatchActivateEventCallback callback)123   void DispatchActivateEvent(
124       blink::mojom::ServiceWorker::DispatchActivateEventCallback callback)
125       override {
126     events_.emplace_back(ServiceWorkerMetrics::EventType::ACTIVATE);
127     std::move(callback).Run(
128         reject_activate_ ? blink::mojom::ServiceWorkerEventStatus::REJECTED
129                          : blink::mojom::ServiceWorkerEventStatus::COMPLETED);
130   }
131 
OnConnectionError()132   void OnConnectionError() override {
133     // Do nothing. This allows the object to stay until the test is over, so
134     // |events_| can be accessed even after the worker is stopped in the case of
135     // rejected install.
136   }
137 
138  private:
139   std::vector<ServiceWorkerMetrics::EventType> events_;
140   bool reject_install_ = false;
141   bool reject_activate_ = false;
142 };
143 
144 enum NotificationType {
145   REGISTRATION_COMPLETED,
146   REGISTRATION_STORED,
147   REGISTRATION_DELETED,
148   STORAGE_RECOVERED,
149 };
150 
151 struct NotificationLog {
152   NotificationType type;
153   GURL scope;
154   int64_t registration_id;
155 };
156 
157 }  // namespace
158 
159 class ServiceWorkerContextTest : public ServiceWorkerContextCoreObserver,
160                                  public testing::Test {
161  public:
ServiceWorkerContextTest()162   ServiceWorkerContextTest()
163       : task_environment_(BrowserTaskEnvironment::IO_MAINLOOP) {}
164 
SetUp()165   void SetUp() override {
166     helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
167     helper_->context_wrapper()->AddObserver(this);
168   }
169 
TearDown()170   void TearDown() override {
171     helper_.reset();
172     // The helper may post tasks to release resources in |temp_dir_|. Allow
173     // them to run now so that the directory may be deleted.
174     task_environment_.RunUntilIdle();
175     EXPECT_TRUE(!temp_dir_.IsValid() || temp_dir_.Delete())
176         << temp_dir_.GetPath();
177   }
178 
179   // ServiceWorkerContextCoreObserver overrides.
OnRegistrationCompleted(int64_t registration_id,const GURL & scope)180   void OnRegistrationCompleted(int64_t registration_id,
181                                const GURL& scope) override {
182     NotificationLog log;
183     log.type = REGISTRATION_COMPLETED;
184     log.scope = scope;
185     log.registration_id = registration_id;
186     notifications_.push_back(log);
187   }
OnRegistrationStored(int64_t registration_id,const GURL & scope)188   void OnRegistrationStored(int64_t registration_id,
189                             const GURL& scope) override {
190     NotificationLog log;
191     log.type = REGISTRATION_STORED;
192     log.scope = scope;
193     log.registration_id = registration_id;
194     notifications_.push_back(log);
195   }
OnRegistrationDeleted(int64_t registration_id,const GURL & scope)196   void OnRegistrationDeleted(int64_t registration_id,
197                              const GURL& scope) override {
198     NotificationLog log;
199     log.type = REGISTRATION_DELETED;
200     log.scope = scope;
201     log.registration_id = registration_id;
202     notifications_.push_back(log);
203   }
OnStorageWiped()204   void OnStorageWiped() override {
205     NotificationLog log;
206     log.type = STORAGE_RECOVERED;
207     notifications_.push_back(log);
208   }
209 
context()210   ServiceWorkerContextCore* context() { return helper_->context(); }
context_wrapper()211   ServiceWorkerContextWrapper* context_wrapper() {
212     return helper_->context_wrapper();
213   }
GetTemporaryDirectory(base::FilePath * temp_dir)214   void GetTemporaryDirectory(base::FilePath* temp_dir) {
215     ASSERT_FALSE(temp_dir_.IsValid());
216     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
217     *temp_dir = temp_dir_.GetPath();
218   }
219 
220  protected:
221   base::ScopedTempDir temp_dir_;
222   BrowserTaskEnvironment task_environment_;
223   std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
224   std::vector<NotificationLog> notifications_;
225 };
226 
227 class RecordableEmbeddedWorkerInstanceClient
228     : public FakeEmbeddedWorkerInstanceClient {
229  public:
230   enum class Message { StartWorker, StopWorker };
231 
RecordableEmbeddedWorkerInstanceClient(EmbeddedWorkerTestHelper * helper)232   explicit RecordableEmbeddedWorkerInstanceClient(
233       EmbeddedWorkerTestHelper* helper)
234       : FakeEmbeddedWorkerInstanceClient(helper) {}
235 
OnConnectionError()236   void OnConnectionError() override {
237     // Do nothing. This allows the object to stay until the test is over, so
238     // |events_| can be accessed even after the worker is stopped in the case of
239     // rejected install.
240   }
241 
events() const242   const std::vector<Message>& events() const { return events_; }
243 
244  protected:
StartWorker(blink::mojom::EmbeddedWorkerStartParamsPtr params)245   void StartWorker(blink::mojom::EmbeddedWorkerStartParamsPtr params) override {
246     events_.push_back(Message::StartWorker);
247     FakeEmbeddedWorkerInstanceClient::StartWorker(std::move(params));
248   }
249 
StopWorker()250   void StopWorker() override {
251     events_.push_back(Message::StopWorker);
252 
253     // Let stop complete, but don't call the base class's StopWorker(), which
254     // would destroy |this| before the test can retrieve events().
255     host()->OnStopped();
256   }
257 
258  private:
259   std::vector<Message> events_;
260   DISALLOW_COPY_AND_ASSIGN(RecordableEmbeddedWorkerInstanceClient);
261 };
262 
263 class TestServiceWorkerContextObserver : public ServiceWorkerContextObserver {
264  public:
265   enum class EventType {
266     RegistrationCompleted,
267     RegistrationStored,
268     VersionActivated,
269     VersionRedundant,
270     NoControllees,
271     VersionStartedRunning,
272     VersionStoppedRunning,
273     Destruct
274   };
275   struct EventLog {
276     EventType type;
277     base::Optional<GURL> url;
278     base::Optional<int64_t> version_id;
279     base::Optional<int64_t> registration_id;
280     base::Optional<bool> is_running;
281   };
282 
TestServiceWorkerContextObserver(ServiceWorkerContext * context)283   explicit TestServiceWorkerContextObserver(ServiceWorkerContext* context)
284       : scoped_observer_(this) {
285     scoped_observer_.Add(context);
286   }
287 
288   ~TestServiceWorkerContextObserver() override = default;
289 
OnRegistrationCompleted(const GURL & scope)290   void OnRegistrationCompleted(const GURL& scope) override {
291     EventLog log;
292     log.type = EventType::RegistrationCompleted;
293     log.url = scope;
294     events_.push_back(log);
295   }
296 
OnRegistrationStored(int64_t registration_id,const GURL & scope)297   void OnRegistrationStored(int64_t registration_id,
298                             const GURL& scope) override {
299     EventLog log;
300     log.type = EventType::RegistrationStored;
301     log.registration_id = registration_id;
302     log.url = scope;
303     events_.push_back(log);
304   }
305 
OnVersionActivated(int64_t version_id,const GURL & scope)306   void OnVersionActivated(int64_t version_id, const GURL& scope) override {
307     EventLog log;
308     log.type = EventType::VersionActivated;
309     log.version_id = version_id;
310     log.url = scope;
311     events_.push_back(log);
312   }
313 
OnVersionRedundant(int64_t version_id,const GURL & scope)314   void OnVersionRedundant(int64_t version_id, const GURL& scope) override {
315     EventLog log;
316     log.type = EventType::VersionRedundant;
317     log.version_id = version_id;
318     log.url = scope;
319     events_.push_back(log);
320   }
321 
OnNoControllees(int64_t version_id,const GURL & scope)322   void OnNoControllees(int64_t version_id, const GURL& scope) override {
323     EventLog log;
324     log.type = EventType::NoControllees;
325     log.version_id = version_id;
326     log.url = scope;
327     events_.push_back(log);
328   }
329 
OnVersionStartedRunning(int64_t version_id,const ServiceWorkerRunningInfo & running_info)330   void OnVersionStartedRunning(
331       int64_t version_id,
332       const ServiceWorkerRunningInfo& running_info) override {
333     EventLog log;
334     log.type = EventType::VersionStartedRunning;
335     log.version_id = version_id;
336     events_.push_back(log);
337   }
338 
OnVersionStoppedRunning(int64_t version_id)339   void OnVersionStoppedRunning(int64_t version_id) override {
340     EventLog log;
341     log.type = EventType::VersionStoppedRunning;
342     log.version_id = version_id;
343     events_.push_back(log);
344   }
345 
OnDestruct(content::ServiceWorkerContext * context)346   void OnDestruct(content::ServiceWorkerContext* context) override {
347     scoped_observer_.Remove(context);
348 
349     EventLog log;
350     log.type = EventType::Destruct;
351     events_.push_back(log);
352   }
353 
events()354   const std::vector<EventLog>& events() { return events_; }
355 
356  private:
357   ScopedObserver<ServiceWorkerContext, ServiceWorkerContextObserver>
358       scoped_observer_;
359   std::vector<EventLog> events_;
360   DISALLOW_COPY_AND_ASSIGN(TestServiceWorkerContextObserver);
361 };
362 
363 // Make sure OnRegistrationCompleted is called on observer.
TEST_F(ServiceWorkerContextTest,RegistrationCompletedObserver)364 TEST_F(ServiceWorkerContextTest, RegistrationCompletedObserver) {
365   GURL scope("https://www.example.com/");
366   GURL script_url("https://www.example.com/service_worker.js");
367   blink::mojom::ServiceWorkerRegistrationOptions options;
368   options.scope = scope;
369 
370   TestServiceWorkerContextObserver observer(context_wrapper());
371 
372   int64_t registration_id = blink::mojom::kInvalidServiceWorkerRegistrationId;
373   bool called = false;
374   context()->RegisterServiceWorker(
375       script_url, options, blink::mojom::FetchClientSettingsObject::New(),
376       MakeRegisteredCallback(&called, &registration_id));
377   base::RunLoop().RunUntilIdle();
378 
379   ASSERT_TRUE(called);
380   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, registration_id);
381 
382   std::vector<TestServiceWorkerContextObserver::EventLog> events;
383 
384   // Filter the events to be verified.
385   for (auto event : observer.events()) {
386     if (event.type == TestServiceWorkerContextObserver::EventType::
387                           RegistrationCompleted ||
388         event.type ==
389             TestServiceWorkerContextObserver::EventType::RegistrationStored ||
390         event.type ==
391             TestServiceWorkerContextObserver::EventType::VersionActivated)
392       events.push_back(event);
393   }
394   ASSERT_EQ(3u, events.size());
395   EXPECT_EQ(TestServiceWorkerContextObserver::EventType::RegistrationCompleted,
396             events[0].type);
397   EXPECT_EQ(scope, events[0].url);
398   EXPECT_EQ(TestServiceWorkerContextObserver::EventType::RegistrationStored,
399             events[1].type);
400   EXPECT_EQ(scope, events[1].url);
401   EXPECT_EQ(registration_id, events[1].registration_id);
402   EXPECT_EQ(TestServiceWorkerContextObserver::EventType::VersionActivated,
403             events[2].type);
404   EXPECT_EQ(scope, events[2].url);
405 }
406 
407 // Make sure OnNoControllees is called on observer.
TEST_F(ServiceWorkerContextTest,NoControlleesObserver)408 TEST_F(ServiceWorkerContextTest, NoControlleesObserver) {
409   GURL scope("https://www.example.com/");
410   GURL script_url("https://www.example.com/service_worker.js");
411   blink::mojom::ServiceWorkerRegistrationOptions options;
412   options.scope = scope;
413 
414   auto registration = base::MakeRefCounted<ServiceWorkerRegistration>(
415       options, 1l /* dummy registration id */, context()->AsWeakPtr());
416 
417   auto version = base::MakeRefCounted<ServiceWorkerVersion>(
418       registration.get(), script_url, blink::mojom::ScriptType::kClassic,
419       2l /* dummy version id */, context()->AsWeakPtr());
420   version->set_fetch_handler_existence(
421       ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
422   version->SetStatus(ServiceWorkerVersion::ACTIVATED);
423 
424   ServiceWorkerRemoteProviderEndpoint endpoint;
425   base::WeakPtr<ServiceWorkerContainerHost> container_host =
426       CreateContainerHostForWindow(helper_->mock_render_process_id(), true,
427                                    context()->AsWeakPtr(), &endpoint);
428 
429   version->AddControllee(container_host.get());
430   base::RunLoop().RunUntilIdle();
431 
432   TestServiceWorkerContextObserver observer(context_wrapper());
433 
434   version->RemoveControllee(container_host->client_uuid());
435   base::RunLoop().RunUntilIdle();
436 
437   ASSERT_EQ(1u, observer.events().size());
438   EXPECT_EQ(TestServiceWorkerContextObserver::EventType::NoControllees,
439             observer.events()[0].type);
440   EXPECT_EQ(scope, observer.events()[0].url);
441   EXPECT_EQ(2l, observer.events()[0].version_id);
442 }
443 
444 // Make sure OnVersionActivated is called on observer.
TEST_F(ServiceWorkerContextTest,VersionActivatedObserver)445 TEST_F(ServiceWorkerContextTest, VersionActivatedObserver) {
446   GURL scope("https://www.example.com/");
447   GURL script_url("https://www.example.com/service_worker.js");
448   blink::mojom::ServiceWorkerRegistrationOptions options;
449   options.scope = scope;
450 
451   auto registration = base::MakeRefCounted<ServiceWorkerRegistration>(
452       options, 1l /* dummy registration id */, context()->AsWeakPtr());
453 
454   auto version = base::MakeRefCounted<ServiceWorkerVersion>(
455       registration.get(), script_url, blink::mojom::ScriptType::kClassic,
456       2l /* dummy version id */, context()->AsWeakPtr());
457 
458   TestServiceWorkerContextObserver observer(context_wrapper());
459 
460   version->set_fetch_handler_existence(
461       ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST);
462   version->SetStatus(ServiceWorkerVersion::Status::ACTIVATED);
463   base::RunLoop().RunUntilIdle();
464 
465   ASSERT_EQ(1u, observer.events().size());
466   EXPECT_EQ(TestServiceWorkerContextObserver::EventType::VersionActivated,
467             observer.events()[0].type);
468   EXPECT_EQ(2l, observer.events()[0].version_id);
469 }
470 
471 // Make sure OnVersionRedundant is called on observer.
TEST_F(ServiceWorkerContextTest,VersionRedundantObserver)472 TEST_F(ServiceWorkerContextTest, VersionRedundantObserver) {
473   GURL scope("https://www.example.com/");
474   GURL script_url("https://www.example.com/service_worker.js");
475   blink::mojom::ServiceWorkerRegistrationOptions options;
476   options.scope = scope;
477 
478   auto registration = base::MakeRefCounted<ServiceWorkerRegistration>(
479       options, 1l /* dummy registration id */, context()->AsWeakPtr());
480 
481   auto version = base::MakeRefCounted<ServiceWorkerVersion>(
482       registration.get(), script_url, blink::mojom::ScriptType::kClassic,
483       2l /* dummy version id */, context()->AsWeakPtr());
484 
485   TestServiceWorkerContextObserver observer(context_wrapper());
486 
487   version->set_fetch_handler_existence(
488       ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST);
489   version->SetStatus(ServiceWorkerVersion::Status::REDUNDANT);
490   base::RunLoop().RunUntilIdle();
491 
492   ASSERT_EQ(1u, observer.events().size());
493   EXPECT_EQ(TestServiceWorkerContextObserver::EventType::VersionRedundant,
494             observer.events()[0].type);
495   EXPECT_EQ(2l, observer.events()[0].version_id);
496 }
497 
498 // Make sure OnVersionStartedRunning and OnVersionStoppedRunning are called on
499 // observer.
TEST_F(ServiceWorkerContextTest,OnVersionRunningStatusChangedObserver)500 TEST_F(ServiceWorkerContextTest, OnVersionRunningStatusChangedObserver) {
501   GURL scope("https://www.example.com/");
502   GURL script_url("https://www.example.com/service_worker.js");
503   blink::mojom::ServiceWorkerRegistrationOptions options;
504   options.scope = scope;
505 
506   TestServiceWorkerContextObserver observer(context_wrapper());
507   base::RunLoop run_loop;
508   context()->RegisterServiceWorker(
509       script_url, options, blink::mojom::FetchClientSettingsObject::New(),
510       base::BindOnce(&RegisteredCallback, run_loop.QuitClosure()));
511   run_loop.Run();
512 
513   context_wrapper()->StopAllServiceWorkersForOrigin(scope);
514   base::RunLoop().RunUntilIdle();
515 
516   std::vector<TestServiceWorkerContextObserver::EventLog> events;
517 
518   // Filter the events to be verified.
519   for (auto event : observer.events()) {
520     if (event.type == TestServiceWorkerContextObserver::EventType::
521                           VersionStartedRunning ||
522         event.type == TestServiceWorkerContextObserver::EventType::
523                           VersionStoppedRunning) {
524       events.push_back(event);
525     }
526   }
527 
528   ASSERT_EQ(2u, events.size());
529   EXPECT_EQ(TestServiceWorkerContextObserver::EventType::VersionStartedRunning,
530             events[0].type);
531   EXPECT_EQ(TestServiceWorkerContextObserver::EventType::VersionStoppedRunning,
532             events[1].type);
533   EXPECT_EQ(events[0].version_id, events[1].version_id);
534 }
535 
536 // Make sure OnDestruct is called on observer.
TEST_F(ServiceWorkerContextTest,OnDestructObserver)537 TEST_F(ServiceWorkerContextTest, OnDestructObserver) {
538   ServiceWorkerContextWrapper* context = context_wrapper();
539   TestServiceWorkerContextObserver observer(context);
540   helper_->ShutdownContext();
541   base::RunLoop().RunUntilIdle();
542 
543   ASSERT_EQ(1u, observer.events().size());
544   EXPECT_EQ(TestServiceWorkerContextObserver::EventType::Destruct,
545             observer.events()[0].type);
546 }
547 
548 // Make sure basic registration is working.
TEST_F(ServiceWorkerContextTest,Register)549 TEST_F(ServiceWorkerContextTest, Register) {
550   GURL scope("https://www.example.com/");
551   GURL script_url("https://www.example.com/service_worker.js");
552   blink::mojom::ServiceWorkerRegistrationOptions options;
553   options.scope = scope;
554 
555   auto* client =
556       helper_
557           ->AddNewPendingInstanceClient<RecordableEmbeddedWorkerInstanceClient>(
558               helper_.get());
559   auto* worker =
560       helper_->AddNewPendingServiceWorker<InstallActivateWorker>(helper_.get());
561 
562   int64_t registration_id = blink::mojom::kInvalidServiceWorkerRegistrationId;
563   bool called = false;
564   context()->RegisterServiceWorker(
565       script_url, options, blink::mojom::FetchClientSettingsObject::New(),
566       MakeRegisteredCallback(&called, &registration_id));
567 
568   ASSERT_FALSE(called);
569   base::RunLoop().RunUntilIdle();
570   EXPECT_TRUE(called);
571 
572   ASSERT_EQ(2u, worker->events().size());
573   ASSERT_EQ(1u, client->events().size());
574   EXPECT_EQ(RecordableEmbeddedWorkerInstanceClient::Message::StartWorker,
575             client->events()[0]);
576   EXPECT_EQ(ServiceWorkerMetrics::EventType::INSTALL, worker->events()[0]);
577   EXPECT_EQ(ServiceWorkerMetrics::EventType::ACTIVATE, worker->events()[1]);
578 
579   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, registration_id);
580 
581   ASSERT_EQ(2u, notifications_.size());
582   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type);
583   EXPECT_EQ(scope, notifications_[0].scope);
584   EXPECT_EQ(registration_id, notifications_[0].registration_id);
585   EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
586   EXPECT_EQ(scope, notifications_[1].scope);
587   EXPECT_EQ(registration_id, notifications_[1].registration_id);
588 
589   context()->registry()->FindRegistrationForId(
590       registration_id, scope.GetOrigin(),
591       base::BindOnce(&ExpectRegisteredWorkers,
592                      blink::ServiceWorkerStatusCode::kOk,
593                      false /* expect_waiting */, true /* expect_active */));
594   base::RunLoop().RunUntilIdle();
595 }
596 
597 // Test registration when the service worker rejects the install event. The
598 // registration callback should indicate success, but there should be no waiting
599 // or active worker in the registration.
TEST_F(ServiceWorkerContextTest,Register_RejectInstall)600 TEST_F(ServiceWorkerContextTest, Register_RejectInstall) {
601   GURL scope("https://www.example.com/");
602   GURL script_url("https://www.example.com/service_worker.js");
603   blink::mojom::ServiceWorkerRegistrationOptions options;
604   options.scope = scope;
605 
606   auto* client =
607       helper_
608           ->AddNewPendingInstanceClient<RecordableEmbeddedWorkerInstanceClient>(
609               helper_.get());
610   auto* worker =
611       helper_->AddNewPendingServiceWorker<InstallActivateWorker>(helper_.get());
612   worker->SetToRejectInstall();
613 
614   int64_t registration_id = blink::mojom::kInvalidServiceWorkerRegistrationId;
615   bool called = false;
616   context()->RegisterServiceWorker(
617       script_url, options, blink::mojom::FetchClientSettingsObject::New(),
618       MakeRegisteredCallback(&called, &registration_id));
619 
620   ASSERT_FALSE(called);
621   base::RunLoop().RunUntilIdle();
622   EXPECT_TRUE(called);
623 
624   ASSERT_EQ(1u, worker->events().size());
625   ASSERT_EQ(2u, client->events().size());
626   EXPECT_EQ(RecordableEmbeddedWorkerInstanceClient::Message::StartWorker,
627             client->events()[0]);
628   EXPECT_EQ(ServiceWorkerMetrics::EventType::INSTALL, worker->events()[0]);
629   EXPECT_EQ(RecordableEmbeddedWorkerInstanceClient::Message::StopWorker,
630             client->events()[1]);
631 
632   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, registration_id);
633 
634   ASSERT_EQ(1u, notifications_.size());
635   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type);
636   EXPECT_EQ(scope, notifications_[0].scope);
637   EXPECT_EQ(registration_id, notifications_[0].registration_id);
638 
639   context()->registry()->FindRegistrationForId(
640       registration_id, scope.GetOrigin(),
641       base::BindOnce(&ExpectRegisteredWorkers,
642                      blink::ServiceWorkerStatusCode::kErrorNotFound,
643                      false /* expect_waiting */, false /* expect_active */));
644   base::RunLoop().RunUntilIdle();
645 }
646 
647 // Test registration when the service worker rejects the activate event. The
648 // worker should be activated anyway.
TEST_F(ServiceWorkerContextTest,Register_RejectActivate)649 TEST_F(ServiceWorkerContextTest, Register_RejectActivate) {
650   GURL scope("https://www.example.com/");
651   GURL script_url("https://www.example.com/service_worker.js");
652   blink::mojom::ServiceWorkerRegistrationOptions options;
653   options.scope = scope;
654 
655   auto* client =
656       helper_
657           ->AddNewPendingInstanceClient<RecordableEmbeddedWorkerInstanceClient>(
658               helper_.get());
659   auto* worker =
660       helper_->AddNewPendingServiceWorker<InstallActivateWorker>(helper_.get());
661   worker->SetToRejectActivate();
662 
663   int64_t registration_id = blink::mojom::kInvalidServiceWorkerRegistrationId;
664   bool called = false;
665   context()->RegisterServiceWorker(
666       script_url, options, blink::mojom::FetchClientSettingsObject::New(),
667       MakeRegisteredCallback(&called, &registration_id));
668 
669   ASSERT_FALSE(called);
670   base::RunLoop().RunUntilIdle();
671   EXPECT_TRUE(called);
672 
673   ASSERT_EQ(2u, worker->events().size());
674   ASSERT_EQ(1u, client->events().size());
675   EXPECT_EQ(RecordableEmbeddedWorkerInstanceClient::Message::StartWorker,
676             client->events()[0]);
677   EXPECT_EQ(ServiceWorkerMetrics::EventType::INSTALL, worker->events()[0]);
678   EXPECT_EQ(ServiceWorkerMetrics::EventType::ACTIVATE, worker->events()[1]);
679 
680   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, registration_id);
681 
682   ASSERT_EQ(2u, notifications_.size());
683   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type);
684   EXPECT_EQ(scope, notifications_[0].scope);
685   EXPECT_EQ(registration_id, notifications_[0].registration_id);
686   EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
687   EXPECT_EQ(scope, notifications_[1].scope);
688   EXPECT_EQ(registration_id, notifications_[1].registration_id);
689 
690   context()->registry()->FindRegistrationForId(
691       registration_id, scope.GetOrigin(),
692       base::BindOnce(&ExpectRegisteredWorkers,
693                      blink::ServiceWorkerStatusCode::kOk,
694                      false /* expect_waiting */, true /* expect_active */));
695   base::RunLoop().RunUntilIdle();
696 }
697 
698 // Make sure registrations are cleaned up when they are unregistered.
TEST_F(ServiceWorkerContextTest,Unregister)699 TEST_F(ServiceWorkerContextTest, Unregister) {
700   GURL scope("https://www.example.com/");
701   blink::mojom::ServiceWorkerRegistrationOptions options;
702   options.scope = scope;
703 
704   bool called = false;
705   int64_t registration_id = blink::mojom::kInvalidServiceWorkerRegistrationId;
706   context()->RegisterServiceWorker(
707       GURL("https://www.example.com/service_worker.js"), options,
708       blink::mojom::FetchClientSettingsObject::New(),
709       MakeRegisteredCallback(&called, &registration_id));
710 
711   ASSERT_FALSE(called);
712   base::RunLoop().RunUntilIdle();
713   ASSERT_TRUE(called);
714   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, registration_id);
715 
716   called = false;
717   context()->UnregisterServiceWorker(scope, /*is_immediate=*/false,
718                                      MakeUnregisteredCallback(&called));
719 
720   ASSERT_FALSE(called);
721   base::RunLoop().RunUntilIdle();
722   ASSERT_TRUE(called);
723 
724   context()->registry()->FindRegistrationForId(
725       registration_id, scope.GetOrigin(),
726       base::BindOnce(&ExpectRegisteredWorkers,
727                      blink::ServiceWorkerStatusCode::kErrorNotFound,
728                      false /* expect_waiting */, false /* expect_active */));
729   base::RunLoop().RunUntilIdle();
730 
731   ASSERT_EQ(3u, notifications_.size());
732   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type);
733   EXPECT_EQ(scope, notifications_[0].scope);
734   EXPECT_EQ(registration_id, notifications_[0].registration_id);
735   EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
736   EXPECT_EQ(scope, notifications_[1].scope);
737   EXPECT_EQ(registration_id, notifications_[1].registration_id);
738   EXPECT_EQ(REGISTRATION_DELETED, notifications_[2].type);
739   EXPECT_EQ(scope, notifications_[2].scope);
740   EXPECT_EQ(registration_id, notifications_[2].registration_id);
741 }
742 
743 // Make sure registrations are cleaned up when they are unregistered in bulk.
TEST_F(ServiceWorkerContextTest,UnregisterMultiple)744 TEST_F(ServiceWorkerContextTest, UnregisterMultiple) {
745   GURL origin1_s1("https://www.example.com/test");
746   GURL origin1_s2("https://www.example.com/hello");
747   GURL origin2_s1("https://www.example.com:8080/again");
748   GURL origin3_s1("https://www.other.com/");
749   int64_t registration_id1 = blink::mojom::kInvalidServiceWorkerRegistrationId;
750   int64_t registration_id2 = blink::mojom::kInvalidServiceWorkerRegistrationId;
751   int64_t registration_id3 = blink::mojom::kInvalidServiceWorkerRegistrationId;
752   int64_t registration_id4 = blink::mojom::kInvalidServiceWorkerRegistrationId;
753 
754   {
755     bool called = false;
756     blink::mojom::ServiceWorkerRegistrationOptions options;
757     options.scope = origin1_s1;
758     context()->RegisterServiceWorker(
759         GURL("https://www.example.com/service_worker.js"), options,
760         blink::mojom::FetchClientSettingsObject::New(),
761         MakeRegisteredCallback(&called, &registration_id1));
762     ASSERT_FALSE(called);
763     base::RunLoop().RunUntilIdle();
764     ASSERT_TRUE(called);
765   }
766 
767   {
768     bool called = false;
769     blink::mojom::ServiceWorkerRegistrationOptions options;
770     options.scope = origin1_s2;
771     context()->RegisterServiceWorker(
772         GURL("https://www.example.com/service_worker2.js"), options,
773         blink::mojom::FetchClientSettingsObject::New(),
774         MakeRegisteredCallback(&called, &registration_id2));
775     ASSERT_FALSE(called);
776     base::RunLoop().RunUntilIdle();
777     ASSERT_TRUE(called);
778   }
779 
780   {
781     bool called = false;
782     blink::mojom::ServiceWorkerRegistrationOptions options;
783     options.scope = origin2_s1;
784     context()->RegisterServiceWorker(
785         GURL("https://www.example.com:8080/service_worker3.js"), options,
786         blink::mojom::FetchClientSettingsObject::New(),
787         MakeRegisteredCallback(&called, &registration_id3));
788     ASSERT_FALSE(called);
789     base::RunLoop().RunUntilIdle();
790     ASSERT_TRUE(called);
791   }
792 
793   {
794     bool called = false;
795     blink::mojom::ServiceWorkerRegistrationOptions options;
796     options.scope = origin3_s1;
797     context()->RegisterServiceWorker(
798         GURL("https://www.other.com/service_worker4.js"), options,
799         blink::mojom::FetchClientSettingsObject::New(),
800         MakeRegisteredCallback(&called, &registration_id4));
801     ASSERT_FALSE(called);
802     base::RunLoop().RunUntilIdle();
803     ASSERT_TRUE(called);
804   }
805 
806   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
807             registration_id1);
808   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
809             registration_id2);
810   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
811             registration_id3);
812   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
813             registration_id4);
814 
815   bool called = false;
816   context()->DeleteForOrigin(origin1_s1.GetOrigin(),
817                              MakeUnregisteredCallback(&called));
818 
819   ASSERT_FALSE(called);
820   base::RunLoop().RunUntilIdle();
821   ASSERT_TRUE(called);
822 
823   context()->registry()->FindRegistrationForId(
824       registration_id1, origin1_s1.GetOrigin(),
825       base::BindOnce(&ExpectRegisteredWorkers,
826                      blink::ServiceWorkerStatusCode::kErrorNotFound,
827                      false /* expect_waiting */, false /* expect_active */));
828   context()->registry()->FindRegistrationForId(
829       registration_id2, origin1_s2.GetOrigin(),
830       base::BindOnce(&ExpectRegisteredWorkers,
831                      blink::ServiceWorkerStatusCode::kErrorNotFound,
832                      false /* expect_waiting */, false /* expect_active */));
833   context()->registry()->FindRegistrationForId(
834       registration_id3, origin2_s1.GetOrigin(),
835       base::BindOnce(&ExpectRegisteredWorkers,
836                      blink::ServiceWorkerStatusCode::kOk,
837                      false /* expect_waiting */, true /* expect_active */));
838 
839   context()->registry()->FindRegistrationForId(
840       registration_id4, origin3_s1.GetOrigin(),
841       base::BindOnce(&ExpectRegisteredWorkers,
842                      blink::ServiceWorkerStatusCode::kOk,
843                      false /* expect_waiting */, true /* expect_active */));
844 
845   base::RunLoop().RunUntilIdle();
846 
847   ASSERT_EQ(10u, notifications_.size());
848   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type);
849   EXPECT_EQ(registration_id1, notifications_[0].registration_id);
850   EXPECT_EQ(origin1_s1, notifications_[0].scope);
851   EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
852   EXPECT_EQ(registration_id1, notifications_[1].registration_id);
853   EXPECT_EQ(origin1_s1, notifications_[1].scope);
854   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[2].type);
855   EXPECT_EQ(origin1_s2, notifications_[2].scope);
856   EXPECT_EQ(registration_id2, notifications_[2].registration_id);
857   EXPECT_EQ(REGISTRATION_STORED, notifications_[3].type);
858   EXPECT_EQ(origin1_s2, notifications_[3].scope);
859   EXPECT_EQ(registration_id2, notifications_[3].registration_id);
860   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[4].type);
861   EXPECT_EQ(origin2_s1, notifications_[4].scope);
862   EXPECT_EQ(registration_id3, notifications_[4].registration_id);
863   EXPECT_EQ(REGISTRATION_STORED, notifications_[5].type);
864   EXPECT_EQ(origin2_s1, notifications_[5].scope);
865   EXPECT_EQ(registration_id3, notifications_[5].registration_id);
866   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[6].type);
867   EXPECT_EQ(origin3_s1, notifications_[6].scope);
868   EXPECT_EQ(registration_id4, notifications_[6].registration_id);
869   EXPECT_EQ(REGISTRATION_STORED, notifications_[7].type);
870   EXPECT_EQ(origin3_s1, notifications_[7].scope);
871   EXPECT_EQ(registration_id4, notifications_[7].registration_id);
872   EXPECT_EQ(REGISTRATION_DELETED, notifications_[8].type);
873   EXPECT_EQ(origin1_s1, notifications_[8].scope);
874   EXPECT_EQ(registration_id1, notifications_[8].registration_id);
875   EXPECT_EQ(REGISTRATION_DELETED, notifications_[9].type);
876   EXPECT_EQ(origin1_s2, notifications_[9].scope);
877   EXPECT_EQ(registration_id2, notifications_[9].registration_id);
878 }
879 
880 // Make sure registering a new script shares an existing registration.
TEST_F(ServiceWorkerContextTest,RegisterNewScript)881 TEST_F(ServiceWorkerContextTest, RegisterNewScript) {
882   GURL scope("https://www.example.com/");
883   blink::mojom::ServiceWorkerRegistrationOptions options;
884   options.scope = scope;
885 
886   bool called = false;
887   int64_t old_registration_id =
888       blink::mojom::kInvalidServiceWorkerRegistrationId;
889   context()->RegisterServiceWorker(
890       GURL("https://www.example.com/service_worker.js"), options,
891       blink::mojom::FetchClientSettingsObject::New(),
892       MakeRegisteredCallback(&called, &old_registration_id));
893 
894   ASSERT_FALSE(called);
895   base::RunLoop().RunUntilIdle();
896   ASSERT_TRUE(called);
897   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
898             old_registration_id);
899 
900   called = false;
901   int64_t new_registration_id =
902       blink::mojom::kInvalidServiceWorkerRegistrationId;
903   context()->RegisterServiceWorker(
904       GURL("https://www.example.com/service_worker_new.js"), options,
905       blink::mojom::FetchClientSettingsObject::New(),
906       MakeRegisteredCallback(&called, &new_registration_id));
907 
908   ASSERT_FALSE(called);
909   base::RunLoop().RunUntilIdle();
910   ASSERT_TRUE(called);
911 
912   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
913             new_registration_id);
914   EXPECT_EQ(old_registration_id, new_registration_id);
915 
916   ASSERT_EQ(4u, notifications_.size());
917   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type);
918   EXPECT_EQ(scope, notifications_[0].scope);
919   EXPECT_EQ(old_registration_id, notifications_[0].registration_id);
920   EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
921   EXPECT_EQ(scope, notifications_[1].scope);
922   EXPECT_EQ(old_registration_id, notifications_[1].registration_id);
923   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[2].type);
924   EXPECT_EQ(scope, notifications_[2].scope);
925   EXPECT_EQ(new_registration_id, notifications_[2].registration_id);
926   EXPECT_EQ(REGISTRATION_STORED, notifications_[3].type);
927   EXPECT_EQ(scope, notifications_[3].scope);
928   EXPECT_EQ(new_registration_id, notifications_[3].registration_id);
929 }
930 
931 // Make sure that when registering a duplicate scope+script_url
932 // combination, that the same registration is used.
TEST_F(ServiceWorkerContextTest,RegisterDuplicateScript)933 TEST_F(ServiceWorkerContextTest, RegisterDuplicateScript) {
934   GURL scope("https://www.example.com/");
935   GURL script_url("https://www.example.com/service_worker.js");
936   blink::mojom::ServiceWorkerRegistrationOptions options;
937   options.scope = scope;
938 
939   bool called = false;
940   int64_t old_registration_id =
941       blink::mojom::kInvalidServiceWorkerRegistrationId;
942   context()->RegisterServiceWorker(
943       script_url, options, blink::mojom::FetchClientSettingsObject::New(),
944       MakeRegisteredCallback(&called, &old_registration_id));
945 
946   ASSERT_FALSE(called);
947   base::RunLoop().RunUntilIdle();
948   ASSERT_TRUE(called);
949   EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
950             old_registration_id);
951 
952   called = false;
953   int64_t new_registration_id =
954       blink::mojom::kInvalidServiceWorkerRegistrationId;
955   context()->RegisterServiceWorker(
956       script_url, options, blink::mojom::FetchClientSettingsObject::New(),
957       MakeRegisteredCallback(&called, &new_registration_id));
958 
959   ASSERT_FALSE(called);
960   base::RunLoop().RunUntilIdle();
961   ASSERT_TRUE(called);
962   EXPECT_EQ(old_registration_id, new_registration_id);
963 
964   ASSERT_EQ(3u, notifications_.size());
965   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type);
966   EXPECT_EQ(scope, notifications_[0].scope);
967   EXPECT_EQ(old_registration_id, notifications_[0].registration_id);
968   EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
969   EXPECT_EQ(scope, notifications_[1].scope);
970   EXPECT_EQ(old_registration_id, notifications_[1].registration_id);
971   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[2].type);
972   EXPECT_EQ(scope, notifications_[2].scope);
973   EXPECT_EQ(old_registration_id, notifications_[2].registration_id);
974 }
975 
TEST_F(ServiceWorkerContextTest,ContainerHostIterator)976 TEST_F(ServiceWorkerContextTest, ContainerHostIterator) {
977   const int kRenderProcessId1 = 1;
978   const int kRenderProcessId2 = 2;
979   const GURL kOrigin1 = GURL("https://www.example.com/");
980   const GURL kOrigin2 = GURL("https://another-origin.example.net/");
981   std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints;
982 
983   // Host1 : process_id=1, origin1.
984   remote_endpoints.emplace_back();
985   base::WeakPtr<ServiceWorkerContainerHost> container_host1 =
986       CreateContainerHostForWindow(
987           kRenderProcessId1, true /* is_parent_frame_secure */,
988           context()->AsWeakPtr(), &remote_endpoints.back());
989   container_host1->UpdateUrls(kOrigin1, net::SiteForCookies::FromUrl(kOrigin1),
990                               url::Origin::Create(kOrigin1));
991 
992   // Host2 : process_id=2, origin2.
993   remote_endpoints.emplace_back();
994   base::WeakPtr<ServiceWorkerContainerHost> container_host2 =
995       CreateContainerHostForWindow(
996           kRenderProcessId2, true /* is_parent_frame_secure */,
997           context()->AsWeakPtr(), &remote_endpoints.back());
998   container_host2->UpdateUrls(kOrigin2, net::SiteForCookies::FromUrl(kOrigin2),
999                               url::Origin::Create(kOrigin2));
1000 
1001   // Host3 : process_id=2, origin1.
1002   remote_endpoints.emplace_back();
1003   base::WeakPtr<ServiceWorkerContainerHost> container_host3 =
1004       CreateContainerHostForWindow(
1005           kRenderProcessId2, true /* is_parent_frame_secure */,
1006           context()->AsWeakPtr(), &remote_endpoints.back());
1007   container_host3->UpdateUrls(kOrigin1, net::SiteForCookies::FromUrl(kOrigin1),
1008                               url::Origin::Create(kOrigin1));
1009 
1010   // Host4 : process_id=2, origin2, for ServiceWorker.
1011   blink::mojom::ServiceWorkerRegistrationOptions registration_opt;
1012   registration_opt.scope = GURL("https://another-origin.example.net/test/");
1013   scoped_refptr<ServiceWorkerRegistration> registration =
1014       base::MakeRefCounted<ServiceWorkerRegistration>(
1015           registration_opt, 1L /* registration_id */,
1016           helper_->context()->AsWeakPtr());
1017   scoped_refptr<ServiceWorkerVersion> version =
1018       base::MakeRefCounted<ServiceWorkerVersion>(
1019           registration.get(),
1020           GURL("https://another-origin.example.net/test/script_url"),
1021           blink::mojom::ScriptType::kClassic, 1L /* version_id */,
1022           helper_->context()->AsWeakPtr());
1023   remote_endpoints.emplace_back();
1024   // ServiceWorkrProviderHost creates ServiceWorkerContainerHost for a service
1025   // worker execution context.
1026   std::unique_ptr<ServiceWorkerProviderHost> provider_host4 =
1027       CreateProviderHostForServiceWorkerContext(
1028           kRenderProcessId2, true /* is_parent_frame_secure */, version.get(),
1029           context()->AsWeakPtr(), &remote_endpoints.back());
1030   EXPECT_NE(provider_host4->provider_id(),
1031             blink::kInvalidServiceWorkerProviderId);
1032 
1033   ASSERT_TRUE(container_host1);
1034   ASSERT_TRUE(container_host2);
1035   ASSERT_TRUE(container_host3);
1036   ASSERT_TRUE(provider_host4->container_host());
1037 
1038   // Iterate over the client container hosts that belong to kOrigin1.
1039   std::set<ServiceWorkerContainerHost*> results;
1040   for (auto it = context()->GetClientContainerHostIterator(
1041            kOrigin1, true /* include_reserved_clients */,
1042            false /* include_back_forward_cached_clients */);
1043        !it->IsAtEnd(); it->Advance()) {
1044     results.insert(it->GetContainerHost());
1045   }
1046   EXPECT_EQ(2u, results.size());
1047   EXPECT_TRUE(base::Contains(results, container_host1.get()));
1048   EXPECT_TRUE(base::Contains(results, container_host3.get()));
1049 
1050   // Iterate over the container hosts that belong to kOrigin2. This should not
1051   // include provider_host4->container_host() as it's not for controllee.
1052   results.clear();
1053   for (auto it = context()->GetClientContainerHostIterator(
1054            kOrigin2, true /* include_reserved_clients */,
1055            false /* include_back_forward_cached_clients */);
1056        !it->IsAtEnd(); it->Advance()) {
1057     results.insert(it->GetContainerHost());
1058   }
1059   EXPECT_EQ(1u, results.size());
1060   EXPECT_TRUE(base::Contains(results, container_host2.get()));
1061 
1062   context()->UnregisterContainerHostByClientID(container_host1->client_uuid());
1063   context()->UnregisterContainerHostByClientID(container_host2->client_uuid());
1064   context()->UnregisterContainerHostByClientID(container_host3->client_uuid());
1065 }
1066 
1067 class ServiceWorkerContextRecoveryTest
1068     : public ServiceWorkerContextTest,
1069       public testing::WithParamInterface<bool /* is_storage_on_disk */> {
1070  public:
ServiceWorkerContextRecoveryTest()1071   ServiceWorkerContextRecoveryTest() {}
~ServiceWorkerContextRecoveryTest()1072   virtual ~ServiceWorkerContextRecoveryTest() {}
1073 
1074  protected:
is_storage_on_disk() const1075   bool is_storage_on_disk() const { return GetParam(); }
1076 };
1077 
TEST_P(ServiceWorkerContextRecoveryTest,DeleteAndStartOver)1078 TEST_P(ServiceWorkerContextRecoveryTest, DeleteAndStartOver) {
1079   GURL scope("https://www.example.com/");
1080   GURL script_url("https://www.example.com/service_worker.js");
1081   blink::mojom::ServiceWorkerRegistrationOptions options;
1082   options.scope = scope;
1083 
1084   if (is_storage_on_disk()) {
1085     // Reinitialize the helper to test on-disk storage.
1086     base::FilePath user_data_directory;
1087     ASSERT_NO_FATAL_FAILURE(GetTemporaryDirectory(&user_data_directory));
1088     helper_.reset(new EmbeddedWorkerTestHelper(user_data_directory));
1089     helper_->context_wrapper()->AddObserver(this);
1090   }
1091 
1092   int64_t registration_id = blink::mojom::kInvalidServiceWorkerRegistrationId;
1093   bool called = false;
1094   context()->RegisterServiceWorker(
1095       script_url, options, blink::mojom::FetchClientSettingsObject::New(),
1096       MakeRegisteredCallback(&called, &registration_id));
1097 
1098   ASSERT_FALSE(called);
1099   content::RunAllTasksUntilIdle();
1100   EXPECT_TRUE(called);
1101 
1102   context()->registry()->FindRegistrationForId(
1103       registration_id, scope.GetOrigin(),
1104       base::BindOnce(&ExpectRegisteredWorkers,
1105                      blink::ServiceWorkerStatusCode::kOk,
1106                      false /* expect_waiting */, true /* expect_active */));
1107   content::RunAllTasksUntilIdle();
1108 
1109   context()->ScheduleDeleteAndStartOver();
1110 
1111   // The storage is disabled while the recovery process is running, so the
1112   // operation should be aborted.
1113   context()->registry()->FindRegistrationForId(
1114       registration_id, scope.GetOrigin(),
1115       base::BindOnce(&ExpectRegisteredWorkers,
1116                      blink::ServiceWorkerStatusCode::kErrorAbort,
1117                      false /* expect_waiting */, true /* expect_active */));
1118   content::RunAllTasksUntilIdle();
1119 
1120   // The context started over and the storage was re-initialized, so the
1121   // registration should not be found.
1122   context()->registry()->FindRegistrationForId(
1123       registration_id, scope.GetOrigin(),
1124       base::BindOnce(&ExpectRegisteredWorkers,
1125                      blink::ServiceWorkerStatusCode::kErrorNotFound,
1126                      false /* expect_waiting */, true /* expect_active */));
1127   content::RunAllTasksUntilIdle();
1128 
1129   called = false;
1130   context()->RegisterServiceWorker(
1131       script_url, options, blink::mojom::FetchClientSettingsObject::New(),
1132       MakeRegisteredCallback(&called, &registration_id));
1133 
1134   ASSERT_FALSE(called);
1135   content::RunAllTasksUntilIdle();
1136   EXPECT_TRUE(called);
1137 
1138   context()->registry()->FindRegistrationForId(
1139       registration_id, scope.GetOrigin(),
1140       base::BindOnce(&ExpectRegisteredWorkers,
1141                      blink::ServiceWorkerStatusCode::kOk,
1142                      false /* expect_waiting */, true /* expect_active */));
1143   content::RunAllTasksUntilIdle();
1144 
1145   ASSERT_EQ(5u, notifications_.size());
1146   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type);
1147   EXPECT_EQ(scope, notifications_[0].scope);
1148   EXPECT_EQ(registration_id, notifications_[0].registration_id);
1149   EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type);
1150   EXPECT_EQ(scope, notifications_[1].scope);
1151   EXPECT_EQ(registration_id, notifications_[1].registration_id);
1152   EXPECT_EQ(STORAGE_RECOVERED, notifications_[2].type);
1153   EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[3].type);
1154   EXPECT_EQ(scope, notifications_[3].scope);
1155   EXPECT_EQ(registration_id, notifications_[3].registration_id);
1156   EXPECT_EQ(REGISTRATION_STORED, notifications_[4].type);
1157   EXPECT_EQ(scope, notifications_[4].scope);
1158   EXPECT_EQ(registration_id, notifications_[4].registration_id);
1159 }
1160 
1161 INSTANTIATE_TEST_SUITE_P(ServiceWorkerContextRecoveryTest,
1162                          ServiceWorkerContextRecoveryTest,
1163                          testing::Bool() /* is_storage_on_disk */);
1164 
1165 }  // namespace content
1166