OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "base/stl_util.h" | 7 #include "base/stl_util.h" |
8 #include "content/browser/service_worker/embedded_worker_instance.h" | 8 #include "content/browser/service_worker/embedded_worker_instance.h" |
9 #include "content/browser/service_worker/embedded_worker_registry.h" | 9 #include "content/browser/service_worker/embedded_worker_registry.h" |
10 #include "content/browser/service_worker/embedded_worker_test_helper.h" | 10 #include "content/browser/service_worker/embedded_worker_test_helper.h" |
11 #include "content/browser/service_worker/service_worker_context_core.h" | 11 #include "content/browser/service_worker/service_worker_context_core.h" |
12 #include "content/browser/service_worker/service_worker_context_wrapper.h" | 12 #include "content/browser/service_worker/service_worker_context_wrapper.h" |
13 #include "content/common/service_worker/embedded_worker_messages.h" | 13 #include "content/common/service_worker/embedded_worker_messages.h" |
14 #include "content/public/test/test_browser_thread_bundle.h" | 14 #include "content/public/test/test_browser_thread_bundle.h" |
15 #include "testing/gmock/include/gmock/gmock.h" | 15 #include "testing/gmock/include/gmock/gmock.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
17 | 17 |
18 namespace content { | 18 namespace content { |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 const int kRenderProcessId = 11; | 22 const int kRenderProcessId = 11; |
23 | 23 |
24 void SaveStatus(ServiceWorkerStatusCode* out, ServiceWorkerStatusCode status) { | 24 // Takes a scoped_ptr<>* because the object is passed in via Bind() where Pass() |
25 *out = status; | 25 // cannot be used. |
kinuko (google)
2015/09/10 22:14:19
base::Passed() or base::Owned() works?
falken
2015/09/11 09:48:16
Huh yes... I must have made a mistake on my first
| |
26 void DestroyWorker(scoped_ptr<EmbeddedWorkerInstance>* worker, | |
27 ServiceWorkerStatusCode* out_status, | |
28 ServiceWorkerStatusCode status) { | |
29 *out_status = status; | |
30 worker->reset(); | |
26 } | 31 } |
27 | 32 |
28 void SaveStatusAndCall(ServiceWorkerStatusCode* out, | 33 void SaveStatusAndCall(ServiceWorkerStatusCode* out, |
29 const base::Closure& callback, | 34 const base::Closure& callback, |
30 ServiceWorkerStatusCode status) { | 35 ServiceWorkerStatusCode status) { |
31 *out = status; | 36 *out = status; |
32 callback.Run(); | 37 callback.Run(); |
33 } | 38 } |
34 | 39 |
35 } // namespace | 40 } // namespace |
36 | 41 |
37 class EmbeddedWorkerInstanceTest : public testing::Test, | 42 class EmbeddedWorkerInstanceTest : public testing::Test, |
38 public EmbeddedWorkerInstance::Listener { | 43 public EmbeddedWorkerInstance::Listener { |
39 protected: | 44 protected: |
40 EmbeddedWorkerInstanceTest() | 45 EmbeddedWorkerInstanceTest() |
41 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} | 46 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} |
42 | 47 |
48 void OnStopped(EmbeddedWorkerInstance::Status old_status) override { | |
49 stopped_ = true; | |
50 stopped_old_status_ = old_status; | |
51 } | |
52 | |
43 void OnDetached(EmbeddedWorkerInstance::Status old_status) override { | 53 void OnDetached(EmbeddedWorkerInstance::Status old_status) override { |
44 detached_ = true; | 54 detached_ = true; |
45 detached_old_status_ = old_status; | 55 detached_old_status_ = old_status; |
46 } | 56 } |
47 | 57 |
48 bool OnMessageReceived(const IPC::Message& message) override { return false; } | 58 bool OnMessageReceived(const IPC::Message& message) override { return false; } |
49 | 59 |
50 void SetUp() override { | 60 void SetUp() override { |
51 helper_.reset( | 61 helper_.reset( |
52 new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId)); | 62 new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId)); |
(...skipping 19 matching lines...) Expand all Loading... | |
72 return context()->embedded_worker_registry(); | 82 return context()->embedded_worker_registry(); |
73 } | 83 } |
74 | 84 |
75 IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); } | 85 IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); } |
76 | 86 |
77 TestBrowserThreadBundle thread_bundle_; | 87 TestBrowserThreadBundle thread_bundle_; |
78 scoped_ptr<EmbeddedWorkerTestHelper> helper_; | 88 scoped_ptr<EmbeddedWorkerTestHelper> helper_; |
79 bool detached_ = false; | 89 bool detached_ = false; |
80 EmbeddedWorkerInstance::Status detached_old_status_ = | 90 EmbeddedWorkerInstance::Status detached_old_status_ = |
81 EmbeddedWorkerInstance::STOPPED; | 91 EmbeddedWorkerInstance::STOPPED; |
92 bool stopped_ = false; | |
93 EmbeddedWorkerInstance::Status stopped_old_status_ = | |
94 EmbeddedWorkerInstance::STOPPED; | |
82 | 95 |
83 private: | 96 private: |
84 DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceTest); | 97 DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceTest); |
85 }; | 98 }; |
86 | 99 |
100 class FailToSendIPCHelper : public EmbeddedWorkerTestHelper { | |
101 public: | |
102 FailToSendIPCHelper() | |
103 : EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId) {} | |
104 ~FailToSendIPCHelper() override {} | |
105 bool Send(IPC::Message* message) override { return false; } | |
106 }; | |
107 | |
87 TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) { | 108 TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) { |
88 scoped_ptr<EmbeddedWorkerInstance> worker = | 109 scoped_ptr<EmbeddedWorkerInstance> worker = |
89 embedded_worker_registry()->CreateWorker(); | 110 embedded_worker_registry()->CreateWorker(); |
90 EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status()); | 111 EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status()); |
91 | 112 |
92 const int64 service_worker_version_id = 55L; | 113 const int64 service_worker_version_id = 55L; |
93 const GURL pattern("http://example.com/"); | 114 const GURL pattern("http://example.com/"); |
94 const GURL url("http://example.com/worker.js"); | 115 const GURL url("http://example.com/worker.js"); |
95 | 116 |
96 // Simulate adding one process to the pattern. | 117 // Simulate adding one process to the pattern. |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
221 EmbeddedWorkerRegistry* registry = | 242 EmbeddedWorkerRegistry* registry = |
222 helper_->context()->embedded_worker_registry(); | 243 helper_->context()->embedded_worker_registry(); |
223 EXPECT_EQ(0UL, | 244 EXPECT_EQ(0UL, |
224 registry->worker_process_map_[kRenderProcessId].count(worker1_id)); | 245 registry->worker_process_map_[kRenderProcessId].count(worker1_id)); |
225 EXPECT_EQ(1UL, registry->worker_process_map_[kRenderProcessId].count( | 246 EXPECT_EQ(1UL, registry->worker_process_map_[kRenderProcessId].count( |
226 worker2->embedded_worker_id())); | 247 worker2->embedded_worker_id())); |
227 | 248 |
228 worker2->Stop(); | 249 worker2->Stop(); |
229 } | 250 } |
230 | 251 |
231 // Test detaching in the middle of the start worker sequence. | 252 // Test detaching in the middle of the start worker sequence. Additionally, have |
253 // the start callback destroy the worker, as is usual when starting a worker | |
254 // fails, and ensure a crash doesn't occur. | |
232 TEST_F(EmbeddedWorkerInstanceTest, DetachDuringStart) { | 255 TEST_F(EmbeddedWorkerInstanceTest, DetachDuringStart) { |
233 scoped_ptr<EmbeddedWorkerInstance> worker = | 256 scoped_ptr<EmbeddedWorkerInstance> worker = |
234 embedded_worker_registry()->CreateWorker(); | 257 embedded_worker_registry()->CreateWorker(); |
235 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( | 258 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( |
236 new EmbeddedWorkerMsg_StartWorker_Params()); | 259 new EmbeddedWorkerMsg_StartWorker_Params()); |
237 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; | 260 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; |
261 | |
238 // Pretend we had a process allocated but then got detached before | 262 // Pretend we had a process allocated but then got detached before |
239 // the start sequence reached SendStartWorker. | 263 // the start sequence reached SendStartWorker. |
240 worker->process_id_ = -1; | 264 worker->status_ = EmbeddedWorkerInstance::STOPPED; |
241 worker->SendStartWorker(params.Pass(), base::Bind(&SaveStatus, &status), true, | 265 worker->SendStartWorker(params.Pass(), |
266 base::Bind(&DestroyWorker, &worker, &status), true, | |
242 -1, false); | 267 -1, false); |
268 // The callback destroys the worker, but we shouldn't have crashed. | |
243 EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status); | 269 EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status); |
244 } | 270 } |
245 | 271 |
246 // Test stopping in the middle of the start worker sequence, before | 272 // Test stopping in the middle of the start worker sequence, before |
247 // a process is allocated. | 273 // a process is allocated. |
248 TEST_F(EmbeddedWorkerInstanceTest, StopDuringStart) { | 274 TEST_F(EmbeddedWorkerInstanceTest, StopDuringStart) { |
249 scoped_ptr<EmbeddedWorkerInstance> worker = | 275 scoped_ptr<EmbeddedWorkerInstance> worker = |
250 embedded_worker_registry()->CreateWorker(); | 276 embedded_worker_registry()->CreateWorker(); |
251 worker->AddListener(this); | 277 worker->AddListener(this); |
252 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( | |
253 new EmbeddedWorkerMsg_StartWorker_Params()); | |
254 // Pretend we stop during starting before we got a process allocated. | 278 // Pretend we stop during starting before we got a process allocated. |
255 worker->status_ = EmbeddedWorkerInstance::STARTING; | 279 worker->status_ = EmbeddedWorkerInstance::STARTING; |
256 worker->process_id_ = -1; | 280 worker->process_id_ = -1; |
257 worker->Stop(); | 281 worker->Stop(); |
258 EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status()); | 282 EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status()); |
259 EXPECT_TRUE(detached_); | 283 EXPECT_TRUE(detached_); |
260 EXPECT_EQ(EmbeddedWorkerInstance::STARTING, detached_old_status_); | 284 EXPECT_EQ(EmbeddedWorkerInstance::STARTING, detached_old_status_); |
261 } | 285 } |
262 | 286 |
287 // Test for when sending the start IPC failed. | |
288 TEST_F(EmbeddedWorkerInstanceTest, FailToSendStartIPC) { | |
289 helper_.reset(new FailToSendIPCHelper()); | |
290 | |
291 const int64 version_id = 55L; | |
292 const GURL pattern("http://example.com/"); | |
293 const GURL url("http://example.com/worker.js"); | |
294 | |
295 scoped_ptr<EmbeddedWorkerInstance> worker = | |
296 embedded_worker_registry()->CreateWorker(); | |
297 helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId); | |
298 ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED; | |
299 worker->AddListener(this); | |
300 | |
301 // Attempt to start the worker. | |
302 base::RunLoop run_loop; | |
303 worker->Start( | |
304 version_id, pattern, url, | |
305 base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure())); | |
306 run_loop.Run(); | |
307 | |
308 // The callback should have run, and we should have got an OnStopped message. | |
309 EXPECT_EQ(SERVICE_WORKER_ERROR_IPC_FAILED, status); | |
310 EXPECT_TRUE(stopped_); | |
311 EXPECT_EQ(EmbeddedWorkerInstance::STARTING, stopped_old_status_); | |
312 } | |
313 | |
263 } // namespace content | 314 } // namespace content |
OLD | NEW |