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

Side by Side Diff: remoting/host/win/worker_process_launcher_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698