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.
6 #include "base/callback.h"
7 #include "base/command_line.h"
8 #include "base/run_loop.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "content/browser/fileapi/chrome_blob_storage_context.h"
13 #include "content/browser/service_worker/embedded_worker_instance.h"
14 #include "content/browser/service_worker/embedded_worker_registry.h"
15 #include "content/browser/service_worker/service_worker_context_core.h"
16 #include "content/browser/service_worker/service_worker_context_observer.h"
17 #include "content/browser/service_worker/service_worker_context_wrapper.h"
18 #include "content/browser/service_worker/service_worker_registration.h"
19 #include "content/browser/service_worker/service_worker_test_utils.h"
20 #include "content/browser/service_worker/service_worker_version.h"
21 #include "content/common/service_worker/service_worker_messages.h"
22 #include "content/common/service_worker/service_worker_status_code.h"
23 #include "content/common/service_worker/service_worker_types.h"
24 #include "content/public/browser/browser_context.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/navigation_entry.h"
27 #include "content/public/browser/render_process_host.h"
28 #include "content/public/browser/storage_partition.h"
29 #include "content/public/browser/web_contents.h"
30 #include "content/public/common/content_switches.h"
31 #include "content/public/common/referrer.h"
32 #include "content/public/common/security_style.h"
33 #include "content/public/common/ssl_status.h"
34 #include "content/public/test/browser_test_utils.h"
35 #include "content/public/test/content_browser_test.h"
36 #include "content/public/test/content_browser_test_utils.h"
37 #include "content/shell/browser/shell.h"
38 #include "content/shell/browser/shell_content_browser_client.h"
39 #include "net/test/embedded_test_server/embedded_test_server.h"
40 #include "net/test/embedded_test_server/http_request.h"
41 #include "net/test/embedded_test_server/http_response.h"
42 #include "net/url_request/url_request_filter.h"
43 #include "net/url_request/url_request_interceptor.h"
44 #include "net/url_request/url_request_test_job.h"
45 #include "storage/browser/blob/blob_data_handle.h"
46 #include "storage/browser/blob/blob_data_snapshot.h"
47 #include "storage/browser/blob/blob_storage_context.h"
54 ServiceWorkerStatusCode status
;
55 ServiceWorkerFetchEventResult result
;
56 ServiceWorkerResponse response
;
57 scoped_ptr
<storage::BlobDataHandle
> blob_data_handle
;
60 void RunAndQuit(const base::Closure
& closure
,
61 const base::Closure
& quit
,
62 base::SingleThreadTaskRunner
* original_message_loop
) {
64 original_message_loop
->PostTask(FROM_HERE
, quit
);
67 void RunOnIOThreadWithDelay(const base::Closure
& closure
,
68 base::TimeDelta delay
) {
69 base::RunLoop run_loop
;
70 BrowserThread::PostDelayedTask(
73 base::Bind(&RunAndQuit
,
75 run_loop
.QuitClosure(),
76 base::ThreadTaskRunnerHandle::Get()),
81 void RunOnIOThread(const base::Closure
& closure
) {
82 RunOnIOThreadWithDelay(closure
, base::TimeDelta());
86 const base::Callback
<void(const base::Closure
& continuation
)>& closure
) {
87 base::RunLoop run_loop
;
88 base::Closure quit_on_original_thread
=
89 base::Bind(base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask
),
90 base::ThreadTaskRunnerHandle::Get().get(),
92 run_loop
.QuitClosure());
93 BrowserThread::PostTask(BrowserThread::IO
,
95 base::Bind(closure
, quit_on_original_thread
));
99 void ReceivePrepareResult(bool* is_prepared
) {
103 base::Closure
CreatePrepareReceiver(bool* is_prepared
) {
104 return base::Bind(&ReceivePrepareResult
, is_prepared
);
107 // Contrary to the style guide, the output parameter of this function comes
108 // before input parameters so Bind can be used on it to create a FetchCallback
109 // to pass to DispatchFetchEvent.
110 void ReceiveFetchResult(BrowserThread::ID run_quit_thread
,
111 const base::Closure
& quit
,
112 ChromeBlobStorageContext
* blob_context
,
113 FetchResult
* out_result
,
114 ServiceWorkerStatusCode actual_status
,
115 ServiceWorkerFetchEventResult actual_result
,
116 const ServiceWorkerResponse
& actual_response
) {
117 out_result
->status
= actual_status
;
118 out_result
->result
= actual_result
;
119 out_result
->response
= actual_response
;
120 if (!actual_response
.blob_uuid
.empty()) {
121 out_result
->blob_data_handle
=
122 blob_context
->context()->GetBlobDataFromUUID(
123 actual_response
.blob_uuid
);
126 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, quit
);
129 ServiceWorkerVersion::FetchCallback
CreateResponseReceiver(
130 BrowserThread::ID run_quit_thread
,
131 const base::Closure
& quit
,
132 ChromeBlobStorageContext
* blob_context
,
133 FetchResult
* result
) {
134 return base::Bind(&ReceiveFetchResult
, run_quit_thread
, quit
,
135 make_scoped_refptr
<ChromeBlobStorageContext
>(blob_context
),
139 void ReceiveFindRegistrationStatus(
140 BrowserThread::ID run_quit_thread
,
141 const base::Closure
& quit
,
142 ServiceWorkerStatusCode
* out_status
,
143 ServiceWorkerStatusCode status
,
144 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
145 *out_status
= status
;
147 BrowserThread::PostTask(run_quit_thread
, FROM_HERE
, quit
);
150 ServiceWorkerStorage::FindRegistrationCallback
CreateFindRegistrationReceiver(
151 BrowserThread::ID run_quit_thread
,
152 const base::Closure
& quit
,
153 ServiceWorkerStatusCode
* status
) {
154 return base::Bind(&ReceiveFindRegistrationStatus
, run_quit_thread
, quit
,
158 void ReadResponseBody(std::string
* body
,
159 storage::BlobDataHandle
* blob_data_handle
) {
160 ASSERT_TRUE(blob_data_handle
);
161 scoped_ptr
<storage::BlobDataSnapshot
> data
=
162 blob_data_handle
->CreateSnapshot();
163 ASSERT_EQ(1U, data
->items().size());
164 *body
= std::string(data
->items()[0]->bytes(), data
->items()[0]->length());
167 void ExpectResultAndRun(bool expected
,
168 const base::Closure
& continuation
,
170 EXPECT_EQ(expected
, actual
);
174 class WorkerActivatedObserver
175 : public ServiceWorkerContextObserver
,
176 public base::RefCountedThreadSafe
<WorkerActivatedObserver
> {
178 explicit WorkerActivatedObserver(ServiceWorkerContextWrapper
* context
)
179 : context_(context
) {}
181 RunOnIOThread(base::Bind(&WorkerActivatedObserver::InitOnIOThread
, this));
183 // ServiceWorkerContextObserver overrides.
184 void OnVersionStateChanged(int64 version_id
,
185 ServiceWorkerVersion::Status
) override
{
186 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
187 const ServiceWorkerVersion
* version
= context_
->GetLiveVersion(version_id
);
188 if (version
->status() == ServiceWorkerVersion::ACTIVATED
) {
189 context_
->RemoveObserver(this);
190 BrowserThread::PostTask(BrowserThread::UI
,
192 base::Bind(&WorkerActivatedObserver::Quit
, this));
195 void Wait() { run_loop_
.Run(); }
198 friend class base::RefCountedThreadSafe
<WorkerActivatedObserver
>;
199 ~WorkerActivatedObserver() override
{}
200 void InitOnIOThread() { context_
->AddObserver(this); }
201 void Quit() { run_loop_
.Quit(); }
203 base::RunLoop run_loop_
;
204 ServiceWorkerContextWrapper
* context_
;
205 DISALLOW_COPY_AND_ASSIGN(WorkerActivatedObserver
);
208 scoped_ptr
<net::test_server::HttpResponse
> VerifyServiceWorkerHeaderInRequest(
209 const net::test_server::HttpRequest
& request
) {
210 EXPECT_EQ(request
.relative_url
, "/service_worker/generated_sw.js");
211 std::map
<std::string
, std::string
>::const_iterator it
=
212 request
.headers
.find("Service-Worker");
213 EXPECT_TRUE(it
!= request
.headers
.end());
214 EXPECT_EQ("script", it
->second
);
216 scoped_ptr
<net::test_server::BasicHttpResponse
> http_response(
217 new net::test_server::BasicHttpResponse());
218 http_response
->set_content_type("text/javascript");
219 return http_response
.Pass();
222 // The ImportsBustMemcache test requires that the imported script
223 // would naturally be cached in blink's memcache, but the embedded
224 // test server doesn't produce headers that allow the blink's memcache
225 // to do that. This interceptor injects headers that give the import
226 // an experiration far in the future.
227 class LongLivedResourceInterceptor
: public net::URLRequestInterceptor
{
229 LongLivedResourceInterceptor(const std::string
& body
)
231 ~LongLivedResourceInterceptor() override
{}
233 // net::URLRequestInterceptor implementation
234 net::URLRequestJob
* MaybeInterceptRequest(
235 net::URLRequest
* request
,
236 net::NetworkDelegate
* network_delegate
) const override
{
237 const char kHeaders
[] =
239 "Content-Type: text/javascript\0"
240 "Expires: Thu, 1 Jan 2100 20:00:00 GMT\0"
242 std::string
headers(kHeaders
, arraysize(kHeaders
));
243 return new net::URLRequestTestJob(
244 request
, network_delegate
, headers
, body_
, true);
249 DISALLOW_COPY_AND_ASSIGN(LongLivedResourceInterceptor
);
252 void CreateLongLivedResourceInterceptors(
253 const GURL
& worker_url
, const GURL
& import_url
) {
254 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
255 scoped_ptr
<net::URLRequestInterceptor
> interceptor
;
257 interceptor
.reset(new LongLivedResourceInterceptor(
258 "importScripts('long_lived_import.js');"));
259 net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
260 worker_url
, interceptor
.Pass());
262 interceptor
.reset(new LongLivedResourceInterceptor(
263 "// the imported script does nothing"));
264 net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
265 import_url
, interceptor
.Pass());
268 void CountScriptResources(
269 ServiceWorkerContextWrapper
* wrapper
,
271 int* num_resources
) {
274 std::vector
<ServiceWorkerRegistrationInfo
> infos
=
275 wrapper
->GetAllLiveRegistrationInfo();
280 size_t index
= infos
.size() - 1;
281 if (infos
[index
].installing_version
.version_id
!=
282 kInvalidServiceWorkerVersionId
)
283 version_id
= infos
[index
].installing_version
.version_id
;
284 else if (infos
[index
].waiting_version
.version_id
!=
285 kInvalidServiceWorkerVersionId
)
286 version_id
= infos
[1].waiting_version
.version_id
;
287 else if (infos
[index
].active_version
.version_id
!=
288 kInvalidServiceWorkerVersionId
)
289 version_id
= infos
[index
].active_version
.version_id
;
293 ServiceWorkerVersion
* version
= wrapper
->GetLiveVersion(version_id
);
294 *num_resources
= static_cast<int>(version
->script_cache_map()->size());
299 class ServiceWorkerBrowserTest
: public ContentBrowserTest
{
301 using self
= ServiceWorkerBrowserTest
;
303 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
304 command_line
->AppendSwitch(
305 switches::kEnableExperimentalWebPlatformFeatures
);
308 void SetUpOnMainThread() override
{
309 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
310 StoragePartition
* partition
= BrowserContext::GetDefaultStoragePartition(
311 shell()->web_contents()->GetBrowserContext());
312 wrapper_
= static_cast<ServiceWorkerContextWrapper
*>(
313 partition
->GetServiceWorkerContext());
315 // Navigate to the page to set up a renderer page (where we can embed
317 NavigateToURLBlockUntilNavigationsComplete(
319 embedded_test_server()->GetURL("/service_worker/empty.html"), 1);
321 RunOnIOThread(base::Bind(&self::SetUpOnIOThread
, this));
324 void TearDownOnMainThread() override
{
325 RunOnIOThread(base::Bind(&self::TearDownOnIOThread
, this));
329 virtual void SetUpOnIOThread() {}
330 virtual void TearDownOnIOThread() {}
332 ServiceWorkerContextWrapper
* wrapper() { return wrapper_
.get(); }
333 ServiceWorkerContext
* public_context() { return wrapper(); }
335 void AssociateRendererProcessToPattern(const GURL
& pattern
) {
336 wrapper_
->process_manager()->AddProcessReferenceToPattern(
337 pattern
, shell()->web_contents()->GetRenderProcessHost()->GetID());
341 scoped_refptr
<ServiceWorkerContextWrapper
> wrapper_
;
344 class ConsoleListener
: public EmbeddedWorkerInstance::Listener
{
346 void OnReportConsoleMessage(int source_identifier
,
348 const base::string16
& message
,
350 const GURL
& source_url
) override
{
351 messages_
.push_back(message
);
352 if (!quit_
.is_null() && messages_
.size() == expected_message_count_
) {
353 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, quit_
);
358 void WaitForConsoleMessages(size_t expected_message_count
) {
359 if (messages_
.size() >= expected_message_count
)
362 expected_message_count_
= expected_message_count
;
363 base::RunLoop console_run_loop
;
364 quit_
= console_run_loop
.QuitClosure();
365 console_run_loop
.Run();
367 ASSERT_EQ(messages_
.size(), expected_message_count
);
370 bool OnMessageReceived(const IPC::Message
& message
) override
{ return false; }
371 const std::vector
<base::string16
>& messages() const { return messages_
; }
374 std::vector
<base::string16
> messages_
;
375 size_t expected_message_count_
;
379 class ServiceWorkerVersionBrowserTest
: public ServiceWorkerBrowserTest
{
381 using self
= ServiceWorkerVersionBrowserTest
;
383 ~ServiceWorkerVersionBrowserTest() override
{}
385 void TearDownOnIOThread() override
{
386 registration_
= NULL
;
390 void InstallTestHelper(const std::string
& worker_url
,
391 ServiceWorkerStatusCode expected_status
) {
392 RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread
, this,
395 // Dispatch install on a worker.
396 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
397 base::RunLoop install_run_loop
;
398 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
399 base::Bind(&self::InstallOnIOThread
, this,
400 install_run_loop
.QuitClosure(),
402 install_run_loop
.Run();
403 ASSERT_EQ(expected_status
, status
);
406 status
= SERVICE_WORKER_ERROR_FAILED
;
407 base::RunLoop stop_run_loop
;
408 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
409 base::Bind(&self::StopOnIOThread
, this,
410 stop_run_loop
.QuitClosure(),
413 ASSERT_EQ(SERVICE_WORKER_OK
, status
);
416 void ActivateTestHelper(
417 const std::string
& worker_url
,
418 ServiceWorkerStatusCode expected_status
) {
420 base::Bind(&self::SetUpRegistrationOnIOThread
, this, worker_url
));
421 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
422 base::RunLoop run_loop
;
423 BrowserThread::PostTask(
427 &self::ActivateOnIOThread
, this, run_loop
.QuitClosure(), &status
));
429 ASSERT_EQ(expected_status
, status
);
432 void FetchOnRegisteredWorker(
433 ServiceWorkerFetchEventResult
* result
,
434 ServiceWorkerResponse
* response
,
435 scoped_ptr
<storage::BlobDataHandle
>* blob_data_handle
) {
436 blob_context_
= ChromeBlobStorageContext::GetFor(
437 shell()->web_contents()->GetBrowserContext());
438 bool prepare_result
= false;
439 FetchResult fetch_result
;
440 fetch_result
.status
= SERVICE_WORKER_ERROR_FAILED
;
441 base::RunLoop fetch_run_loop
;
442 BrowserThread::PostTask(BrowserThread::IO
,
444 base::Bind(&self::FetchOnIOThread
,
446 fetch_run_loop
.QuitClosure(),
449 fetch_run_loop
.Run();
450 ASSERT_TRUE(prepare_result
);
451 *result
= fetch_result
.result
;
452 *response
= fetch_result
.response
;
453 *blob_data_handle
= fetch_result
.blob_data_handle
.Pass();
454 ASSERT_EQ(SERVICE_WORKER_OK
, fetch_result
.status
);
457 void FetchTestHelper(const std::string
& worker_url
,
458 ServiceWorkerFetchEventResult
* result
,
459 ServiceWorkerResponse
* response
,
460 scoped_ptr
<storage::BlobDataHandle
>* blob_data_handle
) {
462 base::Bind(&self::SetUpRegistrationOnIOThread
, this, worker_url
));
463 FetchOnRegisteredWorker(result
, response
, blob_data_handle
);
466 void SetUpRegistrationOnIOThread(const std::string
& worker_url
) {
467 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
468 const GURL pattern
= embedded_test_server()->GetURL("/service_worker/");
469 registration_
= new ServiceWorkerRegistration(
471 wrapper()->context()->storage()->NewRegistrationId(),
472 wrapper()->context()->AsWeakPtr());
473 version_
= new ServiceWorkerVersion(
475 embedded_test_server()->GetURL(worker_url
),
476 wrapper()->context()->storage()->NewVersionId(),
477 wrapper()->context()->AsWeakPtr());
479 // Make the registration findable via storage functions.
480 wrapper()->context()->storage()->NotifyInstallingRegistration(
481 registration_
.get());
483 AssociateRendererProcessToPattern(pattern
);
486 void TimeoutWorkerOnIOThread() {
487 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
488 version_
->SimulatePingTimeoutForTesting();
491 void AddControlleeOnIOThread() {
492 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
493 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
494 33 /* dummy render process id */,
495 MSG_ROUTING_NONE
/* render_frame_id */, 1 /* dummy provider_id */,
496 SERVICE_WORKER_PROVIDER_FOR_WINDOW
, wrapper()->context()->AsWeakPtr(),
498 host
->SetDocumentUrl(
499 embedded_test_server()->GetURL("/service_worker/host"));
500 host
->AssociateRegistration(registration_
.get(),
501 false /* notify_controllerchange */);
502 wrapper()->context()->AddProviderHost(host
.Pass());
505 void AddWaitingWorkerOnIOThread(const std::string
& worker_url
) {
506 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
507 scoped_refptr
<ServiceWorkerVersion
> waiting_version(
508 new ServiceWorkerVersion(
509 registration_
.get(), embedded_test_server()->GetURL(worker_url
),
510 wrapper()->context()->storage()->NewVersionId(),
511 wrapper()->context()->AsWeakPtr()));
512 waiting_version
->SetStatus(ServiceWorkerVersion::INSTALLED
);
513 registration_
->SetWaitingVersion(waiting_version
.get());
514 registration_
->ActivateWaitingVersionWhenReady();
517 void StartWorker(ServiceWorkerStatusCode expected_status
) {
518 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI
));
519 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
520 base::RunLoop start_run_loop
;
521 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
522 base::Bind(&self::StartOnIOThread
, this,
523 start_run_loop
.QuitClosure(),
525 start_run_loop
.Run();
526 ASSERT_EQ(expected_status
, status
);
529 void StopWorker(ServiceWorkerStatusCode expected_status
) {
530 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI
));
531 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
532 base::RunLoop stop_run_loop
;
533 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
534 base::Bind(&self::StopOnIOThread
, this,
535 stop_run_loop
.QuitClosure(),
538 ASSERT_EQ(expected_status
, status
);
541 void StoreRegistration(int64 version_id
,
542 ServiceWorkerStatusCode expected_status
) {
543 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI
));
544 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
545 base::RunLoop store_run_loop
;
546 BrowserThread::PostTask(
547 BrowserThread::IO
, FROM_HERE
,
548 base::Bind(&self::StoreOnIOThread
, this, store_run_loop
.QuitClosure(),
549 &status
, version_id
));
550 store_run_loop
.Run();
551 ASSERT_EQ(expected_status
, status
);
553 RunOnIOThread(base::Bind(&self::NotifyDoneInstallingRegistrationOnIOThread
,
557 void FindRegistrationForId(int64 id
,
559 ServiceWorkerStatusCode expected_status
) {
560 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI
));
561 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
562 base::RunLoop run_loop
;
563 BrowserThread::PostTask(
564 BrowserThread::IO
, FROM_HERE
,
565 base::Bind(&self::FindRegistrationForIdOnIOThread
, this,
566 run_loop
.QuitClosure(), &status
, id
, origin
));
568 ASSERT_EQ(expected_status
, status
);
571 void FindRegistrationForIdOnIOThread(const base::Closure
& done
,
572 ServiceWorkerStatusCode
* result
,
574 const GURL
& origin
) {
575 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
576 wrapper()->context()->storage()->FindRegistrationForId(
578 CreateFindRegistrationReceiver(BrowserThread::UI
, done
, result
));
581 void NotifyDoneInstallingRegistrationOnIOThread(
582 ServiceWorkerStatusCode status
) {
583 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
584 wrapper()->context()->storage()->NotifyDoneInstallingRegistration(
585 registration_
.get(), version_
.get(), status
);
588 void RemoveLiveRegistrationOnIOThread(int64 id
) {
589 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
590 wrapper()->context()->RemoveLiveRegistration(id
);
593 void StartOnIOThread(const base::Closure
& done
,
594 ServiceWorkerStatusCode
* result
) {
595 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
596 version_
->StartWorker(CreateReceiver(BrowserThread::UI
, done
, result
));
599 void InstallOnIOThread(const base::Closure
& done
,
600 ServiceWorkerStatusCode
* result
) {
601 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
602 version_
->SetStatus(ServiceWorkerVersion::INSTALLING
);
603 version_
->DispatchInstallEvent(
604 CreateReceiver(BrowserThread::UI
, done
, result
));
607 void StoreOnIOThread(const base::Closure
& done
,
608 ServiceWorkerStatusCode
* result
,
610 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
611 ServiceWorkerVersion
* version
=
612 wrapper()->context()->GetLiveVersion(version_id
);
613 wrapper()->context()->storage()->StoreRegistration(
614 registration_
.get(), version
,
615 CreateReceiver(BrowserThread::UI
, done
, result
));
618 void ActivateOnIOThread(const base::Closure
& done
,
619 ServiceWorkerStatusCode
* result
) {
620 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
621 version_
->SetStatus(ServiceWorkerVersion::ACTIVATING
);
622 registration_
->SetActiveVersion(version_
.get());
623 version_
->DispatchActivateEvent(
624 CreateReceiver(BrowserThread::UI
, done
, result
));
627 void FetchOnIOThread(const base::Closure
& done
,
628 bool* prepare_result
,
629 FetchResult
* result
) {
630 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
631 ServiceWorkerFetchRequest
request(
632 embedded_test_server()->GetURL("/service_worker/empty.html"),
634 ServiceWorkerHeaderMap(),
637 version_
->SetStatus(ServiceWorkerVersion::ACTIVATED
);
638 version_
->DispatchFetchEvent(
640 CreatePrepareReceiver(prepare_result
),
641 CreateResponseReceiver(
642 BrowserThread::UI
, done
, blob_context_
.get(), result
));
645 void StopOnIOThread(const base::Closure
& done
,
646 ServiceWorkerStatusCode
* result
) {
647 ASSERT_TRUE(version_
.get());
648 version_
->StopWorker(CreateReceiver(BrowserThread::UI
, done
, result
));
652 scoped_refptr
<ServiceWorkerRegistration
> registration_
;
653 scoped_refptr
<ServiceWorkerVersion
> version_
;
654 scoped_refptr
<ChromeBlobStorageContext
> blob_context_
;
657 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
, StartAndStop
) {
658 RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread
, this,
659 "/service_worker/worker.js"));
662 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
663 base::RunLoop start_run_loop
;
664 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
665 base::Bind(&self::StartOnIOThread
, this,
666 start_run_loop
.QuitClosure(),
668 start_run_loop
.Run();
669 ASSERT_EQ(SERVICE_WORKER_OK
, status
);
672 status
= SERVICE_WORKER_ERROR_FAILED
;
673 base::RunLoop stop_run_loop
;
674 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
675 base::Bind(&self::StopOnIOThread
, this,
676 stop_run_loop
.QuitClosure(),
679 ASSERT_EQ(SERVICE_WORKER_OK
, status
);
682 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
, StartNotFound
) {
683 RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread
, this,
684 "/service_worker/nonexistent.js"));
686 // Start a worker for nonexistent URL.
687 StartWorker(SERVICE_WORKER_ERROR_NETWORK
);
690 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
, ReadResourceFailure
) {
691 // Create a registration.
692 RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread
, this,
693 "/service_worker/worker.js"));
694 version_
->SetStatus(ServiceWorkerVersion::ACTIVATED
);
696 // Add a non-existent resource to the version.
697 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records
;
699 ServiceWorkerDatabase::ResourceRecord(30, version_
->script_url(), 100));
700 version_
->script_cache_map()->SetResources(records
);
702 // Store the registration.
703 StoreRegistration(version_
->version_id(), SERVICE_WORKER_OK
);
705 // Start the worker. We'll fail to read the resource.
706 StartWorker(SERVICE_WORKER_ERROR_DISK_CACHE
);
707 EXPECT_EQ(ServiceWorkerVersion::REDUNDANT
, version_
->status());
709 // The registration should be deleted from storage since the broken worker was
711 RunOnIOThread(base::Bind(&self::RemoveLiveRegistrationOnIOThread
, this,
712 registration_
->id()));
713 FindRegistrationForId(registration_
->id(),
714 registration_
->pattern().GetOrigin(),
715 SERVICE_WORKER_ERROR_NOT_FOUND
);
718 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
,
719 ReadResourceFailure_WaitingWorker
) {
720 // Create a registration and active version.
721 RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread
, this,
722 "/service_worker/worker.js"));
723 base::RunLoop activate_run_loop
;
724 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
725 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
726 base::Bind(&self::ActivateOnIOThread
, this,
727 activate_run_loop
.QuitClosure(), &status
));
728 activate_run_loop
.Run();
729 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
730 ASSERT_TRUE(registration_
->active_version());
732 // Give the version a controllee.
733 RunOnIOThread(base::Bind(&self::AddControlleeOnIOThread
, this));
735 // Add a non-existent resource to the version.
736 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records
;
738 ServiceWorkerDatabase::ResourceRecord(30, version_
->script_url(), 100));
739 version_
->script_cache_map()->SetResources(records
);
741 // Make a waiting version and store it.
742 RunOnIOThread(base::Bind(&self::AddWaitingWorkerOnIOThread
, this,
743 "/service_worker/worker.js"));
744 registration_
->waiting_version()->script_cache_map()->SetResources(records
);
745 StoreRegistration(registration_
->waiting_version()->version_id(),
748 // Start the broken worker. We'll fail to read from disk and the worker should
750 StopWorker(SERVICE_WORKER_OK
); // in case it's already running
751 StartWorker(SERVICE_WORKER_ERROR_DISK_CACHE
);
752 EXPECT_EQ(ServiceWorkerVersion::REDUNDANT
, version_
->status());
754 // The registration should still be in storage since the waiting worker was
756 RunOnIOThread(base::Bind(&self::RemoveLiveRegistrationOnIOThread
, this,
757 registration_
->id()));
758 FindRegistrationForId(registration_
->id(),
759 registration_
->pattern().GetOrigin(),
763 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
, Install
) {
764 InstallTestHelper("/service_worker/worker.js", SERVICE_WORKER_OK
);
767 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
,
768 InstallWithWaitUntil_Fulfilled
) {
769 InstallTestHelper("/service_worker/worker_install_fulfilled.js",
773 // Check that ServiceWorker script requests set a "Service-Worker: script"
775 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
,
776 ServiceWorkerScriptHeader
) {
777 embedded_test_server()->RegisterRequestHandler(
778 base::Bind(&VerifyServiceWorkerHeaderInRequest
));
779 InstallTestHelper("/service_worker/generated_sw.js", SERVICE_WORKER_OK
);
782 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
,
783 Activate_NoEventListener
) {
784 ActivateTestHelper("/service_worker/worker.js", SERVICE_WORKER_OK
);
785 ASSERT_EQ(ServiceWorkerVersion::ACTIVATING
, version_
->status());
788 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
, Activate_Rejected
) {
789 ActivateTestHelper("/service_worker/worker_activate_rejected.js",
790 SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED
);
793 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
,
794 InstallWithWaitUntil_Rejected
) {
795 InstallTestHelper("/service_worker/worker_install_rejected.js",
796 SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED
);
799 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
,
800 InstallWithWaitUntil_RejectConsoleMessage
) {
801 RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread
, this,
802 "/service_worker/worker_install_rejected.js"));
804 ConsoleListener console_listener
;
805 version_
->embedded_worker()->AddListener(&console_listener
);
807 // Dispatch install on a worker.
808 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
809 base::RunLoop install_run_loop
;
810 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
811 base::Bind(&self::InstallOnIOThread
, this,
812 install_run_loop
.QuitClosure(), &status
));
813 install_run_loop
.Run();
814 ASSERT_EQ(SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED
, status
);
816 const base::string16 expected
=
817 base::ASCIIToUTF16("Rejecting oninstall event");
818 console_listener
.WaitForConsoleMessages(1);
819 ASSERT_NE(base::string16::npos
,
820 console_listener
.messages()[0].find(expected
));
821 version_
->embedded_worker()->RemoveListener(&console_listener
);
824 class WaitForLoaded
: public EmbeddedWorkerInstance::Listener
{
826 WaitForLoaded(const base::Closure
& quit
) : quit_(quit
) {}
828 void OnThreadStarted() override
{
829 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, quit_
);
831 bool OnMessageReceived(const IPC::Message
& message
) override
{ return false; }
837 // This test has started flaking somewhat consistently on Win, Mac and Linux.
838 // Disabling for now, see http://crbug.com/496065.
839 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
,
840 DISABLED_TimeoutStartingWorker
) {
841 RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread
, this,
842 "/service_worker/while_true_worker.js"));
844 // Start a worker, waiting until the script is loaded.
845 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
846 base::RunLoop start_run_loop
;
847 base::RunLoop load_run_loop
;
848 WaitForLoaded
wait_for_load(load_run_loop
.QuitClosure());
849 version_
->embedded_worker()->AddListener(&wait_for_load
);
850 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
851 base::Bind(&self::StartOnIOThread
, this,
852 start_run_loop
.QuitClosure(), &status
));
854 version_
->embedded_worker()->RemoveListener(&wait_for_load
);
856 // The script has loaded but start has not completed yet.
857 ASSERT_EQ(SERVICE_WORKER_ERROR_FAILED
, status
);
858 EXPECT_EQ(ServiceWorkerVersion::STARTING
, version_
->running_status());
860 // Simulate execution timeout. Use a delay to prevent killing the worker
861 // before it's started execution.
862 EXPECT_TRUE(version_
->timeout_timer_
.IsRunning());
863 RunOnIOThreadWithDelay(base::Bind(&self::TimeoutWorkerOnIOThread
, this),
864 base::TimeDelta::FromMilliseconds(100));
865 start_run_loop
.Run();
867 EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT
, status
);
870 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
, TimeoutWorkerInEvent
) {
871 RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread
, this,
872 "/service_worker/while_true_in_install_worker.js"));
875 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
876 base::RunLoop start_run_loop
;
877 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
878 base::Bind(&self::StartOnIOThread
, this,
879 start_run_loop
.QuitClosure(), &status
));
880 start_run_loop
.Run();
881 ASSERT_EQ(SERVICE_WORKER_OK
, status
);
883 // Dispatch an event.
884 base::RunLoop install_run_loop
;
885 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
886 base::Bind(&self::InstallOnIOThread
, this,
887 install_run_loop
.QuitClosure(), &status
));
889 // Simulate execution timeout. Use a delay to prevent killing the worker
890 // before it's started execution.
891 EXPECT_TRUE(version_
->timeout_timer_
.IsRunning());
892 RunOnIOThreadWithDelay(base::Bind(&self::TimeoutWorkerOnIOThread
, this),
893 base::TimeDelta::FromMilliseconds(100));
894 install_run_loop
.Run();
896 EXPECT_EQ(SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED
, status
);
899 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
, FetchEvent_Response
) {
900 ServiceWorkerFetchEventResult result
;
901 ServiceWorkerResponse response
;
902 scoped_ptr
<storage::BlobDataHandle
> blob_data_handle
;
903 FetchTestHelper("/service_worker/fetch_event.js",
904 &result
, &response
, &blob_data_handle
);
905 ASSERT_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE
, result
);
906 EXPECT_EQ(301, response
.status_code
);
907 EXPECT_EQ("Moved Permanently", response
.status_text
);
908 ServiceWorkerHeaderMap expected_headers
;
909 expected_headers
["content-language"] = "fi";
910 expected_headers
["content-type"] = "text/html; charset=UTF-8";
911 EXPECT_EQ(expected_headers
, response
.headers
);
915 base::Bind(&ReadResponseBody
,
916 &body
, base::Owned(blob_data_handle
.release())));
917 EXPECT_EQ("This resource is gone. Gone, gone, gone.", body
);
920 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest
,
921 FetchEvent_respondWithRejection
) {
922 ServiceWorkerFetchEventResult result
;
923 ServiceWorkerResponse response
;
924 scoped_ptr
<storage::BlobDataHandle
> blob_data_handle
;
926 RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread
, this,
927 "/service_worker/fetch_event_rejected.js"));
929 ConsoleListener console_listener
;
930 version_
->embedded_worker()->AddListener(&console_listener
);
932 FetchOnRegisteredWorker(&result
, &response
, &blob_data_handle
);
933 const base::string16 expected1
= base::ASCIIToUTF16(
934 "resulted in a network error response: the promise was rejected.");
935 const base::string16 expected2
=
936 base::ASCIIToUTF16("Uncaught (in promise) Rejecting respondWith promise");
937 console_listener
.WaitForConsoleMessages(2);
938 ASSERT_NE(base::string16::npos
,
939 console_listener
.messages()[0].find(expected1
));
940 ASSERT_EQ(0u, console_listener
.messages()[1].find(expected2
));
941 version_
->embedded_worker()->RemoveListener(&console_listener
);
943 ASSERT_EQ(SERVICE_WORKER_FETCH_EVENT_RESULT_RESPONSE
, result
);
944 EXPECT_EQ(0, response
.status_code
);
946 ASSERT_FALSE(blob_data_handle
);
949 IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest
, Reload
) {
950 const char kPageUrl
[] = "/service_worker/reload.html";
951 const char kWorkerUrl
[] = "/service_worker/fetch_event_reload.js";
952 scoped_refptr
<WorkerActivatedObserver
> observer
=
953 new WorkerActivatedObserver(wrapper());
955 public_context()->RegisterServiceWorker(
956 embedded_test_server()->GetURL(kPageUrl
),
957 embedded_test_server()->GetURL(kWorkerUrl
),
958 base::Bind(&ExpectResultAndRun
, true, base::Bind(&base::DoNothing
)));
961 const base::string16 title1
= base::ASCIIToUTF16("reload=false");
962 TitleWatcher
title_watcher1(shell()->web_contents(), title1
);
963 NavigateToURL(shell(), embedded_test_server()->GetURL(kPageUrl
));
964 EXPECT_EQ(title1
, title_watcher1
.WaitAndGetTitle());
966 const base::string16 title2
= base::ASCIIToUTF16("reload=true");
967 TitleWatcher
title_watcher2(shell()->web_contents(), title2
);
968 ReloadBlockUntilNavigationsComplete(shell(), 1);
969 EXPECT_EQ(title2
, title_watcher2
.WaitAndGetTitle());
973 base::RunLoop run_loop
;
974 public_context()->UnregisterServiceWorker(
975 embedded_test_server()->GetURL(kPageUrl
),
976 base::Bind(&ExpectResultAndRun
, true, run_loop
.QuitClosure()));
980 // Flaky on Win/Mac: http://crbug.com/533631
981 #if defined(OS_WIN) || defined(OS_MACOSX)
982 #define MAYBE_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure DISABLED_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure
984 #define MAYBE_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure ResponseFromHTTPSServiceWorkerIsMarkedAsSecure
986 IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest
,
987 MAYBE_ResponseFromHTTPSServiceWorkerIsMarkedAsSecure
) {
988 const char kPageUrl
[] = "files/service_worker/fetch_event_blob.html";
989 const char kWorkerUrl
[] = "files/service_worker/fetch_event_blob.js";
990 net::SpawnedTestServer
https_server(
991 net::SpawnedTestServer::TYPE_HTTPS
,
992 net::BaseTestServer::SSLOptions(
993 net::BaseTestServer::SSLOptions::CERT_OK
),
994 base::FilePath(FILE_PATH_LITERAL("content/test/data/")));
995 ASSERT_TRUE(https_server
.Start());
997 scoped_refptr
<WorkerActivatedObserver
> observer
=
998 new WorkerActivatedObserver(wrapper());
1000 public_context()->RegisterServiceWorker(
1001 https_server
.GetURL(kPageUrl
),
1002 https_server
.GetURL(kWorkerUrl
),
1003 base::Bind(&ExpectResultAndRun
, true, base::Bind(&base::DoNothing
)));
1006 const base::string16 title
= base::ASCIIToUTF16("Title");
1007 TitleWatcher
title_watcher(shell()->web_contents(), title
);
1008 NavigateToURL(shell(), https_server
.GetURL(kPageUrl
));
1009 EXPECT_EQ(title
, title_watcher
.WaitAndGetTitle());
1010 EXPECT_FALSE(shell()->web_contents()->DisplayedInsecureContent());
1011 NavigationEntry
* entry
=
1012 shell()->web_contents()->GetController().GetVisibleEntry();
1013 EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED
, entry
->GetSSL().security_style
);
1017 base::RunLoop run_loop
;
1018 public_context()->UnregisterServiceWorker(
1019 https_server
.GetURL(kPageUrl
),
1020 base::Bind(&ExpectResultAndRun
, true, run_loop
.QuitClosure()));
1024 IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest
,
1025 ResponseFromHTTPServiceWorkerIsNotMarkedAsSecure
) {
1026 const char kPageUrl
[] = "/service_worker/fetch_event_blob.html";
1027 const char kWorkerUrl
[] = "/service_worker/fetch_event_blob.js";
1028 scoped_refptr
<WorkerActivatedObserver
> observer
=
1029 new WorkerActivatedObserver(wrapper());
1031 public_context()->RegisterServiceWorker(
1032 embedded_test_server()->GetURL(kPageUrl
),
1033 embedded_test_server()->GetURL(kWorkerUrl
),
1034 base::Bind(&ExpectResultAndRun
, true, base::Bind(&base::DoNothing
)));
1037 const base::string16 title
= base::ASCIIToUTF16("Title");
1038 TitleWatcher
title_watcher(shell()->web_contents(), title
);
1039 NavigateToURL(shell(), embedded_test_server()->GetURL(kPageUrl
));
1040 EXPECT_EQ(title
, title_watcher
.WaitAndGetTitle());
1041 EXPECT_FALSE(shell()->web_contents()->DisplayedInsecureContent());
1042 NavigationEntry
* entry
=
1043 shell()->web_contents()->GetController().GetVisibleEntry();
1044 EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED
, entry
->GetSSL().security_style
);
1048 base::RunLoop run_loop
;
1049 public_context()->UnregisterServiceWorker(
1050 embedded_test_server()->GetURL(kPageUrl
),
1051 base::Bind(&ExpectResultAndRun
, true, run_loop
.QuitClosure()));
1055 IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest
, ImportsBustMemcache
) {
1056 const char kScopeUrl
[] = "/service_worker/imports_bust_memcache_scope/";
1057 const char kPageUrl
[] = "/service_worker/imports_bust_memcache.html";
1058 const char kScriptUrl
[] = "/service_worker/worker_with_one_import.js";
1059 const char kImportUrl
[] = "/service_worker/long_lived_import.js";
1060 const base::string16
kOKTitle(base::ASCIIToUTF16("OK"));
1061 const base::string16
kFailTitle(base::ASCIIToUTF16("FAIL"));
1064 base::Bind(&CreateLongLivedResourceInterceptors
,
1065 embedded_test_server()->GetURL(kScriptUrl
),
1066 embedded_test_server()->GetURL(kImportUrl
)));
1068 TitleWatcher
title_watcher(shell()->web_contents(), kOKTitle
);
1069 title_watcher
.AlsoWaitForTitle(kFailTitle
);
1070 NavigateToURL(shell(), embedded_test_server()->GetURL(kPageUrl
));
1071 base::string16 title
= title_watcher
.WaitAndGetTitle();
1072 EXPECT_EQ(kOKTitle
, title
);
1074 // Verify the number of resources in the implicit script cache is correct.
1075 const int kExpectedNumResources
= 2;
1076 int num_resources
= 0;
1078 base::Bind(&CountScriptResources
,
1079 base::Unretained(wrapper()),
1080 embedded_test_server()->GetURL(kScopeUrl
),
1082 EXPECT_EQ(kExpectedNumResources
, num_resources
);
1085 class ServiceWorkerBlackBoxBrowserTest
: public ServiceWorkerBrowserTest
{
1087 using self
= ServiceWorkerBlackBoxBrowserTest
;
1089 void FindRegistrationOnIO(const GURL
& document_url
,
1090 ServiceWorkerStatusCode
* status
,
1091 const base::Closure
& continuation
) {
1092 wrapper()->FindRegistrationForDocument(
1094 base::Bind(&ServiceWorkerBlackBoxBrowserTest::FindRegistrationOnIO2
,
1095 this, status
, continuation
));
1098 void FindRegistrationOnIO2(
1099 ServiceWorkerStatusCode
* out_status
,
1100 const base::Closure
& continuation
,
1101 ServiceWorkerStatusCode status
,
1102 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
1103 *out_status
= status
;
1104 if (!registration
.get())
1105 EXPECT_NE(SERVICE_WORKER_OK
, status
);
1110 static int CountRenderProcessHosts() {
1112 for (RenderProcessHost::iterator
iter(RenderProcessHost::AllHostsIterator());
1120 // Flaky timeouts on CrOS: http://crbug.com/387045
1121 #if defined(OS_CHROMEOS)
1122 #define MAYBE_Registration DISABLED_Registration
1124 #define MAYBE_Registration Registration
1126 IN_PROC_BROWSER_TEST_F(ServiceWorkerBlackBoxBrowserTest
, MAYBE_Registration
) {
1127 // Close the only window to be sure we're not re-using its RenderProcessHost.
1129 EXPECT_EQ(0, CountRenderProcessHosts());
1131 const char kWorkerUrl
[] = "/service_worker/fetch_event.js";
1132 const char kScope
[] = "/service_worker/";
1134 // Unregistering nothing should return false.
1136 base::RunLoop run_loop
;
1137 public_context()->UnregisterServiceWorker(
1138 embedded_test_server()->GetURL("/"),
1139 base::Bind(&ExpectResultAndRun
, false, run_loop
.QuitClosure()));
1143 // If we use a worker URL that doesn't exist, registration fails.
1145 base::RunLoop run_loop
;
1146 public_context()->RegisterServiceWorker(
1147 embedded_test_server()->GetURL(kScope
),
1148 embedded_test_server()->GetURL("/does/not/exist"),
1149 base::Bind(&ExpectResultAndRun
, false, run_loop
.QuitClosure()));
1152 EXPECT_EQ(0, CountRenderProcessHosts());
1154 // Register returns when the promise would be resolved.
1156 base::RunLoop run_loop
;
1157 public_context()->RegisterServiceWorker(
1158 embedded_test_server()->GetURL(kScope
),
1159 embedded_test_server()->GetURL(kWorkerUrl
),
1160 base::Bind(&ExpectResultAndRun
, true, run_loop
.QuitClosure()));
1163 EXPECT_EQ(1, CountRenderProcessHosts());
1165 // Registering again should succeed, although the algo still
1166 // might not be complete.
1168 base::RunLoop run_loop
;
1169 public_context()->RegisterServiceWorker(
1170 embedded_test_server()->GetURL(kScope
),
1171 embedded_test_server()->GetURL(kWorkerUrl
),
1172 base::Bind(&ExpectResultAndRun
, true, run_loop
.QuitClosure()));
1176 // The registration algo might not be far enough along to have
1177 // stored the registration data, so it may not be findable
1180 // Unregistering something should return true.
1182 base::RunLoop run_loop
;
1183 public_context()->UnregisterServiceWorker(
1184 embedded_test_server()->GetURL(kScope
),
1185 base::Bind(&ExpectResultAndRun
, true, run_loop
.QuitClosure()));
1188 EXPECT_GE(1, CountRenderProcessHosts()) << "Unregistering doesn't stop the "
1189 "workers eagerly, so their RPHs "
1190 "can still be running.";
1192 // Should not be able to find it.
1194 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
1196 base::Bind(&ServiceWorkerBlackBoxBrowserTest::FindRegistrationOnIO
,
1198 embedded_test_server()->GetURL("/service_worker/empty.html"),
1200 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
, status
);
1204 #if defined(ANDROID)
1205 #define MAYBE_CrossSiteTransfer DISABLED_CrossSiteTransfer
1207 #define MAYBE_CrossSiteTransfer CrossSiteTransfer
1209 IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest
, MAYBE_CrossSiteTransfer
) {
1210 // The first page registers a service worker.
1211 const char kRegisterPageUrl
[] = "/service_worker/cross_site_xfer.html";
1212 const base::string16
kOKTitle1(base::ASCIIToUTF16("OK_1"));
1213 const base::string16
kFailTitle1(base::ASCIIToUTF16("FAIL_1"));
1214 content::TitleWatcher
title_watcher1(shell()->web_contents(), kOKTitle1
);
1215 title_watcher1
.AlsoWaitForTitle(kFailTitle1
);
1217 NavigateToURL(shell(), embedded_test_server()->GetURL(kRegisterPageUrl
));
1218 ASSERT_EQ(kOKTitle1
, title_watcher1
.WaitAndGetTitle());
1220 // Force process swapping behavior.
1221 ShellContentBrowserClient::SetSwapProcessesForRedirect(true);
1223 // The second pages loads via the serviceworker including a subresource.
1224 const char kConfirmPageUrl
[] =
1225 "/service_worker/cross_site_xfer_scope/"
1226 "cross_site_xfer_confirm_via_serviceworker.html";
1227 const base::string16
kOKTitle2(base::ASCIIToUTF16("OK_2"));
1228 const base::string16
kFailTitle2(base::ASCIIToUTF16("FAIL_2"));
1229 content::TitleWatcher
title_watcher2(shell()->web_contents(), kOKTitle2
);
1230 title_watcher2
.AlsoWaitForTitle(kFailTitle2
);
1232 NavigateToURL(shell(), embedded_test_server()->GetURL(kConfirmPageUrl
));
1233 EXPECT_EQ(kOKTitle2
, title_watcher2
.WaitAndGetTitle());
1236 class ServiceWorkerVersionBrowserV8CacheTest
1237 : public ServiceWorkerVersionBrowserTest
,
1238 public ServiceWorkerVersion::Listener
{
1240 using self
= ServiceWorkerVersionBrowserV8CacheTest
;
1241 ~ServiceWorkerVersionBrowserV8CacheTest() override
{
1243 version_
->RemoveListener(this);
1245 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
1246 ServiceWorkerBrowserTest::SetUpCommandLine(command_line
);
1247 command_line
->AppendSwitchASCII(switches::kV8CacheOptions
, "code");
1249 void SetUpRegistrationAndListenerOnIOThread(const std::string
& worker_url
) {
1250 SetUpRegistrationOnIOThread(worker_url
);
1251 version_
->AddListener(this);
1255 // ServiceWorkerVersion::Listener overrides
1256 void OnCachedMetadataUpdated(ServiceWorkerVersion
* version
) override
{
1257 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
1258 cache_updated_closure_
);
1261 base::Closure cache_updated_closure_
;
1264 IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8CacheTest
, Restart
) {
1265 RunOnIOThread(base::Bind(&self::SetUpRegistrationAndListenerOnIOThread
, this,
1266 "/service_worker/worker.js"));
1268 base::RunLoop cached_metadata_run_loop
;
1269 cache_updated_closure_
= cached_metadata_run_loop
.QuitClosure();
1272 StartWorker(SERVICE_WORKER_OK
);
1274 // Wait for the matadata is stored. This run loop should finish when
1275 // OnCachedMetadataUpdated() is called.
1276 cached_metadata_run_loop
.Run();
1278 // Activate the worker.
1279 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_FAILED
;
1280 base::RunLoop activate_run_loop
;
1281 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
1282 base::Bind(&self::ActivateOnIOThread
, this,
1283 activate_run_loop
.QuitClosure(), &status
));
1284 activate_run_loop
.Run();
1285 ASSERT_EQ(SERVICE_WORKER_OK
, status
);
1287 StopWorker(SERVICE_WORKER_OK
);
1288 // Restart the worker.
1289 StartWorker(SERVICE_WORKER_OK
);
1291 StopWorker(SERVICE_WORKER_OK
);
1294 } // namespace content