| Index: content/browser/service_worker/embedded_worker_instance_unittest.cc | 
| diff --git a/content/browser/service_worker/embedded_worker_instance_unittest.cc b/content/browser/service_worker/embedded_worker_instance_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..45b2f29dc7fdcdb8314f8bc1eefd3689c91c9bbd | 
| --- /dev/null | 
| +++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc | 
| @@ -0,0 +1,137 @@ | 
| +// Copyright 2013 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "base/basictypes.h" | 
| +#include "base/stl_util.h" | 
| +#include "content/browser/service_worker/embedded_worker_instance.h" | 
| +#include "content/browser/service_worker/embedded_worker_registry.h" | 
| +#include "content/browser/service_worker/service_worker_context_core.h" | 
| +#include "content/common/service_worker_messages.h" | 
| +#include "content/public/test/test_browser_thread_bundle.h" | 
| +#include "ipc/ipc_message.h" | 
| +#include "ipc/ipc_sender.h" | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| + | 
| +namespace content { | 
| + | 
| +namespace { | 
| + | 
| +typedef std::vector<IPC::Message*> MessageList; | 
| + | 
| +class FakeSender : public IPC::Sender { | 
| + public: | 
| +  FakeSender() {} | 
| +  virtual ~FakeSender() { | 
| +    STLDeleteContainerPointers(sent_messages_.begin(), sent_messages_.end()); | 
| +  } | 
| + | 
| +  // IPC::Sender implementation. | 
| +  virtual bool Send(IPC::Message* message) OVERRIDE { | 
| +    sent_messages_.push_back(message); | 
| +    return true; | 
| +  } | 
| + | 
| +  const MessageList& sent_messages() { return sent_messages_; } | 
| + | 
| + private: | 
| +  MessageList sent_messages_; | 
| +  DISALLOW_COPY_AND_ASSIGN(FakeSender); | 
| +}; | 
| + | 
| +}  // namespace | 
| + | 
| +class EmbeddedWorkerInstanceTest : public testing::Test { | 
| + protected: | 
| +  EmbeddedWorkerInstanceTest() | 
| +      : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} | 
| + | 
| +  virtual void SetUp() OVERRIDE { | 
| +    context_.reset(new ServiceWorkerContextCore(base::FilePath(), NULL)); | 
| +  } | 
| + | 
| +  virtual void TearDown() OVERRIDE { | 
| +    context_.reset(); | 
| +  } | 
| + | 
| +  EmbeddedWorkerRegistry* embedded_worker_registry() { | 
| +    DCHECK(context_); | 
| +    return context_->embedded_worker_registry(); | 
| +  } | 
| + | 
| +  TestBrowserThreadBundle thread_bundle_; | 
| +  scoped_ptr<ServiceWorkerContextCore> context_; | 
| + | 
| +  DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceTest); | 
| +}; | 
| + | 
| +TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) { | 
| +  scoped_ptr<EmbeddedWorkerInstance> worker = | 
| +      embedded_worker_registry()->CreateWorker(); | 
| +  EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status()); | 
| + | 
| +  FakeSender fake_sender; | 
| +  const int process_id = 11; | 
| +  const int thread_id = 33; | 
| +  const int64 service_worker_version_id = 55L; | 
| +  const GURL url("http://example.com/worker.js"); | 
| + | 
| +  // This fails as we have no available process yet. | 
| +  EXPECT_FALSE(worker->Start(service_worker_version_id, url)); | 
| +  EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status()); | 
| + | 
| +  // Simulate adding one process to the worker. | 
| +  worker->AddProcessReference(process_id); | 
| +  embedded_worker_registry()->AddChildProcessSender(process_id, &fake_sender); | 
| + | 
| +  // Start should succeed. | 
| +  EXPECT_TRUE(worker->Start(service_worker_version_id, url)); | 
| +  EXPECT_EQ(EmbeddedWorkerInstance::STARTING, worker->status()); | 
| + | 
| +  // Simulate an upcall from embedded worker to notify that it's started. | 
| +  worker->OnStarted(thread_id); | 
| +  EXPECT_EQ(EmbeddedWorkerInstance::RUNNING, worker->status()); | 
| +  EXPECT_EQ(process_id, worker->process_id()); | 
| +  EXPECT_EQ(thread_id, worker->thread_id()); | 
| + | 
| +  // Stop the worker. | 
| +  EXPECT_TRUE(worker->Stop()); | 
| +  EXPECT_EQ(EmbeddedWorkerInstance::STOPPING, worker->status()); | 
| + | 
| +  // Simulate an upcall from embedded worker to notify that it's stopped. | 
| +  worker->OnStopped(); | 
| +  EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status()); | 
| + | 
| +  // Verify that we've sent two messages to start and terminate the worker. | 
| +  const MessageList& messages = fake_sender.sent_messages(); | 
| +  ASSERT_EQ(2U, messages.size()); | 
| +  ASSERT_EQ(ServiceWorkerMsg_StartWorker::ID, messages[0]->type()); | 
| +  ASSERT_EQ(ServiceWorkerMsg_TerminateWorker::ID, messages[1]->type()); | 
| +} | 
| + | 
| +TEST_F(EmbeddedWorkerInstanceTest, ChooseProcess) { | 
| +  scoped_ptr<EmbeddedWorkerInstance> worker = | 
| +      embedded_worker_registry()->CreateWorker(); | 
| +  EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status()); | 
| + | 
| +  FakeSender fake_sender; | 
| + | 
| +  // Simulate adding processes to the worker. | 
| +  // Process 1 has 1 ref, 2 has 2 refs and 3 has 3 refs. | 
| +  worker->AddProcessReference(1); | 
| +  worker->AddProcessReference(2); | 
| +  worker->AddProcessReference(2); | 
| +  worker->AddProcessReference(3); | 
| +  worker->AddProcessReference(3); | 
| +  worker->AddProcessReference(3); | 
| +  embedded_worker_registry()->AddChildProcessSender(1, &fake_sender); | 
| +  embedded_worker_registry()->AddChildProcessSender(2, &fake_sender); | 
| +  embedded_worker_registry()->AddChildProcessSender(3, &fake_sender); | 
| + | 
| +  // Process 3 has the biggest # of references and it should be chosen. | 
| +  EXPECT_TRUE(worker->Start(1L, GURL("http://example.com/worker.js"))); | 
| +  EXPECT_EQ(EmbeddedWorkerInstance::STARTING, worker->status()); | 
| +  EXPECT_EQ(3, worker->process_id()); | 
| +} | 
| + | 
| +}  // namespace content | 
|  |