service_worker_version_unittest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/run_loop.h" 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/service_worker/embedded_worker_registry.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/service_worker/embedded_worker_test_helper.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_context_core.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_registration.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_test_utils.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_version.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// IPC messages for testing --------------------------------------------------- 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define IPC_MESSAGE_IMPL 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ipc/ipc_message_macros.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define IPC_MESSAGE_START TestMsgStart 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IPC_MESSAGE_CONTROL0(TestMsg_Message); 240529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochIPC_MESSAGE_ROUTED1(TestMsg_MessageFromWorker, int); 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// --------------------------------------------------------------------------- 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content { 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static const int kRenderProcessId = 1; 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MessageReceiver : public EmbeddedWorkerTestHelper { 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MessageReceiver() 375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : EmbeddedWorkerTestHelper(kRenderProcessId), 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu current_embedded_worker_id_(0) {} 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~MessageReceiver() {} 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual bool OnMessageToWorker(int thread_id, 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int embedded_worker_id, 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const IPC::Message& message) OVERRIDE { 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (EmbeddedWorkerTestHelper::OnMessageToWorker( 455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu thread_id, embedded_worker_id, message)) { 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current_embedded_worker_id_ = embedded_worker_id; 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool handled = true; 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(MessageReceiver, message) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IPC_MESSAGE_HANDLER(TestMsg_Message, OnMessage) 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IPC_END_MESSAGE_MAP() 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return handled; 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void SimulateSendValueToBrowser(int embedded_worker_id, int value) { 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch SimulateSend(new TestMsg_MessageFromWorker(embedded_worker_id, value)); 590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void OnMessage() { 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Do nothing. 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int current_embedded_worker_id_; 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MessageReceiver); 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void VerifyCalled(bool* called) { 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *called = true; 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ObserveStatusChanges(ServiceWorkerVersion* version, 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<ServiceWorkerVersion::Status>* statuses) { 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) statuses->push_back(version->status()); 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) version->RegisterStatusChangeCallback( 78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Bind(&ObserveStatusChanges, base::Unretained(version), statuses)); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// A specialized listener class to receive test messages from a worker. 820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass MessageReceiverFromWorker : public EmbeddedWorkerInstance::Listener { 830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public: 840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch explicit MessageReceiverFromWorker(EmbeddedWorkerInstance* instance) 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : instance_(instance) { 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch instance_->AddListener(this); 870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual ~MessageReceiverFromWorker() { 890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch instance_->RemoveListener(this); 900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual void OnStarted() OVERRIDE { NOTREACHED(); } 930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual void OnStopped() OVERRIDE { NOTREACHED(); } 940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool handled = true; 960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IPC_BEGIN_MESSAGE_MAP(MessageReceiverFromWorker, message) 970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IPC_MESSAGE_HANDLER(TestMsg_MessageFromWorker, OnMessageFromWorker) 980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IPC_MESSAGE_UNHANDLED(handled = false) 990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch IPC_END_MESSAGE_MAP() 1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return handled; 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void OnMessageFromWorker(int value) { received_values_.push_back(value); } 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::vector<int>& received_values() const { return received_values_; } 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private: 1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EmbeddedWorkerInstance* instance_; 1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch std::vector<int> received_values_; 1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DISALLOW_COPY_AND_ASSIGN(MessageReceiverFromWorker); 1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ServiceWorkerVersionTest : public testing::Test { 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected: 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ServiceWorkerVersionTest() 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void SetUp() OVERRIDE { 1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu helper_.reset(new MessageReceiver()); 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registration_ = new ServiceWorkerRegistration( 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL("http://www.example.com/*"), 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GURL("http://www.example.com/service_worker.js"), 1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1L, 1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu helper_->context()->AsWeakPtr()); 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_ = new ServiceWorkerVersion( 1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu registration_, 1L, helper_->context()->AsWeakPtr()); 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Simulate adding one process to the worker. 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int embedded_worker_id = version_->embedded_worker()->embedded_worker_id(); 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) helper_->SimulateAddProcessToWorker(embedded_worker_id, kRenderProcessId); 133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ASSERT_TRUE(version_->HasProcessToRun()); 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void TearDown() OVERRIDE { 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_ = 0; 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registration_ = 0; 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) helper_.reset(); 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TestBrowserThreadBundle thread_bundle_; 1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<MessageReceiver> helper_; 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<ServiceWorkerRegistration> registration_; 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<ServiceWorkerVersion> version_; 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionTest); 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) { 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Call StartWorker() multiple times. 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED; 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED; 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ServiceWorkerStatusCode status3 = SERVICE_WORKER_ERROR_FAILED; 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->StartWorker(CreateReceiverOnCurrentThread(&status1)); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->StartWorker(CreateReceiverOnCurrentThread(&status2)); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status()); 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Call StartWorker() after it's started. 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->StartWorker(CreateReceiverOnCurrentThread(&status3)); 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // All should just succeed. 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, status1); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, status2); 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, status3); 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Call StopWorker() multiple times. 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) status1 = SERVICE_WORKER_ERROR_FAILED; 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) status2 = SERVICE_WORKER_ERROR_FAILED; 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) status3 = SERVICE_WORKER_ERROR_FAILED; 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->StopWorker(CreateReceiverOnCurrentThread(&status1)); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->StopWorker(CreateReceiverOnCurrentThread(&status2)); 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Also try calling StartWorker while StopWorker is in queue. 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->StartWorker(CreateReceiverOnCurrentThread(&status3)); 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(ServiceWorkerVersion::STOPPING, version_->running_status()); 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status()); 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // All StopWorker should just succeed, while StartWorker fails. 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, status1); 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, status2); 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status3); 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ServiceWorkerVersionTest, SendMessage) { 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status()); 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Send a message without starting the worker. 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->SendMessage(TestMsg_Message(), 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateReceiverOnCurrentThread(&status)); 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, status); 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The worker should be now started. 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Stop the worker, and then send the message immediately. 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ServiceWorkerStatusCode msg_status = SERVICE_WORKER_ERROR_FAILED; 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ServiceWorkerStatusCode stop_status = SERVICE_WORKER_ERROR_FAILED; 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->StopWorker(CreateReceiverOnCurrentThread(&stop_status)); 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->SendMessage(TestMsg_Message(), 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateReceiverOnCurrentThread(&msg_status)); 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, stop_status); 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // SendMessage should return START_WORKER_FAILED error since it tried to 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // start a worker while it was stopping. 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, msg_status); 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ServiceWorkerVersionTest, ReSendMessageAfterStop) { 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status()); 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Start the worker. 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ServiceWorkerStatusCode start_status = SERVICE_WORKER_ERROR_FAILED; 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->StartWorker(CreateReceiverOnCurrentThread(&start_status)); 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, start_status); 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Stop the worker, and then send the message immediately. 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ServiceWorkerStatusCode msg_status = SERVICE_WORKER_ERROR_FAILED; 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ServiceWorkerStatusCode stop_status = SERVICE_WORKER_ERROR_FAILED; 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->StopWorker(CreateReceiverOnCurrentThread(&stop_status)); 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->SendMessage(TestMsg_Message(), 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateReceiverOnCurrentThread(&msg_status)); 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, stop_status); 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // SendMessage should return START_WORKER_FAILED error since it tried to 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // start a worker while it was stopping. 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, msg_status); 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Resend the message, which should succeed and restart the worker. 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) version_->SendMessage(TestMsg_Message(), 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateReceiverOnCurrentThread(&msg_status)); 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, msg_status); 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status()); 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2480529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(ServiceWorkerVersionTest, ReceiveMessageFromWorker) { 2490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch MessageReceiverFromWorker receiver(version_->embedded_worker()); 2500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Simulate sending some dummy values from the worker. 2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch helper_->SimulateSendValueToBrowser( 2530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch version_->embedded_worker()->embedded_worker_id(), 555); 2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch helper_->SimulateSendValueToBrowser( 2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch version_->embedded_worker()->embedded_worker_id(), 777); 2560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Verify the receiver received the values. 2580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ASSERT_EQ(2U, receiver.received_values().size()); 2590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(555, receiver.received_values()[0]); 2600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(777, receiver.received_values()[1]); 2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ServiceWorkerVersionTest, InstallAndWaitCompletion) { 264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch version_->SetStatus(ServiceWorkerVersion::INSTALLING); 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Dispatch an install event. 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) version_->DispatchInstallEvent(-1, CreateReceiverOnCurrentThread(&status)); 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Wait for the completion. 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool status_change_called = false; 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) version_->RegisterStatusChangeCallback( 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&VerifyCalled, &status_change_called)); 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Version's status must not have changed during installation. 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, status); 279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_FALSE(status_change_called); 280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(ServiceWorkerVersion::INSTALLING, version_->status()); 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ServiceWorkerVersionTest, ActivateAndWaitCompletion) { 284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch version_->SetStatus(ServiceWorkerVersion::ACTIVATING); 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Dispatch an activate event. 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) version_->DispatchActivateEvent(CreateReceiverOnCurrentThread(&status)); 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Wait for the completion. 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool status_change_called = false; 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) version_->RegisterStatusChangeCallback( 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&VerifyCalled, &status_change_called)); 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Version's status must not have changed during activation. 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(SERVICE_WORKER_OK, status); 299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_FALSE(status_change_called); 300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(ServiceWorkerVersion::ACTIVATING, version_->status()); 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ServiceWorkerVersionTest, RepeatedlyObserveStatusChanges) { 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(ServiceWorkerVersion::NEW, version_->status()); 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Repeatedly observe status changes (the callback re-registers itself). 307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<ServiceWorkerVersion::Status> statuses; 308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) version_->RegisterStatusChangeCallback( 309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&ObserveStatusChanges, version_, &statuses)); 310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch version_->SetStatus(ServiceWorkerVersion::INSTALLING); 312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch version_->SetStatus(ServiceWorkerVersion::INSTALLED); 313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch version_->SetStatus(ServiceWorkerVersion::ACTIVATING); 314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch version_->SetStatus(ServiceWorkerVersion::ACTIVATED); 315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch version_->SetStatus(ServiceWorkerVersion::REDUNDANT); 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Verify that we could successfully observe repeated status changes. 318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_EQ(5U, statuses.size()); 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_EQ(ServiceWorkerVersion::INSTALLING, statuses[0]); 320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_EQ(ServiceWorkerVersion::INSTALLED, statuses[1]); 321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_EQ(ServiceWorkerVersion::ACTIVATING, statuses[2]); 322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_EQ(ServiceWorkerVersion::ACTIVATED, statuses[3]); 323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_EQ(ServiceWorkerVersion::REDUNDANT, statuses[4]); 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 326a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochTEST_F(ServiceWorkerVersionTest, AddAndRemoveProcesses) { 327a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Preparation (to reset the process count to 0). 328a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ASSERT_TRUE(version_->HasProcessToRun()); 329a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch version_->RemoveProcessFromWorker(kRenderProcessId); 330a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ASSERT_FALSE(version_->HasProcessToRun()); 331a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 332a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Add another process to the worker twice, and then remove process once. 333a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const int another_process_id = kRenderProcessId + 1; 334a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch version_->AddProcessToWorker(another_process_id); 335a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch version_->AddProcessToWorker(another_process_id); 336a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch version_->RemoveProcessFromWorker(another_process_id); 337a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 338a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // We're ref-counting the process internally, so adding the same process 339a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // multiple times should be handled correctly. 340a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ASSERT_TRUE(version_->HasProcessToRun()); 341a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 342a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Removing the process again (so that # of AddProcess == # of RemoveProcess 343a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // for the process) should remove all process references. 344a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch version_->RemoveProcessFromWorker(another_process_id); 345a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ASSERT_FALSE(version_->HasProcessToRun()); 346a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 347a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace content 349