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 |