| Index: content/browser/service_worker/service_worker_browsertest.cc
|
| diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
|
| index 3c75a907447f48439ce19a6d3756fd1923f412b8..9e635aa89a6a9f9dfc5a5010821e8b50b1c70303 100644
|
| --- a/content/browser/service_worker/service_worker_browsertest.cc
|
| +++ b/content/browser/service_worker/service_worker_browsertest.cc
|
| @@ -131,6 +131,25 @@ ServiceWorkerVersion::FetchCallback CreateResponseReceiver(
|
| result);
|
| }
|
|
|
| +void ReceiveFindRegistrationStatus(
|
| + BrowserThread::ID run_quit_thread,
|
| + const base::Closure& quit,
|
| + ServiceWorkerStatusCode* out_status,
|
| + ServiceWorkerStatusCode status,
|
| + const scoped_refptr<ServiceWorkerRegistration>& registration) {
|
| + *out_status = status;
|
| + if (!quit.is_null())
|
| + BrowserThread::PostTask(run_quit_thread, FROM_HERE, quit);
|
| +}
|
| +
|
| +ServiceWorkerStorage::FindRegistrationCallback CreateFindRegistrationReceiver(
|
| + BrowserThread::ID run_quit_thread,
|
| + const base::Closure& quit,
|
| + ServiceWorkerStatusCode* status) {
|
| + return base::Bind(&ReceiveFindRegistrationStatus, run_quit_thread, quit,
|
| + status);
|
| +}
|
| +
|
| void ReadResponseBody(std::string* body,
|
| storage::BlobDataHandle* blob_data_handle) {
|
| ASSERT_TRUE(blob_data_handle);
|
| @@ -159,7 +178,7 @@ class WorkerActivatedObserver
|
| // ServiceWorkerContextObserver overrides.
|
| void OnVersionStateChanged(int64 version_id,
|
| ServiceWorkerVersion::Status) override {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| const ServiceWorkerVersion* version = context_->GetLiveVersion(version_id);
|
| if (version->status() == ServiceWorkerVersion::ACTIVATED) {
|
| context_->RemoveObserver(this);
|
| @@ -227,7 +246,7 @@ class LongLivedResourceInterceptor : public net::URLRequestInterceptor {
|
|
|
| void CreateLongLivedResourceInterceptors(
|
| const GURL& worker_url, const GURL& import_url) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| + ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| scoped_ptr<net::URLRequestInterceptor> interceptor;
|
|
|
| interceptor.reset(new LongLivedResourceInterceptor(
|
| @@ -548,6 +567,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
|
| }
|
|
|
| void SetUpRegistrationOnIOThread(const std::string& worker_url) {
|
| + ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| const GURL pattern = embedded_test_server()->GetURL("/service_worker/");
|
| registration_ = new ServiceWorkerRegistration(
|
| pattern,
|
| @@ -572,6 +592,32 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
|
| version_->OnPingTimeout();
|
| }
|
|
|
| + void AddControlleeOnIOThread() {
|
| + ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost(
|
| + 33 /* dummy render process id */,
|
| + MSG_ROUTING_NONE /* render_frame_id */, 1 /* dummy provider_id */,
|
| + SERVICE_WORKER_PROVIDER_FOR_WINDOW, wrapper()->context()->AsWeakPtr(),
|
| + NULL));
|
| + host->SetDocumentUrl(
|
| + embedded_test_server()->GetURL("/service_worker/host"));
|
| + host->AssociateRegistration(registration_.get(),
|
| + false /* notify_controllerchange */);
|
| + wrapper()->context()->AddProviderHost(host.Pass());
|
| + }
|
| +
|
| + void AddWaitingWorkerOnIOThread(const std::string& worker_url) {
|
| + ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + scoped_refptr<ServiceWorkerVersion> waiting_version(
|
| + new ServiceWorkerVersion(
|
| + registration_.get(), embedded_test_server()->GetURL(worker_url),
|
| + wrapper()->context()->storage()->NewVersionId(),
|
| + wrapper()->context()->AsWeakPtr()));
|
| + waiting_version->SetStatus(ServiceWorkerVersion::INSTALLED);
|
| + registration_->SetWaitingVersion(waiting_version.get());
|
| + registration_->ActivateWaitingVersionWhenReady();
|
| + }
|
| +
|
| void StartWorker(ServiceWorkerStatusCode expected_status) {
|
| ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
|
| @@ -596,6 +642,58 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
|
| ASSERT_EQ(expected_status, status);
|
| }
|
|
|
| + void StoreRegistration(int64 version_id,
|
| + ServiceWorkerStatusCode expected_status) {
|
| + ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
|
| + base::RunLoop store_run_loop;
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&self::StoreOnIOThread, this, store_run_loop.QuitClosure(),
|
| + &status, version_id));
|
| + store_run_loop.Run();
|
| + ASSERT_EQ(expected_status, status);
|
| +
|
| + RunOnIOThread(base::Bind(&self::NotifyDoneInstallingRegistrationOnIOThread,
|
| + this, status));
|
| + }
|
| +
|
| + void FindRegistrationForId(int64 id,
|
| + const GURL& origin,
|
| + ServiceWorkerStatusCode expected_status) {
|
| + ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
|
| + base::RunLoop run_loop;
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&self::FindRegistrationForIdOnIOThread, this,
|
| + run_loop.QuitClosure(), &status, id, origin));
|
| + run_loop.Run();
|
| + ASSERT_EQ(expected_status, status);
|
| + }
|
| +
|
| + void FindRegistrationForIdOnIOThread(const base::Closure& done,
|
| + ServiceWorkerStatusCode* result,
|
| + int64 id,
|
| + const GURL& origin) {
|
| + ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + wrapper()->context()->storage()->FindRegistrationForId(
|
| + id, origin,
|
| + CreateFindRegistrationReceiver(BrowserThread::UI, done, result));
|
| + }
|
| +
|
| + void NotifyDoneInstallingRegistrationOnIOThread(
|
| + ServiceWorkerStatusCode status) {
|
| + ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + wrapper()->context()->storage()->NotifyDoneInstallingRegistration(
|
| + registration_.get(), version_.get(), status);
|
| + }
|
| +
|
| + void RemoveLiveRegistrationOnIOThread(int64 id) {
|
| + ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + wrapper()->context()->RemoveLiveRegistration(id);
|
| + }
|
| +
|
| void StartOnIOThread(const base::Closure& done,
|
| ServiceWorkerStatusCode* result) {
|
| ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| @@ -610,10 +708,22 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
|
| CreateReceiver(BrowserThread::UI, done, result));
|
| }
|
|
|
| + void StoreOnIOThread(const base::Closure& done,
|
| + ServiceWorkerStatusCode* result,
|
| + int64 version_id) {
|
| + ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + ServiceWorkerVersion* version =
|
| + wrapper()->context()->GetLiveVersion(version_id);
|
| + wrapper()->context()->storage()->StoreRegistration(
|
| + registration_.get(), version,
|
| + CreateReceiver(BrowserThread::UI, done, result));
|
| + }
|
| +
|
| void ActivateOnIOThread(const base::Closure& done,
|
| ServiceWorkerStatusCode* result) {
|
| ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| version_->SetStatus(ServiceWorkerVersion::ACTIVATING);
|
| + registration_->SetActiveVersion(version_.get());
|
| version_->DispatchActivateEvent(
|
| CreateReceiver(BrowserThread::UI, done, result));
|
| }
|
| @@ -730,6 +840,76 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, StartNotFound) {
|
| StartWorker(SERVICE_WORKER_ERROR_NETWORK);
|
| }
|
|
|
| +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, ReadResourceFailure) {
|
| + // Create and store a registration.
|
| + RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, this,
|
| + "/service_worker/worker.js"));
|
| + version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
|
| + StoreRegistration(version_->version_id(), SERVICE_WORKER_OK);
|
| +
|
| + // Add a non-existent resource to the version.
|
| + std::vector<ServiceWorkerDatabase::ResourceRecord> records;
|
| + records.push_back(
|
| + ServiceWorkerDatabase::ResourceRecord(30, version_->script_url(), 100));
|
| + version_->script_cache_map()->SetResources(records);
|
| +
|
| + // Start the worker. We'll fail to read the resource.
|
| + StartWorker(SERVICE_WORKER_ERROR_DISK_CACHE);
|
| + EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, version_->status());
|
| +
|
| + // The registration should be deleted from storage since the broken worker was
|
| + // the stored one.
|
| + RunOnIOThread(base::Bind(&self::RemoveLiveRegistrationOnIOThread, this,
|
| + registration_->id()));
|
| + FindRegistrationForId(registration_->id(),
|
| + registration_->pattern().GetOrigin(),
|
| + SERVICE_WORKER_ERROR_NOT_FOUND);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
|
| + ReadResourceFailure_WaitingWorker) {
|
| + // Create a registration and active version.
|
| + RunOnIOThread(base::Bind(&self::SetUpRegistrationOnIOThread, this,
|
| + "/service_worker/worker.js"));
|
| + base::RunLoop activate_run_loop;
|
| + ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
|
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&self::ActivateOnIOThread, this,
|
| + activate_run_loop.QuitClosure(), &status));
|
| + activate_run_loop.Run();
|
| + EXPECT_EQ(SERVICE_WORKER_OK, status);
|
| + ASSERT_TRUE(registration_->active_version());
|
| +
|
| + // Give the version a controllee.
|
| + RunOnIOThread(base::Bind(&self::AddControlleeOnIOThread, this));
|
| +
|
| + // Add a non-existent resource to the version.
|
| + std::vector<ServiceWorkerDatabase::ResourceRecord> records;
|
| + records.push_back(
|
| + ServiceWorkerDatabase::ResourceRecord(30, version_->script_url(), 100));
|
| + version_->script_cache_map()->SetResources(records);
|
| +
|
| + // Make a waiting version and store it.
|
| + RunOnIOThread(base::Bind(&self::AddWaitingWorkerOnIOThread, this,
|
| + "/service_worker/worker.js"));
|
| + StoreRegistration(registration_->waiting_version()->version_id(),
|
| + SERVICE_WORKER_OK);
|
| +
|
| + // Start the broken worker. We'll fail to read from disk and the worker should
|
| + // be doomed.
|
| + StopWorker(SERVICE_WORKER_OK); // in case it's already running
|
| + StartWorker(SERVICE_WORKER_ERROR_DISK_CACHE);
|
| + EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, version_->status());
|
| +
|
| + // The registration should still be in storage since the waiting worker was
|
| + // the stored one.
|
| + RunOnIOThread(base::Bind(&self::RemoveLiveRegistrationOnIOThread, this,
|
| + registration_->id()));
|
| + FindRegistrationForId(registration_->id(),
|
| + registration_->pattern().GetOrigin(),
|
| + SERVICE_WORKER_OK);
|
| +}
|
| +
|
| IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, Install) {
|
| InstallTestHelper("/service_worker/worker.js", SERVICE_WORKER_OK);
|
| }
|
| @@ -1278,11 +1458,11 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8CacheTest, Restart) {
|
|
|
| // Activate the worker.
|
| ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
|
| - base::RunLoop acrivate_run_loop;
|
| + base::RunLoop activate_run_loop;
|
| BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
| base::Bind(&self::ActivateOnIOThread, this,
|
| - acrivate_run_loop.QuitClosure(), &status));
|
| - acrivate_run_loop.Run();
|
| + activate_run_loop.QuitClosure(), &status));
|
| + activate_run_loop.Run();
|
| ASSERT_EQ(SERVICE_WORKER_OK, status);
|
| // Stop the worker.
|
| StopWorker(SERVICE_WORKER_OK);
|
|
|