15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file. 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/logging.h" 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/run_loop.h" 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/browser_thread_impl.h" 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/fileapi/mock_url_request_delegate.h" 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/service_worker/embedded_worker_test_helper.h" 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/service_worker/service_worker_context_core.h" 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/service_worker/service_worker_controllee_request_handler.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/service_worker/service_worker_provider_host.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/service_worker/service_worker_registration.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/service_worker/service_worker_registration.h" 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/service_worker/service_worker_url_request_job.h" 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/service_worker/service_worker_utils.h" 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/common/resource_request_body.h" 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h" 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/url_request/url_request_context.h" 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace content { 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace { 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int kMockRenderProcessId = 1224; 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint kMockProviderId = 1; 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void EmptyCallback() {} 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ServiceWorkerControlleeRequestHandlerTest : public testing::Test { 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public: 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ServiceWorkerControlleeRequestHandlerTest() 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void SetUp() OVERRIDE { 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) helper_.reset(new EmbeddedWorkerTestHelper(kMockRenderProcessId)); 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // A new unstored registration/version. 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scope_ = GURL("http://host/scope/"); 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) script_url_ = GURL("http://host/script.js"); 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registration_ = new ServiceWorkerRegistration( 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scope_, 1L, context()->AsWeakPtr()); 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) version_ = new ServiceWorkerVersion( 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci registration_.get(), script_url_, 1L, context()->AsWeakPtr()); 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // An empty host. 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost( 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kMockRenderProcessId, kMockProviderId, 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) context()->AsWeakPtr(), NULL)); 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) provider_host_ = host->AsWeakPtr(); 556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) context()->AddProviderHost(host.Pass()); 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) context()->storage()->LazyInitialize(base::Bind(&EmptyCallback)); 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void TearDown() OVERRIDE { 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) version_ = NULL; 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registration_ = NULL; 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) helper_.reset(); 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ServiceWorkerContextCore* context() const { return helper_->context(); } 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected: 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TestBrowserThreadBundle browser_thread_bundle_; 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<EmbeddedWorkerTestHelper> helper_; 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<ServiceWorkerRegistration> registration_; 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<ServiceWorkerVersion> version_; 745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::WeakPtr<ServiceWorkerProviderHost> provider_host_; 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net::URLRequestContext url_request_context_; 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MockURLRequestDelegate url_request_delegate_; 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GURL scope_; 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GURL script_url_; 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(ServiceWorkerControlleeRequestHandlerTest, ActivateWaitingVersion) { 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Store a registration that is installed but not activated yet. 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) version_->SetStatus(ServiceWorkerVersion::INSTALLED); 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci registration_->SetWaitingVersion(version_.get()); 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) context()->storage()->StoreRegistration( 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci registration_.get(), 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci version_.get(), 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Conduct a main resource load. 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GURL kDocUrl("http://host/scope/doc"); 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<net::URLRequest> request = url_request_context_.CreateRequest( 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kDocUrl, 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net::DEFAULT_PRIORITY, 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &url_request_delegate_, 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NULL); 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<ServiceWorkerControlleeRequestHandler> handler( 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new ServiceWorkerControlleeRequestHandler( 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) context()->AsWeakPtr(), 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) provider_host_, 10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::WeakPtr<storage::BlobStorageContext>(), 10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RESOURCE_TYPE_MAIN_FRAME, 10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<ResourceRequestBody>())); 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<net::URLRequestJob> job = 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) handler->MaybeCreateJob(request.get(), NULL); 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ServiceWorkerURLRequestJob* sw_job = 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static_cast<ServiceWorkerURLRequestJob*>(job.get()); 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_FALSE(sw_job->ShouldFallbackToNetwork()); 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker()); 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_FALSE(version_->HasControllee()); 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(ServiceWorkerVersion::ACTIVATED, 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) version_->status()); 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_FALSE(sw_job->ShouldFallbackToNetwork()); 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_TRUE(sw_job->ShouldForwardToServiceWorker()); 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_TRUE(version_->HasControllee()); 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Navigations should trigger an update too. 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) handler.reset(NULL); 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_TRUE(version_->update_timer_.IsRunning()); 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Test to not regress crbug/414118. 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ServiceWorkerControlleeRequestHandlerTest, DeletedProviderHost) { 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Store a registration so the call to FindRegistrationForDocument will read 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // from the database. 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci version_->SetStatus(ServiceWorkerVersion::ACTIVATED); 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci registration_->SetActiveVersion(version_.get()); 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci context()->storage()->StoreRegistration( 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci registration_.get(), 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci version_.get(), 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::RunLoop().RunUntilIdle(); 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci version_ = NULL; 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci registration_ = NULL; 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Conduct a main resource load. 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL kDocUrl("http://host/scope/doc"); 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<net::URLRequest> request = url_request_context_.CreateRequest( 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kDocUrl, 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::DEFAULT_PRIORITY, 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &url_request_delegate_, 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NULL); 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<ServiceWorkerControlleeRequestHandler> handler( 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new ServiceWorkerControlleeRequestHandler( 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci context()->AsWeakPtr(), 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci provider_host_, 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtr<storage::BlobStorageContext>(), 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RESOURCE_TYPE_MAIN_FRAME, 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<ResourceRequestBody>())); 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::URLRequestJob> job = 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handler->MaybeCreateJob(request.get(), NULL); 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerURLRequestJob* sw_job = 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<ServiceWorkerURLRequestJob*>(job.get()); 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(sw_job->ShouldFallbackToNetwork()); 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker()); 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Shouldn't crash if the ProviderHost is deleted prior to completion of 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // the database lookup. 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci context()->RemoveProviderHost(kMockRenderProcessId, kMockProviderId); 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(provider_host_.get()); 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::RunLoop().RunUntilIdle(); 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(sw_job->ShouldFallbackToNetwork()); 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_FALSE(sw_job->ShouldForwardToServiceWorker()); 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace content 173