Chromium Code Reviews| Index: remoting/host/win/worker_process_launcher_unittest.cc |
| diff --git a/remoting/host/win/worker_process_launcher_unittest.cc b/remoting/host/win/worker_process_launcher_unittest.cc |
| index c5a6c85e6ad4f3124af520ee01e00e8ddac3d65b..168faedc4d8dd7a208b0e6cff99b641f1cbbb4c3 100644 |
| --- a/remoting/host/win/worker_process_launcher_unittest.cc |
| +++ b/remoting/host/win/worker_process_launcher_unittest.cc |
| @@ -12,12 +12,13 @@ |
| #include "ipc/ipc_listener.h" |
| #include "ipc/ipc_message.h" |
| #include "remoting/base/auto_thread_task_runner.h" |
| +#include "remoting/host/chromoting_messages.h" |
| #include "remoting/host/host_exit_codes.h" |
| #include "remoting/host/win/launch_process_with_token.h" |
| #include "remoting/host/win/worker_process_launcher.h" |
| #include "remoting/host/worker_process_ipc_delegate.h" |
| -#include "testing/gmock_mutant.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| +#include "testing/gmock_mutant.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| using base::win::ScopedHandle; |
| @@ -37,27 +38,18 @@ namespace { |
| const char kIpcSecurityDescriptor[] = "D:(A;;GA;;;AU)"; |
| -class MockProcessLauncherDelegate |
| - : public WorkerProcessLauncher::Delegate { |
| +class MockProcessLauncherDelegate : public WorkerProcessLauncher::Delegate { |
| public: |
| MockProcessLauncherDelegate() {} |
| virtual ~MockProcessLauncherDelegate() {} |
| - virtual DWORD GetProcessId() const OVERRIDE { |
| - return const_cast<MockProcessLauncherDelegate*>(this)->GetProcessId(); |
| - } |
| - |
| - virtual bool IsPermanentError(int failure_count) const OVERRIDE { |
| - return const_cast<MockProcessLauncherDelegate*>(this)->IsPermanentError( |
| - failure_count); |
| - } |
| - |
| // IPC::Sender implementation. |
| MOCK_METHOD1(Send, bool(IPC::Message*)); |
| - // WorkerProcessLauncher::Delegate implementation |
| - MOCK_METHOD0(GetProcessId, DWORD()); |
| - MOCK_METHOD1(IsPermanentError, bool(int)); |
| + // WorkerProcessLauncher::Delegate interface. |
| + MOCK_METHOD0(CloseChannel, void()); |
| + MOCK_CONST_METHOD0(GetProcessId, DWORD()); |
| + MOCK_CONST_METHOD1(IsPermanentError, bool(int)); |
| MOCK_METHOD1(KillProcess, void(DWORD)); |
| MOCK_METHOD2(LaunchProcess, bool(IPC::Listener*, ScopedHandle*)); |
| @@ -65,13 +57,12 @@ class MockProcessLauncherDelegate |
| DISALLOW_COPY_AND_ASSIGN(MockProcessLauncherDelegate); |
| }; |
| -class MockIpcDelegate |
| - : public WorkerProcessIpcDelegate { |
| +class MockIpcDelegate : public WorkerProcessIpcDelegate { |
| public: |
| MockIpcDelegate() {} |
| virtual ~MockIpcDelegate() {} |
| - // WorkerProcessIpcDelegate implementation |
| + // WorkerProcessIpcDelegate interface. |
| MOCK_METHOD1(OnChannelConnected, void(int32)); |
| MOCK_METHOD1(OnMessageReceived, bool(const IPC::Message&)); |
| MOCK_METHOD0(OnPermanentError, void()); |
| @@ -80,11 +71,35 @@ class MockIpcDelegate |
| DISALLOW_COPY_AND_ASSIGN(MockIpcDelegate); |
| }; |
| +class MockWorkerListener : public IPC::Listener { |
| + public: |
| + MockWorkerListener() {} |
| + virtual ~MockWorkerListener() {} |
| + |
| + MOCK_METHOD3(OnCrash, void(const std::string&, const std::string&, int)); |
| + |
| + // IPC::Listener implementation |
| + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(MockWorkerListener); |
| +}; |
| + |
| +bool MockWorkerListener::OnMessageReceived(const IPC::Message& message) { |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(MockWorkerListener, message) |
| + IPC_MESSAGE_HANDLER(ChromotingDaemonMsg_Crash, OnCrash) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + |
| + EXPECT_TRUE(handled); |
| + |
| + return handled; |
| +} |
| + |
| } // namespace |
| -class WorkerProcessLauncherTest |
| - : public testing::Test, |
| - public IPC::Listener { |
| +class WorkerProcessLauncherTest : public testing::Test { |
| public: |
| WorkerProcessLauncherTest(); |
| virtual ~WorkerProcessLauncherTest(); |
| @@ -92,9 +107,6 @@ class WorkerProcessLauncherTest |
| virtual void SetUp() OVERRIDE; |
| virtual void TearDown() OVERRIDE; |
| - // IPC::Listener implementation |
| - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
| - |
| // WorkerProcessLauncher::Delegate mocks |
| void KillProcess(DWORD exit_code); |
| bool LaunchProcess(IPC::Listener* delegate, |
| @@ -104,8 +116,23 @@ class WorkerProcessLauncherTest |
| bool FailLaunchAndStopWorker(IPC::Listener* delegate, |
| ScopedHandle* process_exit_event_out); |
| - void ConnectChannel(); |
| - void DisconnectChannel(); |
| + // Connects the client end of the channel (the worker process's end). |
| + void ConnectClient(); |
| + |
| + // Disconnects the client end of the channel. |
| + void DisconnectClient(); |
| + |
| + // Disconnects the server end of the channel (the launcher's end). |
| + void DisconnectServer(); |
| + |
| + // Sends a message to the worker process. |
| + bool SendToProcess(IPC::Message* message); |
| + |
| + // Sends a fake message to the launcher. |
| + void SendFakeMessageToLauncher(); |
| + |
| + // Requests the worker to crash. |
| + void CrashWorker(); |
| // Starts the worker. |
| void StartWorker(); |
| @@ -120,7 +147,13 @@ class WorkerProcessLauncherTest |
| MessageLoop message_loop_; |
| scoped_refptr<AutoThreadTaskRunner> task_runner_; |
| - MockIpcDelegate ipc_delegate_; |
| + // Receives mesages sent to the worker process. |
|
Wez
2013/03/07 01:54:35
typo
alexeypa (please no reviews)
2013/03/07 21:28:30
Done.
|
| + MockWorkerListener client_listener_; |
| + |
| + // Receives messages sent from the worker process. |
| + MockIpcDelegate server_listener_; |
| + |
| + // Implements WorkerProcessLauncher::Delegate. |
| scoped_ptr<MockProcessLauncherDelegate> launcher_delegate_; |
| // The name of the IPC channel. |
| @@ -163,7 +196,11 @@ void WorkerProcessLauncherTest::SetUp() { |
| launcher_delegate_.reset(new MockProcessLauncherDelegate()); |
| EXPECT_CALL(*launcher_delegate_, Send(_)) |
| .Times(AnyNumber()) |
| - .WillRepeatedly(Return(false)); |
| + .WillRepeatedly(Invoke(this, &WorkerProcessLauncherTest::SendToProcess)); |
| + EXPECT_CALL(*launcher_delegate_, CloseChannel()) |
| + .Times(AnyNumber()) |
| + .WillRepeatedly(Invoke(this, |
| + &WorkerProcessLauncherTest::DisconnectServer)); |
| EXPECT_CALL(*launcher_delegate_, GetProcessId()) |
| .Times(AnyNumber()) |
| .WillRepeatedly(ReturnPointee(&client_pid_)); |
| @@ -175,18 +212,13 @@ void WorkerProcessLauncherTest::SetUp() { |
| .WillRepeatedly(Invoke(this, &WorkerProcessLauncherTest::KillProcess)); |
| // Set up IPC delegate. |
| - EXPECT_CALL(ipc_delegate_, OnMessageReceived(_)) |
| - .Times(AnyNumber()) |
| - .WillRepeatedly(Return(false)); |
| + EXPECT_CALL(server_listener_, OnMessageReceived(_)) |
| + .Times(0); |
| } |
| void WorkerProcessLauncherTest::TearDown() { |
| } |
| -bool WorkerProcessLauncherTest::OnMessageReceived(const IPC::Message& message) { |
| - return false; |
| -} |
| - |
| void WorkerProcessLauncherTest::KillProcess(DWORD exit_code) { |
| BOOL result = SetEvent(process_exit_event_); |
| EXPECT_TRUE(result); |
| @@ -229,7 +261,7 @@ bool WorkerProcessLauncherTest::LaunchProcessAndConnect( |
| task_runner_->PostTask( |
| FROM_HERE, |
| - base::Bind(&WorkerProcessLauncherTest::ConnectChannel, |
| + base::Bind(&WorkerProcessLauncherTest::ConnectClient, |
| base::Unretained(this))); |
| return true; |
| } |
| @@ -244,26 +276,47 @@ bool WorkerProcessLauncherTest::FailLaunchAndStopWorker( |
| return false; |
| } |
| -void WorkerProcessLauncherTest::ConnectChannel() { |
| +void WorkerProcessLauncherTest::ConnectClient() { |
| channel_client_.reset(new IPC::ChannelProxy( |
| IPC::ChannelHandle(channel_name_), |
| IPC::Channel::MODE_CLIENT, |
| - this, |
| + &client_listener_, |
| task_runner_)); |
| } |
| -void WorkerProcessLauncherTest::DisconnectChannel() { |
| +void WorkerProcessLauncherTest::DisconnectClient() { |
| channel_client_.reset(); |
| } |
| +void WorkerProcessLauncherTest::DisconnectServer() { |
| + channel_server_.reset(); |
| +} |
| + |
| +bool WorkerProcessLauncherTest::SendToProcess(IPC::Message* message) { |
| + if (channel_server_) |
| + return channel_server_->Send(message); |
| + |
| + delete message; |
| + return false; |
| +} |
| + |
| +void WorkerProcessLauncherTest::SendFakeMessageToLauncher() { |
| + if (channel_client_) |
| + channel_client_->Send(new ChromotingDesktopNetworkMsg_DisconnectSession()); |
| +} |
| + |
| +void WorkerProcessLauncherTest::CrashWorker() { |
| + launcher_->Crash(FROM_HERE); |
| +} |
| + |
| void WorkerProcessLauncherTest::StartWorker() { |
| launcher_.reset(new WorkerProcessLauncher( |
| - task_runner_, launcher_delegate_.Pass(), &ipc_delegate_)); |
| + task_runner_, launcher_delegate_.Pass(), &server_listener_)); |
| } |
| void WorkerProcessLauncherTest::StopWorker() { |
| launcher_.reset(); |
| - DisconnectChannel(); |
| + DisconnectClient(); |
| channel_name_.clear(); |
| channel_server_.reset(); |
| task_runner_ = NULL; |
| @@ -278,9 +331,9 @@ TEST_F(WorkerProcessLauncherTest, Start) { |
| .Times(1) |
| .WillRepeatedly(Invoke(this, &WorkerProcessLauncherTest::LaunchProcess)); |
| - EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) |
| + EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
| .Times(0); |
| - EXPECT_CALL(ipc_delegate_, OnPermanentError()) |
| + EXPECT_CALL(server_listener_, OnPermanentError()) |
| .Times(0); |
| StartWorker(); |
| @@ -296,11 +349,11 @@ TEST_F(WorkerProcessLauncherTest, StartAndConnect) { |
| .WillRepeatedly(Invoke( |
| this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); |
| - EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) |
| + EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
| .Times(1) |
| .WillOnce(InvokeWithoutArgs(this, |
| &WorkerProcessLauncherTest::StopWorker)); |
| - EXPECT_CALL(ipc_delegate_, OnPermanentError()) |
| + EXPECT_CALL(server_listener_, OnPermanentError()) |
| .Times(0); |
| StartWorker(); |
| @@ -315,14 +368,14 @@ TEST_F(WorkerProcessLauncherTest, Restart) { |
| .WillRepeatedly(Invoke( |
| this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); |
| Expectation first_connect = |
| - EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) |
| + EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
| .Times(2) |
| .WillOnce(InvokeWithoutArgs(CreateFunctor( |
| this, &WorkerProcessLauncherTest::KillProcess, CONTROL_C_EXIT))) |
| .WillOnce(InvokeWithoutArgs(this, |
| &WorkerProcessLauncherTest::StopWorker)); |
| - EXPECT_CALL(ipc_delegate_, OnPermanentError()) |
| + EXPECT_CALL(server_listener_, OnPermanentError()) |
| .Times(0); |
| StartWorker(); |
| @@ -338,14 +391,14 @@ TEST_F(WorkerProcessLauncherTest, DropIpcChannel) { |
| this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); |
| Expectation first_connect = |
| - EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) |
| + EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
| .Times(2) |
| .WillOnce(InvokeWithoutArgs( |
| - this, &WorkerProcessLauncherTest::DisconnectChannel)) |
| + this, &WorkerProcessLauncherTest::DisconnectClient)) |
| .WillOnce(InvokeWithoutArgs( |
| this, &WorkerProcessLauncherTest::StopWorker)); |
| - EXPECT_CALL(ipc_delegate_, OnPermanentError()) |
| + EXPECT_CALL(server_listener_, OnPermanentError()) |
| .Times(0); |
| StartWorker(); |
| @@ -360,11 +413,11 @@ TEST_F(WorkerProcessLauncherTest, PermanentError) { |
| .WillRepeatedly(Invoke( |
| this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); |
| - EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) |
| + EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
| .Times(1) |
| .WillOnce(InvokeWithoutArgs(CreateFunctor( |
| this, &WorkerProcessLauncherTest::KillProcess, CONTROL_C_EXIT))); |
| - EXPECT_CALL(ipc_delegate_, OnPermanentError()) |
| + EXPECT_CALL(server_listener_, OnPermanentError()) |
| .Times(1) |
| .WillOnce(InvokeWithoutArgs(this, |
| &WorkerProcessLauncherTest::StopWorker)); |
| @@ -383,9 +436,9 @@ TEST_F(WorkerProcessLauncherTest, InvalidClientPid) { |
| .WillOnce(Invoke( |
| this, &WorkerProcessLauncherTest::FailLaunchAndStopWorker)); |
| - EXPECT_CALL(ipc_delegate_, OnChannelConnected(_)) |
| + EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
| .Times(0); |
| - EXPECT_CALL(ipc_delegate_, OnPermanentError()) |
| + EXPECT_CALL(server_listener_, OnPermanentError()) |
| .Times(0); |
| client_pid_ = GetCurrentProcessId() + 4; |
| @@ -393,4 +446,53 @@ TEST_F(WorkerProcessLauncherTest, InvalidClientPid) { |
| message_loop_.Run(); |
| } |
| +// Requests the worker to crash and expects it to honor the request. |
| +TEST_F(WorkerProcessLauncherTest, Crash) { |
| + EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) |
| + .Times(2) |
| + .WillRepeatedly(Invoke( |
| + this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); |
| + |
| + EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
| + .Times(2) |
| + .WillOnce(InvokeWithoutArgs(this, |
| + &WorkerProcessLauncherTest::CrashWorker)) |
| + .WillOnce(InvokeWithoutArgs(this, |
| + &WorkerProcessLauncherTest::StopWorker)); |
| + |
| + EXPECT_CALL(client_listener_, OnCrash(_, _, _)) |
| + .Times(1) |
| + .WillOnce(InvokeWithoutArgs(CreateFunctor( |
| + this, &WorkerProcessLauncherTest::KillProcess, |
| + EXCEPTION_BREAKPOINT))); |
| + |
| + StartWorker(); |
| + message_loop_.Run(); |
| +} |
| + |
| +// Requests the worker to crash and terminates the worker even if it does not |
| +// comply. |
|
Wez
2013/03/07 01:54:35
How - are we relying on the timeout? i.e. will thi
alexeypa (please no reviews)
2013/03/07 21:28:30
Good point. I added reduced the delay to 1ms when
Wez
2013/03/08 01:45:15
nit: Could that be zero ms, i.e. kill it as soon a
alexeypa (please no reviews)
2013/03/08 17:43:19
Done.
|
| +TEST_F(WorkerProcessLauncherTest, CrashAnyway) { |
| + EXPECT_CALL(*launcher_delegate_, LaunchProcess(_, _)) |
| + .Times(2) |
| + .WillRepeatedly(Invoke( |
| + this, &WorkerProcessLauncherTest::LaunchProcessAndConnect)); |
| + |
| + EXPECT_CALL(server_listener_, OnChannelConnected(_)) |
| + .Times(2) |
| + .WillOnce(InvokeWithoutArgs(this, |
| + &WorkerProcessLauncherTest::CrashWorker)) |
| + .WillOnce(InvokeWithoutArgs(this, |
| + &WorkerProcessLauncherTest::StopWorker)); |
| + |
| + // Ignore the crash request and try send another message to the launcher. |
| + EXPECT_CALL(client_listener_, OnCrash(_, _, _)) |
| + .Times(1) |
| + .WillOnce(InvokeWithoutArgs( |
| + this, &WorkerProcessLauncherTest::SendFakeMessageToLauncher)); |
| + |
| + StartWorker(); |
| + message_loop_.Run(); |
| +} |
| + |
| } // namespace remoting |