1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/browser/service_worker/service_worker_version.h"
6 
7 #include <stdint.h>
8 #include <memory>
9 #include <tuple>
10 #include <utility>
11 
12 #include "base/bind.h"
13 #include "base/callback_helpers.h"
14 #include "base/containers/span.h"
15 #include "base/macros.h"
16 #include "base/memory/ptr_util.h"
17 #include "base/run_loop.h"
18 #include "base/test/bind.h"
19 #include "base/test/metrics/histogram_tester.h"
20 #include "base/test/scoped_feature_list.h"
21 #include "base/test/simple_test_tick_clock.h"
22 #include "base/time/time.h"
23 #include "content/browser/renderer_host/frame_tree_node.h"
24 #include "content/browser/service_worker/embedded_worker_status.h"
25 #include "content/browser/service_worker/embedded_worker_test_helper.h"
26 #include "content/browser/service_worker/fake_embedded_worker_instance_client.h"
27 #include "content/browser/service_worker/fake_service_worker.h"
28 #include "content/browser/service_worker/service_worker_container_host.h"
29 #include "content/browser/service_worker/service_worker_context_core.h"
30 #include "content/browser/service_worker/service_worker_ping_controller.h"
31 #include "content/browser/service_worker/service_worker_registration.h"
32 #include "content/browser/service_worker/service_worker_test_utils.h"
33 #include "content/common/service_worker/service_worker_utils.h"
34 #include "content/public/common/content_features.h"
35 #include "content/public/test/browser_task_environment.h"
36 #include "content/public/test/mock_render_process_host.h"
37 #include "content/public/test/test_service.mojom.h"
38 #include "content/public/test/test_utils.h"
39 #include "net/base/test_completion_callback.h"
40 #include "services/metrics/public/cpp/ukm_recorder.h"
41 #include "testing/gtest/include/gtest/gtest.h"
42 #include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
43 #include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
44 #include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom.h"
45 #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
46 
47 namespace content {
48 namespace service_worker_version_unittest {
49 
VerifyCalled(bool * called,base::OnceClosure quit_closure=base::OnceClosure ())50 base::OnceCallback<void()> VerifyCalled(
51     bool* called,
52     base::OnceClosure quit_closure = base::OnceClosure()) {
53   return base::BindOnce(
54       [](bool* called, base::OnceClosure quit_closure) {
55         *called = true;
56         if (!quit_closure.is_null())
57           std::move(quit_closure).Run();
58       },
59       called, std::move(quit_closure));
60 }
61 
ObserveStatusChanges(ServiceWorkerVersion * version,std::vector<ServiceWorkerVersion::Status> * statuses)62 void ObserveStatusChanges(ServiceWorkerVersion* version,
63                           std::vector<ServiceWorkerVersion::Status>* statuses) {
64   statuses->push_back(version->status());
65   version->RegisterStatusChangeCallback(base::BindOnce(
66       &ObserveStatusChanges, base::Unretained(version), statuses));
67 }
68 
GetYesterday()69 base::Time GetYesterday() {
70   return base::Time::Now() - base::TimeDelta::FromDays(1) -
71          base::TimeDelta::FromSeconds(1);
72 }
73 
74 class ServiceWorkerVersionTest : public testing::Test {
75  protected:
76   using FetchHandlerExistence = blink::mojom::FetchHandlerExistence;
77 
78   struct CachedMetadataUpdateListener : public ServiceWorkerVersion::Observer {
79     CachedMetadataUpdateListener() = default;
80     ~CachedMetadataUpdateListener() override = default;
OnCachedMetadataUpdatedcontent::service_worker_version_unittest::ServiceWorkerVersionTest::CachedMetadataUpdateListener81     void OnCachedMetadataUpdated(ServiceWorkerVersion* version,
82                                  size_t size) override {
83       ++updated_count;
84     }
85     int updated_count = 0;
86   };
87 
ServiceWorkerVersionTest()88   ServiceWorkerVersionTest()
89       : task_environment_(BrowserTaskEnvironment::IO_MAINLOOP,
90                           base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
91 
SetUp()92   void SetUp() override {
93     helper_ = GetHelper();
94 
95     scope_ = GURL("https://www.example.com/test/");
96     blink::mojom::ServiceWorkerRegistrationOptions options;
97     options.scope = scope_;
98     registration_ = CreateNewServiceWorkerRegistration(
99         helper_->context()->registry(), options);
100     version_ = CreateNewServiceWorkerVersion(
101         helper_->context()->registry(), registration_.get(),
102         GURL("https://www.example.com/test/service_worker.js"),
103         blink::mojom::ScriptType::kClassic);
104     EXPECT_EQ(url::Origin::Create(scope_), version_->origin());
105     std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> records;
106     records.push_back(WriteToDiskCacheWithIdSync(
107         helper_->context()->GetStorageControl(), version_->script_url(), 10,
108         {} /* headers */, "I'm a body", "I'm a meta data"));
109     version_->script_cache_map()->SetResources(records);
110     version_->SetMainScriptResponse(
111         EmbeddedWorkerTestHelper::CreateMainScriptResponse());
112     if (GetFetchHandlerExistence() !=
113         ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN) {
114       version_->set_fetch_handler_existence(GetFetchHandlerExistence());
115     }
116 
117     // Make the registration findable via storage functions.
118     base::Optional<blink::ServiceWorkerStatusCode> status;
119     base::RunLoop run_loop;
120     helper_->context()->registry()->StoreRegistration(
121         registration_.get(), version_.get(),
122         ReceiveServiceWorkerStatus(&status, run_loop.QuitClosure()));
123     run_loop.Run();
124     ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
125   }
126 
GetHelper()127   virtual std::unique_ptr<EmbeddedWorkerTestHelper> GetHelper() {
128     return std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath());
129   }
130 
TearDown()131   void TearDown() override {
132     version_ = nullptr;
133     registration_ = nullptr;
134     helper_.reset();
135   }
136 
IsPingActivated(ServiceWorkerVersion * version) const137   bool IsPingActivated(ServiceWorkerVersion* version) const {
138     return version->ping_controller_.IsActivated();
139   }
140 
NotifyScriptEvaluationStart(ServiceWorkerVersion * version)141   void NotifyScriptEvaluationStart(ServiceWorkerVersion* version) {
142     version->OnScriptEvaluationStart();
143   }
144 
SimulateDispatchEvent(ServiceWorkerMetrics::EventType event_type)145   void SimulateDispatchEvent(ServiceWorkerMetrics::EventType event_type) {
146     base::Optional<blink::ServiceWorkerStatusCode> status;
147     base::RunLoop run_loop;
148 
149     // Make sure worker is running.
150     version_->RunAfterStartWorker(
151         event_type,
152         ReceiveServiceWorkerStatus(&status, run_loop.QuitClosure()));
153     run_loop.Run();
154     EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
155     EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
156 
157     // Start request, as if an event is being dispatched.
158     int request_id = version_->StartRequest(event_type, base::DoNothing());
159     base::RunLoop().RunUntilIdle();
160 
161     // And finish request, as if a response to the event was received.
162     EXPECT_TRUE(version_->FinishRequest(request_id, /*was_handled=*/true));
163   }
164 
SetTickClockForTesting(base::SimpleTestTickClock * tick_clock)165   void SetTickClockForTesting(base::SimpleTestTickClock* tick_clock) {
166     version_->SetTickClockForTesting(tick_clock);
167   }
168 
GetFetchHandlerExistence() const169   virtual ServiceWorkerVersion::FetchHandlerExistence GetFetchHandlerExistence()
170       const {
171     return ServiceWorkerVersion::FetchHandlerExistence::EXISTS;
172   }
173 
ActivateWithControllee(int controllee_process_id=33)174   ServiceWorkerRemoteContainerEndpoint ActivateWithControllee(
175       int controllee_process_id = 33) {
176     version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
177     registration_->SetActiveVersion(version_);
178     ServiceWorkerRemoteContainerEndpoint remote_endpoint;
179     base::WeakPtr<ServiceWorkerContainerHost> container_host =
180         CreateContainerHostForWindow(
181             controllee_process_id, true /* is_parent_frame_secure */,
182             helper_->context()->AsWeakPtr(), &remote_endpoint);
183     container_host->UpdateUrls(
184         registration_->scope(),
185         net::SiteForCookies::FromUrl(registration_->scope()),
186         url::Origin::Create(registration_->scope()));
187     container_host->SetControllerRegistration(
188         registration_, false /* notify_controllerchange */);
189     EXPECT_TRUE(version_->HasControllee());
190     EXPECT_TRUE(container_host->controller());
191     return remote_endpoint;
192   }
193 
194   BrowserTaskEnvironment task_environment_;
195   std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
196   scoped_refptr<ServiceWorkerRegistration> registration_;
197   scoped_refptr<ServiceWorkerVersion> version_;
198   GURL scope_;
199 
200  private:
201   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionTest);
202 };
203 
204 // An instance client that breaks the Mojo connection upon receiving the
205 // Start() message.
206 class FailStartInstanceClient : public FakeEmbeddedWorkerInstanceClient {
207  public:
FailStartInstanceClient(EmbeddedWorkerTestHelper * helper)208   FailStartInstanceClient(EmbeddedWorkerTestHelper* helper)
209       : FakeEmbeddedWorkerInstanceClient(helper) {}
210 
StartWorker(blink::mojom::EmbeddedWorkerStartParamsPtr params)211   void StartWorker(blink::mojom::EmbeddedWorkerStartParamsPtr params) override {
212     // Don't save the Mojo ptrs. The connection breaks.
213   }
214 
215  private:
216   DISALLOW_COPY_AND_ASSIGN(FailStartInstanceClient);
217 };
218 
TEST_F(ServiceWorkerVersionTest,ConcurrentStartAndStop)219 TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) {
220   // Call StartWorker() multiple times.
221   base::Optional<blink::ServiceWorkerStatusCode> status1;
222   base::Optional<blink::ServiceWorkerStatusCode> status2;
223   base::Optional<blink::ServiceWorkerStatusCode> status3;
224   base::RunLoop run_loop_1;
225   base::RunLoop run_loop_2;
226   base::RunLoop run_loop_3;
227 
228   version_->StartWorker(
229       ServiceWorkerMetrics::EventType::UNKNOWN,
230       ReceiveServiceWorkerStatus(&status1, run_loop_1.QuitClosure()));
231   EXPECT_EQ(EmbeddedWorkerStatus::STARTING, version_->running_status());
232   version_->StartWorker(
233       ServiceWorkerMetrics::EventType::UNKNOWN,
234       ReceiveServiceWorkerStatus(&status2, run_loop_2.QuitClosure()));
235   base::RunLoop().RunUntilIdle();
236   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
237 
238   // Call StartWorker() after it's started.
239   version_->StartWorker(
240       ServiceWorkerMetrics::EventType::UNKNOWN,
241       ReceiveServiceWorkerStatus(&status3, run_loop_3.QuitClosure()));
242 
243   run_loop_1.Run();
244   run_loop_2.Run();
245   run_loop_3.Run();
246 
247   // All should just succeed.
248   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status1.value());
249   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status2.value());
250   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status3.value());
251 
252   {
253     // Call StopWorker() multiple times.
254     bool has_stopped1 = false;
255     bool has_stopped2 = false;
256     base::RunLoop run_loop_1;
257     base::RunLoop run_loop_2;
258 
259     version_->StopWorker(VerifyCalled(&has_stopped1, run_loop_1.QuitClosure()));
260     version_->StopWorker(VerifyCalled(&has_stopped2, run_loop_2.QuitClosure()));
261 
262     EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, version_->running_status());
263     run_loop_1.Run();
264     run_loop_2.Run();
265     EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
266 
267     // All StopWorker should just succeed.
268     EXPECT_TRUE(has_stopped1);
269     EXPECT_TRUE(has_stopped2);
270   }
271 
272   // Start worker again.
273   status1.reset();
274   status2.reset();
275 
276   base::RunLoop run_loop_4;
277   base::RunLoop run_loop_5;
278 
279   version_->StartWorker(
280       ServiceWorkerMetrics::EventType::UNKNOWN,
281       ReceiveServiceWorkerStatus(&status1, run_loop_4.QuitClosure()));
282 
283   EXPECT_EQ(EmbeddedWorkerStatus::STARTING, version_->running_status());
284   run_loop_4.Run();
285   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
286 
287   {
288     // Call StopWorker()
289     bool has_stopped = false;
290     version_->StopWorker(VerifyCalled(&has_stopped));
291 
292     // And try calling StartWorker while StopWorker is in queue.
293     version_->StartWorker(
294         ServiceWorkerMetrics::EventType::UNKNOWN,
295         ReceiveServiceWorkerStatus(&status2, run_loop_5.QuitClosure()));
296 
297     EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, version_->running_status());
298     run_loop_5.Run();
299     EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
300 
301     // All should just succeed.
302     EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status1.value());
303     EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status2.value());
304     EXPECT_TRUE(has_stopped);
305   }
306 }
307 
TEST_F(ServiceWorkerVersionTest,DispatchEventToStoppedWorker)308 TEST_F(ServiceWorkerVersionTest, DispatchEventToStoppedWorker) {
309   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
310 
311   // Dispatch an event without starting the worker.
312   version_->SetStatus(ServiceWorkerVersion::INSTALLING);
313   EXPECT_TRUE(version_->HasNoWork());
314   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::INSTALL);
315 
316   // The worker may still be handling events dispatched directly from
317   // controllees. We cannot say the version doesn't handle any tasks until the
318   // worker reports "No Work" (= ServiceWorkerVersion::OnRequestTermination()
319   // is called).
320   EXPECT_FALSE(version_->HasNoWork());
321 
322   // The worker should be now started.
323   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
324 
325   // Stop the worker, and then dispatch an event immediately after that.
326   bool has_stopped = false;
327   version_->StopWorker(VerifyCalled(&has_stopped));
328   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::INSTALL);
329   EXPECT_TRUE(has_stopped);
330 
331   // The worker may still be handling events dispatched directly from
332   // controllees. We cannot say the version doesn't handle any tasks until the
333   // worker reports "No Work" (= ServiceWorkerVersion::OnRequestTermination()
334   // is called).
335   EXPECT_FALSE(version_->HasNoWork());
336 
337   // The worker should be now started again.
338   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
339 }
340 
TEST_F(ServiceWorkerVersionTest,StartUnregisteredButStillLiveWorker)341 TEST_F(ServiceWorkerVersionTest, StartUnregisteredButStillLiveWorker) {
342   // Start the worker.
343   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
344             StartServiceWorker(version_.get()));
345   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
346 
347   // Delete the registration.
348   base::Optional<blink::ServiceWorkerStatusCode> status;
349   base::RunLoop run_loop;
350   helper_->context()->registry()->DeleteRegistration(
351       registration_, registration_->scope().GetOrigin(),
352       ReceiveServiceWorkerStatus(&status, run_loop.QuitClosure()));
353   run_loop.Run();
354   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
355 
356   // The live registration is marked as uninstalling, but still exists.
357   ASSERT_TRUE(registration_->is_uninstalling());
358 
359   // Stop the worker.
360   StopServiceWorker(version_.get());
361 
362   // Dispatch an event on the unregistered and stopped but still live worker.
363   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME);
364 
365   // The worker should be now started again.
366   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
367 }
368 
TEST_F(ServiceWorkerVersionTest,InstallAndWaitCompletion)369 TEST_F(ServiceWorkerVersionTest, InstallAndWaitCompletion) {
370   version_->SetStatus(ServiceWorkerVersion::INSTALLING);
371 
372   // Wait for the completion.
373   bool status_change_called = false;
374   version_->RegisterStatusChangeCallback(VerifyCalled(&status_change_called));
375 
376   // Dispatch an install event.
377   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::INSTALL);
378 
379   // Version's status must not have changed during installation.
380   EXPECT_FALSE(status_change_called);
381   EXPECT_EQ(ServiceWorkerVersion::INSTALLING, version_->status());
382 }
383 
TEST_F(ServiceWorkerVersionTest,ActivateAndWaitCompletion)384 TEST_F(ServiceWorkerVersionTest, ActivateAndWaitCompletion) {
385   // TODO(mek): This test (and the one above for the install event) made more
386   // sense back when ServiceWorkerVersion was responsible for updating the
387   // status. Now a better version of this test should probably be added to
388   // ServiceWorkerRegistrationTest instead.
389 
390   version_->SetStatus(ServiceWorkerVersion::ACTIVATING);
391 
392   // Wait for the completion.
393   bool status_change_called = false;
394   version_->RegisterStatusChangeCallback(VerifyCalled(&status_change_called));
395 
396   // Dispatch an activate event.
397   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::ACTIVATE);
398 
399   // Version's status must not have changed during activation.
400   EXPECT_FALSE(status_change_called);
401   EXPECT_EQ(ServiceWorkerVersion::ACTIVATING, version_->status());
402 }
403 
TEST_F(ServiceWorkerVersionTest,RepeatedlyObserveStatusChanges)404 TEST_F(ServiceWorkerVersionTest, RepeatedlyObserveStatusChanges) {
405   EXPECT_EQ(ServiceWorkerVersion::NEW, version_->status());
406 
407   // Repeatedly observe status changes (the callback re-registers itself).
408   std::vector<ServiceWorkerVersion::Status> statuses;
409   version_->RegisterStatusChangeCallback(base::BindOnce(
410       &ObserveStatusChanges, base::RetainedRef(version_), &statuses));
411 
412   version_->SetStatus(ServiceWorkerVersion::INSTALLING);
413   version_->SetStatus(ServiceWorkerVersion::INSTALLED);
414   version_->SetStatus(ServiceWorkerVersion::ACTIVATING);
415   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
416   version_->SetStatus(ServiceWorkerVersion::REDUNDANT);
417 
418   // Verify that we could successfully observe repeated status changes.
419   ASSERT_EQ(5U, statuses.size());
420   ASSERT_EQ(ServiceWorkerVersion::INSTALLING, statuses[0]);
421   ASSERT_EQ(ServiceWorkerVersion::INSTALLED, statuses[1]);
422   ASSERT_EQ(ServiceWorkerVersion::ACTIVATING, statuses[2]);
423   ASSERT_EQ(ServiceWorkerVersion::ACTIVATED, statuses[3]);
424   ASSERT_EQ(ServiceWorkerVersion::REDUNDANT, statuses[4]);
425 }
426 
TEST_F(ServiceWorkerVersionTest,Doom)427 TEST_F(ServiceWorkerVersionTest, Doom) {
428   // Add a controllee.
429   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
430   registration_->SetActiveVersion(version_);
431   ServiceWorkerRemoteContainerEndpoint remote_endpoint;
432   base::WeakPtr<ServiceWorkerContainerHost> container_host =
433       CreateContainerHostForWindow(
434           33 /* dummy render process id */, true /* is_parent_frame_secure */,
435           helper_->context()->AsWeakPtr(), &remote_endpoint);
436   container_host->UpdateUrls(
437       registration_->scope(),
438       net::SiteForCookies::FromUrl(registration_->scope()),
439       url::Origin::Create(registration_->scope()));
440   container_host->SetControllerRegistration(registration_, false);
441   EXPECT_TRUE(version_->HasControllee());
442   EXPECT_TRUE(container_host->controller());
443 
444   // Doom the version.
445   version_->Doom();
446 
447   // The controllee should have been removed.
448   EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, version_->status());
449   EXPECT_FALSE(version_->HasControllee());
450   EXPECT_FALSE(container_host->controller());
451 }
452 
TEST_F(ServiceWorkerVersionTest,SetDevToolsAttached)453 TEST_F(ServiceWorkerVersionTest, SetDevToolsAttached) {
454   base::Optional<blink::ServiceWorkerStatusCode> status;
455   base::RunLoop run_loop;
456   version_->StartWorker(
457       ServiceWorkerMetrics::EventType::UNKNOWN,
458       ReceiveServiceWorkerStatus(&status, run_loop.QuitClosure()));
459 
460   ASSERT_EQ(EmbeddedWorkerStatus::STARTING, version_->running_status());
461 
462   ASSERT_TRUE(version_->timeout_timer_.IsRunning());
463   ASSERT_FALSE(version_->start_time_.is_null());
464   ASSERT_FALSE(version_->skip_recording_startup_time_);
465 
466   // Simulate DevTools is attached. This should deactivate the timer for start
467   // timeout, but not stop the timer itself.
468   version_->SetDevToolsAttached(true);
469   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
470   EXPECT_TRUE(version_->start_time_.is_null());
471   EXPECT_TRUE(version_->skip_recording_startup_time_);
472 
473   // Simulate DevTools is detached. This should reactivate the timer for start
474   // timeout.
475   version_->SetDevToolsAttached(false);
476   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
477   EXPECT_FALSE(version_->start_time_.is_null());
478   EXPECT_TRUE(version_->skip_recording_startup_time_);
479 
480   run_loop.Run();
481   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
482   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
483 }
484 
TEST_F(ServiceWorkerVersionTest,RequestTerminationWithDevToolsAttached)485 TEST_F(ServiceWorkerVersionTest, RequestTerminationWithDevToolsAttached) {
486   auto* service_worker =
487       helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get());
488 
489   version_->SetDevToolsAttached(true);
490 
491   base::Optional<blink::ServiceWorkerStatusCode> status;
492   base::RunLoop run_loop;
493   version_->StartWorker(
494       ServiceWorkerMetrics::EventType::UNKNOWN,
495       ReceiveServiceWorkerStatus(&status, run_loop.QuitClosure()));
496   run_loop.Run();
497   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
498   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
499 
500   // Idle delay is not set at this point. The renderer process uses the default
501   // value.
502   EXPECT_FALSE(service_worker->idle_delay().has_value());
503 
504   // If OnRequestTermination() is called when DevTools is attached, then the
505   // worker's idle timeout is set to the default value forcefully because the
506   // worker needs to be running until DevTools is detached even if there's no
507   // inflight event.
508   version_->OnRequestTermination();
509   service_worker->FlushForTesting();
510   EXPECT_EQ(blink::mojom::kServiceWorkerDefaultIdleDelayInSeconds,
511             service_worker->idle_delay()->InSeconds());
512 }
513 
514 // Test that update isn't triggered for a non-stale worker.
TEST_F(ServiceWorkerVersionTest,StaleUpdate_FreshWorker)515 TEST_F(ServiceWorkerVersionTest, StaleUpdate_FreshWorker) {
516   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
517   registration_->SetActiveVersion(version_);
518   registration_->set_last_update_check(base::Time::Now());
519   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::PUSH);
520 
521   EXPECT_TRUE(version_->stale_time_.is_null());
522   EXPECT_FALSE(version_->update_timer_.IsRunning());
523 }
524 
525 // Test that update isn't triggered for a non-active worker.
TEST_F(ServiceWorkerVersionTest,StaleUpdate_NonActiveWorker)526 TEST_F(ServiceWorkerVersionTest, StaleUpdate_NonActiveWorker) {
527   version_->SetStatus(ServiceWorkerVersion::INSTALLING);
528   registration_->SetInstallingVersion(version_);
529   registration_->set_last_update_check(GetYesterday());
530   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::INSTALL);
531 
532   EXPECT_TRUE(version_->stale_time_.is_null());
533   EXPECT_FALSE(version_->update_timer_.IsRunning());
534 }
535 
536 // Test that staleness is detected when starting a worker.
TEST_F(ServiceWorkerVersionTest,StaleUpdate_StartWorker)537 TEST_F(ServiceWorkerVersionTest, StaleUpdate_StartWorker) {
538   // Starting the worker marks it as stale.
539   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
540   registration_->SetActiveVersion(version_);
541   registration_->set_last_update_check(GetYesterday());
542   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::PUSH);
543   EXPECT_FALSE(version_->stale_time_.is_null());
544   EXPECT_FALSE(version_->update_timer_.IsRunning());
545 
546   // Update is actually scheduled after the worker stops.
547   StopServiceWorker(version_.get());
548   EXPECT_TRUE(version_->stale_time_.is_null());
549   EXPECT_TRUE(version_->update_timer_.IsRunning());
550 }
551 
552 // Test that staleness is detected on a running worker.
TEST_F(ServiceWorkerVersionTest,StaleUpdate_RunningWorker)553 TEST_F(ServiceWorkerVersionTest, StaleUpdate_RunningWorker) {
554   // Start a fresh worker.
555   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
556   registration_->SetActiveVersion(version_);
557   registration_->set_last_update_check(base::Time::Now());
558   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::PUSH);
559   EXPECT_TRUE(version_->stale_time_.is_null());
560 
561   // Simulate it running for a day. It will be marked stale.
562   registration_->set_last_update_check(GetYesterday());
563   version_->OnTimeoutTimer();
564   EXPECT_FALSE(version_->stale_time_.is_null());
565   EXPECT_FALSE(version_->update_timer_.IsRunning());
566 
567   // Simulate it running for past the wait threshold. The update will be
568   // scheduled.
569   version_->stale_time_ = base::TimeTicks::Now() -
570                           ServiceWorkerVersion::kStartNewWorkerTimeout -
571                           base::TimeDelta::FromMinutes(1);
572   version_->OnTimeoutTimer();
573   EXPECT_TRUE(version_->stale_time_.is_null());
574   EXPECT_TRUE(version_->update_timer_.IsRunning());
575 }
576 
577 // Test that a stream of events doesn't restart the timer.
TEST_F(ServiceWorkerVersionTest,StaleUpdate_DoNotDeferTimer)578 TEST_F(ServiceWorkerVersionTest, StaleUpdate_DoNotDeferTimer) {
579   // Make a stale worker.
580   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
581   registration_->SetActiveVersion(version_);
582   registration_->set_last_update_check(GetYesterday());
583   base::TimeTicks stale_time = base::TimeTicks::Now() -
584                                ServiceWorkerVersion::kStartNewWorkerTimeout -
585                                base::TimeDelta::FromMinutes(1);
586   version_->stale_time_ = stale_time;
587 
588   // Stale time is not deferred.
589   version_->RunAfterStartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
590                                 base::DoNothing());
591   version_->RunAfterStartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
592                                 base::DoNothing());
593   base::RunLoop().RunUntilIdle();
594   EXPECT_EQ(stale_time, version_->stale_time_);
595 
596   // Timeout triggers the update.
597   version_->OnTimeoutTimer();
598   EXPECT_TRUE(version_->stale_time_.is_null());
599   EXPECT_TRUE(version_->update_timer_.IsRunning());
600 
601   // Update timer is not deferred.
602   base::TimeTicks run_time = version_->update_timer_.desired_run_time();
603   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::PUSH);
604   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::PUSH);
605   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::PUSH);
606   base::RunLoop().RunUntilIdle();
607   EXPECT_TRUE(version_->stale_time_.is_null());
608   EXPECT_EQ(run_time, version_->update_timer_.desired_run_time());
609 }
610 
TEST_F(ServiceWorkerVersionTest,StartRequestWithNullContext)611 TEST_F(ServiceWorkerVersionTest, StartRequestWithNullContext) {
612   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
613             StartServiceWorker(version_.get()));
614   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
615   version_->context_ = nullptr;
616   version_->StartRequest(ServiceWorkerMetrics::EventType::PUSH,
617                          base::DoNothing());
618   // Test passes if it doesn't crash.
619 }
620 
621 // Tests the delay mechanism for self-updating service workers, to prevent
622 // them from running forever (see https://crbug.com/805496).
TEST_F(ServiceWorkerVersionTest,ResetUpdateDelay)623 TEST_F(ServiceWorkerVersionTest, ResetUpdateDelay) {
624   const base::TimeDelta kMinute = base::TimeDelta::FromMinutes(1);
625   const base::TimeDelta kNoDelay = base::TimeDelta();
626 
627   // Initialize the delay.
628   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
629   registration_->SetActiveVersion(version_);
630   registration_->set_self_update_delay(kMinute);
631 
632   // Events that can be triggered by a worker should not reset the delay.
633   // See the comment in ServiceWorkerVersion::StartRequestWithCustomTimeout.
634   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::INSTALL);
635   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::ACTIVATE);
636   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::MESSAGE);
637   base::RunLoop().RunUntilIdle();
638   EXPECT_EQ(kMinute, registration_->self_update_delay());
639 
640   // Events that can only be triggered externally reset the delay.
641   // Repeat the test for several such events.
642   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::SYNC);
643   base::RunLoop().RunUntilIdle();
644   EXPECT_EQ(kNoDelay, registration_->self_update_delay());
645 
646   registration_->set_self_update_delay(kMinute);
647   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::NOTIFICATION_CLICK);
648   base::RunLoop().RunUntilIdle();
649   EXPECT_EQ(kNoDelay, registration_->self_update_delay());
650 
651   registration_->set_self_update_delay(kMinute);
652   SimulateDispatchEvent(ServiceWorkerMetrics::EventType::PUSH);
653   base::RunLoop().RunUntilIdle();
654   EXPECT_EQ(kNoDelay, registration_->self_update_delay());
655 }
656 
TEST_F(ServiceWorkerVersionTest,UpdateCachedMetadata)657 TEST_F(ServiceWorkerVersionTest, UpdateCachedMetadata) {
658   CachedMetadataUpdateListener listener;
659   version_->AddObserver(&listener);
660   ASSERT_EQ(0, listener.updated_count);
661   auto* service_worker =
662       helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get());
663   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
664             StartServiceWorker(version_.get()));
665   service_worker->RunUntilInitializeGlobalScope();
666 
667   // Simulate requesting SetCachedMetadata from the service worker global scope.
668   std::vector<uint8_t> data{1, 2, 3};
669   service_worker->host()->SetCachedMetadata(version_->script_url(), data);
670   base::RunLoop().RunUntilIdle();
671   EXPECT_EQ(1, listener.updated_count);
672 
673   // Simulate requesting ClearCachedMetadata from the service worker global
674   // scope.
675   service_worker->host()->ClearCachedMetadata(version_->script_url());
676   base::RunLoop().RunUntilIdle();
677   EXPECT_EQ(2, listener.updated_count);
678   version_->RemoveObserver(&listener);
679 }
680 
TEST_F(ServiceWorkerVersionTest,RestartWorker)681 TEST_F(ServiceWorkerVersionTest, RestartWorker) {
682   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
683             StartServiceWorker(version_.get()));
684   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
685   bool has_stopped = false;
686 
687   base::Optional<blink::ServiceWorkerStatusCode> status;
688   base::RunLoop run_loop;
689   version_->StartRequest(
690       ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
691       ReceiveServiceWorkerStatus(&status, run_loop.QuitClosure()));
692 
693   // Restart the worker. The inflight event should have been failed.
694   version_->StopWorker(VerifyCalled(&has_stopped));
695   EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, version_->running_status());
696   run_loop.Run();
697 
698   // Restart the worker.
699   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
700             StartServiceWorker(version_.get()));
701 
702   // The worker should have been stopped.
703   EXPECT_TRUE(has_stopped);
704   // All inflight events should have been aborted.
705   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed, status.value());
706   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
707 
708   // SetAllRequestExpirations() after restarting should not crash since all
709   // events should have been removed at this point: crbug.com/791451.
710   version_->SetAllRequestExpirations(base::TimeTicks());
711 }
712 
713 class DelayMessageWorker : public FakeServiceWorker {
714  public:
DelayMessageWorker(EmbeddedWorkerTestHelper * helper)715   explicit DelayMessageWorker(EmbeddedWorkerTestHelper* helper)
716       : FakeServiceWorker(helper) {}
717   ~DelayMessageWorker() override = default;
718 
DispatchExtendableMessageEvent(blink::mojom::ExtendableMessageEventPtr event,DispatchExtendableMessageEventCallback callback)719   void DispatchExtendableMessageEvent(
720       blink::mojom::ExtendableMessageEventPtr event,
721       DispatchExtendableMessageEventCallback callback) override {
722     event_ = std::move(event);
723     callback_ = std::move(callback);
724     if (quit_closure_)
725       std::move(quit_closure_).Run();
726   }
727 
AbortMessageEvent()728   void AbortMessageEvent() {
729     std::move(callback_).Run(blink::mojom::ServiceWorkerEventStatus::ABORTED);
730   }
731 
RunUntilDispatchMessageEvent()732   void RunUntilDispatchMessageEvent() {
733     if (event_)
734       return;
735     base::RunLoop loop;
736     quit_closure_ = loop.QuitClosure();
737     loop.Run();
738   }
739 
740  private:
741   blink::mojom::ExtendableMessageEventPtr event_;
742   DispatchExtendableMessageEventCallback callback_;
743   base::OnceClosure quit_closure_;
744 
745   DISALLOW_COPY_AND_ASSIGN(DelayMessageWorker);
746 };
747 
TEST_F(ServiceWorkerVersionTest,RequestTimeout)748 TEST_F(ServiceWorkerVersionTest, RequestTimeout) {
749   auto* client = helper_->AddNewPendingInstanceClient<
750       DelayedFakeEmbeddedWorkerInstanceClient>(helper_.get());
751   auto* worker =
752       helper_->AddNewPendingServiceWorker<DelayMessageWorker>(helper_.get());
753 
754   base::Optional<blink::ServiceWorkerStatusCode> error_status;
755   base::RunLoop run_loop;
756   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
757   client->UnblockStartWorker();
758   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
759             StartServiceWorker(version_.get()));
760 
761   // Create a request.
762   int request_id = version_->StartRequest(
763       ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
764       ReceiveServiceWorkerStatus(&error_status, run_loop.QuitClosure()));
765 
766   // Dispatch a dummy event.
767   version_->endpoint()->DispatchExtendableMessageEvent(
768       blink::mojom::ExtendableMessageEvent::New(),
769       version_->CreateSimpleEventCallback(request_id));
770   worker->RunUntilDispatchMessageEvent();
771 
772   // Request callback has not completed yet.
773   EXPECT_FALSE(error_status);
774 
775   // Simulate timeout.
776   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
777   version_->SetAllRequestExpirations(base::TimeTicks::Now());
778   version_->timeout_timer_.user_task().Run();
779 
780   // The renderer should have received a StopWorker request.
781   client->RunUntilStopWorker();
782 
783   // The request should have timed out.
784   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout,
785             error_status.value());
786   // Calling FinishRequest should be no-op, since the request timed out.
787   EXPECT_FALSE(version_->FinishRequest(request_id, /*was_handled=*/true));
788 
789   // Simulate the renderer aborting the inflight event.
790   // This should not crash: https://crbug.com/676984.
791   worker->AbortMessageEvent();
792   base::RunLoop().RunUntilIdle();
793 
794   // Simulate the renderer stopping the worker.
795   client->UnblockStopWorker();
796   base::RunLoop().RunUntilIdle();
797   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
798 }
799 
TEST_F(ServiceWorkerVersionTest,RequestNowTimeout)800 TEST_F(ServiceWorkerVersionTest, RequestNowTimeout) {
801   base::Optional<blink::ServiceWorkerStatusCode> status;
802   base::RunLoop run_loop;
803   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
804   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
805             StartServiceWorker(version_.get()));
806 
807   // Create a request that should expire Now().
808   int request_id = version_->StartRequestWithCustomTimeout(
809       ServiceWorkerMetrics::EventType::SYNC,
810       ReceiveServiceWorkerStatus(&status, run_loop.QuitClosure()),
811       base::TimeDelta(), ServiceWorkerVersion::CONTINUE_ON_TIMEOUT);
812 
813   base::RunLoop().RunUntilIdle();
814   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
815   version_->timeout_timer_.user_task().Run();
816   run_loop.Run();
817   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout, status.value());
818 
819   EXPECT_FALSE(version_->FinishRequest(request_id, /*was_handled=*/true));
820 
821   // CONTINUE_ON_TIMEOUT timeouts don't stop the service worker.
822   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
823 }
824 
TEST_F(ServiceWorkerVersionTest,RequestNowTimeoutKill)825 TEST_F(ServiceWorkerVersionTest, RequestNowTimeoutKill) {
826   base::Optional<blink::ServiceWorkerStatusCode> status;
827   base::RunLoop run_loop;
828   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
829   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
830             StartServiceWorker(version_.get()));
831 
832   // Create a request that should expire Now().
833   int request_id = version_->StartRequestWithCustomTimeout(
834       ServiceWorkerMetrics::EventType::SYNC,
835       ReceiveServiceWorkerStatus(&status, run_loop.QuitClosure()),
836       base::TimeDelta(), ServiceWorkerVersion::KILL_ON_TIMEOUT);
837 
838   base::RunLoop().RunUntilIdle();
839   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
840   version_->timeout_timer_.user_task().Run();
841   run_loop.Run();
842   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout, status.value());
843 
844   EXPECT_FALSE(version_->FinishRequest(request_id, /*was_handled=*/true));
845 
846   // KILL_ON_TIMEOUT timeouts should stop the service worker.
847   base::RunLoop().RunUntilIdle();
848   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
849 }
850 
TEST_F(ServiceWorkerVersionTest,RequestCustomizedTimeout)851 TEST_F(ServiceWorkerVersionTest, RequestCustomizedTimeout) {
852   base::Optional<blink::ServiceWorkerStatusCode> first_status;
853   base::Optional<blink::ServiceWorkerStatusCode> second_status;
854   base::RunLoop first_run_loop;
855   base::RunLoop second_run_loop;
856 
857   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
858   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
859             StartServiceWorker(version_.get()));
860 
861   base::SimpleTestTickClock tick_clock;
862   SetTickClockForTesting(&tick_clock);
863 
864   // Create two requests. One which times out in 10 seconds, one in 20 seconds.
865   int timeout_seconds = 10;
866   int first_request_id = version_->StartRequestWithCustomTimeout(
867       ServiceWorkerMetrics::EventType::SYNC,
868       ReceiveServiceWorkerStatus(&first_status, first_run_loop.QuitClosure()),
869       base::TimeDelta::FromSeconds(2 * timeout_seconds),
870       ServiceWorkerVersion::KILL_ON_TIMEOUT);
871 
872   int second_request_id = version_->StartRequestWithCustomTimeout(
873       ServiceWorkerMetrics::EventType::SYNC,
874       ReceiveServiceWorkerStatus(&second_status, second_run_loop.QuitClosure()),
875       base::TimeDelta::FromSeconds(timeout_seconds),
876       ServiceWorkerVersion::CONTINUE_ON_TIMEOUT);
877 
878   // The status should not have changed since neither task has timed out yet.
879   base::RunLoop().RunUntilIdle();
880   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
881   version_->timeout_timer_.user_task().Run();
882   base::RunLoop().RunUntilIdle();
883   EXPECT_FALSE(first_status);
884   EXPECT_FALSE(second_status);
885 
886   // Now advance time until the second task timeout should expire.
887   tick_clock.Advance(base::TimeDelta::FromSeconds(timeout_seconds + 1));
888   version_->timeout_timer_.user_task().Run();
889   second_run_loop.Run();
890   EXPECT_FALSE(first_status);
891   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout,
892             second_status.value());
893 
894   // CONTINUE_ON_TIMEOUT timeouts don't stop the service worker.
895   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
896 
897   // Now advance time until both tasks should be expired.
898   tick_clock.Advance(base::TimeDelta::FromSeconds(timeout_seconds + 1));
899   version_->timeout_timer_.user_task().Run();
900   first_run_loop.Run();
901   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout,
902             first_status.value());
903   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout,
904             second_status.value());
905 
906   EXPECT_FALSE(version_->FinishRequest(first_request_id, /*was_handled=*/true));
907 
908   EXPECT_FALSE(
909       version_->FinishRequest(second_request_id, /*was_handled=*/true));
910   base::RunLoop().RunUntilIdle();
911 
912   // KILL_ON_TIMEOUT timeouts should stop the service worker.
913   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
914 }
915 
TEST_F(ServiceWorkerVersionTest,MixedRequestTimeouts)916 TEST_F(ServiceWorkerVersionTest, MixedRequestTimeouts) {
917   base::Optional<blink::ServiceWorkerStatusCode> sync_status;
918   base::Optional<blink::ServiceWorkerStatusCode> fetch_status;
919   base::RunLoop sync_run_loop;
920   base::RunLoop fetch_run_loop;
921 
922   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
923   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
924             StartServiceWorker(version_.get()));
925 
926   // Create a fetch request that should expire sometime later.
927   int fetch_request_id = version_->StartRequest(
928       ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
929       ReceiveServiceWorkerStatus(&fetch_status, fetch_run_loop.QuitClosure()));
930   // Create a request that should expire Now().
931   int sync_request_id = version_->StartRequestWithCustomTimeout(
932       ServiceWorkerMetrics::EventType::SYNC,
933       ReceiveServiceWorkerStatus(&sync_status, sync_run_loop.QuitClosure()),
934       base::TimeDelta(), ServiceWorkerVersion::CONTINUE_ON_TIMEOUT);
935   base::RunLoop().RunUntilIdle();
936   EXPECT_FALSE(sync_status);
937 
938   // Verify the sync has timed out but not the fetch.
939   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
940   version_->timeout_timer_.user_task().Run();
941   sync_run_loop.Run();
942   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout, sync_status.value());
943   EXPECT_FALSE(fetch_status);
944 
945   // Background sync timeouts don't stop the service worker.
946   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
947 
948   // Gracefully handle the sync event finishing after the timeout.
949   EXPECT_FALSE(version_->FinishRequest(sync_request_id, /*was_handled=*/true));
950 
951   // Verify that the fetch times out later.
952   version_->SetAllRequestExpirations(base::TimeTicks::Now());
953   version_->timeout_timer_.user_task().Run();
954   fetch_run_loop.Run();
955   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout,
956             fetch_status.value());
957 
958   // Fetch request should no longer exist.
959   EXPECT_FALSE(version_->FinishRequest(fetch_request_id, /*was_handled=*/true));
960   base::RunLoop().RunUntilIdle();
961 
962   // Other timeouts do stop the service worker.
963   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
964 }
965 
TEST_F(ServiceWorkerVersionTest,FailToStart_RendererCrash)966 TEST_F(ServiceWorkerVersionTest, FailToStart_RendererCrash) {
967   base::Optional<blink::ServiceWorkerStatusCode> status;
968   base::RunLoop run_loop;
969   auto* client = helper_->AddNewPendingInstanceClient<
970       DelayedFakeEmbeddedWorkerInstanceClient>(helper_.get());
971   version_->StartWorker(
972       ServiceWorkerMetrics::EventType::UNKNOWN,
973       ReceiveServiceWorkerStatus(&status, run_loop.QuitClosure()));
974   base::RunLoop().RunUntilIdle();
975 
976   // Callback has not completed yet.
977   EXPECT_FALSE(status);
978   EXPECT_EQ(EmbeddedWorkerStatus::STARTING, version_->running_status());
979 
980   // Simulate renderer crash: break EmbeddedWorkerInstance's Mojo connection to
981   // the renderer-side client.
982   client->Disconnect();
983   run_loop.Run();
984   // Callback completed.
985   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed,
986             status.value());
987   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
988 }
989 
TEST_F(ServiceWorkerVersionTest,FailToStart_Timeout)990 TEST_F(ServiceWorkerVersionTest, FailToStart_Timeout) {
991   base::Optional<blink::ServiceWorkerStatusCode> status;
992   base::RunLoop run_loop;
993 
994   // Start starting the worker.
995   auto* client = helper_->AddNewPendingInstanceClient<
996       DelayedFakeEmbeddedWorkerInstanceClient>(helper_.get());
997   client->UnblockStopWorker();
998   version_->StartWorker(
999       ServiceWorkerMetrics::EventType::UNKNOWN,
1000       ReceiveServiceWorkerStatus(&status, run_loop.QuitClosure()));
1001   base::RunLoop().RunUntilIdle();
1002 
1003   // Callback has not completed yet.
1004   EXPECT_FALSE(status);
1005   EXPECT_EQ(EmbeddedWorkerStatus::STARTING, version_->running_status());
1006 
1007   // Simulate timeout.
1008   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
1009   version_->start_time_ = base::TimeTicks::Now() -
1010                           ServiceWorkerVersion::kStartNewWorkerTimeout -
1011                           base::TimeDelta::FromMinutes(1);
1012   version_->timeout_timer_.user_task().Run();
1013   run_loop.Run();
1014   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout, status.value());
1015   base::RunLoop().RunUntilIdle();
1016   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
1017 }
1018 
1019 // Test that a service worker stalled in stopping will timeout and not get in a
1020 // sticky error state.
TEST_F(ServiceWorkerVersionTest,StallInStopping_DetachThenStart)1021 TEST_F(ServiceWorkerVersionTest, StallInStopping_DetachThenStart) {
1022   // Start a worker.
1023   auto* client = helper_->AddNewPendingInstanceClient<
1024       DelayedFakeEmbeddedWorkerInstanceClient>(helper_.get());
1025   client->UnblockStartWorker();
1026   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1027             StartServiceWorker(version_.get()));
1028 
1029   // Try to stop the worker.
1030   bool has_stopped = false;
1031   base::RunLoop run_loop;
1032   version_->StopWorker(VerifyCalled(&has_stopped, run_loop.QuitClosure()));
1033   EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, version_->running_status());
1034   base::RunLoop().RunUntilIdle();
1035 
1036   // Worker is now stalled in stopping. Verify a fast timeout is in place.
1037   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
1038   EXPECT_EQ(ServiceWorkerVersion::kStopWorkerTimeout,
1039             version_->timeout_timer_.GetCurrentDelay());
1040 
1041   // Simulate timeout.
1042   version_->stop_time_ = base::TimeTicks::Now() -
1043                          ServiceWorkerVersion::kStopWorkerTimeout -
1044                          base::TimeDelta::FromSeconds(1);
1045   version_->timeout_timer_.user_task().Run();
1046   run_loop.Run();
1047   EXPECT_TRUE(has_stopped);
1048   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
1049 
1050   // Try to start the worker again. It should work.
1051   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1052             StartServiceWorker(version_.get()));
1053 
1054   // The timeout interval should be reset to normal.
1055   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
1056   EXPECT_EQ(ServiceWorkerVersion::kTimeoutTimerDelay,
1057             version_->timeout_timer_.GetCurrentDelay());
1058 }
1059 
1060 // Test that a service worker stalled in stopping with a start worker
1061 // request queued up will timeout and restart.
TEST_F(ServiceWorkerVersionTest,StallInStopping_DetachThenRestart)1062 TEST_F(ServiceWorkerVersionTest, StallInStopping_DetachThenRestart) {
1063   // Start a worker.
1064   auto* client = helper_->AddNewPendingInstanceClient<
1065       DelayedFakeEmbeddedWorkerInstanceClient>(helper_.get());
1066   client->UnblockStartWorker();
1067   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1068             StartServiceWorker(version_.get()));
1069 
1070   // Try to stop the worker.
1071   bool has_stopped = false;
1072   version_->StopWorker(VerifyCalled(&has_stopped));
1073   EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, version_->running_status());
1074 
1075   // Worker is now stalled in stopping. Add a start worker request.
1076   base::Optional<blink::ServiceWorkerStatusCode> start_status;
1077   base::RunLoop run_loop;
1078   version_->StartWorker(
1079       ServiceWorkerMetrics::EventType::UNKNOWN,
1080       ReceiveServiceWorkerStatus(&start_status, run_loop.QuitClosure()));
1081 
1082   // Simulate timeout. The worker should stop and get restarted.
1083   EXPECT_TRUE(version_->timeout_timer_.IsRunning());
1084   version_->stop_time_ = base::TimeTicks::Now() -
1085                          ServiceWorkerVersion::kStopWorkerTimeout -
1086                          base::TimeDelta::FromSeconds(1);
1087   version_->timeout_timer_.user_task().Run();
1088   run_loop.Run();
1089   EXPECT_TRUE(has_stopped);
1090   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, start_status.value());
1091 }
1092 
TEST_F(ServiceWorkerVersionTest,RendererCrashDuringEvent)1093 TEST_F(ServiceWorkerVersionTest, RendererCrashDuringEvent) {
1094   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
1095 
1096   auto* client =
1097       helper_->AddNewPendingInstanceClient<FakeEmbeddedWorkerInstanceClient>(
1098           helper_.get());
1099   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1100             StartServiceWorker(version_.get()));
1101 
1102   base::RunLoop loop;
1103   blink::ServiceWorkerStatusCode status = blink::ServiceWorkerStatusCode::kOk;
1104   int request_id = version_->StartRequest(
1105       ServiceWorkerMetrics::EventType::SYNC,
1106       base::BindOnce(
1107           [](base::OnceClosure done, blink::ServiceWorkerStatusCode* out_status,
1108              blink::ServiceWorkerStatusCode result_status) {
1109             *out_status = result_status;
1110             std::move(done).Run();
1111           },
1112           loop.QuitClosure(), &status));
1113 
1114   // Simulate renderer crash: break EmbeddedWorkerInstance's Mojo connection to
1115   // the renderer-side client. The request callback should be called.
1116   client->Disconnect();
1117   loop.Run();
1118   EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed, status);
1119   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
1120 
1121   // Request already failed, calling finish should return false.
1122   EXPECT_FALSE(version_->FinishRequest(request_id, /*was_handled=*/true));
1123 }
1124 
TEST_F(ServiceWorkerVersionTest,PingController)1125 TEST_F(ServiceWorkerVersionTest, PingController) {
1126   // Start starting an worker. Ping should not be active.
1127   version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
1128                         base::DoNothing());
1129   EXPECT_FALSE(IsPingActivated(version_.get()));
1130 
1131   // Start script evaluation. Ping should be active.
1132   NotifyScriptEvaluationStart(version_.get());
1133   EXPECT_TRUE(IsPingActivated(version_.get()));
1134 
1135   // Finish starting the worker. Ping should still be active.
1136   base::RunLoop().RunUntilIdle();
1137   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
1138   EXPECT_TRUE(IsPingActivated(version_.get()));
1139 }
1140 
1141 // Test starting a service worker from a disallowed origin.
TEST_F(ServiceWorkerVersionTest,BadOrigin)1142 TEST_F(ServiceWorkerVersionTest, BadOrigin) {
1143   const GURL scope("bad-origin://www.example.com/test/");
1144   blink::mojom::ServiceWorkerRegistrationOptions options;
1145   options.scope = scope;
1146   auto registration = CreateNewServiceWorkerRegistration(
1147       helper_->context()->registry(), options);
1148   auto version = CreateNewServiceWorkerVersion(
1149       helper_->context()->registry(), registration_.get(),
1150       GURL("bad-origin://www.example.com/test/service_worker.js"),
1151       blink::mojom::ScriptType::kClassic);
1152   ASSERT_EQ(blink::ServiceWorkerStatusCode::kErrorDisallowed,
1153             StartServiceWorker(version.get()));
1154 }
1155 
TEST_F(ServiceWorkerVersionTest,ForegroundServiceWorkerCountUpdatedByControllee)1156 TEST_F(ServiceWorkerVersionTest,
1157        ForegroundServiceWorkerCountUpdatedByControllee) {
1158   // Start the worker before we have a controllee.
1159   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1160             StartServiceWorker(version_.get()));
1161   EXPECT_EQ(
1162       0,
1163       helper_->mock_render_process_host()->foreground_service_worker_count());
1164 
1165   // Add a controllee in a different process from the service worker.
1166   auto remote_endpoint = ActivateWithControllee();
1167 
1168   // RenderProcessHost should be notified of foreground worker.
1169   base::RunLoop().RunUntilIdle();
1170   EXPECT_EQ(
1171       1,
1172       helper_->mock_render_process_host()->foreground_service_worker_count());
1173 
1174   // Remove the controllee.
1175   remote_endpoint.host_remote()->reset();
1176   base::RunLoop().RunUntilIdle();
1177   EXPECT_FALSE(version_->HasControllee());
1178 
1179   // RenderProcessHost should be notified that there are no foreground workers.
1180   base::RunLoop().RunUntilIdle();
1181   EXPECT_EQ(
1182       0,
1183       helper_->mock_render_process_host()->foreground_service_worker_count());
1184 }
1185 
TEST_F(ServiceWorkerVersionTest,ForegroundServiceWorkerCountNotUpdatedBySameProcessControllee)1186 TEST_F(ServiceWorkerVersionTest,
1187        ForegroundServiceWorkerCountNotUpdatedBySameProcessControllee) {
1188   // Start the worker before we have a controllee.
1189   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1190             StartServiceWorker(version_.get()));
1191   EXPECT_EQ(
1192       0,
1193       helper_->mock_render_process_host()->foreground_service_worker_count());
1194 
1195   // Add a controllee in the same process as the service worker.
1196   auto remote_endpoint =
1197       ActivateWithControllee(version_->embedded_worker()->process_id());
1198 
1199   // RenderProcessHost should be notified of foreground worker.
1200   base::RunLoop().RunUntilIdle();
1201   EXPECT_EQ(
1202       0,
1203       helper_->mock_render_process_host()->foreground_service_worker_count());
1204 }
1205 
TEST_F(ServiceWorkerVersionTest,ForegroundServiceWorkerCountUpdatedByControlleeProcessIdChange)1206 TEST_F(ServiceWorkerVersionTest,
1207        ForegroundServiceWorkerCountUpdatedByControlleeProcessIdChange) {
1208   // Start the worker before we have a controllee.
1209   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1210             StartServiceWorker(version_.get()));
1211   EXPECT_EQ(
1212       0,
1213       helper_->mock_render_process_host()->foreground_service_worker_count());
1214 
1215   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
1216   registration_->SetActiveVersion(version_);
1217 
1218   // Add a controllee, but don't begin the navigation commit yet.  This will
1219   // cause the client to have an invalid process id like we see in real
1220   // navigations.
1221   ServiceWorkerRemoteContainerEndpoint remote_endpoint;
1222   std::unique_ptr<ServiceWorkerContainerHostAndInfo> host_and_info =
1223       CreateContainerHostAndInfoForWindow(helper_->context()->AsWeakPtr(),
1224                                           /*are_ancestors_secure=*/true);
1225   base::WeakPtr<ServiceWorkerContainerHost> container_host =
1226       std::move(host_and_info->host);
1227   remote_endpoint.BindForWindow(std::move(host_and_info->info));
1228   container_host->UpdateUrls(
1229       registration_->scope(),
1230       net::SiteForCookies::FromUrl(registration_->scope()),
1231       url::Origin::Create(registration_->scope()));
1232   container_host->SetControllerRegistration(
1233       registration_, false /* notify_controllerchange */);
1234   EXPECT_TRUE(version_->HasControllee());
1235   EXPECT_TRUE(container_host->controller());
1236 
1237   // RenderProcessHost should be notified of foreground worker.
1238   base::RunLoop().RunUntilIdle();
1239   EXPECT_EQ(
1240       1,
1241       helper_->mock_render_process_host()->foreground_service_worker_count());
1242 
1243   // This is necessary to make OnBeginNavigationCommit() work.
1244   auto remote_controller = container_host->GetRemoteControllerServiceWorker();
1245 
1246   // Establish a dummy connection to allow sending messages without errors.
1247   mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
1248       reporter;
1249   auto dummy = reporter.InitWithNewPipeAndPassReceiver();
1250 
1251   // Now begin the navigation commit with the same process id used by the
1252   // worker. This should cause the worker to stop being considered foreground
1253   // priority.
1254   container_host->OnBeginNavigationCommit(
1255       version_->embedded_worker()->process_id(),
1256       /* render_frame_id = */ 1, network::CrossOriginEmbedderPolicy(),
1257       std::move(reporter), ukm::UkmRecorder::GetNewSourceID());
1258 
1259   // RenderProcessHost should be notified of foreground worker.
1260   base::RunLoop().RunUntilIdle();
1261   EXPECT_EQ(
1262       0,
1263       helper_->mock_render_process_host()->foreground_service_worker_count());
1264 }
1265 
TEST_F(ServiceWorkerVersionTest,ForegroundServiceWorkerCountUpdatedByWorkerStatus)1266 TEST_F(ServiceWorkerVersionTest,
1267        ForegroundServiceWorkerCountUpdatedByWorkerStatus) {
1268   // Add a controllee in a different process from the service worker.
1269   auto remote_endpoint = ActivateWithControllee();
1270 
1271   // RenderProcessHost should not be notified of foreground worker yet since
1272   // there is no worker running.
1273   base::RunLoop().RunUntilIdle();
1274   EXPECT_EQ(
1275       0,
1276       helper_->mock_render_process_host()->foreground_service_worker_count());
1277 
1278   // Starting the worker should notify the RenderProcessHost of the foreground
1279   // worker.
1280   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1281             StartServiceWorker(version_.get()));
1282   EXPECT_EQ(
1283       1,
1284       helper_->mock_render_process_host()->foreground_service_worker_count());
1285 
1286   // Stopping the worker should notify the RenderProcessHost that the foreground
1287   // worker has been removed.
1288   version_->StopWorker(base::DoNothing());
1289   base::RunLoop().RunUntilIdle();
1290   EXPECT_EQ(
1291       0,
1292       helper_->mock_render_process_host()->foreground_service_worker_count());
1293 }
1294 
1295 class ServiceWorkerVersionNoFetchHandlerTest : public ServiceWorkerVersionTest {
1296  protected:
GetFetchHandlerExistence() const1297   ServiceWorkerVersion::FetchHandlerExistence GetFetchHandlerExistence()
1298       const override {
1299     return ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST;
1300   }
1301 };
1302 
TEST_F(ServiceWorkerVersionNoFetchHandlerTest,ForegroundServiceWorkerCountNotUpdated)1303 TEST_F(ServiceWorkerVersionNoFetchHandlerTest,
1304        ForegroundServiceWorkerCountNotUpdated) {
1305   // Start the worker before we have a controllee.
1306   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1307             StartServiceWorker(version_.get()));
1308   EXPECT_EQ(
1309       0,
1310       helper_->mock_render_process_host()->foreground_service_worker_count());
1311 
1312   // Add a controllee in a different process from the service worker.
1313   auto remote_endpoint = ActivateWithControllee();
1314 
1315   // RenderProcessHost should not be notified if the service worker does not
1316   // have a FetchEvent handler.
1317   base::RunLoop().RunUntilIdle();
1318   EXPECT_EQ(
1319       0,
1320       helper_->mock_render_process_host()->foreground_service_worker_count());
1321 }
1322 
TEST_F(ServiceWorkerVersionTest,FailToStart_UseNewRendererProcess)1323 TEST_F(ServiceWorkerVersionTest, FailToStart_UseNewRendererProcess) {
1324   ServiceWorkerContextCore* context = helper_->context();
1325   int64_t id = version_->version_id();
1326   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
1327 
1328   // Start once. It should choose the "existing process".
1329   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1330             StartServiceWorker(version_.get()));
1331   EXPECT_EQ(helper_->mock_render_process_id(),
1332             version_->embedded_worker()->process_id());
1333 
1334   StopServiceWorker(version_.get());
1335 
1336   // Fail once.
1337   helper_->AddPendingInstanceClient(
1338       std::make_unique<FailStartInstanceClient>(helper_.get()));
1339   ASSERT_EQ(blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed,
1340             StartServiceWorker(version_.get()));
1341   EXPECT_EQ(1, context->GetVersionFailureCount(id));
1342 
1343   // Fail again.
1344   helper_->AddPendingInstanceClient(
1345       std::make_unique<FailStartInstanceClient>(helper_.get()));
1346   ASSERT_EQ(blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed,
1347             StartServiceWorker(version_.get()));
1348   EXPECT_EQ(2, context->GetVersionFailureCount(id));
1349 
1350   // Succeed. It should choose the "new process".
1351   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1352             StartServiceWorker(version_.get()));
1353   EXPECT_EQ(helper_->new_render_process_id(),
1354             version_->embedded_worker()->process_id());
1355   EXPECT_EQ(0, context->GetVersionFailureCount(id));
1356   version_->StopWorker(base::DoNothing());
1357   base::RunLoop().RunUntilIdle();
1358 
1359   // Start again. It should choose the "existing process" again as we no longer
1360   // force creation of a new process.
1361   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1362             StartServiceWorker(version_.get()));
1363   EXPECT_EQ(helper_->mock_render_process_id(),
1364             version_->embedded_worker()->process_id());
1365   version_->StopWorker(base::DoNothing());
1366   base::RunLoop().RunUntilIdle();
1367 }
1368 
TEST_F(ServiceWorkerVersionTest,FailToStart_RestartStalledWorker)1369 TEST_F(ServiceWorkerVersionTest, FailToStart_RestartStalledWorker) {
1370   base::Optional<blink::ServiceWorkerStatusCode> status;
1371   base::RunLoop run_loop;
1372   // Stall in starting.
1373   auto* client = helper_->AddNewPendingInstanceClient<
1374       DelayedFakeEmbeddedWorkerInstanceClient>(helper_.get());
1375   client->UnblockStopWorker();
1376   version_->StartWorker(
1377       ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
1378       ReceiveServiceWorkerStatus(&status, run_loop.QuitClosure()));
1379 
1380   base::RunLoop().RunUntilIdle();
1381   EXPECT_FALSE(status);
1382 
1383   // The restart logic is triggered because OnStopped is called before
1384   // OnStarted. So the Start message is sent again. The delayed instance client
1385   // was already consumed, so a default fake instance client will be created,
1386   // which starts normally.
1387   bool has_stopped = false;
1388   version_->StopWorker(VerifyCalled(&has_stopped));
1389   run_loop.Run();
1390 
1391   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
1392   EXPECT_TRUE(has_stopped);
1393   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
1394 }
1395 
TEST_F(ServiceWorkerVersionTest,InstalledFetchEventHandlerExists)1396 TEST_F(ServiceWorkerVersionTest, InstalledFetchEventHandlerExists) {
1397   auto* service_worker =
1398       helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get());
1399   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1400             StartServiceWorker(version_.get()));
1401   service_worker->RunUntilInitializeGlobalScope();
1402   EXPECT_EQ(FetchHandlerExistence::EXISTS,
1403             service_worker->fetch_handler_existence());
1404 }
1405 
TEST_F(ServiceWorkerVersionNoFetchHandlerTest,InstalledFetchEventHandlerDoesNotExist)1406 TEST_F(ServiceWorkerVersionNoFetchHandlerTest,
1407        InstalledFetchEventHandlerDoesNotExist) {
1408   auto* service_worker =
1409       helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get());
1410   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1411             StartServiceWorker(version_.get()));
1412   service_worker->RunUntilInitializeGlobalScope();
1413   EXPECT_EQ(FetchHandlerExistence::DOES_NOT_EXIST,
1414             service_worker->fetch_handler_existence());
1415 }
1416 
1417 class StoreMessageServiceWorker : public FakeServiceWorker {
1418  public:
StoreMessageServiceWorker(EmbeddedWorkerTestHelper * helper)1419   explicit StoreMessageServiceWorker(EmbeddedWorkerTestHelper* helper)
1420       : FakeServiceWorker(helper) {}
1421   ~StoreMessageServiceWorker() override = default;
1422 
1423   // Returns messages from AddMessageToConsole.
1424   const std::vector<std::pair<blink::mojom::ConsoleMessageLevel, std::string>>&
console_messages()1425   console_messages() {
1426     return console_messages_;
1427   }
1428 
SetAddMessageToConsoleReceivedCallback(const base::RepeatingClosure & closure)1429   void SetAddMessageToConsoleReceivedCallback(
1430       const base::RepeatingClosure& closure) {
1431     add_message_to_console_callback_ = closure;
1432   }
1433 
1434  private:
AddMessageToConsole(blink::mojom::ConsoleMessageLevel level,const std::string & message)1435   void AddMessageToConsole(blink::mojom::ConsoleMessageLevel level,
1436                            const std::string& message) override {
1437     console_messages_.emplace_back(level, message);
1438     if (add_message_to_console_callback_)
1439       add_message_to_console_callback_.Run();
1440   }
1441 
1442   std::vector<std::pair<blink::mojom::ConsoleMessageLevel, std::string>>
1443       console_messages_;
1444   base::RepeatingClosure add_message_to_console_callback_;
1445 };
1446 
TEST_F(ServiceWorkerVersionTest,AddMessageToConsole)1447 TEST_F(ServiceWorkerVersionTest, AddMessageToConsole) {
1448   auto* service_worker =
1449       helper_->AddNewPendingServiceWorker<StoreMessageServiceWorker>(
1450           helper_.get());
1451 
1452   // Attempt to start the worker and immediate AddMessageToConsole should not
1453   // cause a crash.
1454   std::pair<blink::mojom::ConsoleMessageLevel, std::string> test_message =
1455       std::make_pair(blink::mojom::ConsoleMessageLevel::kVerbose, "");
1456   ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
1457             StartServiceWorker(version_.get()));
1458   version_->AddMessageToConsole(test_message.first, test_message.second);
1459   service_worker->RunUntilInitializeGlobalScope();
1460   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
1461 
1462   // Messages sent before sending StartWorker message won't be dispatched.
1463   ASSERT_EQ(0UL, service_worker->console_messages().size());
1464 
1465   // Messages sent after sending StartWorker message should be reached to
1466   // the renderer.
1467   base::RunLoop loop;
1468   service_worker->SetAddMessageToConsoleReceivedCallback(loop.QuitClosure());
1469   version_->AddMessageToConsole(test_message.first, test_message.second);
1470   loop.Run();
1471   ASSERT_EQ(1UL, service_worker->console_messages().size());
1472   EXPECT_EQ(test_message, service_worker->console_messages()[0]);
1473 }
1474 
1475 // Test that writing metadata aborts gracefully when a remote connection to
1476 // the Storage Service is disconnected.
TEST_F(ServiceWorkerVersionTest,WriteMetadata_RemoteStorageDisconnection)1477 TEST_F(ServiceWorkerVersionTest, WriteMetadata_RemoteStorageDisconnection) {
1478   const std::string kMetadata("Test metadata");
1479 
1480   net::TestCompletionCallback completion;
1481   version_->script_cache_map()->WriteMetadata(
1482       version_->script_url(), base::as_bytes(base::make_span(kMetadata)),
1483       completion.callback());
1484 
1485   helper_->context()->registry()->SimulateStorageRestartForTesting();
1486 
1487   ASSERT_EQ(completion.WaitForResult(), net::ERR_FAILED);
1488 }
1489 
1490 // Test that writing metadata aborts gracefully when the storage is disabled.
TEST_F(ServiceWorkerVersionTest,WriteMetadata_StorageDisabled)1491 TEST_F(ServiceWorkerVersionTest, WriteMetadata_StorageDisabled) {
1492   const std::string kMetadata("Test metadata");
1493 
1494   helper_->context()->registry()->GetRemoteStorageControl()->Disable();
1495   helper_->context()->registry()->GetRemoteStorageControl().FlushForTesting();
1496 
1497   net::TestCompletionCallback completion;
1498   version_->script_cache_map()->WriteMetadata(
1499       version_->script_url(), base::as_bytes(base::make_span(kMetadata)),
1500       completion.callback());
1501 
1502   ASSERT_EQ(completion.WaitForResult(), net::ERR_FAILED);
1503 }
1504 
1505 class ServiceWorkerVersionTerminationOnNoControlleeTest
1506     : public ServiceWorkerVersionTest,
1507       public testing::WithParamInterface<bool> {
1508  public:
ServiceWorkerVersionTerminationOnNoControlleeTest()1509   ServiceWorkerVersionTerminationOnNoControlleeTest() {
1510     if (IsTerminationEnabled()) {
1511       // The value should be the same with |kTerminationDelay|.
1512       feature_list_.InitAndEnableFeatureWithParameters(
1513           features::kServiceWorkerTerminationOnNoControllee,
1514           {{"termination_delay_in_ms", "5000"}});
1515     } else {
1516       feature_list_.InitAndDisableFeature(
1517           features::kServiceWorkerTerminationOnNoControllee);
1518     }
1519   }
1520 
CreateControllee()1521   ServiceWorkerContainerHost* CreateControllee() {
1522     remote_endpoints_.emplace_back();
1523     base::WeakPtr<ServiceWorkerContainerHost> container_host =
1524         CreateContainerHostForWindow(
1525             33 /* dummy render process id */, true /* is_parent_frame_secure */,
1526             helper_->context()->AsWeakPtr(), &remote_endpoints_.back());
1527     return container_host.get();
1528   }
1529 
IsTerminationEnabled()1530   static bool IsTerminationEnabled() { return GetParam(); }
1531 
1532  protected:
1533   // The value should be the same with the number set in the constructor.
1534   static constexpr base::TimeDelta kTerminationDelay =
1535       base::TimeDelta::FromMilliseconds(5000);
1536 
1537   static constexpr base::TimeDelta kDefaultIdleDelay =
1538       base::TimeDelta::FromSeconds(
1539           blink::mojom::kServiceWorkerDefaultIdleDelayInSeconds);
1540 
1541  private:
1542   base::test::ScopedFeatureList feature_list_;
1543   std::vector<ServiceWorkerRemoteContainerEndpoint> remote_endpoints_;
1544 };
1545 
1546 // static
1547 constexpr base::TimeDelta
1548     ServiceWorkerVersionTerminationOnNoControlleeTest::kTerminationDelay;
1549 
1550 // static
1551 constexpr base::TimeDelta
1552     ServiceWorkerVersionTerminationOnNoControlleeTest::kDefaultIdleDelay;
1553 
1554 INSTANTIATE_TEST_SUITE_P(All,
1555                          ServiceWorkerVersionTerminationOnNoControlleeTest,
1556                          testing::Bool());
1557 
1558 // Confirm if the idle delay is updated when all controllees are gone.
TEST_P(ServiceWorkerVersionTerminationOnNoControlleeTest,IdleDelayOnNoControllee)1559 TEST_P(ServiceWorkerVersionTerminationOnNoControlleeTest,
1560        IdleDelayOnNoControllee) {
1561   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
1562   FakeServiceWorker* service_worker_in_renderer =
1563       helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get());
1564 
1565   // Add a controllee before starting a worker.
1566   ServiceWorkerContainerHost* controllee = CreateControllee();
1567   version_->AddControllee(controllee);
1568 
1569   // Start the worker.
1570   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
1571             StartServiceWorker(version_.get()));
1572   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
1573 
1574   // The idle delay is set to the default until all controllees are gone.
1575   task_environment_.RunUntilIdle();
1576   EXPECT_FALSE(service_worker_in_renderer->idle_delay().has_value());
1577 
1578   // The idle delay is updated to |kTerminationDelay|, which is the same with
1579   // when all controllees are gone.
1580   version_->RemoveControllee(controllee->client_uuid());
1581   task_environment_.RunUntilIdle();
1582   if (IsTerminationEnabled()) {
1583     EXPECT_EQ(kTerminationDelay,
1584               service_worker_in_renderer->idle_delay().value());
1585   } else {
1586     EXPECT_FALSE(service_worker_in_renderer->idle_delay().has_value());
1587   }
1588 }
1589 
1590 // Confirm if the idle timeout is not updated if a controllee still exists.
TEST_P(ServiceWorkerVersionTerminationOnNoControlleeTest,NoIdleDelayUntilAllControlleeAreGone)1591 TEST_P(ServiceWorkerVersionTerminationOnNoControlleeTest,
1592        NoIdleDelayUntilAllControlleeAreGone) {
1593   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
1594   FakeServiceWorker* service_worker_in_renderer =
1595       helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get());
1596 
1597   // Add controlees before starting a worker.
1598   ServiceWorkerContainerHost* controllee1 = CreateControllee();
1599   ServiceWorkerContainerHost* controllee2 = CreateControllee();
1600   version_->AddControllee(controllee1);
1601   version_->AddControllee(controllee2);
1602 
1603   // Start the worker.
1604   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
1605             StartServiceWorker(version_.get()));
1606   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
1607 
1608   // The idle delay should not be updated until all controllees are gone.
1609   version_->RemoveControllee(controllee1->client_uuid());
1610   task_environment_.RunUntilIdle();
1611   EXPECT_FALSE(service_worker_in_renderer->idle_delay().has_value());
1612 
1613   // The idle delay is set to |kTerminationDelay| when all controllees are gone.
1614   version_->RemoveControllee(controllee2->client_uuid());
1615   task_environment_.RunUntilIdle();
1616   if (IsTerminationEnabled()) {
1617     EXPECT_EQ(kTerminationDelay,
1618               service_worker_in_renderer->idle_delay().value());
1619   } else {
1620     EXPECT_FALSE(service_worker_in_renderer->idle_delay().has_value());
1621   }
1622 }
1623 
1624 // Confirm the timeout is set back to the default when a new controllee is added
1625 // to the ServiceWorkerVersion before it's terminated.
TEST_P(ServiceWorkerVersionTerminationOnNoControlleeTest,AddControlleeAfterNoControllee)1626 TEST_P(ServiceWorkerVersionTerminationOnNoControlleeTest,
1627        AddControlleeAfterNoControllee) {
1628   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
1629   FakeServiceWorker* service_worker_in_renderer =
1630       helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get());
1631   EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
1632             StartServiceWorker(version_.get()));
1633   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
1634 
1635   {
1636     // The idle timeout is set to |kTerminationDelay| if all controllees are
1637     // gone.
1638     ServiceWorkerContainerHost* controllee = CreateControllee();
1639     version_->AddControllee(controllee);
1640     version_->RemoveControllee(controllee->client_uuid());
1641     task_environment_.RunUntilIdle();
1642     if (IsTerminationEnabled()) {
1643       EXPECT_EQ(kTerminationDelay,
1644                 service_worker_in_renderer->idle_delay().value());
1645     } else {
1646       EXPECT_FALSE(service_worker_in_renderer->idle_delay().has_value());
1647     }
1648   }
1649 
1650   {
1651     // The idle timeout is set to the default again if a new client is started
1652     // to be controlled by the service worker.
1653     ServiceWorkerContainerHost* controllee = CreateControllee();
1654     version_->AddControllee(controllee);
1655     task_environment_.RunUntilIdle();
1656     if (IsTerminationEnabled()) {
1657       EXPECT_EQ(kDefaultIdleDelay,
1658                 service_worker_in_renderer->idle_delay().value());
1659     } else {
1660       EXPECT_FALSE(service_worker_in_renderer->idle_delay().has_value());
1661     }
1662 
1663     // The idle timeout is set to |kTerminationDelay| again when all controllees
1664     // are gone.
1665     version_->RemoveControllee(controllee->client_uuid());
1666     task_environment_.RunUntilIdle();
1667     if (IsTerminationEnabled()) {
1668       EXPECT_EQ(kTerminationDelay,
1669                 service_worker_in_renderer->idle_delay().value());
1670     } else {
1671       EXPECT_FALSE(service_worker_in_renderer->idle_delay().has_value());
1672     }
1673   }
1674 }
1675 
1676 // Confirm no crash happens if the worker is stopped.
TEST_P(ServiceWorkerVersionTerminationOnNoControlleeTest,StoppedWorker)1677 TEST_P(ServiceWorkerVersionTerminationOnNoControlleeTest, StoppedWorker) {
1678   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
1679   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
1680 
1681   ServiceWorkerContainerHost* controllee = CreateControllee();
1682   version_->AddControllee(controllee);
1683   version_->RemoveControllee(controllee->client_uuid());
1684 }
1685 
1686 // FakeEmbeddedWorkerInstanceClient which waits to call OnStarted() until
1687 // CallOnStarted() is called.
1688 class WaitToCallOnStartedEmbeddedWorkerInstanceClient
1689     : public FakeEmbeddedWorkerInstanceClient {
1690  public:
WaitToCallOnStartedEmbeddedWorkerInstanceClient(EmbeddedWorkerTestHelper * helper)1691   explicit WaitToCallOnStartedEmbeddedWorkerInstanceClient(
1692       EmbeddedWorkerTestHelper* helper)
1693       : FakeEmbeddedWorkerInstanceClient(helper) {}
1694 
CallOnStarted()1695   void CallOnStarted() {
1696     host()->OnStarted(blink::mojom::ServiceWorkerStartStatus::kNormalCompletion,
1697                       true /* has_fetch_handler */, helper()->GetNextThreadId(),
1698                       blink::mojom::EmbeddedWorkerStartTiming::New());
1699   }
1700 
1701  protected:
EvaluateScript()1702   void EvaluateScript() override { host()->OnScriptEvaluationStart(); }
1703 };
1704 
1705 // Call AddControllee() and RemoveControllee() while starting a worker.
1706 // This is a regression test for https://crbug.com/1099744.
TEST_P(ServiceWorkerVersionTerminationOnNoControlleeTest,RemoveControlleeBeforeStarted)1707 TEST_P(ServiceWorkerVersionTerminationOnNoControlleeTest,
1708        RemoveControlleeBeforeStarted) {
1709   version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
1710   EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
1711   auto* embedded_worker_in_renderer = helper_->AddNewPendingInstanceClient<
1712       WaitToCallOnStartedEmbeddedWorkerInstanceClient>(helper_.get());
1713   auto* service_worker_in_renderer =
1714       helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get());
1715   base::RunLoop loop;
1716   version_->StartWorker(
1717       ServiceWorkerMetrics::EventType::UNKNOWN,
1718       base::BindLambdaForTesting(
1719           [&](blink::ServiceWorkerStatusCode) { loop.Quit(); }));
1720 
1721   // Add and remove controllee during starting the worker. This doesn't update
1722   // the idle delay.
1723   ServiceWorkerContainerHost* controllee = CreateControllee();
1724   version_->AddControllee(controllee);
1725   version_->RemoveControllee(controllee->client_uuid());
1726   service_worker_in_renderer->RunUntilInitializeGlobalScope();
1727   EXPECT_FALSE(service_worker_in_renderer->idle_delay().has_value());
1728   EXPECT_EQ(EmbeddedWorkerStatus::STARTING, version_->running_status());
1729 
1730   // Start the worker and make sure the fake service worker receives all the
1731   // messages. At the OnStarted message, the browser sends the idle timeout
1732   // because there's no controllee at this point.
1733   embedded_worker_in_renderer->CallOnStarted();
1734   loop.Run();
1735   service_worker_in_renderer->FlushForTesting();
1736   EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
1737   if (IsTerminationEnabled()) {
1738     EXPECT_EQ(kTerminationDelay,
1739               service_worker_in_renderer->idle_delay().value());
1740   } else {
1741     EXPECT_FALSE(service_worker_in_renderer->idle_delay().has_value());
1742   }
1743 }
1744 
1745 }  // namespace service_worker_version_unittest
1746 }  // namespace content
1747