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