| 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 |