Chromium Code Reviews| Index: content/browser/service_worker/service_worker_version_unittest.cc |
| diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc |
| index d2984ca684c3c6dc79c6ea176f8b56724aaff1b5..211c8d9e713abc69ddeff10517021b07d2d876fb 100644 |
| --- a/content/browser/service_worker/service_worker_version_unittest.cc |
| +++ b/content/browser/service_worker/service_worker_version_unittest.cc |
| @@ -13,8 +13,75 @@ |
| #include "content/public/test/test_browser_thread_bundle.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| +// IPC messages for testing --------------------------------------------------- |
| + |
| +#define IPC_MESSAGE_IMPL |
| +#include "ipc/ipc_message_macros.h" |
| + |
| +#define IPC_MESSAGE_START TestMsgStart |
| + |
| +IPC_MESSAGE_CONTROL0(TestMsg_Message); |
| +IPC_MESSAGE_CONTROL1(TestMsg_Request, int); |
| +IPC_MESSAGE_CONTROL1(TestMsg_Response, int); |
| + |
| +// --------------------------------------------------------------------------- |
| + |
| namespace content { |
| +namespace { |
| + |
| +class MessageReceiver : public EmbeddedWorkerTestHelper { |
| + public: |
| + MessageReceiver(ServiceWorkerContextCore* context) |
| + : EmbeddedWorkerTestHelper(context), |
| + current_embedded_worker_id_(0), |
| + current_request_id_(0) {} |
| + virtual ~MessageReceiver() {} |
| + |
| + virtual void OnSendMessageToWorker(int thread_id, |
| + int embedded_worker_id, |
| + int request_id, |
| + const IPC::Message& message) OVERRIDE { |
| + current_embedded_worker_id_ = embedded_worker_id; |
| + current_request_id_ = request_id; |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(MessageReceiver, message) |
| + IPC_MESSAGE_HANDLER(TestMsg_Message, OnMessage) |
| + IPC_MESSAGE_HANDLER(TestMsg_Request, OnRequest) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + ASSERT_TRUE(handled); |
| + } |
| + |
| + private: |
| + void OnMessage() { |
| + // Do nothing. |
| + } |
| + |
| + void OnRequest(int value) { |
| + // Double the given value and send back the response. |
| + SimulateSendMessageToBrowser(current_embedded_worker_id_, |
| + current_request_id_, |
| + TestMsg_Response(value * 2)); |
| + } |
| + |
| + int current_embedded_worker_id_; |
| + int current_request_id_; |
| + DISALLOW_COPY_AND_ASSIGN(MessageReceiver); |
| +}; |
| + |
| +void ReceiveResponse(ServiceWorkerStatusCode* status_out, |
| + int* value_out, |
| + ServiceWorkerStatusCode status, |
| + const IPC::Message& message) { |
| + Tuple1<int> param; |
| + ASSERT_TRUE(TestMsg_Response::Read(&message, ¶m)); |
| + *status_out = status; |
| + *value_out = param.a; |
| +} |
| + |
| +} // namespace |
| + |
| class ServiceWorkerVersionTest : public testing::Test { |
| protected: |
| ServiceWorkerVersionTest() |
| @@ -22,16 +89,27 @@ class ServiceWorkerVersionTest : public testing::Test { |
| virtual void SetUp() OVERRIDE { |
| context_.reset(new ServiceWorkerContextCore(base::FilePath(), NULL)); |
| - helper_.reset(new EmbeddedWorkerTestHelper(context_.get())); |
| + helper_.reset(new MessageReceiver(context_.get())); |
| registration_ = new ServiceWorkerRegistration( |
| GURL("http://www.example.com/*"), |
| GURL("http://www.example.com/service_worker.js"), |
| 1L); |
| + version_ = new ServiceWorkerVersion( |
| + registration_, |
| + embedded_worker_registry(), |
| + 1L); |
| + |
| + // Simulate adding one process to the worker. |
| + int embedded_worker_id = version_->embedded_worker()->embedded_worker_id(); |
| + helper_->SimulateAddProcess(embedded_worker_id, 1); |
| } |
| virtual void TearDown() OVERRIDE { |
| + version_->Shutdown(); |
| + version_ = 0; |
| registration_->Shutdown(); |
| + registration_ = 0; |
| helper_.reset(); |
| context_.reset(); |
| } |
| @@ -44,36 +122,24 @@ class ServiceWorkerVersionTest : public testing::Test { |
| scoped_ptr<ServiceWorkerContextCore> context_; |
| scoped_ptr<EmbeddedWorkerTestHelper> helper_; |
| scoped_refptr<ServiceWorkerRegistration> registration_; |
| + scoped_refptr<ServiceWorkerVersion> version_; |
| DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionTest); |
| }; |
| TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) { |
| - const int64 version_id = 1L; |
| - |
| - scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion( |
| - registration_, |
| - embedded_worker_registry(), |
| - version_id); |
| - int embedded_worker_id = version->embedded_worker()->embedded_worker_id(); |
| - |
| - // Simulate adding one process to the worker. |
| - helper_->SimulateAddProcess(embedded_worker_id, 1); |
| - |
| - BrowserThread::ID current = BrowserThread::IO; |
| - |
| // Call StartWorker() multiple times. |
| ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED; |
| ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED; |
| ServiceWorkerStatusCode status3 = SERVICE_WORKER_ERROR_FAILED; |
| - version->StartWorker(CreateReceiver(current, base::Closure(), &status1)); |
| - version->StartWorker(CreateReceiver(current, base::Closure(), &status2)); |
| + version_->StartWorker(CreateReceiverOnCurrentThread(&status1)); |
| + version_->StartWorker(CreateReceiverOnCurrentThread(&status2)); |
| - EXPECT_EQ(ServiceWorkerVersion::STARTING, version->status()); |
| + EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->status()); |
| base::RunLoop().RunUntilIdle(); |
| - EXPECT_EQ(ServiceWorkerVersion::RUNNING, version->status()); |
| + EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->status()); |
| // Call StartWorker() after it's started. |
| - version->StartWorker(CreateReceiver(current, base::Closure(), &status3)); |
| + version_->StartWorker(CreateReceiverOnCurrentThread(&status3)); |
| base::RunLoop().RunUntilIdle(); |
| // All should just succeed. |
| @@ -85,22 +151,67 @@ TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) { |
| status1 = SERVICE_WORKER_ERROR_FAILED; |
| status2 = SERVICE_WORKER_ERROR_FAILED; |
| status3 = SERVICE_WORKER_ERROR_FAILED; |
| - version->StopWorker(CreateReceiver(current, base::Closure(), &status1)); |
| - version->StopWorker(CreateReceiver(current, base::Closure(), &status2)); |
| + version_->StopWorker(CreateReceiverOnCurrentThread(&status1)); |
| + version_->StopWorker(CreateReceiverOnCurrentThread(&status2)); |
| // Also try calling StartWorker while StopWorker is in queue. |
| - version->StartWorker(CreateReceiver(current, base::Closure(), &status3)); |
| + version_->StartWorker(CreateReceiverOnCurrentThread(&status3)); |
| - EXPECT_EQ(ServiceWorkerVersion::STOPPING, version->status()); |
| + EXPECT_EQ(ServiceWorkerVersion::STOPPING, version_->status()); |
| base::RunLoop().RunUntilIdle(); |
| - EXPECT_EQ(ServiceWorkerVersion::STOPPED, version->status()); |
| + EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->status()); |
| // All StopWorker should just succeed, while StartWorker fails. |
| EXPECT_EQ(SERVICE_WORKER_OK, status1); |
| EXPECT_EQ(SERVICE_WORKER_OK, status2); |
| EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status3); |
| +} |
| + |
| +TEST_F(ServiceWorkerVersionTest, SendMessage) { |
| + EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->status()); |
| + |
| + // Send a message without starting the worker. |
| + ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; |
| + version_->SendMessage(TestMsg_Message(), |
| + CreateReceiverOnCurrentThread(&status)); |
| + base::RunLoop().RunUntilIdle(); |
| + EXPECT_EQ(SERVICE_WORKER_OK, status); |
| + |
| + // The worker should be now started. |
| + EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->status()); |
| + |
| + // Stop the worker, and then send the message immediately. |
| + ServiceWorkerStatusCode msg_status = SERVICE_WORKER_ERROR_FAILED; |
| + ServiceWorkerStatusCode stop_status = SERVICE_WORKER_ERROR_FAILED; |
| + version_->StopWorker(CreateReceiverOnCurrentThread(&stop_status)); |
| + version_->SendMessage(TestMsg_Message(), |
| + CreateReceiverOnCurrentThread(&msg_status)); |
| + base::RunLoop().RunUntilIdle(); |
| + EXPECT_EQ(SERVICE_WORKER_OK, stop_status); |
| + |
| + // SendMessage should return START_WORKER_FAILED error since it tried to |
|
alecflett
2014/02/04 20:53:24
I think you should also add a test for letting the
kinuko
2014/02/04 22:50:24
Done.
|
| + // start a worker while it was stopping. |
| + EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, msg_status); |
| +} |
| - version->Shutdown(); |
| +TEST_F(ServiceWorkerVersionTest, SendMessageAndRegisterCallback) { |
| + // Send multiple messages and verify responses. |
| + ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED; |
| + ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED; |
| + int value1 = -1, value2 = -1; |
| + |
| + version_->SendMessageAndRegisterCallback( |
| + TestMsg_Request(111), |
| + base::Bind(&ReceiveResponse, &status1, &value1)); |
| + version_->SendMessageAndRegisterCallback( |
| + TestMsg_Request(333), |
| + base::Bind(&ReceiveResponse, &status2, &value2)); |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + EXPECT_EQ(SERVICE_WORKER_OK, status1); |
| + EXPECT_EQ(SERVICE_WORKER_OK, status2); |
| + EXPECT_EQ(111 * 2, value1); |
| + EXPECT_EQ(333 * 2, value2); |
| } |
| } // namespace content |