Commit 12e095b7 authored by Asami Doi's avatar Asami Doi Committed by Commit Bot

ServiceWorker: Add browser tests to make sure the implementation

to use an existing script on offline is correct or not.

The goal is to import and evaluate as a module script at ServiceWorker.
Users can use it by adding type 'module' when register a service
worker script.

The reason why I use browser tests instead of WPT tests is I want to
make sure an installed script works well offline. There is no way to
terminate a worker from WPT tests. These new tests are for 'classic'
and 'module' scripts.

Change-Id: I17f201080eeced93b8dccb8a3867721798b3699c
Cq-Include-Trybots: luci.chromium.try:linux_mojo
Bug: 824647
Reviewed-on: https://chromium-review.googlesource.com/c/1276046
Commit-Queue: Asami Doi <asamidoi@google.com>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarHiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601465}
parent c9dd6b7d
...@@ -582,9 +582,12 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest { ...@@ -582,9 +582,12 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
} }
void InstallTestHelper(const std::string& worker_url, void InstallTestHelper(const std::string& worker_url,
blink::ServiceWorkerStatusCode expected_status) { blink::ServiceWorkerStatusCode expected_status,
RunOnIOThread(base::BindOnce(&self::SetUpRegistrationOnIOThread, blink::mojom::ScriptType script_type =
base::Unretained(this), worker_url)); blink::mojom::ScriptType::kClassic) {
RunOnIOThread(
base::BindOnce(&self::SetUpRegistrationWithScriptTypeOnIOThread,
base::Unretained(this), worker_url, script_type));
// Dispatch install on a worker. // Dispatch install on a worker.
base::Optional<blink::ServiceWorkerStatusCode> status; base::Optional<blink::ServiceWorkerStatusCode> status;
...@@ -605,8 +608,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest { ...@@ -605,8 +608,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
stop_run_loop.Run(); stop_run_loop.Run();
} }
void ActivateTestHelper(const std::string& worker_url, void ActivateTestHelper(blink::ServiceWorkerStatusCode expected_status) {
blink::ServiceWorkerStatusCode expected_status) {
base::Optional<blink::ServiceWorkerStatusCode> status; base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop run_loop; base::RunLoop run_loop;
base::PostTaskWithTraits( base::PostTaskWithTraits(
...@@ -641,10 +643,18 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest { ...@@ -641,10 +643,18 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
} }
void SetUpRegistrationOnIOThread(const std::string& worker_url) { void SetUpRegistrationOnIOThread(const std::string& worker_url) {
SetUpRegistrationWithScriptTypeOnIOThread(
worker_url, blink::mojom::ScriptType::kClassic);
}
void SetUpRegistrationWithScriptTypeOnIOThread(
const std::string& worker_url,
blink::mojom::ScriptType script_type) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO)); ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
const GURL scope = embedded_test_server()->GetURL("/service_worker/"); const GURL scope = embedded_test_server()->GetURL("/service_worker/");
blink::mojom::ServiceWorkerRegistrationOptions options; blink::mojom::ServiceWorkerRegistrationOptions options;
options.scope = scope; options.scope = scope;
options.type = script_type;
registration_ = new ServiceWorkerRegistration( registration_ = new ServiceWorkerRegistration(
options, wrapper()->context()->storage()->NewRegistrationId(), options, wrapper()->context()->storage()->NewRegistrationId(),
wrapper()->context()->AsWeakPtr()); wrapper()->context()->AsWeakPtr());
...@@ -654,10 +664,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest { ...@@ -654,10 +664,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
version_ = new ServiceWorkerVersion( version_ = new ServiceWorkerVersion(
registration_.get(), embedded_test_server()->GetURL(worker_url), registration_.get(), embedded_test_server()->GetURL(worker_url),
blink::mojom::ScriptType::kClassic, script_type, wrapper()->context()->storage()->NewVersionId(),
wrapper()->context()->storage()->NewVersionId(),
wrapper()->context()->AsWeakPtr()); wrapper()->context()->AsWeakPtr());
// Make the registration findable via storage functions. // Make the registration findable via storage functions.
wrapper()->context()->storage()->NotifyInstallingRegistration( wrapper()->context()->storage()->NotifyInstallingRegistration(
registration_.get()); registration_.get());
...@@ -1130,8 +1138,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, ...@@ -1130,8 +1138,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
// Create a registration and active version. // Create a registration and active version.
InstallTestHelper("/service_worker/worker.js", InstallTestHelper("/service_worker/worker.js",
blink::ServiceWorkerStatusCode::kOk); blink::ServiceWorkerStatusCode::kOk);
ActivateTestHelper("/service_worker/worker.js", ActivateTestHelper(blink::ServiceWorkerStatusCode::kOk);
blink::ServiceWorkerStatusCode::kOk);
ASSERT_TRUE(registration_->active_version()); ASSERT_TRUE(registration_->active_version());
// Give the version a controllee. // Give the version a controllee.
...@@ -1213,8 +1220,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, ...@@ -1213,8 +1220,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
StartServerAndNavigateToSetup(); StartServerAndNavigateToSetup();
InstallTestHelper("/service_worker/worker.js", InstallTestHelper("/service_worker/worker.js",
blink::ServiceWorkerStatusCode::kOk); blink::ServiceWorkerStatusCode::kOk);
ActivateTestHelper("/service_worker/worker.js", ActivateTestHelper(blink::ServiceWorkerStatusCode::kOk);
blink::ServiceWorkerStatusCode::kOk);
ASSERT_EQ(ServiceWorkerVersion::ACTIVATING, version_->status()); ASSERT_EQ(ServiceWorkerVersion::ACTIVATING, version_->status());
} }
...@@ -1223,7 +1229,6 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, Activate_Rejected) { ...@@ -1223,7 +1229,6 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, Activate_Rejected) {
InstallTestHelper("/service_worker/worker_activate_rejected.js", InstallTestHelper("/service_worker/worker_activate_rejected.js",
blink::ServiceWorkerStatusCode::kOk); blink::ServiceWorkerStatusCode::kOk);
ActivateTestHelper( ActivateTestHelper(
"/service_worker/worker_activate_rejected.js",
blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected); blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected);
} }
...@@ -1268,6 +1273,44 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, ...@@ -1268,6 +1273,44 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
&console_listener)); &console_listener));
} }
// Tests starting an installed classic service worker while offline.
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
StartInstalledClassicScriptWhileOffline) {
StartServerAndNavigateToSetup();
// Install a service worker.
InstallTestHelper("/service_worker/worker_with_one_import.js",
blink::ServiceWorkerStatusCode::kOk,
blink::mojom::ScriptType::kClassic);
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
// Emulate offline by stopping the test server.
EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
EXPECT_FALSE(embedded_test_server()->Started());
// Restart the worker while offline.
StartWorker(blink::ServiceWorkerStatusCode::kOk);
}
// Tests starting an installed module service worker while offline.
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
StartInstalledModuleScriptWhileOffline) {
StartServerAndNavigateToSetup();
// Install a service worker.
InstallTestHelper("/service_worker/static_import_worker.js",
blink::ServiceWorkerStatusCode::kOk,
blink::mojom::ScriptType::kModule);
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
// Emulate offline by stopping the test server.
EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
EXPECT_FALSE(embedded_test_server()->Started());
// Restart the worker while offline.
StartWorker(blink::ServiceWorkerStatusCode::kOk);
}
class WaitForLoaded : public EmbeddedWorkerInstance::Listener { class WaitForLoaded : public EmbeddedWorkerInstance::Listener {
public: public:
explicit WaitForLoaded(base::OnceClosure quit) : quit_(std::move(quit)) {} explicit WaitForLoaded(base::OnceClosure quit) : quit_(std::move(quit)) {}
...@@ -1362,8 +1405,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchEvent_Response) { ...@@ -1362,8 +1405,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchEvent_Response) {
std::unique_ptr<storage::BlobDataHandle> blob_data_handle; std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
InstallTestHelper("/service_worker/fetch_event.js", InstallTestHelper("/service_worker/fetch_event.js",
blink::ServiceWorkerStatusCode::kOk); blink::ServiceWorkerStatusCode::kOk);
ActivateTestHelper("/service_worker/fetch_event.js", ActivateTestHelper(blink::ServiceWorkerStatusCode::kOk);
blink::ServiceWorkerStatusCode::kOk);
FetchOnRegisteredWorker(&result, &response, &blob_data_handle); FetchOnRegisteredWorker(&result, &response, &blob_data_handle);
ASSERT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse, ASSERT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse,
...@@ -1391,8 +1433,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, ...@@ -1391,8 +1433,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
const base::Time start_time(base::Time::Now()); const base::Time start_time(base::Time::Now());
InstallTestHelper("/service_worker/fetch_event_response_via_cache.js", InstallTestHelper("/service_worker/fetch_event_response_via_cache.js",
blink::ServiceWorkerStatusCode::kOk); blink::ServiceWorkerStatusCode::kOk);
ActivateTestHelper("/service_worker/fetch_event_response_via_cache.js", ActivateTestHelper(blink::ServiceWorkerStatusCode::kOk);
blink::ServiceWorkerStatusCode::kOk);
FetchOnRegisteredWorker(&result, &response1, &blob_data_handle); FetchOnRegisteredWorker(&result, &response1, &blob_data_handle);
ASSERT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse, ASSERT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse,
...@@ -1423,8 +1464,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, ...@@ -1423,8 +1464,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle; std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
InstallTestHelper("/service_worker/fetch_event_rejected.js", InstallTestHelper("/service_worker/fetch_event_rejected.js",
blink::ServiceWorkerStatusCode::kOk); blink::ServiceWorkerStatusCode::kOk);
ActivateTestHelper("/service_worker/fetch_event_rejected.js", ActivateTestHelper(blink::ServiceWorkerStatusCode::kOk);
blink::ServiceWorkerStatusCode::kOk);
ConsoleListener console_listener; ConsoleListener console_listener;
RunOnIOThread(base::BindOnce(&EmbeddedWorkerInstance::AddObserver, RunOnIOThread(base::BindOnce(&EmbeddedWorkerInstance::AddObserver,
......
...@@ -37,9 +37,25 @@ ServiceWorkerReadFromCacheJob::ServiceWorkerReadFromCacheJob( ...@@ -37,9 +37,25 @@ ServiceWorkerReadFromCacheJob::ServiceWorkerReadFromCacheJob(
version_(version), version_(version),
weak_factory_(this) { weak_factory_(this) {
DCHECK(version_); DCHECK(version_);
DCHECK(resource_type_ == RESOURCE_TYPE_SCRIPT || #if DCHECK_IS_ON()
(resource_type_ == RESOURCE_TYPE_SERVICE_WORKER && switch (version_->script_type()) {
version_->script_url() == request_->url())); case blink::mojom::ScriptType::kClassic:
// For classic scripts, the main service worker script should have the
// "service worker" resource type and imported scripts should have the
// "script" resource type.
DCHECK(resource_type_ == RESOURCE_TYPE_SCRIPT ||
(resource_type_ == RESOURCE_TYPE_SERVICE_WORKER &&
version_->script_url() == request_->url()));
break;
case blink::mojom::ScriptType::kModule:
// For module scripts, both the main service worker script and
// static-imported scripts should have the "service worker" resource type
// because static import inherits the resource type of the top-level
// module script.
DCHECK_EQ(RESOURCE_TYPE_SERVICE_WORKER, resource_type_);
break;
}
#endif // DCHECK_IS_ON()
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("ServiceWorker", TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("ServiceWorker",
"ServiceWorkerReadFromCacheJob", this, "ServiceWorkerReadFromCacheJob", this,
"URL", request_->url().spec()); "URL", request_->url().spec());
......
...@@ -408,6 +408,14 @@ void ServiceWorkerRegisterJob::UpdateAndContinue() { ...@@ -408,6 +408,14 @@ void ServiceWorkerRegisterJob::UpdateAndContinue() {
set_new_version(new ServiceWorkerVersion( set_new_version(new ServiceWorkerVersion(
registration(), script_url_, worker_script_type_, version_id, context_)); registration(), script_url_, worker_script_type_, version_id, context_));
new_version()->set_force_bypass_cache_for_scripts(force_bypass_cache_); new_version()->set_force_bypass_cache_for_scripts(force_bypass_cache_);
// Module service workers don't support pause after download so we can't
// perform script comparison.
// TODO(asamidoi): Support pause after download in module workers.
if (worker_script_type_ == blink::mojom::ScriptType::kModule) {
skip_script_comparison_ = true;
}
if (registration()->has_installed_version() && !skip_script_comparison_) { if (registration()->has_installed_version() && !skip_script_comparison_) {
new_version()->SetToPauseAfterDownload( new_version()->SetToPauseAfterDownload(
base::BindOnce(&ServiceWorkerRegisterJob::OnPausedAfterDownload, base::BindOnce(&ServiceWorkerRegisterJob::OnPausedAfterDownload,
......
...@@ -814,6 +814,8 @@ void ServiceWorkerVersion::Doom() { ...@@ -814,6 +814,8 @@ void ServiceWorkerVersion::Doom() {
} }
void ServiceWorkerVersion::SetToPauseAfterDownload(base::OnceClosure callback) { void ServiceWorkerVersion::SetToPauseAfterDownload(base::OnceClosure callback) {
// TODO(asamidoi): Support pause after download in module workers.
DCHECK_EQ(blink::mojom::ScriptType::kClassic, script_type_);
pause_after_download_callback_ = std::move(callback); pause_after_download_callback_ = std::move(callback);
} }
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as module from './worker.js';
...@@ -265,7 +265,13 @@ std::unique_ptr<WebURLLoader> WorkerFetchContext::CreateURLLoader( ...@@ -265,7 +265,13 @@ std::unique_ptr<WebURLLoader> WorkerFetchContext::CreateURLLoader(
->CreateURLLoader(wrapped, CreateResourceLoadingTaskRunnerHandle()); ->CreateURLLoader(wrapped, CreateResourceLoadingTaskRunnerHandle());
} }
if (request.GetRequestContext() == mojom::RequestContextType::SCRIPT) { // Use |script_loader_factory_| to load types SCRIPT (classic imported
// scripts) and SERVICE_WORKER (module main scripts and module imported
// scripts). Note that classic main scripts are also SERVICE_WORKER but loaded
// by the shadow page on the main thread, not here.
if (request.GetRequestContext() == mojom::RequestContextType::SCRIPT ||
request.GetRequestContext() ==
mojom::RequestContextType::SERVICE_WORKER) {
if (!script_loader_factory_) if (!script_loader_factory_)
script_loader_factory_ = web_context_->CreateScriptLoaderFactory(); script_loader_factory_ = web_context_->CreateScriptLoaderFactory();
if (script_loader_factory_) { if (script_loader_factory_) {
......
...@@ -309,6 +309,13 @@ void WebEmbeddedWorkerImpl::OnShadowPageInitialized() { ...@@ -309,6 +309,13 @@ void WebEmbeddedWorkerImpl::OnShadowPageInitialized() {
return; return;
} }
// If this is a module service worker, start the worker thread now. The worker
// thread will fetch the script.
if (worker_start_data_.script_type == mojom::ScriptType::kModule) {
StartWorkerThread();
return;
}
// Note: We only get here if this is a new (i.e., not installed) service // Note: We only get here if this is a new (i.e., not installed) service
// worker. // worker.
DCHECK(!main_script_loader_); DCHECK(!main_script_loader_);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment