Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "base/run_loop.h" | 6 #include "base/run_loop.h" |
| 7 #include "content/browser/service_worker/embedded_worker_registry.h" | 7 #include "content/browser/service_worker/embedded_worker_registry.h" |
| 8 #include "content/browser/service_worker/embedded_worker_test_helper.h" | 8 #include "content/browser/service_worker/embedded_worker_test_helper.h" |
| 9 #include "content/browser/service_worker/service_worker_context_core.h" | 9 #include "content/browser/service_worker/service_worker_context_core.h" |
| 10 #include "content/browser/service_worker/service_worker_registration.h" | 10 #include "content/browser/service_worker/service_worker_registration.h" |
| 11 #include "content/browser/service_worker/service_worker_test_utils.h" | 11 #include "content/browser/service_worker/service_worker_test_utils.h" |
| 12 #include "content/browser/service_worker/service_worker_version.h" | 12 #include "content/browser/service_worker/service_worker_version.h" |
| 13 #include "content/public/test/test_browser_thread_bundle.h" | 13 #include "content/public/test/test_browser_thread_bundle.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 15 |
| 16 // IPC messages for testing --------------------------------------------------- | |
| 17 | |
| 18 #define IPC_MESSAGE_IMPL | |
| 19 #include "ipc/ipc_message_macros.h" | |
| 20 | |
| 21 #define IPC_MESSAGE_START TestMsgStart | |
| 22 | |
| 23 IPC_MESSAGE_CONTROL0(TestMsg_Message); | |
| 24 IPC_MESSAGE_CONTROL1(TestMsg_Request, int); | |
| 25 IPC_MESSAGE_CONTROL1(TestMsg_Response, int); | |
| 26 | |
| 27 // --------------------------------------------------------------------------- | |
| 28 | |
| 16 namespace content { | 29 namespace content { |
| 17 | 30 |
| 31 namespace { | |
| 32 | |
| 33 class MessageReceiver : public EmbeddedWorkerTestHelper { | |
| 34 public: | |
| 35 MessageReceiver(ServiceWorkerContextCore* context) | |
| 36 : EmbeddedWorkerTestHelper(context), | |
| 37 current_embedded_worker_id_(0), | |
| 38 current_request_id_(0) {} | |
| 39 virtual ~MessageReceiver() {} | |
| 40 | |
| 41 virtual void OnSendMessageToWorker(int thread_id, | |
| 42 int embedded_worker_id, | |
| 43 int request_id, | |
| 44 const IPC::Message& message) OVERRIDE { | |
| 45 current_embedded_worker_id_ = embedded_worker_id; | |
| 46 current_request_id_ = request_id; | |
| 47 bool handled = true; | |
| 48 IPC_BEGIN_MESSAGE_MAP(MessageReceiver, message) | |
| 49 IPC_MESSAGE_HANDLER(TestMsg_Message, OnMessage) | |
| 50 IPC_MESSAGE_HANDLER(TestMsg_Request, OnRequest) | |
| 51 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 52 IPC_END_MESSAGE_MAP() | |
| 53 ASSERT_TRUE(handled); | |
| 54 } | |
| 55 | |
| 56 private: | |
| 57 void OnMessage() { | |
| 58 // Do nothing. | |
| 59 } | |
| 60 | |
| 61 void OnRequest(int value) { | |
| 62 // Double the given value and send back the response. | |
| 63 SimulateSendMessageToBrowser(current_embedded_worker_id_, | |
| 64 current_request_id_, | |
| 65 TestMsg_Response(value * 2)); | |
| 66 } | |
| 67 | |
| 68 int current_embedded_worker_id_; | |
| 69 int current_request_id_; | |
| 70 DISALLOW_COPY_AND_ASSIGN(MessageReceiver); | |
| 71 }; | |
| 72 | |
| 73 void ReceiveResponse(ServiceWorkerStatusCode* status_out, | |
| 74 int* value_out, | |
| 75 ServiceWorkerStatusCode status, | |
| 76 const IPC::Message& message) { | |
| 77 Tuple1<int> param; | |
| 78 ASSERT_TRUE(TestMsg_Response::Read(&message, ¶m)); | |
| 79 *status_out = status; | |
| 80 *value_out = param.a; | |
| 81 } | |
| 82 | |
| 83 } // namespace | |
| 84 | |
| 18 class ServiceWorkerVersionTest : public testing::Test { | 85 class ServiceWorkerVersionTest : public testing::Test { |
| 19 protected: | 86 protected: |
| 20 ServiceWorkerVersionTest() | 87 ServiceWorkerVersionTest() |
| 21 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} | 88 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} |
| 22 | 89 |
| 23 virtual void SetUp() OVERRIDE { | 90 virtual void SetUp() OVERRIDE { |
| 24 context_.reset(new ServiceWorkerContextCore(base::FilePath(), NULL)); | 91 context_.reset(new ServiceWorkerContextCore(base::FilePath(), NULL)); |
| 25 helper_.reset(new EmbeddedWorkerTestHelper(context_.get())); | 92 helper_.reset(new MessageReceiver(context_.get())); |
| 26 | 93 |
| 27 registration_ = new ServiceWorkerRegistration( | 94 registration_ = new ServiceWorkerRegistration( |
| 28 GURL("http://www.example.com/*"), | 95 GURL("http://www.example.com/*"), |
| 29 GURL("http://www.example.com/service_worker.js"), | 96 GURL("http://www.example.com/service_worker.js"), |
| 30 1L); | 97 1L); |
| 98 version_ = new ServiceWorkerVersion( | |
| 99 registration_, | |
| 100 embedded_worker_registry(), | |
| 101 1L); | |
| 102 | |
| 103 // Simulate adding one process to the worker. | |
| 104 int embedded_worker_id = version_->embedded_worker()->embedded_worker_id(); | |
| 105 helper_->SimulateAddProcess(embedded_worker_id, 1); | |
| 31 } | 106 } |
| 32 | 107 |
| 33 virtual void TearDown() OVERRIDE { | 108 virtual void TearDown() OVERRIDE { |
| 109 version_->Shutdown(); | |
| 110 version_ = 0; | |
| 34 registration_->Shutdown(); | 111 registration_->Shutdown(); |
| 112 registration_ = 0; | |
| 35 helper_.reset(); | 113 helper_.reset(); |
| 36 context_.reset(); | 114 context_.reset(); |
| 37 } | 115 } |
| 38 | 116 |
| 39 EmbeddedWorkerRegistry* embedded_worker_registry() { | 117 EmbeddedWorkerRegistry* embedded_worker_registry() { |
| 40 return context_->embedded_worker_registry(); | 118 return context_->embedded_worker_registry(); |
| 41 } | 119 } |
| 42 | 120 |
| 43 TestBrowserThreadBundle thread_bundle_; | 121 TestBrowserThreadBundle thread_bundle_; |
| 44 scoped_ptr<ServiceWorkerContextCore> context_; | 122 scoped_ptr<ServiceWorkerContextCore> context_; |
| 45 scoped_ptr<EmbeddedWorkerTestHelper> helper_; | 123 scoped_ptr<EmbeddedWorkerTestHelper> helper_; |
| 46 scoped_refptr<ServiceWorkerRegistration> registration_; | 124 scoped_refptr<ServiceWorkerRegistration> registration_; |
| 125 scoped_refptr<ServiceWorkerVersion> version_; | |
| 47 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionTest); | 126 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerVersionTest); |
| 48 }; | 127 }; |
| 49 | 128 |
| 50 TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) { | 129 TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) { |
| 51 const int64 version_id = 1L; | |
| 52 | |
| 53 scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion( | |
| 54 registration_, | |
| 55 embedded_worker_registry(), | |
| 56 version_id); | |
| 57 int embedded_worker_id = version->embedded_worker()->embedded_worker_id(); | |
| 58 | |
| 59 // Simulate adding one process to the worker. | |
| 60 helper_->SimulateAddProcess(embedded_worker_id, 1); | |
| 61 | |
| 62 BrowserThread::ID current = BrowserThread::IO; | |
| 63 | |
| 64 // Call StartWorker() multiple times. | 130 // Call StartWorker() multiple times. |
| 65 ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED; | 131 ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED; |
| 66 ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED; | 132 ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED; |
| 67 ServiceWorkerStatusCode status3 = SERVICE_WORKER_ERROR_FAILED; | 133 ServiceWorkerStatusCode status3 = SERVICE_WORKER_ERROR_FAILED; |
| 68 version->StartWorker(CreateReceiver(current, base::Closure(), &status1)); | 134 version_->StartWorker(CreateReceiverOnCurrentThread(&status1)); |
| 69 version->StartWorker(CreateReceiver(current, base::Closure(), &status2)); | 135 version_->StartWorker(CreateReceiverOnCurrentThread(&status2)); |
| 70 | 136 |
| 71 EXPECT_EQ(ServiceWorkerVersion::STARTING, version->status()); | 137 EXPECT_EQ(ServiceWorkerVersion::STARTING, version_->status()); |
| 72 base::RunLoop().RunUntilIdle(); | 138 base::RunLoop().RunUntilIdle(); |
| 73 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version->status()); | 139 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->status()); |
| 74 | 140 |
| 75 // Call StartWorker() after it's started. | 141 // Call StartWorker() after it's started. |
| 76 version->StartWorker(CreateReceiver(current, base::Closure(), &status3)); | 142 version_->StartWorker(CreateReceiverOnCurrentThread(&status3)); |
| 77 base::RunLoop().RunUntilIdle(); | 143 base::RunLoop().RunUntilIdle(); |
| 78 | 144 |
| 79 // All should just succeed. | 145 // All should just succeed. |
| 80 EXPECT_EQ(SERVICE_WORKER_OK, status1); | 146 EXPECT_EQ(SERVICE_WORKER_OK, status1); |
| 81 EXPECT_EQ(SERVICE_WORKER_OK, status2); | 147 EXPECT_EQ(SERVICE_WORKER_OK, status2); |
| 82 EXPECT_EQ(SERVICE_WORKER_OK, status3); | 148 EXPECT_EQ(SERVICE_WORKER_OK, status3); |
| 83 | 149 |
| 84 // Call StopWorker() multiple times. | 150 // Call StopWorker() multiple times. |
| 85 status1 = SERVICE_WORKER_ERROR_FAILED; | 151 status1 = SERVICE_WORKER_ERROR_FAILED; |
| 86 status2 = SERVICE_WORKER_ERROR_FAILED; | 152 status2 = SERVICE_WORKER_ERROR_FAILED; |
| 87 status3 = SERVICE_WORKER_ERROR_FAILED; | 153 status3 = SERVICE_WORKER_ERROR_FAILED; |
| 88 version->StopWorker(CreateReceiver(current, base::Closure(), &status1)); | 154 version_->StopWorker(CreateReceiverOnCurrentThread(&status1)); |
| 89 version->StopWorker(CreateReceiver(current, base::Closure(), &status2)); | 155 version_->StopWorker(CreateReceiverOnCurrentThread(&status2)); |
| 90 | 156 |
| 91 // Also try calling StartWorker while StopWorker is in queue. | 157 // Also try calling StartWorker while StopWorker is in queue. |
| 92 version->StartWorker(CreateReceiver(current, base::Closure(), &status3)); | 158 version_->StartWorker(CreateReceiverOnCurrentThread(&status3)); |
| 93 | 159 |
| 94 EXPECT_EQ(ServiceWorkerVersion::STOPPING, version->status()); | 160 EXPECT_EQ(ServiceWorkerVersion::STOPPING, version_->status()); |
| 95 base::RunLoop().RunUntilIdle(); | 161 base::RunLoop().RunUntilIdle(); |
| 96 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version->status()); | 162 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->status()); |
| 97 | 163 |
| 98 // All StopWorker should just succeed, while StartWorker fails. | 164 // All StopWorker should just succeed, while StartWorker fails. |
| 99 EXPECT_EQ(SERVICE_WORKER_OK, status1); | 165 EXPECT_EQ(SERVICE_WORKER_OK, status1); |
| 100 EXPECT_EQ(SERVICE_WORKER_OK, status2); | 166 EXPECT_EQ(SERVICE_WORKER_OK, status2); |
| 101 EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status3); | 167 EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status3); |
| 168 } | |
| 102 | 169 |
| 103 version->Shutdown(); | 170 TEST_F(ServiceWorkerVersionTest, SendMessage) { |
| 171 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->status()); | |
| 172 | |
| 173 // Send a message without starting the worker. | |
| 174 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; | |
| 175 version_->SendMessage(TestMsg_Message(), | |
| 176 CreateReceiverOnCurrentThread(&status)); | |
| 177 base::RunLoop().RunUntilIdle(); | |
| 178 EXPECT_EQ(SERVICE_WORKER_OK, status); | |
| 179 | |
| 180 // The worker should be now started. | |
| 181 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->status()); | |
| 182 | |
| 183 // Stop the worker, and then send the message immediately. | |
| 184 ServiceWorkerStatusCode msg_status = SERVICE_WORKER_ERROR_FAILED; | |
| 185 ServiceWorkerStatusCode stop_status = SERVICE_WORKER_ERROR_FAILED; | |
| 186 version_->StopWorker(CreateReceiverOnCurrentThread(&stop_status)); | |
| 187 version_->SendMessage(TestMsg_Message(), | |
| 188 CreateReceiverOnCurrentThread(&msg_status)); | |
| 189 base::RunLoop().RunUntilIdle(); | |
| 190 EXPECT_EQ(SERVICE_WORKER_OK, stop_status); | |
| 191 | |
| 192 // 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.
| |
| 193 // start a worker while it was stopping. | |
| 194 EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, msg_status); | |
| 195 } | |
| 196 | |
| 197 TEST_F(ServiceWorkerVersionTest, SendMessageAndRegisterCallback) { | |
| 198 // Send multiple messages and verify responses. | |
| 199 ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED; | |
| 200 ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED; | |
| 201 int value1 = -1, value2 = -1; | |
| 202 | |
| 203 version_->SendMessageAndRegisterCallback( | |
| 204 TestMsg_Request(111), | |
| 205 base::Bind(&ReceiveResponse, &status1, &value1)); | |
| 206 version_->SendMessageAndRegisterCallback( | |
| 207 TestMsg_Request(333), | |
| 208 base::Bind(&ReceiveResponse, &status2, &value2)); | |
| 209 base::RunLoop().RunUntilIdle(); | |
| 210 | |
| 211 EXPECT_EQ(SERVICE_WORKER_OK, status1); | |
| 212 EXPECT_EQ(SERVICE_WORKER_OK, status2); | |
| 213 EXPECT_EQ(111 * 2, value1); | |
| 214 EXPECT_EQ(333 * 2, value2); | |
| 104 } | 215 } |
| 105 | 216 |
| 106 } // namespace content | 217 } // namespace content |
| OLD | NEW |