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)
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pattern_ = GURL("http://www.example.com/");
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    registration_ = new ServiceWorkerRegistration(
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        pattern_,
1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        1L,
1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        helper_->context()->AsWeakPtr());
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    version_ = new ServiceWorkerVersion(
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        registration_.get(),
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        GURL("http://www.example.com/service_worker.js"),
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        1L,
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        helper_->context()->AsWeakPtr());
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Simulate adding one process to the pattern.
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    helper_->SimulateAddProcessToPattern(pattern_, kRenderProcessId);
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_TRUE(helper_->context()->process_manager()
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ->PatternHasProcessToRun(pattern_));
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    version_ = 0;
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    registration_ = 0;
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    helper_.reset();
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestBrowserThreadBundle thread_bundle_;
1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<MessageReceiver> helper_;
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<ServiceWorkerRegistration> registration_;
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<ServiceWorkerVersion> version_;
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GURL pattern_;
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionTest);
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) {
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Call StartWorker() multiple times.
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED;
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED;
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ServiceWorkerStatusCode status3 = SERVICE_WORKER_ERROR_FAILED;
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->StartWorker(CreateReceiverOnCurrentThread(&status1));
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->StartWorker(CreateReceiverOnCurrentThread(&status2));
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->running_status());
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Call StartWorker() after it's started.
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->StartWorker(CreateReceiverOnCurrentThread(&status3));
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // All should just succeed.
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, status1);
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, status2);
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, status3);
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Call StopWorker() multiple times.
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  status1 = SERVICE_WORKER_ERROR_FAILED;
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  status2 = SERVICE_WORKER_ERROR_FAILED;
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  status3 = SERVICE_WORKER_ERROR_FAILED;
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->StopWorker(CreateReceiverOnCurrentThread(&status1));
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->StopWorker(CreateReceiverOnCurrentThread(&status2));
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Also try calling StartWorker while StopWorker is in queue.
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->StartWorker(CreateReceiverOnCurrentThread(&status3));
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(ServiceWorkerVersion::STOPPING, version_->running_status());
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // All StopWorker should just succeed, while StartWorker fails.
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, status1);
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, status2);
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status3);
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ServiceWorkerVersionTest, SendMessage) {
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Send a message without starting the worker.
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->SendMessage(TestMsg_Message(),
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        CreateReceiverOnCurrentThread(&status));
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, status);
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The worker should be now started.
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Stop the worker, and then send the message immediately.
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ServiceWorkerStatusCode msg_status = SERVICE_WORKER_ERROR_FAILED;
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ServiceWorkerStatusCode stop_status = SERVICE_WORKER_ERROR_FAILED;
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->StopWorker(CreateReceiverOnCurrentThread(&stop_status));
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->SendMessage(TestMsg_Message(),
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       CreateReceiverOnCurrentThread(&msg_status));
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, stop_status);
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // SendMessage should return START_WORKER_FAILED error since it tried to
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // start a worker while it was stopping.
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, msg_status);
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ServiceWorkerVersionTest, ReSendMessageAfterStop) {
224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->running_status());
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Start the worker.
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ServiceWorkerStatusCode start_status = SERVICE_WORKER_ERROR_FAILED;
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->StartWorker(CreateReceiverOnCurrentThread(&start_status));
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, start_status);
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Stop the worker, and then send the message immediately.
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ServiceWorkerStatusCode msg_status = SERVICE_WORKER_ERROR_FAILED;
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ServiceWorkerStatusCode stop_status = SERVICE_WORKER_ERROR_FAILED;
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->StopWorker(CreateReceiverOnCurrentThread(&stop_status));
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->SendMessage(TestMsg_Message(),
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       CreateReceiverOnCurrentThread(&msg_status));
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, stop_status);
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // SendMessage should return START_WORKER_FAILED error since it tried to
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // start a worker while it was stopping.
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, msg_status);
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Resend the message, which should succeed and restart the worker.
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  version_->SendMessage(TestMsg_Message(),
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       CreateReceiverOnCurrentThread(&msg_status));
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, msg_status);
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->running_status());
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2540529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(ServiceWorkerVersionTest, ReceiveMessageFromWorker) {
2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MessageReceiverFromWorker receiver(version_->embedded_worker());
2560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Simulate sending some dummy values from the worker.
2580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  helper_->SimulateSendValueToBrowser(
2590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      version_->embedded_worker()->embedded_worker_id(), 555);
2600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  helper_->SimulateSendValueToBrowser(
2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      version_->embedded_worker()->embedded_worker_id(), 777);
2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Verify the receiver received the values.
2640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_EQ(2U, receiver.received_values().size());
2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(555, receiver.received_values()[0]);
2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(777, receiver.received_values()[1]);
2670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ServiceWorkerVersionTest, InstallAndWaitCompletion) {
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  version_->SetStatus(ServiceWorkerVersion::INSTALLING);
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Dispatch an install event.
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  version_->DispatchInstallEvent(-1, CreateReceiverOnCurrentThread(&status));
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Wait for the completion.
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool status_change_called = false;
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  version_->RegisterStatusChangeCallback(
279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&VerifyCalled, &status_change_called));
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Version's status must not have changed during installation.
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, status);
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(status_change_called);
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(ServiceWorkerVersion::INSTALLING, version_->status());
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ServiceWorkerVersionTest, ActivateAndWaitCompletion) {
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  version_->SetStatus(ServiceWorkerVersion::ACTIVATING);
291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Dispatch an activate event.
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  version_->DispatchActivateEvent(CreateReceiverOnCurrentThread(&status));
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Wait for the completion.
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool status_change_called = false;
298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  version_->RegisterStatusChangeCallback(
299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&VerifyCalled, &status_change_called));
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Version's status must not have changed during activation.
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, status);
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(status_change_called);
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(ServiceWorkerVersion::ACTIVATING, version_->status());
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ServiceWorkerVersionTest, RepeatedlyObserveStatusChanges) {
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(ServiceWorkerVersion::NEW, version_->status());
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Repeatedly observe status changes (the callback re-registers itself).
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::vector<ServiceWorkerVersion::Status> statuses;
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  version_->RegisterStatusChangeCallback(
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&ObserveStatusChanges, version_, &statuses));
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  version_->SetStatus(ServiceWorkerVersion::INSTALLING);
318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  version_->SetStatus(ServiceWorkerVersion::INSTALLED);
319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  version_->SetStatus(ServiceWorkerVersion::ACTIVATING);
320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  version_->SetStatus(ServiceWorkerVersion::REDUNDANT);
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Verify that we could successfully observe repeated status changes.
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_EQ(5U, statuses.size());
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(ServiceWorkerVersion::INSTALLING, statuses[0]);
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(ServiceWorkerVersion::INSTALLED, statuses[1]);
327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_EQ(ServiceWorkerVersion::ACTIVATING, statuses[2]);
328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_EQ(ServiceWorkerVersion::ACTIVATED, statuses[3]);
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ASSERT_EQ(ServiceWorkerVersion::REDUNDANT, statuses[4]);
330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) {
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Verify the timer is not running when version initializes its status.
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(version_->stop_worker_timer_.IsRunning());
3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Verify the timer is running when version status changes frome ACTIVATING
3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // to ACTIVATED.
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, status);
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  version_->SetStatus(ServiceWorkerVersion::ACTIVATING);
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(version_->stop_worker_timer_.IsRunning());
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The timer should be running if the worker is restarted without controllee.
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  status = SERVICE_WORKER_ERROR_FAILED;
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  version_->StopWorker(CreateReceiverOnCurrentThread(&status));
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, status);
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  status = SERVICE_WORKER_ERROR_FAILED;
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  version_->StartWorker(CreateReceiverOnCurrentThread(&status));
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(SERVICE_WORKER_OK, status);
3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(version_->stop_worker_timer_.IsRunning());
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The timer should not be running if a controllee is added.
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<ServiceWorkerProviderHost> host(
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new ServiceWorkerProviderHost(33 /* dummy render process id */,
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    1 /* dummy provider_id */,
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    helper_->context()->AsWeakPtr(),
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    NULL));
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  version_->AddControllee(host.get());
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(version_->stop_worker_timer_.IsRunning());
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The timer should be running if the controllee is removed.
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  version_->RemoveControllee(host.get());
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(version_->stop_worker_timer_.IsRunning());
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace content
373