| 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 "remoting/host/desktop_process.h" | 5 #include "remoting/host/desktop_process.h" |
| 6 | 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" |
| 7 #include "base/location.h" | 9 #include "base/location.h" |
| 8 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
| 9 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/run_loop.h" |
| 10 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
| 11 #include "ipc/ipc_channel.h" | 14 #include "ipc/ipc_channel.h" |
| 12 #include "ipc/ipc_channel_proxy.h" | 15 #include "ipc/ipc_channel_proxy.h" |
| 13 #include "ipc/ipc_listener.h" | 16 #include "ipc/ipc_listener.h" |
| 14 #include "ipc/ipc_message.h" | 17 #include "ipc/ipc_message.h" |
| 15 #include "remoting/base/auto_thread.h" | 18 #include "remoting/base/auto_thread.h" |
| 16 #include "remoting/base/auto_thread_task_runner.h" | 19 #include "remoting/base/auto_thread_task_runner.h" |
| 17 #include "remoting/host/chromoting_messages.h" | 20 #include "remoting/host/chromoting_messages.h" |
| 18 #include "remoting/host/desktop_process.h" | 21 #include "remoting/host/desktop_process.h" |
| 19 #include "remoting/host/host_exit_codes.h" | 22 #include "remoting/host/host_exit_codes.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 37 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; | 40 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
| 38 | 41 |
| 39 MOCK_METHOD1(OnDesktopAttached, void(IPC::PlatformFileForTransit)); | 42 MOCK_METHOD1(OnDesktopAttached, void(IPC::PlatformFileForTransit)); |
| 40 MOCK_METHOD1(OnChannelConnected, void(int32)); | 43 MOCK_METHOD1(OnChannelConnected, void(int32)); |
| 41 MOCK_METHOD0(OnChannelError, void()); | 44 MOCK_METHOD0(OnChannelError, void()); |
| 42 | 45 |
| 43 private: | 46 private: |
| 44 DISALLOW_COPY_AND_ASSIGN(MockDaemonListener); | 47 DISALLOW_COPY_AND_ASSIGN(MockDaemonListener); |
| 45 }; | 48 }; |
| 46 | 49 |
| 50 class MockNetworkListener : public IPC::Listener { |
| 51 public: |
| 52 MockNetworkListener() {} |
| 53 virtual ~MockNetworkListener() {} |
| 54 |
| 55 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
| 56 |
| 57 MOCK_METHOD1(OnDesktopAttached, void(IPC::PlatformFileForTransit)); |
| 58 MOCK_METHOD1(OnChannelConnected, void(int32)); |
| 59 MOCK_METHOD0(OnChannelError, void()); |
| 60 |
| 61 private: |
| 62 DISALLOW_COPY_AND_ASSIGN(MockNetworkListener); |
| 63 }; |
| 64 |
| 47 bool MockDaemonListener::OnMessageReceived(const IPC::Message& message) { | 65 bool MockDaemonListener::OnMessageReceived(const IPC::Message& message) { |
| 48 bool handled = true; | 66 bool handled = true; |
| 49 IPC_BEGIN_MESSAGE_MAP(MockDaemonListener, message) | 67 IPC_BEGIN_MESSAGE_MAP(MockDaemonListener, message) |
| 50 IPC_MESSAGE_HANDLER(ChromotingDesktopDaemonMsg_DesktopAttached, | 68 IPC_MESSAGE_HANDLER(ChromotingDesktopDaemonMsg_DesktopAttached, |
| 51 OnDesktopAttached) | 69 OnDesktopAttached) |
| 52 IPC_MESSAGE_UNHANDLED(handled = false) | 70 IPC_MESSAGE_UNHANDLED(handled = false) |
| 53 IPC_END_MESSAGE_MAP() | 71 IPC_END_MESSAGE_MAP() |
| 54 | 72 |
| 55 EXPECT_TRUE(handled); | 73 EXPECT_TRUE(handled); |
| 56 return handled; | 74 return handled; |
| 57 } | 75 } |
| 58 | 76 |
| 77 bool MockNetworkListener::OnMessageReceived(const IPC::Message& message) { |
| 78 bool handled = true; |
| 79 |
| 80 // TODO(alexeypa): handle received messages here. |
| 81 |
| 82 EXPECT_TRUE(handled); |
| 83 return handled; |
| 84 } |
| 85 |
| 59 } // namespace | 86 } // namespace |
| 60 | 87 |
| 61 class DesktopProcessTest : public testing::Test { | 88 class DesktopProcessTest : public testing::Test { |
| 62 public: | 89 public: |
| 63 DesktopProcessTest(); | 90 DesktopProcessTest(); |
| 64 virtual ~DesktopProcessTest(); | 91 virtual ~DesktopProcessTest(); |
| 65 | 92 |
| 66 // testing::Test overrides | 93 // testing::Test overrides |
| 67 virtual void SetUp() OVERRIDE; | 94 virtual void SetUp() OVERRIDE; |
| 68 virtual void TearDown() OVERRIDE; | 95 virtual void TearDown() OVERRIDE; |
| 69 | 96 |
| 70 // MockDaemonListener mocks | 97 // MockDaemonListener mocks |
| 71 void ConnectNetworkChannel(IPC::PlatformFileForTransit desktop_process); | 98 void ConnectNetworkChannel(IPC::PlatformFileForTransit desktop_process); |
| 72 void OnDesktopAttached(IPC::PlatformFileForTransit desktop_process); | 99 void OnDesktopAttached(IPC::PlatformFileForTransit desktop_process); |
| 73 | 100 |
| 74 // Disconnects the daemon-to-desktop channel causing the desktop process to | 101 // Disconnects the daemon-to-desktop channel causing the desktop process to |
| 75 // exit. | 102 // exit. |
| 76 void DisconnectChannels(); | 103 void DisconnectChannels(); |
| 77 | 104 |
| 78 void QuitMessageLoop(); | |
| 79 | |
| 80 // Runs the desktop process code in a separate thread. | 105 // Runs the desktop process code in a separate thread. |
| 81 void RunDesktopProcess(); | 106 void RunDesktopProcess(); |
| 82 | 107 |
| 83 // Creates the desktop process and sends a crash request to it. | 108 // Creates the desktop process and sends a crash request to it. |
| 84 void RunDeathTest(); | 109 void RunDeathTest(); |
| 85 | 110 |
| 86 // Sends a crash request to the desktop process. | 111 // Sends a crash request to the desktop process. |
| 87 void SendCrashRequest(); | 112 void SendCrashRequest(); |
| 88 | 113 |
| 89 protected: | 114 protected: |
| 90 // Name of the daemon-to_desktop channel. | |
| 91 std::string channel_name_; | |
| 92 | |
| 93 // The daemon's end of the daemon-to-desktop channel. | 115 // The daemon's end of the daemon-to-desktop channel. |
| 94 scoped_ptr<IPC::ChannelProxy> daemon_channel_; | 116 scoped_ptr<IPC::ChannelProxy> daemon_channel_; |
| 95 | 117 |
| 96 // Delegate that is passed to |daemon_channel_|. | 118 // Delegate that is passed to |daemon_channel_|. |
| 97 MockDaemonListener daemon_listener_; | 119 MockDaemonListener daemon_listener_; |
| 98 | 120 |
| 99 // Runs the daemon's end of the channel. | 121 // Runs the daemon's end of the channel. |
| 100 MessageLoop message_loop_; | 122 MessageLoop message_loop_; |
| 101 | 123 |
| 102 scoped_refptr<AutoThreadTaskRunner> io_task_runner_; | 124 scoped_refptr<AutoThreadTaskRunner> io_task_runner_; |
| 103 | 125 |
| 104 // The network's end of the network-to-desktop channel. | 126 // The network's end of the network-to-desktop channel. |
| 105 scoped_ptr<IPC::ChannelProxy> network_channel_; | 127 scoped_ptr<IPC::ChannelProxy> network_channel_; |
| 106 | 128 |
| 107 // Delegate that is passed to |network_channel_|. | 129 // Delegate that is passed to |network_channel_|. |
| 108 MockDaemonListener network_listener_; | 130 MockNetworkListener network_listener_; |
| 109 }; | 131 }; |
| 110 | 132 |
| 111 | 133 |
| 112 DesktopProcessTest::DesktopProcessTest() | 134 DesktopProcessTest::DesktopProcessTest() |
| 113 : message_loop_(MessageLoop::TYPE_UI) { | 135 : message_loop_(MessageLoop::TYPE_UI) { |
| 114 } | 136 } |
| 115 | 137 |
| 116 DesktopProcessTest::~DesktopProcessTest() { | 138 DesktopProcessTest::~DesktopProcessTest() { |
| 117 } | 139 } |
| 118 | 140 |
| 119 void DesktopProcessTest::SetUp() { | 141 void DesktopProcessTest::SetUp() { |
| 120 scoped_refptr<AutoThreadTaskRunner> ui_task_runner = new AutoThreadTaskRunner( | |
| 121 message_loop_.message_loop_proxy(), | |
| 122 base::Bind(&DesktopProcessTest::QuitMessageLoop, | |
| 123 base::Unretained(this))); | |
| 124 | |
| 125 io_task_runner_ = AutoThread::CreateWithType("IPC thread", ui_task_runner, | |
| 126 MessageLoop::TYPE_IO); | |
| 127 | |
| 128 // Create the daemon-to-desktop process channel. | |
| 129 channel_name_ = IPC::Channel::GenerateUniqueRandomChannelID(); | |
| 130 daemon_channel_.reset(new IPC::ChannelProxy( | |
| 131 IPC::ChannelHandle(channel_name_), | |
| 132 IPC::Channel::MODE_SERVER, | |
| 133 &daemon_listener_, | |
| 134 io_task_runner_)); | |
| 135 } | 142 } |
| 136 | 143 |
| 137 void DesktopProcessTest::TearDown() { | 144 void DesktopProcessTest::TearDown() { |
| 138 } | 145 } |
| 139 | 146 |
| 140 void DesktopProcessTest::ConnectNetworkChannel( | 147 void DesktopProcessTest::ConnectNetworkChannel( |
| 141 IPC::PlatformFileForTransit desktop_process) { | 148 IPC::PlatformFileForTransit desktop_process) { |
| 142 | 149 |
| 143 #if defined(OS_POSIX) | 150 #if defined(OS_POSIX) |
| 144 IPC::ChannelHandle channel_handle("", desktop_process); | 151 IPC::ChannelHandle channel_handle("", desktop_process); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 161 base::ClosePlatformFile(desktop_process.fd); | 168 base::ClosePlatformFile(desktop_process.fd); |
| 162 #endif // defined(OS_POSIX) | 169 #endif // defined(OS_POSIX) |
| 163 } | 170 } |
| 164 | 171 |
| 165 void DesktopProcessTest::DisconnectChannels() { | 172 void DesktopProcessTest::DisconnectChannels() { |
| 166 daemon_channel_.reset(); | 173 daemon_channel_.reset(); |
| 167 network_channel_.reset(); | 174 network_channel_.reset(); |
| 168 io_task_runner_ = NULL; | 175 io_task_runner_ = NULL; |
| 169 } | 176 } |
| 170 | 177 |
| 171 void DesktopProcessTest::QuitMessageLoop() { | 178 void DesktopProcessTest::RunDesktopProcess() { |
| 172 message_loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure()); | 179 base::RunLoop run_loop; |
| 173 } | 180 base::Closure quit_ui_task_runner = base::Bind( |
| 181 base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask), |
| 182 message_loop_.message_loop_proxy(), |
| 183 FROM_HERE, run_loop.QuitClosure()); |
| 184 scoped_refptr<AutoThreadTaskRunner> ui_task_runner = new AutoThreadTaskRunner( |
| 185 message_loop_.message_loop_proxy(), quit_ui_task_runner); |
| 174 | 186 |
| 175 void DesktopProcessTest::RunDesktopProcess() { | 187 io_task_runner_ = AutoThread::CreateWithType("IPC thread", ui_task_runner, |
| 176 DesktopProcess desktop_process(channel_name_); | 188 MessageLoop::TYPE_IO); |
| 177 EXPECT_EQ(desktop_process.Run(), kSuccessExitCode); | 189 |
| 190 std::string channel_name = IPC::Channel::GenerateUniqueRandomChannelID(); |
| 191 daemon_channel_.reset(new IPC::ChannelProxy( |
| 192 IPC::ChannelHandle(channel_name), |
| 193 IPC::Channel::MODE_SERVER, |
| 194 &daemon_listener_, |
| 195 io_task_runner_)); |
| 196 |
| 197 DesktopProcess desktop_process(ui_task_runner, channel_name); |
| 198 EXPECT_TRUE(desktop_process.Start()); |
| 199 |
| 200 ui_task_runner = NULL; |
| 201 run_loop.Run(); |
| 178 } | 202 } |
| 179 | 203 |
| 180 void DesktopProcessTest::RunDeathTest() { | 204 void DesktopProcessTest::RunDeathTest() { |
| 181 InSequence s; | 205 InSequence s; |
| 182 EXPECT_CALL(daemon_listener_, OnChannelConnected(_)); | 206 EXPECT_CALL(daemon_listener_, OnChannelConnected(_)); |
| 183 EXPECT_CALL(daemon_listener_, OnDesktopAttached(_)) | 207 EXPECT_CALL(daemon_listener_, OnDesktopAttached(_)) |
| 184 .WillOnce(DoAll( | 208 .WillOnce(DoAll( |
| 185 Invoke(this, &DesktopProcessTest::OnDesktopAttached), | 209 Invoke(this, &DesktopProcessTest::OnDesktopAttached), |
| 186 InvokeWithoutArgs(this, &DesktopProcessTest::SendCrashRequest))); | 210 InvokeWithoutArgs(this, &DesktopProcessTest::SendCrashRequest))); |
| 187 | 211 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 217 this, &DesktopProcessTest::DisconnectChannels)); | 241 this, &DesktopProcessTest::DisconnectChannels)); |
| 218 | 242 |
| 219 RunDesktopProcess(); | 243 RunDesktopProcess(); |
| 220 } | 244 } |
| 221 | 245 |
| 222 // Run the desktop process and ask it to crash. | 246 // Run the desktop process and ask it to crash. |
| 223 TEST_F(DesktopProcessTest, DeathTest) { | 247 TEST_F(DesktopProcessTest, DeathTest) { |
| 224 testing::GTEST_FLAG(death_test_style) = "threadsafe"; | 248 testing::GTEST_FLAG(death_test_style) = "threadsafe"; |
| 225 | 249 |
| 226 EXPECT_DEATH(RunDeathTest(), ""); | 250 EXPECT_DEATH(RunDeathTest(), ""); |
| 227 | |
| 228 DisconnectChannels(); | |
| 229 } | 251 } |
| 230 | 252 |
| 231 } // namespace remoting | 253 } // namespace remoting |
| OLD | NEW |