OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/bind.h" | 6 #include "base/bind.h" |
7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/win/scoped_handle.h" | 9 #include "base/win/scoped_handle.h" |
10 #include "ipc/ipc_channel.h" | 10 #include "ipc/ipc_channel.h" |
11 #include "ipc/ipc_channel_proxy.h" | 11 #include "ipc/ipc_channel_proxy.h" |
12 #include "ipc/ipc_listener.h" | 12 #include "ipc/ipc_listener.h" |
13 #include "ipc/ipc_message.h" | 13 #include "ipc/ipc_message.h" |
14 #include "remoting/base/auto_thread_task_runner.h" | 14 #include "remoting/base/auto_thread_task_runner.h" |
| 15 #include "remoting/host/chromoting_messages.h" |
15 #include "remoting/host/host_exit_codes.h" | 16 #include "remoting/host/host_exit_codes.h" |
16 #include "remoting/host/win/launch_process_with_token.h" | 17 #include "remoting/host/win/launch_process_with_token.h" |
17 #include "remoting/host/win/worker_process_launcher.h" | 18 #include "remoting/host/win/worker_process_launcher.h" |
18 #include "remoting/host/worker_process_ipc_delegate.h" | 19 #include "remoting/host/worker_process_ipc_delegate.h" |
| 20 #include "testing/gmock/include/gmock/gmock.h" |
19 #include "testing/gmock_mutant.h" | 21 #include "testing/gmock_mutant.h" |
20 #include "testing/gmock/include/gmock/gmock.h" | |
21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
22 | 23 |
23 using base::win::ScopedHandle; | 24 using base::win::ScopedHandle; |
24 using testing::_; | 25 using testing::_; |
25 using testing::AnyNumber; | 26 using testing::AnyNumber; |
26 using testing::CreateFunctor; | 27 using testing::CreateFunctor; |
27 using testing::DoAll; | 28 using testing::DoAll; |
28 using testing::Expectation; | 29 using testing::Expectation; |
29 using testing::Invoke; | 30 using testing::Invoke; |
30 using testing::InvokeWithoutArgs; | 31 using testing::InvokeWithoutArgs; |
31 using testing::Return; | 32 using testing::Return; |
32 using testing::ReturnPointee; | 33 using testing::ReturnPointee; |
33 | 34 |
34 namespace remoting { | 35 namespace remoting { |
35 | 36 |
36 namespace { | 37 namespace { |
37 | 38 |
38 const char kIpcSecurityDescriptor[] = "D:(A;;GA;;;AU)"; | 39 const char kIpcSecurityDescriptor[] = "D:(A;;GA;;;AU)"; |
39 | 40 |
40 class MockProcessLauncherDelegate | 41 class MockProcessLauncherDelegate : public WorkerProcessLauncher::Delegate { |
41 : public WorkerProcessLauncher::Delegate { | |
42 public: | 42 public: |
43 MockProcessLauncherDelegate() {} | 43 MockProcessLauncherDelegate() {} |
44 virtual ~MockProcessLauncherDelegate() {} | 44 virtual ~MockProcessLauncherDelegate() {} |
45 | 45 |
46 virtual DWORD GetProcessId() const OVERRIDE { | |
47 return const_cast<MockProcessLauncherDelegate*>(this)->GetProcessId(); | |
48 } | |
49 | |
50 virtual bool IsPermanentError(int failure_count) const OVERRIDE { | |
51 return const_cast<MockProcessLauncherDelegate*>(this)->IsPermanentError( | |
52 failure_count); | |
53 } | |
54 | |
55 // IPC::Sender implementation. | 46 // IPC::Sender implementation. |
56 MOCK_METHOD1(Send, bool(IPC::Message*)); | 47 MOCK_METHOD1(Send, bool(IPC::Message*)); |
57 | 48 |
58 // WorkerProcessLauncher::Delegate implementation | 49 // WorkerProcessLauncher::Delegate interface. |
59 MOCK_METHOD0(GetProcessId, DWORD()); | 50 MOCK_METHOD0(CloseChannel, void()); |
60 MOCK_METHOD1(IsPermanentError, bool(int)); | 51 MOCK_CONST_METHOD0(GetProcessId, DWORD()); |
| 52 MOCK_CONST_METHOD1(IsPermanentError, bool(int)); |
61 MOCK_METHOD1(KillProcess, void(DWORD)); | 53 MOCK_METHOD1(KillProcess, void(DWORD)); |
62 MOCK_METHOD2(LaunchProcess, bool(IPC::Listener*, ScopedHandle*)); | 54 MOCK_METHOD2(LaunchProcess, bool(IPC::Listener*, ScopedHandle*)); |
63 | 55 |
64 private: | 56 private: |
65 DISALLOW_COPY_AND_ASSIGN(MockProcessLauncherDelegate); | 57 DISALLOW_COPY_AND_ASSIGN(MockProcessLauncherDelegate); |
66 }; | 58 }; |
67 | 59 |
68 class MockIpcDelegate | 60 class MockIpcDelegate : public WorkerProcessIpcDelegate { |
69 : public WorkerProcessIpcDelegate { | |
70 public: | 61 public: |
71 MockIpcDelegate() {} | 62 MockIpcDelegate() {} |
72 virtual ~MockIpcDelegate() {} | 63 virtual ~MockIpcDelegate() {} |
73 | 64 |
74 // WorkerProcessIpcDelegate implementation | 65 // WorkerProcessIpcDelegate interface. |
75 MOCK_METHOD1(OnChannelConnected, void(int32)); | 66 MOCK_METHOD1(OnChannelConnected, void(int32)); |
76 MOCK_METHOD1(OnMessageReceived, bool(const IPC::Message&)); | 67 MOCK_METHOD1(OnMessageReceived, bool(const IPC::Message&)); |
77 MOCK_METHOD0(OnPermanentError, void()); | 68 MOCK_METHOD0(OnPermanentError, void()); |
78 | 69 |
79 private: | 70 private: |
80 DISALLOW_COPY_AND_ASSIGN(MockIpcDelegate); | 71 DISALLOW_COPY_AND_ASSIGN(MockIpcDelegate); |
81 }; | 72 }; |
82 | 73 |
| 74 class MockWorkerListener : public IPC::Listener { |
| 75 public: |
| 76 MockWorkerListener() {} |
| 77 virtual ~MockWorkerListener() {} |
| 78 |
| 79 MOCK_METHOD3(OnCrash, void(const std::string&, const std::string&, int)); |
| 80 |
| 81 // IPC::Listener implementation |
| 82 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
| 83 |
| 84 private: |
| 85 DISALLOW_COPY_AND_ASSIGN(MockWorkerListener); |
| 86 }; |
| 87 |
| 88 bool MockWorkerListener::OnMessageReceived(const IPC::Message& message) { |
| 89 bool handled = true; |
| 90 IPC_BEGIN_MESSAGE_MAP(MockWorkerListener, message) |
| 91 IPC_MESSAGE_HANDLER(ChromotingDaemonMsg_Crash, OnCrash) |
| 92 IPC_MESSAGE_UNHANDLED(handled = false) |
| 93 IPC_END_MESSAGE_MAP() |
| 94 |
| 95 EXPECT_TRUE(handled); |
| 96 |
| 97 return handled; |
| 98 } |
| 99 |
83 } // namespace | 100 } // namespace |
84 | 101 |
85 class WorkerProcessLauncherTest | 102 class WorkerProcessLauncherTest : public testing::Test { |
86 : public testing::Test, | |
87 public IPC::Listener { | |
88 public: | 103 public: |
89 WorkerProcessLauncherTest(); | 104 WorkerProcessLauncherTest(); |
90 virtual ~WorkerProcessLauncherTest(); | 105 virtual ~WorkerProcessLauncherTest(); |
91 | 106 |
92 virtual void SetUp() OVERRIDE; | 107 virtual void SetUp() OVERRIDE; |
93 virtual void TearDown() OVERRIDE; | 108 virtual void TearDown() OVERRIDE; |
94 | 109 |
95 // IPC::Listener implementation | |
96 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; | |
97 | |
98 // WorkerProcessLauncher::Delegate mocks | 110 // WorkerProcessLauncher::Delegate mocks |
99 void KillProcess(DWORD exit_code); | 111 void KillProcess(DWORD exit_code); |
100 bool LaunchProcess(IPC::Listener* delegate, | 112 bool LaunchProcess(IPC::Listener* delegate, |
101 ScopedHandle* process_exit_event_out); | 113 ScopedHandle* process_exit_event_out); |
102 bool LaunchProcessAndConnect(IPC::Listener* delegate, | 114 bool LaunchProcessAndConnect(IPC::Listener* delegate, |
103 ScopedHandle* process_exit_event_out); | 115 ScopedHandle* process_exit_event_out); |
104 bool FailLaunchAndStopWorker(IPC::Listener* delegate, | 116 bool FailLaunchAndStopWorker(IPC::Listener* delegate, |
105 ScopedHandle* process_exit_event_out); | 117 ScopedHandle* process_exit_event_out); |
106 | 118 |
107 void ConnectChannel(); | 119 // Connects the client end of the channel (the worker process's end). |
108 void DisconnectChannel(); | 120 void ConnectClient(); |
| 121 |
| 122 // Disconnects the client end of the channel. |
| 123 void DisconnectClient(); |
| 124 |
| 125 // Disconnects the server end of the channel (the launcher's end). |
| 126 void DisconnectServer(); |
| 127 |
| 128 // Sends a message to the worker process. |
| 129 bool SendToProcess(IPC::Message* message); |
| 130 |
| 131 // Sends a fake message to the launcher. |
| 132 void SendFakeMessageToLauncher(); |
| 133 |
| 134 // Requests the worker to crash. |
| 135 void CrashWorker(); |
109 | 136 |
110 // Starts the worker. | 137 // Starts the worker. |
111 void StartWorker(); | 138 void StartWorker(); |
112 | 139 |
113 // Stops the worker. | 140 // Stops the worker. |
114 void StopWorker(); | 141 void StopWorker(); |
115 | 142 |
116 // Quits |message_loop_|. | 143 // Quits |message_loop_|. |
117 void QuitMainMessageLoop(); | 144 void QuitMainMessageLoop(); |
118 | 145 |
119 protected: | 146 protected: |
120 MessageLoop message_loop_; | 147 MessageLoop message_loop_; |
121 scoped_refptr<AutoThreadTaskRunner> task_runner_; | 148 scoped_refptr<AutoThreadTaskRunner> task_runner_; |
122 | 149 |
123 MockIpcDelegate ipc_delegate_; | 150 // Receives messages sent to the worker process. |
| 151 MockWorkerListener client_listener_; |
| 152 |
| 153 // Receives messages sent from the worker process. |
| 154 MockIpcDelegate server_listener_; |
| 155 |
| 156 // Implements WorkerProcessLauncher::Delegate. |
124 scoped_ptr<MockProcessLauncherDelegate> launcher_delegate_; | 157 scoped_ptr<MockProcessLauncherDelegate> launcher_delegate_; |
125 | 158 |
126 // The name of the IPC channel. | 159 // The name of the IPC channel. |
127 std::string channel_name_; | 160 std::string channel_name_; |
128 | 161 |
129 // Client and server ends of the IPC channel. | 162 // Client and server ends of the IPC channel. |
130 scoped_ptr<IPC::ChannelProxy> channel_client_; | 163 scoped_ptr<IPC::ChannelProxy> channel_client_; |
131 scoped_ptr<IPC::ChannelProxy> channel_server_; | 164 scoped_ptr<IPC::ChannelProxy> channel_server_; |
132 | 165 |
133 // Returned as the worker process PID to the launcher. | 166 // Returned as the worker process PID to the launcher. |
(...skipping 22 matching lines...) Expand all Loading... |
156 void WorkerProcessLauncherTest::SetUp() { | 189 void WorkerProcessLauncherTest::SetUp() { |
157 task_runner_ = new AutoThreadTaskRunner( | 190 task_runner_ = new AutoThreadTaskRunner( |
158 message_loop_.message_loop_proxy(), | 191 message_loop_.message_loop_proxy(), |
159 base::Bind(&WorkerProcessLauncherTest::QuitMainMessageLoop, | 192 base::Bind(&WorkerProcessLauncherTest::QuitMainMessageLoop, |
160 base::Unretained(this))); | 193 base::Unretained(this))); |
161 | 194 |
162 // Set up process launcher delegate | 195 // Set up process launcher delegate |
163 launcher_delegate_.reset(new MockProcessLauncherDelegate()); | 196 launcher_delegate_.reset(new MockProcessLauncherDelegate()); |
164 EXPECT_CALL(*launcher_delegate_, Send(_)) | 197 EXPECT_CALL(*launcher_delegate_, Send(_)) |
165 .Times(AnyNumber()) | 198 .Times(AnyNumber()) |
166 .WillRepeatedly(Return(false)); | 199 .WillRepeatedly(Invoke(this, &WorkerProcessLauncherTest::SendToProcess)); |
| 200 EXPECT_CALL(*launcher_delegate_, CloseChannel()) |
| 201 .Times(AnyNumber()) |
| 202 .WillRepeatedly(Invoke(this, |
| 203 &WorkerProcessLauncherTest::DisconnectServer)); |
167 EXPECT_CALL(*launcher_delegate_, GetProcessId()) | 204 EXPECT_CALL(*launcher_delegate_, GetProcessId()) |
168 .Times(AnyNumber()) | 205 .Times(AnyNumber()) |
169 .WillRepeatedly(ReturnPointee(&client_pid_)); | 206 .WillRepeatedly(ReturnPointee(&client_pid_)); |
170 EXPECT_CALL(*launcher_delegate_, IsPermanentError(_)) | 207 EXPECT_CALL(*launcher_delegate_, IsPermanentError(_)) |
171 .Times(AnyNumber()) | 208 .Times(AnyNumber()) |
172 .WillRepeatedly(ReturnPointee(&permanent_error_)); | 209 .WillRepeatedly(ReturnPointee(&permanent_error_)); |
173 EXPECT_CALL(*launcher_delegate_, KillProcess(_)) | 210 EXPECT_CALL(*launcher_delegate_, KillProcess(_)) |
174 .Times(AnyNumber()) | 211 .Times(AnyNumber()) |
175 .WillRepeatedly(Invoke(this, &WorkerProcessLauncherTest::KillProcess)); | 212 .WillRepeatedly(Invoke(this, &WorkerProcessLauncherTest::KillProcess)); |
176 | 213 |
177 // Set up IPC delegate. | 214 // Set up IPC delegate. |
178 EXPECT_CALL(ipc_delegate_, OnMessageReceived(_)) | 215 EXPECT_CALL(server_listener_, OnMessageReceived(_)) |
179 .Times(AnyNumber()) | 216 .Times(0); |
180 .WillRepeatedly(Return(false)); | |
181 } | 217 } |
182 | 218 |
183 void WorkerProcessLauncherTest::TearDown() { | 219 void WorkerProcessLauncherTest::TearDown() { |
184 } | 220 } |
185 | 221 |
186 bool WorkerProcessLauncherTest::OnMessageReceived(const IPC::Message& message) { | |
187 return false; | |
188 } | |
189 | |
190 void WorkerProcessLauncherTest::KillProcess(DWORD exit_code) { | 222 void WorkerProcessLauncherTest::KillProcess(DWORD exit_code) { |
191 BOOL result = SetEvent(process_exit_event_); | 223 BOOL result = SetEvent(process_exit_event_); |
192 EXPECT_TRUE(result); | 224 EXPECT_TRUE(result); |
193 } | 225 } |
194 | 226 |
195 bool WorkerProcessLauncherTest::LaunchProcess( | 227 bool WorkerProcessLauncherTest::LaunchProcess( |
196 IPC::Listener* delegate, | 228 IPC::Listener* delegate, |
197 ScopedHandle* process_exit_event_out) { | 229 ScopedHandle* process_exit_event_out) { |
198 process_exit_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL)); | 230 process_exit_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL)); |
199 if (!process_exit_event_.IsValid()) | 231 if (!process_exit_event_.IsValid()) |
(...skipping 22 matching lines...) Expand all Loading... |
222 } | 254 } |
223 | 255 |
224 bool WorkerProcessLauncherTest::LaunchProcessAndConnect( | 256 bool WorkerProcessLauncherTest::LaunchProcessAndConnect( |
225 IPC::Listener* delegate, | 257 IPC::Listener* delegate, |
226 ScopedHandle* process_exit_event_out) { | 258 ScopedHandle* process_exit_event_out) { |
227 if (!LaunchProcess(delegate, process_exit_event_out)) | 259 if (!LaunchProcess(delegate, process_exit_event_out)) |
228 return false; | 260 return false; |
229 | 261 |
230 task_runner_->PostTask( | 262 task_runner_->PostTask( |
231 FROM_HERE, | 263 FROM_HERE, |
232 base::Bind(&WorkerProcessLauncherTest::ConnectChannel, | 264 base::Bind(&WorkerProcessLauncherTest::ConnectClient, |
233 base::Unretained(this))); | 265 base::Unretained(this))); |
234 return true; | 266 return true; |
235 } | 267 } |
236 | 268 |
237 bool WorkerProcessLauncherTest::FailLaunchAndStopWorker( | 269 bool WorkerProcessLauncherTest::FailLaunchAndStopWorker( |
238 IPC::Listener* delegate, | 270 IPC::Listener* delegate, |
239 ScopedHandle* process_exit_event_out) { | 271 ScopedHandle* process_exit_event_out) { |
240 task_runner_->PostTask( | 272 task_runner_->PostTask( |
241 FROM_HERE, | 273 FROM_HERE, |
242 base::Bind(&WorkerProcessLauncherTest::StopWorker, | 274 base::Bind(&WorkerProcessLauncherTest::StopWorker, |
243 base::Unretained(this))); | 275 base::Unretained(this))); |
244 return false; | 276 return false; |
245 } | 277 } |
246 | 278 |
247 void WorkerProcessLauncherTest::ConnectChannel() { | 279 void WorkerProcessLauncherTest::ConnectClient() { |
248 channel_client_.reset(new IPC::ChannelProxy( | 280 channel_client_.reset(new IPC::ChannelProxy( |
249 IPC::ChannelHandle(channel_name_), | 281 IPC::ChannelHandle(channel_name_), |
250 IPC::Channel::MODE_CLIENT, | 282 IPC::Channel::MODE_CLIENT, |
251 this, | 283 &client_listener_, |
252 task_runner_)); | 284 task_runner_)); |
| 285 |
| 286 // Pretend that |kLaunchSuccessTimeoutSeconds| passed since launching |
| 287 // the worker process. This will make the backoff algorithm think that this |
| 288 // launch attempt was successful and it will not delay the next launch. |
| 289 launcher_->ResetLaunchSuccessTimeoutForTest(); |
253 } | 290 } |
254 | 291 |
255 void WorkerProcessLauncherTest::DisconnectChannel() { | 292 void WorkerProcessLauncherTest::DisconnectClient() { |
256 channel_client_.reset(); | 293 channel_client_.reset(); |
257 } | 294 } |
258 | 295 |
| 296 void WorkerProcessLauncherTest::DisconnectServer() { |
| 297 channel_server_.reset(); |
| 298 } |
| 299 |
| 300 bool WorkerProcessLauncherTest::SendToProcess(IPC::Message* message) { |
| 301 if (channel_server_) |
| 302 return channel_server_->Send(message); |
| 303 |
| 304 delete message; |
| 305 return false; |
| 306 } |
| 307 |
| 308 void WorkerProcessLauncherTest::SendFakeMessageToLauncher() { |
| 309 if (channel_client_) |
| 310 channel_client_->Send(new ChromotingDesktopNetworkMsg_DisconnectSession()); |
| 311 } |
| 312 |
| 313 void WorkerProcessLauncherTest::CrashWorker() { |
| 314 launcher_->Crash(FROM_HERE); |
| 315 } |
| 316 |
259 void WorkerProcessLauncherTest::StartWorker() { | 317 void WorkerProcessLauncherTest::StartWorker() { |
260 launcher_.reset(new WorkerProcessLauncher( | 318 launcher_.reset(new WorkerProcessLauncher( |
261 task_runner_, launcher_delegate_.Pass(), &ipc_delegate_)); | 319 task_runner_, launcher_delegate_.Pass(), &server_listener_)); |
| 320 |
| 321 launcher_->SetKillProcessTimeoutForTest(base::TimeDelta::FromMilliseconds(0)); |
262 } | 322 } |
263 | 323 |
264 void WorkerProcessLauncherTest::StopWorker() { | 324 void WorkerProcessLauncherTest::StopWorker() { |
265 launcher_.reset(); | 325 launcher_.reset(); |
266 DisconnectChannel(); | 326 DisconnectClient(); |
267 channel_name_.clear(); | 327 channel_name_.clear(); |
268 channel_server_.reset(); | 328 channel_server_.reset(); |
269 task_runner_ = NULL; | 329 task_runner_ = NULL; |
270 } | 330 } |
271 | 331 |
272 void WorkerProcessLauncherTest::QuitMainMessageLoop() { | 332 void WorkerProcessLauncherTest::QuitMainMessageLoop() { |
273 message_loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure()); | 333 message_loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
274 } | 334 } |
275 | 335 |
276 TEST_F(WorkerProcessLauncherTest, Start) { | 336 TEST_F(WorkerProcessLauncherTest, Start) { |
277 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) | 337 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) |
278 .Times(1) | 338 .Times(1) |
279 .WillRepeatedly(Invoke(this, &WorkerProcessLauncherTest::LaunchProcess)); | 339 .WillRepeatedly(Invoke(this, &WorkerProcessLauncherTest::LaunchProcess)); |
280 | 340 |
281 EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) | 341 EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
282 .Times(0); | 342 .Times(0); |
283 EXPECT_CALL(ipc_delegate_, OnPermanentError()) | 343 EXPECT_CALL(server_listener_, OnPermanentError()) |
284 .Times(0); | 344 .Times(0); |
285 | 345 |
286 StartWorker(); | 346 StartWorker(); |
287 StopWorker(); | 347 StopWorker(); |
288 message_loop_.Run(); | 348 message_loop_.Run(); |
289 } | 349 } |
290 | 350 |
291 // Starts and connects to the worker process. Expect OnChannelConnected to be | 351 // Starts and connects to the worker process. Expect OnChannelConnected to be |
292 // called. | 352 // called. |
293 TEST_F(WorkerProcessLauncherTest, StartAndConnect) { | 353 TEST_F(WorkerProcessLauncherTest, StartAndConnect) { |
294 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) | 354 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) |
295 .Times(1) | 355 .Times(1) |
296 .WillRepeatedly(Invoke( | 356 .WillRepeatedly(Invoke( |
297 this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); | 357 this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); |
298 | 358 |
299 EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) | 359 EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
300 .Times(1) | 360 .Times(1) |
301 .WillOnce(InvokeWithoutArgs(this, | 361 .WillOnce(InvokeWithoutArgs(this, |
302 &WorkerProcessLauncherTest::StopWorker)); | 362 &WorkerProcessLauncherTest::StopWorker)); |
303 EXPECT_CALL(ipc_delegate_, OnPermanentError()) | 363 EXPECT_CALL(server_listener_, OnPermanentError()) |
304 .Times(0); | 364 .Times(0); |
305 | 365 |
306 StartWorker(); | 366 StartWorker(); |
307 message_loop_.Run(); | 367 message_loop_.Run(); |
308 } | 368 } |
309 | 369 |
310 // Kills the worker process after the 1st connect and expects it to be | 370 // Kills the worker process after the 1st connect and expects it to be |
311 // restarted. | 371 // restarted. |
312 TEST_F(WorkerProcessLauncherTest, Restart) { | 372 TEST_F(WorkerProcessLauncherTest, Restart) { |
313 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) | 373 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) |
314 .Times(2) | 374 .Times(2) |
315 .WillRepeatedly(Invoke( | 375 .WillRepeatedly(Invoke( |
316 this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); | 376 this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); |
317 Expectation first_connect = | 377 Expectation first_connect = |
318 EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) | 378 EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
319 .Times(2) | 379 .Times(2) |
320 .WillOnce(InvokeWithoutArgs(CreateFunctor( | 380 .WillOnce(InvokeWithoutArgs(CreateFunctor( |
321 this, &WorkerProcessLauncherTest::KillProcess, CONTROL_C_EXIT))) | 381 this, &WorkerProcessLauncherTest::KillProcess, CONTROL_C_EXIT))) |
322 .WillOnce(InvokeWithoutArgs(this, | 382 .WillOnce(InvokeWithoutArgs(this, |
323 &WorkerProcessLauncherTest::StopWorker)); | 383 &WorkerProcessLauncherTest::StopWorker)); |
324 | 384 |
325 EXPECT_CALL(ipc_delegate_, OnPermanentError()) | 385 EXPECT_CALL(server_listener_, OnPermanentError()) |
326 .Times(0); | 386 .Times(0); |
327 | 387 |
328 StartWorker(); | 388 StartWorker(); |
329 message_loop_.Run(); | 389 message_loop_.Run(); |
330 } | 390 } |
331 | 391 |
332 // Drops the IPC channel to the worker process after the 1st connect and expects | 392 // Drops the IPC channel to the worker process after the 1st connect and expects |
333 // the worker process to be restarted. | 393 // the worker process to be restarted. |
334 TEST_F(WorkerProcessLauncherTest, DropIpcChannel) { | 394 TEST_F(WorkerProcessLauncherTest, DropIpcChannel) { |
335 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) | 395 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) |
336 .Times(2) | 396 .Times(2) |
337 .WillRepeatedly(Invoke( | 397 .WillRepeatedly(Invoke( |
338 this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); | 398 this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); |
339 | 399 |
340 Expectation first_connect = | 400 Expectation first_connect = |
341 EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) | 401 EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
342 .Times(2) | 402 .Times(2) |
343 .WillOnce(InvokeWithoutArgs( | 403 .WillOnce(InvokeWithoutArgs( |
344 this, &WorkerProcessLauncherTest::DisconnectChannel)) | 404 this, &WorkerProcessLauncherTest::DisconnectClient)) |
345 .WillOnce(InvokeWithoutArgs( | 405 .WillOnce(InvokeWithoutArgs( |
346 this, &WorkerProcessLauncherTest::StopWorker)); | 406 this, &WorkerProcessLauncherTest::StopWorker)); |
347 | 407 |
348 EXPECT_CALL(ipc_delegate_, OnPermanentError()) | 408 EXPECT_CALL(server_listener_, OnPermanentError()) |
349 .Times(0); | 409 .Times(0); |
350 | 410 |
351 StartWorker(); | 411 StartWorker(); |
352 message_loop_.Run(); | 412 message_loop_.Run(); |
353 } | 413 } |
354 | 414 |
355 // Returns a permanent error exit code and expects OnPermanentError() to be | 415 // Returns a permanent error exit code and expects OnPermanentError() to be |
356 // invoked. | 416 // invoked. |
357 TEST_F(WorkerProcessLauncherTest, PermanentError) { | 417 TEST_F(WorkerProcessLauncherTest, PermanentError) { |
358 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) | 418 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) |
359 .Times(1) | 419 .Times(1) |
360 .WillRepeatedly(Invoke( | 420 .WillRepeatedly(Invoke( |
361 this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); | 421 this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); |
362 | 422 |
363 EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) | 423 EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
364 .Times(1) | 424 .Times(1) |
365 .WillOnce(InvokeWithoutArgs(CreateFunctor( | 425 .WillOnce(InvokeWithoutArgs(CreateFunctor( |
366 this, &WorkerProcessLauncherTest::KillProcess, CONTROL_C_EXIT))); | 426 this, &WorkerProcessLauncherTest::KillProcess, CONTROL_C_EXIT))); |
367 EXPECT_CALL(ipc_delegate_, OnPermanentError()) | 427 EXPECT_CALL(server_listener_, OnPermanentError()) |
368 .Times(1) | 428 .Times(1) |
369 .WillOnce(InvokeWithoutArgs(this, | 429 .WillOnce(InvokeWithoutArgs(this, |
370 &WorkerProcessLauncherTest::StopWorker)); | 430 &WorkerProcessLauncherTest::StopWorker)); |
371 | 431 |
372 permanent_error_ = true; | 432 permanent_error_ = true; |
373 StartWorker(); | 433 StartWorker(); |
374 message_loop_.Run(); | 434 message_loop_.Run(); |
375 } | 435 } |
376 | 436 |
377 // Returns invalid client PID and expects the connection to be rejected. | 437 // Returns invalid client PID and expects the connection to be rejected. |
378 TEST_F(WorkerProcessLauncherTest, InvalidClientPid) { | 438 TEST_F(WorkerProcessLauncherTest, InvalidClientPid) { |
379 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) | 439 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) |
380 .Times(2) | 440 .Times(2) |
381 .WillOnce(Invoke( | 441 .WillOnce(Invoke( |
382 this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)) | 442 this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)) |
383 .WillOnce(Invoke( | 443 .WillOnce(Invoke( |
384 this, &WorkerProcessLauncherTest::FailLaunchAndStopWorker)); | 444 this, &WorkerProcessLauncherTest::FailLaunchAndStopWorker)); |
385 | 445 |
386 EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) | 446 EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
387 .Times(0); | 447 .Times(0); |
388 EXPECT_CALL(ipc_delegate_, OnPermanentError()) | 448 EXPECT_CALL(server_listener_, OnPermanentError()) |
389 .Times(0); | 449 .Times(0); |
390 | 450 |
391 client_pid_ = GetCurrentProcessId() + 4; | 451 client_pid_ = GetCurrentProcessId() + 4; |
392 StartWorker(); | 452 StartWorker(); |
393 message_loop_.Run(); | 453 message_loop_.Run(); |
394 } | 454 } |
395 | 455 |
| 456 // Requests the worker to crash and expects it to honor the request. |
| 457 TEST_F(WorkerProcessLauncherTest, Crash) { |
| 458 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) |
| 459 .Times(2) |
| 460 .WillRepeatedly(Invoke( |
| 461 this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); |
| 462 |
| 463 EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
| 464 .Times(2) |
| 465 .WillOnce(InvokeWithoutArgs(this, |
| 466 &WorkerProcessLauncherTest::CrashWorker)) |
| 467 .WillOnce(InvokeWithoutArgs(this, |
| 468 &WorkerProcessLauncherTest::StopWorker)); |
| 469 |
| 470 EXPECT_CALL(client_listener_, OnCrash(_, _, _)) |
| 471 .Times(1) |
| 472 .WillOnce(InvokeWithoutArgs(CreateFunctor( |
| 473 this, &WorkerProcessLauncherTest::KillProcess, |
| 474 EXCEPTION_BREAKPOINT))); |
| 475 |
| 476 StartWorker(); |
| 477 message_loop_.Run(); |
| 478 } |
| 479 |
| 480 // Requests the worker to crash and terminates the worker even if it does not |
| 481 // comply. |
| 482 TEST_F(WorkerProcessLauncherTest, CrashAnyway) { |
| 483 EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) |
| 484 .Times(2) |
| 485 .WillRepeatedly(Invoke( |
| 486 this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); |
| 487 |
| 488 EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
| 489 .Times(2) |
| 490 .WillOnce(InvokeWithoutArgs(this, |
| 491 &WorkerProcessLauncherTest::CrashWorker)) |
| 492 .WillOnce(InvokeWithoutArgs(this, |
| 493 &WorkerProcessLauncherTest::StopWorker)); |
| 494 |
| 495 // Ignore the crash request and try send another message to the launcher. |
| 496 EXPECT_CALL(client_listener_, OnCrash(_, _, _)) |
| 497 .Times(1) |
| 498 .WillOnce(InvokeWithoutArgs( |
| 499 this, &WorkerProcessLauncherTest::SendFakeMessageToLauncher)); |
| 500 |
| 501 StartWorker(); |
| 502 message_loop_.Run(); |
| 503 } |
| 504 |
396 } // namespace remoting | 505 } // namespace remoting |
OLD | NEW |