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 |