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/browser/service_worker/service_worker_registration.h"
6 
7 #include <stdint.h>
8 #include <utility>
9 
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/callback_helpers.h"
13 #include "base/compiler_specific.h"
14 #include "base/files/scoped_temp_dir.h"
15 #include "base/logging.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/optional.h"
18 #include "base/run_loop.h"
19 #include "base/test/bind_test_util.h"
20 #include "base/test/scoped_feature_list.h"
21 #include "base/test/simple_test_tick_clock.h"
22 #include "base/test/test_simple_task_runner.h"
23 #include "base/threading/thread_task_runner_handle.h"
24 #include "base/time/time.h"
25 #include "content/browser/service_worker/embedded_worker_status.h"
26 #include "content/browser/service_worker/embedded_worker_test_helper.h"
27 #include "content/browser/service_worker/fake_embedded_worker_instance_client.h"
28 #include "content/browser/service_worker/fake_service_worker.h"
29 #include "content/browser/service_worker/service_worker_container_host.h"
30 #include "content/browser/service_worker/service_worker_context_core.h"
31 #include "content/browser/service_worker/service_worker_context_core_observer.h"
32 #include "content/browser/service_worker/service_worker_context_wrapper.h"
33 #include "content/browser/service_worker/service_worker_provider_host.h"
34 #include "content/browser/service_worker/service_worker_register_job.h"
35 #include "content/browser/service_worker/service_worker_registration_object_host.h"
36 #include "content/browser/service_worker/service_worker_test_utils.h"
37 #include "content/browser/service_worker/test_service_worker_observer.h"
38 #include "content/browser/storage_partition_impl.h"
39 #include "content/common/service_worker/service_worker_utils.h"
40 #include "content/public/common/content_client.h"
41 #include "content/public/test/browser_task_environment.h"
42 #include "content/public/test/test_browser_context.h"
43 #include "content/public/test/url_loader_interceptor.h"
44 #include "content/test/fake_network.h"
45 #include "content/test/test_content_browser_client.h"
46 #include "mojo/core/embedder/embedder.h"
47 #include "mojo/public/cpp/bindings/associated_receiver.h"
48 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
49 #include "testing/gtest/include/gtest/gtest.h"
50 #include "third_party/blink/public/common/features.h"
51 #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
52 #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
53 #include "url/gurl.h"
54 #include "url/origin.h"
55 
56 namespace content {
57 
58 namespace {
59 
60 // From service_worker_registration.cc.
61 constexpr base::TimeDelta kMaxLameDuckTime = base::TimeDelta::FromMinutes(5);
62 
CreateInflightRequest(ServiceWorkerVersion * version)63 int CreateInflightRequest(ServiceWorkerVersion* version) {
64   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, StartServiceWorker(version));
65   return version->StartRequest(ServiceWorkerMetrics::EventType::PUSH,
66                                base::DoNothing());
67 }
68 
SaveStatusCallback(bool * called,blink::ServiceWorkerStatusCode * out,blink::ServiceWorkerStatusCode status)69 void SaveStatusCallback(bool* called,
70                         blink::ServiceWorkerStatusCode* out,
71                         blink::ServiceWorkerStatusCode status) {
72   *called = true;
73   *out = status;
74 }
75 
76 }  // namespace
77 
78 class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient {
79  public:
AllowServiceWorkerOnIO(const GURL & scope,const GURL & site_for_cookies,const base::Optional<url::Origin> & top_frame_origin,const GURL & script_url,content::ResourceContext * context,base::RepeatingCallback<WebContents * ()> wc_getter)80   bool AllowServiceWorkerOnIO(
81       const GURL& scope,
82       const GURL& site_for_cookies,
83       const base::Optional<url::Origin>& top_frame_origin,
84       const GURL& script_url,
85       content::ResourceContext* context,
86       base::RepeatingCallback<WebContents*()> wc_getter) override {
87     return false;
88   }
89 
AllowServiceWorkerOnUI(const GURL & scope,const GURL & site_for_cookies,const base::Optional<url::Origin> & top_frame_origin,const GURL & script_url,content::BrowserContext * context,base::RepeatingCallback<WebContents * ()> wc_getter)90   bool AllowServiceWorkerOnUI(
91       const GURL& scope,
92       const GURL& site_for_cookies,
93       const base::Optional<url::Origin>& top_frame_origin,
94       const GURL& script_url,
95       content::BrowserContext* context,
96       base::RepeatingCallback<WebContents*()> wc_getter) override {
97     return false;
98   }
99 };
100 
RequestTermination(mojo::AssociatedRemote<blink::mojom::EmbeddedWorkerInstanceHost> * host)101 void RequestTermination(
102     mojo::AssociatedRemote<blink::mojom::EmbeddedWorkerInstanceHost>* host) {
103   // We can't wait for the callback since Stop() arrives first which severs
104   // the connection.
105   (*host)->RequestTermination(base::DoNothing());
106 }
107 
108 class MockServiceWorkerRegistrationObject
109     : public blink::mojom::ServiceWorkerRegistrationObject {
110  public:
MockServiceWorkerRegistrationObject(mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerRegistrationObject> receiver)111   explicit MockServiceWorkerRegistrationObject(
112       mojo::PendingAssociatedReceiver<
113           blink::mojom::ServiceWorkerRegistrationObject> receiver)
114       : receiver_(this, std::move(receiver)) {}
115   ~MockServiceWorkerRegistrationObject() override = default;
116 
update_found_called_count() const117   int update_found_called_count() const { return update_found_called_count_; }
set_version_attributes_called_count() const118   int set_version_attributes_called_count() const {
119     return set_version_attributes_called_count_;
120   }
set_update_via_cache_called_count() const121   int set_update_via_cache_called_count() const {
122     return set_update_via_cache_called_count_;
123   }
changed_mask() const124   const blink::mojom::ChangedServiceWorkerObjectsMask& changed_mask() const {
125     return *changed_mask_;
126   }
installing() const127   const blink::mojom::ServiceWorkerObjectInfoPtr& installing() const {
128     return installing_;
129   }
waiting() const130   const blink::mojom::ServiceWorkerObjectInfoPtr& waiting() const {
131     return waiting_;
132   }
active() const133   const blink::mojom::ServiceWorkerObjectInfoPtr& active() const {
134     return active_;
135   }
update_via_cache() const136   blink::mojom::ServiceWorkerUpdateViaCache update_via_cache() const {
137     return update_via_cache_;
138   }
139 
140  private:
141   // Implements blink::mojom::ServiceWorkerRegistrationObject.
SetServiceWorkerObjects(blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,blink::mojom::ServiceWorkerObjectInfoPtr installing,blink::mojom::ServiceWorkerObjectInfoPtr waiting,blink::mojom::ServiceWorkerObjectInfoPtr active)142   void SetServiceWorkerObjects(
143       blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
144       blink::mojom::ServiceWorkerObjectInfoPtr installing,
145       blink::mojom::ServiceWorkerObjectInfoPtr waiting,
146       blink::mojom::ServiceWorkerObjectInfoPtr active) override {
147     set_version_attributes_called_count_++;
148     changed_mask_ = std::move(changed_mask);
149     installing_ = std::move(installing);
150     waiting_ = std::move(waiting);
151     active_ = std::move(active);
152   }
SetUpdateViaCache(blink::mojom::ServiceWorkerUpdateViaCache update_via_cache)153   void SetUpdateViaCache(
154       blink::mojom::ServiceWorkerUpdateViaCache update_via_cache) override {
155     set_update_via_cache_called_count_++;
156     update_via_cache_ = update_via_cache;
157   }
UpdateFound()158   void UpdateFound() override { update_found_called_count_++; }
159 
160   int update_found_called_count_ = 0;
161   int set_version_attributes_called_count_ = 0;
162   int set_update_via_cache_called_count_ = 0;
163   blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask_;
164   blink::mojom::ServiceWorkerObjectInfoPtr installing_;
165   blink::mojom::ServiceWorkerObjectInfoPtr waiting_;
166   blink::mojom::ServiceWorkerObjectInfoPtr active_;
167   blink::mojom::ServiceWorkerUpdateViaCache update_via_cache_ =
168       blink::mojom::ServiceWorkerUpdateViaCache::kImports;
169 
170   mojo::AssociatedReceiver<blink::mojom::ServiceWorkerRegistrationObject>
171       receiver_;
172 };
173 
174 class ServiceWorkerRegistrationTest : public testing::Test {
175  public:
ServiceWorkerRegistrationTest()176   ServiceWorkerRegistrationTest()
177       : task_environment_(BrowserTaskEnvironment::IO_MAINLOOP) {}
178 
SetUp()179   void SetUp() override {
180     helper_ = std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath());
181 
182     // Create a StoragePartition with the testing browser context so that the
183     // ServiceWorkerUpdateChecker can find the BrowserContext through it.
184     storage_partition_impl_ = StoragePartitionImpl::Create(
185         helper_->browser_context(), /* in_memory= */ true, base::FilePath(),
186         /* partition_domain= */ "");
187     storage_partition_impl_->Initialize();
188     helper_->context_wrapper()->set_storage_partition(
189         storage_partition_impl_.get());
190 
191     context()->storage()->LazyInitializeForTest();
192   }
193 
context()194   ServiceWorkerContextCore* context() { return helper_->context(); }
registry()195   ServiceWorkerRegistry* registry() { return helper_->context()->registry(); }
storage()196   ServiceWorkerStorage* storage() { return helper_->context()->storage(); }
197 
198   class RegistrationListener : public ServiceWorkerRegistration::Listener {
199    public:
RegistrationListener()200     RegistrationListener() {}
~RegistrationListener()201     ~RegistrationListener() {
202       if (observed_registration_.get())
203         observed_registration_->RemoveListener(this);
204     }
205 
OnVersionAttributesChanged(ServiceWorkerRegistration * registration,blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,const ServiceWorkerRegistrationInfo & info)206     void OnVersionAttributesChanged(
207         ServiceWorkerRegistration* registration,
208         blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
209         const ServiceWorkerRegistrationInfo& info) override {
210       observed_registration_ = registration;
211       observed_changed_mask_ = std::move(changed_mask);
212       observed_info_ = info;
213     }
214 
OnRegistrationFailed(ServiceWorkerRegistration * registration)215     void OnRegistrationFailed(
216         ServiceWorkerRegistration* registration) override {
217       NOTREACHED();
218     }
219 
OnUpdateFound(ServiceWorkerRegistration * registration)220     void OnUpdateFound(ServiceWorkerRegistration* registration) override {
221       NOTREACHED();
222     }
223 
Reset()224     void Reset() {
225       observed_registration_ = nullptr;
226       observed_changed_mask_ = nullptr;
227       observed_info_ = ServiceWorkerRegistrationInfo();
228     }
229 
230     scoped_refptr<ServiceWorkerRegistration> observed_registration_;
231     blink::mojom::ChangedServiceWorkerObjectsMaskPtr observed_changed_mask_;
232     ServiceWorkerRegistrationInfo observed_info_;
233   };
234 
235  protected:
236   BrowserTaskEnvironment task_environment_;
237   std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
238   std::unique_ptr<StoragePartitionImpl> storage_partition_impl_;
239 };
240 
TEST_F(ServiceWorkerRegistrationTest,SetAndUnsetVersions)241 TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
242   const GURL kScope("http://www.example.not/");
243   const GURL kScript("http://www.example.not/service_worker.js");
244   int64_t kRegistrationId = 1L;
245 
246   blink::mojom::ServiceWorkerRegistrationOptions options;
247   options.scope = kScope;
248   scoped_refptr<ServiceWorkerRegistration> registration =
249       base::MakeRefCounted<ServiceWorkerRegistration>(options, kRegistrationId,
250                                                       context()->AsWeakPtr());
251 
252   const int64_t version_1_id = 1L;
253   const int64_t version_2_id = 2L;
254   scoped_refptr<ServiceWorkerVersion> version_1 =
255       base::MakeRefCounted<ServiceWorkerVersion>(
256           registration.get(), kScript, blink::mojom::ScriptType::kClassic,
257           version_1_id, context()->AsWeakPtr());
258   scoped_refptr<ServiceWorkerVersion> version_2 =
259       base::MakeRefCounted<ServiceWorkerVersion>(
260           registration.get(), kScript, blink::mojom::ScriptType::kClassic,
261           version_2_id, context()->AsWeakPtr());
262 
263   RegistrationListener listener;
264   registration->AddListener(&listener);
265   registration->SetActiveVersion(version_1);
266 
267   EXPECT_EQ(version_1.get(), registration->active_version());
268   EXPECT_EQ(registration, listener.observed_registration_);
269   EXPECT_TRUE(listener.observed_changed_mask_->active);
270   EXPECT_EQ(kScope, listener.observed_info_.scope);
271   EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
272   EXPECT_EQ(kScript, listener.observed_info_.active_version.script_url);
273   EXPECT_EQ(listener.observed_info_.installing_version.version_id,
274             blink::mojom::kInvalidServiceWorkerVersionId);
275   EXPECT_EQ(listener.observed_info_.waiting_version.version_id,
276             blink::mojom::kInvalidServiceWorkerVersionId);
277   listener.Reset();
278 
279   registration->SetInstallingVersion(version_2);
280 
281   EXPECT_EQ(version_2.get(), registration->installing_version());
282   EXPECT_TRUE(listener.observed_changed_mask_->installing);
283   EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
284   EXPECT_EQ(version_2_id,
285             listener.observed_info_.installing_version.version_id);
286   EXPECT_EQ(listener.observed_info_.waiting_version.version_id,
287             blink::mojom::kInvalidServiceWorkerVersionId);
288   listener.Reset();
289 
290   registration->SetWaitingVersion(version_2);
291 
292   EXPECT_EQ(version_2.get(), registration->waiting_version());
293   EXPECT_FALSE(registration->installing_version());
294   EXPECT_TRUE(listener.observed_changed_mask_->waiting);
295   EXPECT_TRUE(listener.observed_changed_mask_->installing);
296   EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
297   EXPECT_EQ(version_2_id, listener.observed_info_.waiting_version.version_id);
298   EXPECT_EQ(listener.observed_info_.installing_version.version_id,
299             blink::mojom::kInvalidServiceWorkerVersionId);
300   listener.Reset();
301 
302   registration->UnsetVersion(version_2.get());
303 
304   EXPECT_FALSE(registration->waiting_version());
305   EXPECT_TRUE(listener.observed_changed_mask_->waiting);
306   EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
307   EXPECT_EQ(listener.observed_info_.waiting_version.version_id,
308             blink::mojom::kInvalidServiceWorkerVersionId);
309   EXPECT_EQ(listener.observed_info_.installing_version.version_id,
310             blink::mojom::kInvalidServiceWorkerVersionId);
311 }
312 
TEST_F(ServiceWorkerRegistrationTest,FailedRegistrationNoCrash)313 TEST_F(ServiceWorkerRegistrationTest, FailedRegistrationNoCrash) {
314   const GURL kScope("http://www.example.not/");
315   int64_t kRegistrationId = 1L;
316   blink::mojom::ServiceWorkerRegistrationOptions options;
317   options.scope = kScope;
318   auto registration = base::MakeRefCounted<ServiceWorkerRegistration>(
319       options, kRegistrationId, context()->AsWeakPtr());
320   // Prepare a ServiceWorkerContainerHost.
321   ServiceWorkerRemoteProviderEndpoint remote_endpoint;
322   base::WeakPtr<ServiceWorkerContainerHost> container_host =
323       CreateContainerHostForWindow(helper_->mock_render_process_id(),
324                                    true /* is_parent_frame_secure */,
325                                    context()->AsWeakPtr(), &remote_endpoint);
326   auto registration_object_host =
327       std::make_unique<ServiceWorkerRegistrationObjectHost>(
328           context()->AsWeakPtr(), container_host.get(), registration);
329   // To enable the caller end point
330   // |registration_object_host->remote_registration_| to make calls safely with
331   // no need to pass |object_info_->receiver| through a message pipe endpoint.
332   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr object_info =
333       registration_object_host->CreateObjectInfo();
334   mojo::AssociateWithDisconnectedPipe(object_info->receiver.PassHandle());
335 
336   registration->NotifyRegistrationFailed();
337   // Don't crash when |registration_object_host| gets destructed.
338 }
339 
TEST_F(ServiceWorkerRegistrationTest,NavigationPreload)340 TEST_F(ServiceWorkerRegistrationTest, NavigationPreload) {
341   const GURL kScope("http://www.example.not/");
342   const GURL kScript("https://www.example.not/service_worker.js");
343   // Setup.
344 
345   blink::mojom::ServiceWorkerRegistrationOptions options;
346   options.scope = kScope;
347   scoped_refptr<ServiceWorkerRegistration> registration =
348       CreateNewServiceWorkerRegistration(context()->registry(), options);
349   scoped_refptr<ServiceWorkerVersion> version_1 = CreateNewServiceWorkerVersion(
350       context()->registry(), registration.get(), kScript,
351       blink::mojom::ScriptType::kClassic);
352   version_1->set_fetch_handler_existence(
353       ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
354   registration->SetActiveVersion(version_1);
355   version_1->SetStatus(ServiceWorkerVersion::ACTIVATED);
356   scoped_refptr<ServiceWorkerVersion> version_2 = CreateNewServiceWorkerVersion(
357       context()->registry(), registration.get(), kScript,
358       blink::mojom::ScriptType::kClassic);
359   version_2->set_fetch_handler_existence(
360       ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
361   registration->SetWaitingVersion(version_2);
362   version_2->SetStatus(ServiceWorkerVersion::INSTALLED);
363 
364   // Navigation preload is disabled by default.
365   EXPECT_FALSE(version_1->navigation_preload_state().enabled);
366   // Enabling it sets the flag on the active version.
367   registration->EnableNavigationPreload(true);
368   EXPECT_TRUE(version_1->navigation_preload_state().enabled);
369   // A new active version gets the flag.
370   registration->SetActiveVersion(version_2);
371   version_2->SetStatus(ServiceWorkerVersion::ACTIVATING);
372   EXPECT_TRUE(version_2->navigation_preload_state().enabled);
373   // Disabling it unsets the flag on the active version.
374   registration->EnableNavigationPreload(false);
375   EXPECT_FALSE(version_2->navigation_preload_state().enabled);
376 }
377 
378 // Sets up a registration with a waiting worker, and an active worker
379 // with a controllee and an inflight request.
380 class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest,
381                                     public testing::WithParamInterface<bool> {
382  public:
ServiceWorkerActivationTest()383   ServiceWorkerActivationTest() : ServiceWorkerRegistrationTest() {}
384 
SetUp()385   void SetUp() override {
386     ServiceWorkerRegistrationTest::SetUp();
387 
388     const GURL kUrl("https://www.example.not/");
389     const GURL kScope("https://www.example.not/");
390     const GURL kScript("https://www.example.not/service_worker.js");
391 
392     blink::mojom::ServiceWorkerRegistrationOptions options;
393     options.scope = kScope;
394     registration_ =
395         CreateNewServiceWorkerRegistration(context()->registry(), options);
396 
397     // Create an active version.
398     scoped_refptr<ServiceWorkerVersion> version_1 =
399         CreateNewServiceWorkerVersion(context()->registry(),
400                                       registration_.get(), kScript,
401                                       blink::mojom::ScriptType::kClassic);
402     version_1->set_fetch_handler_existence(
403         ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
404     registration_->SetActiveVersion(version_1);
405     version_1->SetStatus(ServiceWorkerVersion::ACTIVATED);
406 
407     // Store the registration.
408     std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> records_1;
409     records_1.push_back(WriteToDiskCacheSync(
410         helper_->context()->storage(), version_1->script_url(),
411         {} /* headers */, "I'm the body", "I'm the meta data"));
412     version_1->script_cache_map()->SetResources(records_1);
413     version_1->SetMainScriptResponse(
414         EmbeddedWorkerTestHelper::CreateMainScriptResponse());
415     base::Optional<blink::ServiceWorkerStatusCode> status;
416     base::RunLoop run_loop;
417     context()->registry()->StoreRegistration(
418         registration_.get(), version_1.get(),
419         ReceiveServiceWorkerStatus(&status, run_loop.QuitClosure()));
420     run_loop.Run();
421     ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
422 
423     // Give the active version a controllee.
424     container_host_ = CreateContainerHostForWindow(
425         helper_->mock_render_process_id(), true /* is_parent_frame_secure */,
426         context()->AsWeakPtr(), &remote_endpoint_);
427     DCHECK(remote_endpoint_.client_receiver()->is_valid());
428     DCHECK(remote_endpoint_.host_remote()->is_bound());
429     container_host_->UpdateUrls(kUrl, net::SiteForCookies::FromUrl(kUrl),
430                                 url::Origin::Create(kUrl));
431     container_host_->SetControllerRegistration(
432         registration_, false /* notify_controllerchange */);
433 
434     // Setup the Mojo implementation fakes for the renderer-side service worker.
435     // These will be bound once the service worker starts.
436     version_1_client_ =
437         helper_->AddNewPendingInstanceClient<FakeEmbeddedWorkerInstanceClient>(
438             helper_.get());
439     version_1_service_worker_ =
440         helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get());
441 
442     // Start the active version and give it an in-flight request.
443     inflight_request_id_ = CreateInflightRequest(version_1.get());
444 
445     // Create a waiting version.
446     scoped_refptr<ServiceWorkerVersion> version_2 =
447         CreateNewServiceWorkerVersion(context()->registry(),
448                                       registration_.get(), kScript,
449                                       blink::mojom::ScriptType::kClassic);
450     std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> records_2;
451     records_2.push_back(WriteToDiskCacheSync(
452         helper_->context()->storage(), version_2->script_url(),
453         {} /* headers */, "I'm the body", "I'm the meta data"));
454     version_2->script_cache_map()->SetResources(records_2);
455     version_2->SetMainScriptResponse(
456         EmbeddedWorkerTestHelper::CreateMainScriptResponse());
457     version_2->set_fetch_handler_existence(
458         ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
459     registration_->SetWaitingVersion(version_2);
460 
461     // Setup the Mojo implementation fakes for the renderer-side service worker.
462     // These will be bound once the service worker starts.
463     version_2_client_ =
464         helper_->AddNewPendingInstanceClient<FakeEmbeddedWorkerInstanceClient>(
465             helper_.get());
466     version_2_service_worker_ =
467         helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get());
468 
469     // Start the worker.
470     ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
471               StartServiceWorker(version_2.get()));
472     version_2->SetStatus(ServiceWorkerVersion::INSTALLED);
473 
474     // Set it to activate when ready. The original version should still be
475     // active.
476     registration_->ActivateWaitingVersionWhenReady();
477     base::RunLoop().RunUntilIdle();
478     EXPECT_EQ(version_1.get(), registration_->active_version());
479 
480     if (devtools_should_be_attached()) {
481       // Attach DevTools to the active worker. This shouldn't prevent from
482       // promoting the waiting worker to active.
483       version_1->SetDevToolsAttached(true);
484     }
485   }
486 
TearDown()487   void TearDown() override {
488     registration_->active_version()->RemoveObserver(registration_.get());
489     ServiceWorkerRegistrationTest::TearDown();
490   }
491 
devtools_should_be_attached() const492   bool devtools_should_be_attached() const { return GetParam(); }
493 
registration()494   ServiceWorkerRegistration* registration() { return registration_.get(); }
inflight_request_id() const495   int inflight_request_id() const { return inflight_request_id_; }
496 
AddControllee()497   void AddControllee() {
498     container_host_->SetControllerRegistration(
499         registration(), false /* notify_controllerchange */);
500   }
501 
RemoveControllee()502   void RemoveControllee() {
503     container_host_->SetControllerRegistration(
504         nullptr, false /* notify_controllerchange */);
505   }
506 
IsLameDuckTimerRunning()507   bool IsLameDuckTimerRunning() {
508     return registration_->lame_duck_timer_.IsRunning();
509   }
510 
RunLameDuckTimer()511   void RunLameDuckTimer() { registration_->RemoveLameDuckIfNeeded(); }
512 
513   // Simulates skipWaiting(). Note that skipWaiting() might not try to activate
514   // the worker "immediately", if it can't yet be activated yet. If activation
515   // is delayed, |out_result| will not be set. If activation is attempted,
516   // |out_result| is generally true but false in case of a fatal/unexpected
517   // error like ServiceWorkerContext shutdown.
SimulateSkipWaiting(ServiceWorkerVersion * version,base::Optional<bool> * out_result)518   void SimulateSkipWaiting(ServiceWorkerVersion* version,
519                            base::Optional<bool>* out_result) {
520     SimulateSkipWaitingWithCallback(version, out_result, base::DoNothing());
521   }
522 
SimulateSkipWaitingWithCallback(ServiceWorkerVersion * version,base::Optional<bool> * out_result,base::OnceClosure done_callback)523   void SimulateSkipWaitingWithCallback(ServiceWorkerVersion* version,
524                                        base::Optional<bool>* out_result,
525                                        base::OnceClosure done_callback) {
526     version->SkipWaiting(base::BindOnce(
527         [](base::OnceClosure done_callback, base::Optional<bool>* out_result,
528            bool success) {
529           *out_result = success;
530           std::move(done_callback).Run();
531         },
532         std::move(done_callback), out_result));
533     base::RunLoop().RunUntilIdle();
534   }
535 
version_1_client()536   FakeEmbeddedWorkerInstanceClient* version_1_client() {
537     return version_1_client_;
538   }
version_2_client()539   FakeEmbeddedWorkerInstanceClient* version_2_client() {
540     return version_2_client_;
541   }
version_1_service_worker()542   FakeServiceWorker* version_1_service_worker() {
543     return version_1_service_worker_;
544   }
version_2_service_worker()545   FakeServiceWorker* version_2_service_worker() {
546     return version_2_service_worker_;
547   }
548 
549  private:
550   scoped_refptr<ServiceWorkerRegistration> registration_;
551 
552   // Mojo implementation fakes for the renderer-side service workers. Their
553   // lifetime is bound to the Mojo connection.
554   FakeEmbeddedWorkerInstanceClient* version_1_client_ = nullptr;
555   FakeServiceWorker* version_1_service_worker_ = nullptr;
556   FakeEmbeddedWorkerInstanceClient* version_2_client_ = nullptr;
557   FakeServiceWorker* version_2_service_worker_ = nullptr;
558 
559   base::WeakPtr<ServiceWorkerContainerHost> container_host_;
560   ServiceWorkerRemoteProviderEndpoint remote_endpoint_;
561   int inflight_request_id_ = -1;
562 
563   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerActivationTest);
564 };
565 
566 // Test activation triggered by finishing all requests.
TEST_P(ServiceWorkerActivationTest,NoInflightRequest)567 TEST_P(ServiceWorkerActivationTest, NoInflightRequest) {
568   scoped_refptr<ServiceWorkerRegistration> reg = registration();
569   scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
570   scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
571   auto runner = base::MakeRefCounted<base::TestSimpleTaskRunner>();
572   reg->SetTaskRunnerForTest(runner);
573 
574   // Remove the controllee. Since there is an in-flight request,
575   // activation should not yet happen.
576   RemoveControllee();
577   base::RunLoop().RunUntilIdle();
578   EXPECT_EQ(version_1.get(), reg->active_version());
579   // The idle timer living in the renderer is requested to notify the idle state
580   // to the browser ASAP.
581   EXPECT_EQ(base::TimeDelta::FromSeconds(0),
582             version_1_service_worker()->idle_delay().value());
583 
584   // Finish the request. Activation should happen.
585   version_1->FinishRequest(inflight_request_id(), true /* was_handled */);
586   EXPECT_EQ(version_1.get(), reg->active_version());
587   RequestTermination(&version_1_client()->host());
588 
589   TestServiceWorkerObserver observer(helper_->context_wrapper());
590   observer.RunUntilActivated(version_2.get(), runner);
591   EXPECT_EQ(version_2.get(), reg->active_version());
592 }
593 
594 // Test activation triggered by skipWaiting and finishing requests.
TEST_P(ServiceWorkerActivationTest,SkipWaitingWithInflightRequest)595 TEST_P(ServiceWorkerActivationTest, SkipWaitingWithInflightRequest) {
596   scoped_refptr<ServiceWorkerRegistration> reg = registration();
597   scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
598   scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
599 
600   base::Optional<bool> result;
601   base::RunLoop skip_waiting_loop;
602   // Set skip waiting flag. Since there is still an in-flight request,
603   // activation should not happen.
604   SimulateSkipWaitingWithCallback(version_2.get(), &result,
605                                   skip_waiting_loop.QuitClosure());
606   EXPECT_FALSE(result.has_value());
607   EXPECT_EQ(version_1.get(), reg->active_version());
608   EXPECT_EQ(base::TimeDelta::FromSeconds(0),
609             version_1_service_worker()->idle_delay().value());
610 
611   // Finish the request. FinishRequest() doesn't immediately make the worker
612   // reach the "no work" state. It needs to be notfied of the idle state by
613   // RequestTermination().
614   version_1->FinishRequest(inflight_request_id(), true /* was_handled */);
615 
616   EXPECT_EQ(version_1.get(), reg->active_version());
617   RequestTermination(&version_1_client()->host());
618 
619   // Wait until SkipWaiting resolves.
620   skip_waiting_loop.Run();
621 
622   EXPECT_TRUE(result.has_value());
623   EXPECT_TRUE(*result);
624   EXPECT_EQ(version_2.get(), reg->active_version());
625 }
626 
627 // Test activation triggered by skipWaiting.
TEST_P(ServiceWorkerActivationTest,SkipWaiting)628 TEST_P(ServiceWorkerActivationTest, SkipWaiting) {
629   scoped_refptr<ServiceWorkerRegistration> reg = registration();
630   scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
631   scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
632 
633   // Finish the in-flight request. Since there is a controllee,
634   // activation should not happen.
635   version_1->FinishRequest(inflight_request_id(), true /* was_handled */);
636   base::RunLoop().RunUntilIdle();
637   EXPECT_EQ(version_1.get(), reg->active_version());
638 
639   // Call skipWaiting. Activation happens after RequestTermination is triggered.
640   base::Optional<bool> result;
641   base::RunLoop skip_waiting_loop;
642   SimulateSkipWaitingWithCallback(version_2.get(), &result,
643                                   skip_waiting_loop.QuitClosure());
644 
645   EXPECT_EQ(base::TimeDelta::FromSeconds(0),
646             version_1_service_worker()->idle_delay().value());
647   EXPECT_FALSE(result.has_value());
648   EXPECT_EQ(version_1.get(), reg->active_version());
649   RequestTermination(&version_1_client()->host());
650 
651   // Wait until SkipWaiting resolves.
652   skip_waiting_loop.Run();
653 
654   EXPECT_TRUE(result.has_value());
655   EXPECT_TRUE(*result);
656   EXPECT_EQ(version_2.get(), reg->active_version());
657 }
658 
TEST_P(ServiceWorkerActivationTest,TimeSinceSkipWaiting_Installing)659 TEST_P(ServiceWorkerActivationTest, TimeSinceSkipWaiting_Installing) {
660   scoped_refptr<ServiceWorkerRegistration> reg = registration();
661   scoped_refptr<ServiceWorkerVersion> version = reg->waiting_version();
662   base::SimpleTestTickClock clock;
663   clock.SetNowTicks(base::TimeTicks::Now());
664   version->SetTickClockForTesting(&clock);
665 
666   // Reset version to the installing phase.
667   reg->UnsetVersion(version.get());
668   version->SetStatus(ServiceWorkerVersion::INSTALLING);
669 
670   base::Optional<bool> result;
671   // Call skipWaiting(). The time ticks since skip waiting shouldn't start
672   // since the version is not yet installed.
673   SimulateSkipWaiting(version.get(), &result);
674   EXPECT_TRUE(result.has_value());
675   EXPECT_TRUE(*result);
676   clock.Advance(base::TimeDelta::FromSeconds(11));
677   EXPECT_EQ(base::TimeDelta(), version->TimeSinceSkipWaiting());
678 
679   // Install the version. Now the skip waiting time starts ticking.
680   version->SetStatus(ServiceWorkerVersion::INSTALLED);
681   reg->SetWaitingVersion(version);
682   base::RunLoop().RunUntilIdle();
683   clock.Advance(base::TimeDelta::FromSeconds(33));
684   EXPECT_EQ(base::TimeDelta::FromSeconds(33), version->TimeSinceSkipWaiting());
685 
686   result.reset();
687   // Call skipWaiting() again. It doesn't reset the time.
688   SimulateSkipWaiting(version.get(), &result);
689   EXPECT_FALSE(result.has_value());
690   EXPECT_EQ(base::TimeDelta::FromSeconds(33), version->TimeSinceSkipWaiting());
691 }
692 
693 // Test lame duck timer triggered by skip waiting.
TEST_P(ServiceWorkerActivationTest,LameDuckTime_SkipWaiting)694 TEST_P(ServiceWorkerActivationTest, LameDuckTime_SkipWaiting) {
695   scoped_refptr<ServiceWorkerRegistration> reg = registration();
696   scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
697   scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
698   base::SimpleTestTickClock clock_1;
699   base::SimpleTestTickClock clock_2;
700   clock_1.SetNowTicks(base::TimeTicks::Now());
701   clock_2.SetNowTicks(clock_1.NowTicks());
702   version_1->SetTickClockForTesting(&clock_1);
703   version_2->SetTickClockForTesting(&clock_2);
704 
705   base::Optional<bool> result;
706   // Set skip waiting flag. Since there is still an in-flight request,
707   // activation should not happen. But the lame duck timer should start.
708   EXPECT_FALSE(IsLameDuckTimerRunning());
709   SimulateSkipWaiting(version_2.get(), &result);
710   EXPECT_FALSE(result.has_value());
711   EXPECT_EQ(version_1.get(), reg->active_version());
712   EXPECT_TRUE(IsLameDuckTimerRunning());
713 
714   // Move forward by lame duck time.
715   clock_2.Advance(kMaxLameDuckTime + base::TimeDelta::FromSeconds(1));
716 
717   // Activation should happen by the lame duck timer.
718   RunLameDuckTimer();
719   base::RunLoop().RunUntilIdle();
720   EXPECT_TRUE(result.has_value());
721   EXPECT_TRUE(*result);
722   EXPECT_EQ(version_2.get(), reg->active_version());
723   EXPECT_FALSE(IsLameDuckTimerRunning());
724 
725   // Restore the TickClock to the default. This is required because the dtor
726   // of ServiceWorkerVersions can access the TickClock and it should outlive
727   // ServiceWorkerVersion.
728   version_1->SetTickClockForTesting(base::DefaultTickClock::GetInstance());
729   version_2->SetTickClockForTesting(base::DefaultTickClock::GetInstance());
730 }
731 
732 // Test lame duck timer triggered by loss of controllee.
TEST_P(ServiceWorkerActivationTest,LameDuckTime_NoControllee)733 TEST_P(ServiceWorkerActivationTest, LameDuckTime_NoControllee) {
734   scoped_refptr<ServiceWorkerRegistration> reg = registration();
735   scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
736   scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
737   base::SimpleTestTickClock clock_1;
738   base::SimpleTestTickClock clock_2;
739   clock_1.SetNowTicks(base::TimeTicks::Now());
740   clock_2.SetNowTicks(clock_1.NowTicks());
741   version_1->SetTickClockForTesting(&clock_1);
742   version_2->SetTickClockForTesting(&clock_2);
743 
744   // Remove the controllee. Since there is still an in-flight request,
745   // activation should not happen. But the lame duck timer should start.
746   EXPECT_FALSE(IsLameDuckTimerRunning());
747   RemoveControllee();
748   base::RunLoop().RunUntilIdle();
749   EXPECT_EQ(version_1.get(), reg->active_version());
750   EXPECT_TRUE(IsLameDuckTimerRunning());
751 
752   // Move clock forward by a little bit.
753   constexpr base::TimeDelta kLittleBit = base::TimeDelta::FromMinutes(1);
754   clock_1.Advance(kLittleBit);
755 
756   // Add a controllee again to reset the lame duck period.
757   AddControllee();
758   base::RunLoop().RunUntilIdle();
759   EXPECT_TRUE(IsLameDuckTimerRunning());
760 
761   // Remove the controllee.
762   RemoveControllee();
763   base::RunLoop().RunUntilIdle();
764   EXPECT_TRUE(IsLameDuckTimerRunning());
765 
766   // Move clock forward to the next lame duck timer tick.
767   clock_1.Advance(kMaxLameDuckTime - kLittleBit +
768                   base::TimeDelta::FromSeconds(1));
769 
770   // Run the lame duck timer. Activation should not yet happen
771   // since the lame duck period has not expired.
772   RunLameDuckTimer();
773   base::RunLoop().RunUntilIdle();
774   EXPECT_EQ(version_1.get(), reg->active_version());
775   EXPECT_TRUE(IsLameDuckTimerRunning());
776 
777   // Continue on to the next lame duck timer tick.
778   clock_1.Advance(kMaxLameDuckTime + base::TimeDelta::FromSeconds(1));
779 
780   // Activation should happen by the lame duck timer.
781   RunLameDuckTimer();
782   base::RunLoop().RunUntilIdle();
783   EXPECT_EQ(version_2.get(), reg->active_version());
784   EXPECT_FALSE(IsLameDuckTimerRunning());
785 }
786 
787 INSTANTIATE_TEST_SUITE_P(ServiceWorkerActivationTestWithDevTools,
788                          ServiceWorkerActivationTest,
789                          testing::Bool());
790 
791 // Sets up a registration with a ServiceWorkerRegistrationObjectHost to hold it.
792 class ServiceWorkerRegistrationObjectHostTest
793     : public ServiceWorkerRegistrationTest {
794  protected:
SetUp()795   void SetUp() override {
796     ServiceWorkerRegistrationTest::SetUp();
797     mojo::core::SetDefaultProcessErrorCallback(base::AdaptCallbackForRepeating(
798         base::BindOnce(&ServiceWorkerRegistrationObjectHostTest::OnMojoError,
799                        base::Unretained(this))));
800   }
801 
TearDown()802   void TearDown() override {
803     mojo::core::SetDefaultProcessErrorCallback(
804         mojo::core::ProcessErrorCallback());
805     ServiceWorkerRegistrationTest::TearDown();
806   }
807 
808   // Pass nullptr for |out_error_msg| if it's not needed.
CallUpdate(blink::mojom::ServiceWorkerRegistrationObjectHost * registration_host,std::string * out_error_msg)809   blink::mojom::ServiceWorkerErrorType CallUpdate(
810       blink::mojom::ServiceWorkerRegistrationObjectHost* registration_host,
811       std::string* out_error_msg) {
812     blink::mojom::ServiceWorkerErrorType out_error =
813         blink::mojom::ServiceWorkerErrorType::kUnknown;
814     registration_host->Update(
815         blink::mojom::FetchClientSettingsObject::New(),
816         base::BindLambdaForTesting(
817             [&out_error, &out_error_msg](
818                 blink::mojom::ServiceWorkerErrorType error,
819                 const base::Optional<std::string>& error_msg) {
820               out_error = error;
821               if (out_error_msg) {
822                 *out_error_msg = error_msg ? *error_msg : "";
823               }
824             }));
825     base::RunLoop().RunUntilIdle();
826     return out_error;
827   }
828 
CallDelayUpdate(blink::mojom::ServiceWorkerContainerType provider_type,ServiceWorkerRegistration * registration,ServiceWorkerVersion * version)829   blink::ServiceWorkerStatusCode CallDelayUpdate(
830       blink::mojom::ServiceWorkerContainerType provider_type,
831       ServiceWorkerRegistration* registration,
832       ServiceWorkerVersion* version) {
833     base::Optional<blink::ServiceWorkerStatusCode> status;
834     base::RunLoop run_loop;
835     ServiceWorkerRegistrationObjectHost::DelayUpdate(
836         blink::mojom::ServiceWorkerContainerType::kForServiceWorker,
837         registration, version,
838         base::BindOnce(
839             [](base::Optional<blink::ServiceWorkerStatusCode>* out_status,
840                base::OnceClosure callback,
841                blink::ServiceWorkerStatusCode status) {
842               *out_status = status;
843               std::move(callback).Run();
844             },
845             &status, run_loop.QuitClosure()));
846     run_loop.Run();
847     return status.value();
848   }
849 
CallUnregister(blink::mojom::ServiceWorkerRegistrationObjectHost * registration_host)850   blink::mojom::ServiceWorkerErrorType CallUnregister(
851       blink::mojom::ServiceWorkerRegistrationObjectHost* registration_host) {
852     blink::mojom::ServiceWorkerErrorType error =
853         blink::mojom::ServiceWorkerErrorType::kUnknown;
854     registration_host->Unregister(base::BindOnce(
855         [](blink::mojom::ServiceWorkerErrorType* out_error,
856            blink::mojom::ServiceWorkerErrorType error,
857            const base::Optional<std::string>& error_msg) {
858           *out_error = error;
859         },
860         &error));
861     base::RunLoop().RunUntilIdle();
862     return error;
863   }
864 
FindRegistrationInStorage(int64_t registration_id,const GURL & scope)865   blink::ServiceWorkerStatusCode FindRegistrationInStorage(
866       int64_t registration_id,
867       const GURL& scope) {
868     base::Optional<blink::ServiceWorkerStatusCode> status;
869     registry()->FindRegistrationForId(
870         registration_id, scope,
871         base::AdaptCallbackForRepeating(base::BindOnce(
872             [](base::Optional<blink::ServiceWorkerStatusCode>* out_status,
873                blink::ServiceWorkerStatusCode status,
874                scoped_refptr<ServiceWorkerRegistration> registration) {
875               *out_status = status;
876             },
877             &status)));
878     base::RunLoop().RunUntilIdle();
879     return status.value();
880   }
881 
CreateNewRegistration(const GURL & scope)882   scoped_refptr<ServiceWorkerRegistration> CreateNewRegistration(
883       const GURL& scope) {
884     blink::mojom::ServiceWorkerRegistrationOptions options;
885     options.scope = scope;
886     return CreateNewServiceWorkerRegistration(context()->registry(), options);
887   }
888 
CreateVersion(ServiceWorkerRegistration * registration,const GURL & script_url)889   scoped_refptr<ServiceWorkerVersion> CreateVersion(
890       ServiceWorkerRegistration* registration,
891       const GURL& script_url) {
892     scoped_refptr<ServiceWorkerVersion> version = CreateNewServiceWorkerVersion(
893         context()->registry(), registration, script_url,
894         blink::mojom::ScriptType::kClassic);
895     std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> records;
896     records.push_back(WriteToDiskCacheSync(storage(), version->script_url(),
897                                            {} /* headers */, "I'm the body",
898                                            "I'm the meta data"));
899     version->script_cache_map()->SetResources(records);
900     version->SetMainScriptResponse(
901         EmbeddedWorkerTestHelper::CreateMainScriptResponse());
902     version->set_fetch_handler_existence(
903         ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
904     version->SetStatus(ServiceWorkerVersion::INSTALLING);
905     return version;
906   }
907 
SetUpRegistration(const GURL & scope,const GURL & script_url)908   int64_t SetUpRegistration(const GURL& scope, const GURL& script_url) {
909     storage()->LazyInitializeForTest();
910 
911     // Prepare ServiceWorkerRegistration and ServiceWorkerVersion.
912     scoped_refptr<ServiceWorkerRegistration> registration =
913         CreateNewRegistration(scope);
914     scoped_refptr<ServiceWorkerVersion> version =
915         CreateVersion(registration.get(), script_url);
916 
917     // Make the registration findable via storage functions.
918     bool called = false;
919     blink::ServiceWorkerStatusCode status =
920         blink::ServiceWorkerStatusCode::kErrorFailed;
921     registry()->StoreRegistration(
922         registration.get(), version.get(),
923         base::BindOnce(&SaveStatusCallback, &called, &status));
924     base::RunLoop().RunUntilIdle();
925     EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
926 
927     return registration->id();
928   }
929 
PrepareContainerHost(const GURL & document_url,base::WeakPtr<ServiceWorkerContainerHost> * out_container_host)930   ServiceWorkerRemoteProviderEndpoint PrepareContainerHost(
931       const GURL& document_url,
932       base::WeakPtr<ServiceWorkerContainerHost>* out_container_host) {
933     ServiceWorkerRemoteProviderEndpoint remote_endpoint;
934     base::WeakPtr<ServiceWorkerContainerHost> container_host =
935         CreateContainerHostForWindow(helper_->mock_render_process_id(),
936                                      true /* is_parent_frame_secure */,
937                                      context()->AsWeakPtr(), &remote_endpoint);
938     container_host->UpdateUrls(document_url,
939                                net::SiteForCookies::FromUrl(document_url),
940                                url::Origin::Create(document_url));
941     if (out_container_host)
942       *out_container_host = container_host;
943     return remote_endpoint;
944   }
945 
946   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
GetRegistrationFromRemote(blink::mojom::ServiceWorkerContainerHost * container_host,const GURL & url)947   GetRegistrationFromRemote(
948       blink::mojom::ServiceWorkerContainerHost* container_host,
949       const GURL& url) {
950     blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info;
951     container_host->GetRegistration(
952         url, base::BindOnce(
953                  [](blink::mojom::ServiceWorkerRegistrationObjectInfoPtr*
954                         out_registration_info,
955                     blink::mojom::ServiceWorkerErrorType error,
956                     const base::Optional<std::string>& error_msg,
957                     blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
958                         registration) {
959                    ASSERT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
960                              error);
961                    *out_registration_info = std::move(registration);
962                  },
963                  &registration_info));
964     base::RunLoop().RunUntilIdle();
965     EXPECT_TRUE(registration_info->host_remote.is_valid());
966     return registration_info;
967   }
968 
OnMojoError(const std::string & error)969   void OnMojoError(const std::string& error) { bad_messages_.push_back(error); }
970 
971   std::vector<std::string> bad_messages_;
972 };
973 
974 class ServiceWorkerRegistrationObjectHostUpdateTest
975     : public ServiceWorkerRegistrationObjectHostTest,
976       public testing::WithParamInterface<bool> {
977  public:
ServiceWorkerRegistrationObjectHostUpdateTest()978   ServiceWorkerRegistrationObjectHostUpdateTest()
979       : interceptor_(base::BindRepeating(&FakeNetwork::HandleRequest,
980                                          base::Unretained(&fake_network_))) {}
981  private:
982   FakeNetwork fake_network_;
983   URLLoaderInterceptor interceptor_;
984 };
985 
986 INSTANTIATE_TEST_SUITE_P(ServiceWorkerRegistrationObjectHostUpdateTestP,
987                          ServiceWorkerRegistrationObjectHostUpdateTest,
988                          testing::Bool());
989 
TEST_F(ServiceWorkerRegistrationObjectHostTest,BreakConnection_Destroy)990 TEST_F(ServiceWorkerRegistrationObjectHostTest, BreakConnection_Destroy) {
991   const GURL kScope("https://www.example.com/");
992   const GURL kScriptUrl("https://www.example.com/sw.js");
993   int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
994   ServiceWorkerRemoteProviderEndpoint remote_endpoint =
995       PrepareContainerHost(kScope, nullptr /* out_container_host */);
996   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
997       GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
998   mojo::AssociatedRemote<blink::mojom::ServiceWorkerRegistrationObjectHost>
999       registration_host;
1000   registration_host.Bind(std::move(info->host_remote));
1001 
1002   EXPECT_NE(nullptr, context()->GetLiveRegistration(registration_id));
1003   registration_host.reset();
1004   base::RunLoop().RunUntilIdle();
1005   EXPECT_EQ(nullptr, context()->GetLiveRegistration(registration_id));
1006 }
1007 
TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,Update_Success)1008 TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest, Update_Success) {
1009   const GURL kScope("https://www.example.com/");
1010   const GURL kScriptUrl("https://www.example.com/sw.js");
1011   SetUpRegistration(kScope, kScriptUrl);
1012   ServiceWorkerRemoteProviderEndpoint remote_endpoint =
1013       PrepareContainerHost(kScope, nullptr /* out_container_host */);
1014   mojo::AssociatedRemote<blink::mojom::ServiceWorkerRegistrationObjectHost>
1015       registration_host;
1016   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
1017       GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
1018   registration_host.Bind(std::move(info->host_remote));
1019   // Ignore the messages to the registration object, otherwise the callbacks
1020   // issued from |registration_host| may wait for receiving the messages to
1021   // |info->receiver|.
1022   info->receiver.reset();
1023 
1024   EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
1025             CallUpdate(registration_host.get(), /*out_error_msg=*/nullptr));
1026 }
1027 
TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,Update_CrossOriginShouldFail)1028 TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,
1029        Update_CrossOriginShouldFail) {
1030   const GURL kScope("https://www.example.com/");
1031   const GURL kScriptUrl("https://www.example.com/sw.js");
1032   SetUpRegistration(kScope, kScriptUrl);
1033   base::WeakPtr<ServiceWorkerContainerHost> container_host;
1034   ServiceWorkerRemoteProviderEndpoint remote_endpoint =
1035       PrepareContainerHost(kScope, &container_host);
1036   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
1037       GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
1038   mojo::AssociatedRemote<blink::mojom::ServiceWorkerRegistrationObjectHost>
1039       registration_host;
1040   registration_host.Bind(std::move(info->host_remote));
1041 
1042   ASSERT_TRUE(bad_messages_.empty());
1043   GURL url("https://does.not.exist/");
1044   container_host->UpdateUrls(url, net::SiteForCookies::FromUrl(url),
1045                              url::Origin::Create(url));
1046   CallUpdate(registration_host.get(), /*out_error_msg=*/nullptr);
1047   EXPECT_EQ(1u, bad_messages_.size());
1048 }
1049 
TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,Update_ContentSettingsDisallowsServiceWorker)1050 TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,
1051        Update_ContentSettingsDisallowsServiceWorker) {
1052   const GURL kScope("https://www.example.com/");
1053   const GURL kScriptUrl("https://www.example.com/sw.js");
1054   SetUpRegistration(kScope, kScriptUrl);
1055   ServiceWorkerRemoteProviderEndpoint remote_endpoint =
1056       PrepareContainerHost(kScope, nullptr /* out_container_host */);
1057   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
1058       GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
1059   mojo::AssociatedRemote<blink::mojom::ServiceWorkerRegistrationObjectHost>
1060       registration_host;
1061   registration_host.Bind(std::move(info->host_remote));
1062 
1063   ServiceWorkerTestContentBrowserClient test_browser_client;
1064   ContentBrowserClient* old_browser_client =
1065       SetBrowserClientForTesting(&test_browser_client);
1066   std::string error_msg;
1067   EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kDisabled,
1068             CallUpdate(registration_host.get(), &error_msg));
1069   EXPECT_EQ(
1070       error_msg,
1071       "Failed to update a ServiceWorker for scope ('https://www.example.com/') "
1072       "with script ('https://www.example.com/sw.js'): The user denied "
1073       "permission to use Service Worker.");
1074   SetBrowserClientForTesting(old_browser_client);
1075 }
1076 
TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,Update_NoDelayFromControllee)1077 TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,
1078        Update_NoDelayFromControllee) {
1079   const GURL kScope("https://www.example.com/");
1080   const GURL kScriptUrl("https://www.example.com/sw.js");
1081   int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
1082   ServiceWorkerRemoteProviderEndpoint remote_endpoint =
1083       PrepareContainerHost(kScope, nullptr /* out_container_host */);
1084   mojo::AssociatedRemote<blink::mojom::ServiceWorkerRegistrationObjectHost>
1085       registration_host;
1086 
1087   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
1088       GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
1089   registration_host.Bind(std::move(info->host_remote));
1090   // Ignore the messages to the registration object, otherwise the callbacks
1091   // issued from |registration_host| may wait for receiving the messages to
1092   // |info->receiver|.
1093   info->receiver.reset();
1094 
1095   // Get registration and set |self_update_delay| to zero.
1096   ServiceWorkerRegistration* registration =
1097       context()->GetLiveRegistration(registration_id);
1098   ASSERT_TRUE(registration);
1099   registration->set_self_update_delay(base::TimeDelta());
1100   EXPECT_EQ(base::TimeDelta(), registration->self_update_delay());
1101 
1102   EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
1103             CallUpdate(registration_host.get(), /*out_error_msg=*/nullptr));
1104   EXPECT_EQ(base::TimeDelta(), registration->self_update_delay());
1105 }
1106 
TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,Update_DelayFromWorkerWithoutControllee)1107 TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,
1108        Update_DelayFromWorkerWithoutControllee) {
1109   const GURL kScope("https://www.example.com/");
1110   const GURL kScriptUrl("https://www.example.com/sw.js");
1111   scoped_refptr<ServiceWorkerRegistration> registration =
1112       CreateNewRegistration(kScope);
1113   scoped_refptr<ServiceWorkerVersion> version =
1114       CreateVersion(registration.get(), kScriptUrl);
1115 
1116   // Initially set |self_update_delay| to zero.
1117   registration->set_self_update_delay(base::TimeDelta());
1118   EXPECT_EQ(base::TimeDelta(), registration->self_update_delay());
1119 
1120   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
1121             CallDelayUpdate(
1122                 blink::mojom::ServiceWorkerContainerType::kForServiceWorker,
1123                 registration.get(), version.get()));
1124   EXPECT_LT(base::TimeDelta(), registration->self_update_delay());
1125 
1126   // TODO(falken): Add a test verifying that a delayed update will be executed
1127   // eventually.
1128 
1129   // Set |self_update_delay| to a time so that update() will reject immediately.
1130   registration->set_self_update_delay(base::TimeDelta::FromMinutes(5));
1131   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout,
1132             CallDelayUpdate(
1133                 blink::mojom::ServiceWorkerContainerType::kForServiceWorker,
1134                 registration.get(), version.get()));
1135   EXPECT_LE(base::TimeDelta::FromMinutes(5), registration->self_update_delay());
1136 }
1137 
TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,Update_NoDelayFromWorkerWithControllee)1138 TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,
1139        Update_NoDelayFromWorkerWithControllee) {
1140   const GURL kScope("https://www.example.com/");
1141   const GURL kScriptUrl("https://www.example.com/sw.js");
1142   scoped_refptr<ServiceWorkerRegistration> registration =
1143       CreateNewRegistration(kScope);
1144 
1145   scoped_refptr<ServiceWorkerVersion> version =
1146       CreateVersion(registration.get(), kScriptUrl);
1147   version->SetStatus(ServiceWorkerVersion::ACTIVATED);
1148 
1149   ServiceWorkerRemoteProviderEndpoint remote_endpoint;
1150   base::WeakPtr<ServiceWorkerContainerHost> container_host =
1151       CreateContainerHostForWindow(helper_->mock_render_process_id(),
1152                                    true /* is_parent_frame_secure */,
1153                                    context()->AsWeakPtr(), &remote_endpoint);
1154   container_host->UpdateUrls(kScope, net::SiteForCookies::FromUrl(kScope),
1155                              url::Origin::Create(kScope));
1156   version->AddControllee(container_host.get());
1157 
1158   // Initially set |self_update_delay| to zero.
1159   registration->set_self_update_delay(base::TimeDelta());
1160   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
1161             CallDelayUpdate(
1162                 blink::mojom::ServiceWorkerContainerType::kForServiceWorker,
1163                 registration.get(), version.get()));
1164   EXPECT_EQ(base::TimeDelta(), registration->self_update_delay());
1165 
1166   // Set |self_update_delay| to a time so that update() will reject immediately
1167   // if the worker doesn't have at least one controlee.
1168   registration->set_self_update_delay(base::TimeDelta::FromMinutes(5));
1169   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
1170             CallDelayUpdate(
1171                 blink::mojom::ServiceWorkerContainerType::kForServiceWorker,
1172                 registration.get(), version.get()));
1173   EXPECT_EQ(base::TimeDelta::FromMinutes(5), registration->self_update_delay());
1174 }
1175 
TEST_F(ServiceWorkerRegistrationObjectHostTest,Unregister_Success)1176 TEST_F(ServiceWorkerRegistrationObjectHostTest, Unregister_Success) {
1177   const GURL kScope("https://www.example.com/");
1178   const GURL kScriptUrl("https://www.example.com/sw.js");
1179   int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
1180   ServiceWorkerRemoteProviderEndpoint remote_endpoint =
1181       PrepareContainerHost(kScope, nullptr /* out_container_host */);
1182   mojo::AssociatedRemote<blink::mojom::ServiceWorkerRegistrationObjectHost>
1183       registration_host;
1184   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
1185       GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
1186   registration_host.Bind(std::move(info->host_remote));
1187   // Ignore the messages to the registration object and corresponding service
1188   // worker objects, otherwise the callbacks issued from |registration_host|
1189   // may wait for receiving the messages to them.
1190   info->receiver.reset();
1191   info->waiting->receiver.reset();
1192 
1193   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
1194             FindRegistrationInStorage(registration_id, kScope));
1195   EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
1196             CallUnregister(registration_host.get()));
1197 
1198   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
1199             FindRegistrationInStorage(registration_id, kScope));
1200   EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNotFound,
1201             CallUnregister(registration_host.get()));
1202 }
1203 
TEST_F(ServiceWorkerRegistrationObjectHostTest,Unregister_CrossOriginShouldFail)1204 TEST_F(ServiceWorkerRegistrationObjectHostTest,
1205        Unregister_CrossOriginShouldFail) {
1206   const GURL kScope("https://www.example.com/");
1207   const GURL kScriptUrl("https://www.example.com/sw.js");
1208   SetUpRegistration(kScope, kScriptUrl);
1209   base::WeakPtr<ServiceWorkerContainerHost> container_host;
1210   ServiceWorkerRemoteProviderEndpoint remote_endpoint =
1211       PrepareContainerHost(kScope, &container_host);
1212   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
1213       GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
1214   mojo::AssociatedRemote<blink::mojom::ServiceWorkerRegistrationObjectHost>
1215       registration_host;
1216   registration_host.Bind(std::move(info->host_remote));
1217 
1218   ASSERT_TRUE(bad_messages_.empty());
1219   container_host->UpdateUrls(
1220       GURL("https://does.not.exist/"),
1221       net::SiteForCookies::FromUrl(GURL("https://does.not.exist/")),
1222       url::Origin::Create(GURL("https://does.not.exist/")));
1223   CallUnregister(registration_host.get());
1224   EXPECT_EQ(1u, bad_messages_.size());
1225 }
1226 
TEST_F(ServiceWorkerRegistrationObjectHostTest,Unregister_ContentSettingsDisallowsServiceWorker)1227 TEST_F(ServiceWorkerRegistrationObjectHostTest,
1228        Unregister_ContentSettingsDisallowsServiceWorker) {
1229   const GURL kScope("https://www.example.com/");
1230   const GURL kScriptUrl("https://www.example.com/sw.js");
1231   SetUpRegistration(kScope, kScriptUrl);
1232   ServiceWorkerRemoteProviderEndpoint remote_endpoint =
1233       PrepareContainerHost(kScope, nullptr /* out_container_host */);
1234   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
1235       GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
1236   mojo::AssociatedRemote<blink::mojom::ServiceWorkerRegistrationObjectHost>
1237       registration_host;
1238   registration_host.Bind(std::move(info->host_remote));
1239 
1240   ServiceWorkerTestContentBrowserClient test_browser_client;
1241   ContentBrowserClient* old_browser_client =
1242       SetBrowserClientForTesting(&test_browser_client);
1243   EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kDisabled,
1244             CallUnregister(registration_host.get()));
1245   SetBrowserClientForTesting(old_browser_client);
1246 }
1247 
TEST_F(ServiceWorkerRegistrationObjectHostTest,SetVersionAttributes)1248 TEST_F(ServiceWorkerRegistrationObjectHostTest, SetVersionAttributes) {
1249   const GURL kScope("https://www.example.com/");
1250   const GURL kScriptUrl("https://www.example.com/sw.js");
1251   int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
1252   ServiceWorkerRemoteProviderEndpoint remote_endpoint =
1253       PrepareContainerHost(kScope, nullptr /* out_container_host */);
1254   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
1255       GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
1256   EXPECT_EQ(registration_id, info->registration_id);
1257   EXPECT_TRUE(info->receiver.is_valid());
1258   auto mock_registration_object =
1259       std::make_unique<MockServiceWorkerRegistrationObject>(
1260           std::move(info->receiver));
1261 
1262   ServiceWorkerRegistration* registration =
1263       context()->GetLiveRegistration(registration_id);
1264   ASSERT_NE(nullptr, registration);
1265   const int64_t version_1_id = 1L;
1266   const int64_t version_2_id = 2L;
1267   scoped_refptr<ServiceWorkerVersion> version_1 =
1268       base::MakeRefCounted<ServiceWorkerVersion>(
1269           registration, kScriptUrl, blink::mojom::ScriptType::kClassic,
1270           version_1_id, context()->AsWeakPtr());
1271   scoped_refptr<ServiceWorkerVersion> version_2 =
1272       base::MakeRefCounted<ServiceWorkerVersion>(
1273           registration, kScriptUrl, blink::mojom::ScriptType::kClassic,
1274           version_2_id, context()->AsWeakPtr());
1275 
1276   // Set an active worker.
1277   registration->SetActiveVersion(version_1);
1278   EXPECT_EQ(version_1.get(), registration->active_version());
1279   base::RunLoop().RunUntilIdle();
1280   EXPECT_EQ(1, mock_registration_object->set_version_attributes_called_count());
1281   EXPECT_FALSE(mock_registration_object->changed_mask().installing);
1282   EXPECT_FALSE(mock_registration_object->installing());
1283   EXPECT_FALSE(mock_registration_object->changed_mask().waiting);
1284   EXPECT_FALSE(mock_registration_object->waiting());
1285   EXPECT_TRUE(mock_registration_object->changed_mask().active);
1286   EXPECT_TRUE(mock_registration_object->active());
1287   EXPECT_EQ(version_1_id, mock_registration_object->active()->version_id);
1288   EXPECT_EQ(kScriptUrl, mock_registration_object->active()->url);
1289 
1290   // Set an installing worker.
1291   registration->SetInstallingVersion(version_2);
1292   EXPECT_EQ(version_2.get(), registration->installing_version());
1293   base::RunLoop().RunUntilIdle();
1294   EXPECT_EQ(2, mock_registration_object->set_version_attributes_called_count());
1295   EXPECT_TRUE(mock_registration_object->changed_mask().installing);
1296   EXPECT_TRUE(mock_registration_object->installing());
1297   EXPECT_FALSE(mock_registration_object->changed_mask().waiting);
1298   EXPECT_FALSE(mock_registration_object->waiting());
1299   EXPECT_FALSE(mock_registration_object->changed_mask().active);
1300   EXPECT_FALSE(mock_registration_object->active());
1301   EXPECT_EQ(version_2_id, mock_registration_object->installing()->version_id);
1302   EXPECT_EQ(kScriptUrl, mock_registration_object->installing()->url);
1303 
1304   // Promote the installing worker to waiting.
1305   registration->SetWaitingVersion(version_2);
1306   EXPECT_EQ(version_2.get(), registration->waiting_version());
1307   EXPECT_FALSE(registration->installing_version());
1308   base::RunLoop().RunUntilIdle();
1309   EXPECT_EQ(3, mock_registration_object->set_version_attributes_called_count());
1310   EXPECT_TRUE(mock_registration_object->changed_mask().installing);
1311   EXPECT_FALSE(mock_registration_object->installing());
1312   EXPECT_TRUE(mock_registration_object->changed_mask().waiting);
1313   EXPECT_TRUE(mock_registration_object->waiting());
1314   EXPECT_FALSE(mock_registration_object->changed_mask().active);
1315   EXPECT_FALSE(mock_registration_object->active());
1316   EXPECT_EQ(version_2_id, mock_registration_object->waiting()->version_id);
1317   EXPECT_EQ(kScriptUrl, mock_registration_object->waiting()->url);
1318 
1319   // Remove the waiting worker.
1320   registration->UnsetVersion(version_2.get());
1321   EXPECT_FALSE(registration->waiting_version());
1322   base::RunLoop().RunUntilIdle();
1323   EXPECT_EQ(4, mock_registration_object->set_version_attributes_called_count());
1324   EXPECT_FALSE(mock_registration_object->changed_mask().installing);
1325   EXPECT_FALSE(mock_registration_object->installing());
1326   EXPECT_TRUE(mock_registration_object->changed_mask().waiting);
1327   EXPECT_FALSE(mock_registration_object->waiting());
1328   EXPECT_FALSE(mock_registration_object->changed_mask().active);
1329   EXPECT_FALSE(mock_registration_object->active());
1330 }
1331 
TEST_F(ServiceWorkerRegistrationObjectHostTest,SetUpdateViaCache)1332 TEST_F(ServiceWorkerRegistrationObjectHostTest, SetUpdateViaCache) {
1333   const GURL kScope("https://www.example.com/");
1334   const GURL kScriptUrl("https://www.example.com/sw.js");
1335   int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
1336   ServiceWorkerRemoteProviderEndpoint remote_endpoint =
1337       PrepareContainerHost(kScope, nullptr /* out_container_host */);
1338   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
1339       GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
1340   EXPECT_EQ(registration_id, info->registration_id);
1341   EXPECT_TRUE(info->receiver.is_valid());
1342   auto mock_registration_object =
1343       std::make_unique<MockServiceWorkerRegistrationObject>(
1344           std::move(info->receiver));
1345 
1346   ServiceWorkerRegistration* registration =
1347       context()->GetLiveRegistration(registration_id);
1348   ASSERT_EQ(blink::mojom::ServiceWorkerUpdateViaCache::kImports,
1349             registration->update_via_cache());
1350   ASSERT_EQ(0, mock_registration_object->set_update_via_cache_called_count());
1351   ASSERT_EQ(blink::mojom::ServiceWorkerUpdateViaCache::kImports,
1352             mock_registration_object->update_via_cache());
1353 
1354   registration->SetUpdateViaCache(
1355       blink::mojom::ServiceWorkerUpdateViaCache::kImports);
1356   base::RunLoop().RunUntilIdle();
1357   EXPECT_EQ(0, mock_registration_object->set_update_via_cache_called_count());
1358   EXPECT_EQ(blink::mojom::ServiceWorkerUpdateViaCache::kImports,
1359             mock_registration_object->update_via_cache());
1360 
1361   registration->SetUpdateViaCache(
1362       blink::mojom::ServiceWorkerUpdateViaCache::kAll);
1363   base::RunLoop().RunUntilIdle();
1364   EXPECT_EQ(1, mock_registration_object->set_update_via_cache_called_count());
1365   EXPECT_EQ(blink::mojom::ServiceWorkerUpdateViaCache::kAll,
1366             mock_registration_object->update_via_cache());
1367 
1368   registration->SetUpdateViaCache(
1369       blink::mojom::ServiceWorkerUpdateViaCache::kNone);
1370   base::RunLoop().RunUntilIdle();
1371   EXPECT_EQ(2, mock_registration_object->set_update_via_cache_called_count());
1372   EXPECT_EQ(blink::mojom::ServiceWorkerUpdateViaCache::kNone,
1373             mock_registration_object->update_via_cache());
1374 
1375   registration->SetUpdateViaCache(
1376       blink::mojom::ServiceWorkerUpdateViaCache::kImports);
1377   base::RunLoop().RunUntilIdle();
1378   EXPECT_EQ(3, mock_registration_object->set_update_via_cache_called_count());
1379   EXPECT_EQ(blink::mojom::ServiceWorkerUpdateViaCache::kImports,
1380             mock_registration_object->update_via_cache());
1381 }
1382 
TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,UpdateFound)1383 TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest, UpdateFound) {
1384   const GURL kScope("https://www.example.com/");
1385   const GURL kScriptUrl("https://www.example.com/sw.js");
1386   int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
1387   ServiceWorkerRemoteProviderEndpoint remote_endpoint =
1388       PrepareContainerHost(kScope, nullptr /* out_container_host */);
1389   blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
1390       GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
1391   EXPECT_EQ(registration_id, info->registration_id);
1392   EXPECT_TRUE(info->receiver.is_valid());
1393   auto mock_registration_object =
1394       std::make_unique<MockServiceWorkerRegistrationObject>(
1395           std::move(info->receiver));
1396 
1397   ServiceWorkerRegistration* registration =
1398       context()->GetLiveRegistration(registration_id);
1399   ASSERT_NE(nullptr, registration);
1400   EXPECT_EQ(0, mock_registration_object->update_found_called_count());
1401   registration->NotifyUpdateFound();
1402   base::RunLoop().RunUntilIdle();
1403   EXPECT_EQ(1, mock_registration_object->update_found_called_count());
1404 }
1405 
1406 }  // namespace content
1407