Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: content/browser/service_worker/service_worker_version_unittest.cc

Issue 139923005: Implement ServiceWorkerVersion::SendMessage() (for dispatching events etc) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed comments Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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, &param));
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
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, ReSendMessageAfterStop) {
198 EXPECT_EQ(ServiceWorkerVersion::STOPPED, version_->status());
199
200 // Start the worker.
201 ServiceWorkerStatusCode start_status = SERVICE_WORKER_ERROR_FAILED;
202 version_->StartWorker(CreateReceiverOnCurrentThread(&start_status));
203 base::RunLoop().RunUntilIdle();
204 EXPECT_EQ(SERVICE_WORKER_OK, start_status);
205 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->status());
206
207 // Stop the worker, and then send the message immediately.
208 ServiceWorkerStatusCode msg_status = SERVICE_WORKER_ERROR_FAILED;
209 ServiceWorkerStatusCode stop_status = SERVICE_WORKER_ERROR_FAILED;
210 version_->StopWorker(CreateReceiverOnCurrentThread(&stop_status));
211 version_->SendMessage(TestMsg_Message(),
212 CreateReceiverOnCurrentThread(&msg_status));
213 base::RunLoop().RunUntilIdle();
214 EXPECT_EQ(SERVICE_WORKER_OK, stop_status);
215
216 // SendMessage should return START_WORKER_FAILED error since it tried to
217 // start a worker while it was stopping.
218 EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, msg_status);
219
220 // Resend the message, which should succeed and restart the worker.
221 version_->SendMessage(TestMsg_Message(),
222 CreateReceiverOnCurrentThread(&msg_status));
223 base::RunLoop().RunUntilIdle();
224 EXPECT_EQ(SERVICE_WORKER_OK, msg_status);
225 EXPECT_EQ(ServiceWorkerVersion::RUNNING, version_->status());
226 }
227
228 TEST_F(ServiceWorkerVersionTest, SendMessageAndRegisterCallback) {
229 // Send multiple messages and verify responses.
230 ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED;
231 ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED;
232 int value1 = -1, value2 = -1;
233
234 version_->SendMessageAndRegisterCallback(
235 TestMsg_Request(111),
236 base::Bind(&ReceiveResponse, &status1, &value1));
237 version_->SendMessageAndRegisterCallback(
238 TestMsg_Request(333),
239 base::Bind(&ReceiveResponse, &status2, &value2));
240 base::RunLoop().RunUntilIdle();
241
242 EXPECT_EQ(SERVICE_WORKER_OK, status1);
243 EXPECT_EQ(SERVICE_WORKER_OK, status2);
244 EXPECT_EQ(111 * 2, value1);
245 EXPECT_EQ(333 * 2, value2);
104 } 246 }
105 247
106 } // namespace content 248 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698