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

Side by Side Diff: remoting/host/ipc_desktop_environment_unittest.cc

Issue 12096071: Adding a unit test to verify the IPC channel between the network and desktop processes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CR feedback. Created 7 years, 10 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
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/callback.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/message_loop.h"
12 #include "base/process.h"
13 #include "base/process_util.h"
14 #include "base/run_loop.h"
15 #include "base/win/scoped_handle.h"
16 #include "ipc/ipc_channel.h"
17 #include "ipc/ipc_channel_proxy.h"
18 #include "ipc/ipc_listener.h"
19 #include "ipc/ipc_message.h"
20 #include "ipc/ipc_platform_file.h"
21 #include "media/video/capture/screen/screen_capturer_fake.h"
22 #include "media/video/capture/screen/screen_capturer_mock_objects.h"
23 #include "remoting/base/auto_thread.h"
24 #include "remoting/base/auto_thread_task_runner.h"
25 #include "remoting/host/chromoting_messages.h"
26 #include "remoting/host/desktop_process.h"
27 #include "remoting/host/desktop_session_connector.h"
28 #include "remoting/host/desktop_session_proxy.h"
29 #include "remoting/host/host_mock_objects.h"
30 #include "remoting/host/ipc_desktop_environment.h"
31 #include "remoting/protocol/protocol_mock_objects.h"
32 #include "testing/gmock/include/gmock/gmock.h"
33 #include "testing/gtest/include/gtest/gtest.h"
34
35 using testing::_;
36 using testing::AnyNumber;
37 using testing::Return;
38
39 namespace remoting {
40
41 namespace {
42
43 class MockDaemonListener : public IPC::Listener {
44 public:
45 MockDaemonListener() {}
46 virtual ~MockDaemonListener() {}
47
48 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
49
50 MOCK_METHOD1(OnDesktopAttached, void(IPC::PlatformFileForTransit));
51 MOCK_METHOD1(OnChannelConnected, void(int32));
52 MOCK_METHOD0(OnChannelError, void());
53
54 private:
55 DISALLOW_COPY_AND_ASSIGN(MockDaemonListener);
56 };
57
58 bool MockDaemonListener::OnMessageReceived(const IPC::Message& message) {
59 bool handled = true;
60 IPC_BEGIN_MESSAGE_MAP(MockDaemonListener, message)
61 IPC_MESSAGE_HANDLER(ChromotingDesktopDaemonMsg_DesktopAttached,
62 OnDesktopAttached)
63 IPC_MESSAGE_UNHANDLED(handled = false)
64 IPC_END_MESSAGE_MAP()
65
66 EXPECT_TRUE(handled);
67 return handled;
68 }
69
70 } // namespace
71
72 class IpcDesktopEnvironmentTest
73 : public testing::Test,
74 public DesktopSessionConnector {
75 public:
76 IpcDesktopEnvironmentTest();
77 virtual ~IpcDesktopEnvironmentTest();
78
79 virtual void SetUp() OVERRIDE;
80
81 // DesktopSessionConnector implementation.
82 virtual void ConnectTerminal(
83 scoped_refptr<DesktopSessionProxy> desktop_session_proxy) OVERRIDE;
84 virtual void DisconnectTerminal(
85 scoped_refptr<DesktopSessionProxy> desktop_session_proxy) OVERRIDE;
86 virtual void OnDesktopSessionAgentAttached(
87 int terminal_id,
88 base::ProcessHandle desktop_process,
89 IPC::PlatformFileForTransit desktop_pipe) OVERRIDE;
90 virtual void OnTerminalDisconnected(int terminal_id) OVERRIDE;
91
92 // Creates a DesktopEnvironment with a fake media::ScreenCapturer, to mock
93 // DesktopEnvironmentFactory::Create().
94 DesktopEnvironment* CreateDesktopEnvironment();
95
96 // Creates a dummy EventExecutor, to mock
97 // DesktopEnvironment::CreateEventExecutor().
98 EventExecutor* CreateEventExecutor();
99
100 // Creates a fake media::ScreenCapturer, to mock
101 // DesktopEnvironment::CreateVideoCapturer().
102 media::ScreenCapturer* CreateVideoCapturer();
103
104 void DeleteDesktopEnvironment();
105
106 protected:
107 void OnDisconnectCallback();
108
109 // Invoked when ChromotingDesktopDaemonMsg_DesktopAttached message is
110 // received.
111 void OnDesktopAttached(IPC::PlatformFileForTransit desktop_pipe);
112
113 // Invoked when the daemon-to-desktop channel is closed.
114 void OnDesktopSessionClosed();
115
116 // The main message loop.
117 MessageLoop message_loop_;
118
119 // Runs until |desktop_session_proxy_| is connected to the desktop.
120 base::RunLoop setup_run_loop_;
121
122 // Runs until there are references to |task_runner_|.
123 base::RunLoop main_run_loop_;
124
125 scoped_refptr<AutoThreadTaskRunner> task_runner_;
126
127 // Factory for weak pointers to DesktopSessionConnector interface.
128 base::WeakPtrFactory<DesktopSessionConnector> connector_factory_;
129
130 // The daemons's end of the daemon-to-desktop channel.
131 scoped_ptr<IPC::ChannelProxy> daemon_channel_;
132
133 // Name of the daemon-to-desktop channel.
134 std::string daemon_channel_name_;
135
136 // Delegate that is passed to |daemon_channel_|.
137 MockDaemonListener daemon_listener_;
138
139 scoped_ptr<IpcDesktopEnvironment> desktop_environment_;
140
141 // Event executor created by |desktop_environment_|.
142 scoped_ptr<EventExecutor> event_executor_;
143
144 // Screen capturer created by |desktop_environment_|.
145 scoped_ptr<media::ScreenCapturer> video_capturer_;
146
147 // Represents the desktop process running in a user session.
148 scoped_ptr<DesktopProcess> desktop_process_;
149
150 // Points to the DesktopSessionProxy instance created by
151 // IpdDesktopEnvironment.
152 scoped_refptr<DesktopSessionProxy> desktop_session_proxy_;
153
154 media::MockScreenCapturerDelegate screen_capturer_delegate_;
155 };
156
157 IpcDesktopEnvironmentTest::IpcDesktopEnvironmentTest()
158 : message_loop_(MessageLoop::TYPE_UI),
159 connector_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
160 }
161
162 IpcDesktopEnvironmentTest::~IpcDesktopEnvironmentTest() {
163 }
164
165 void IpcDesktopEnvironmentTest::SetUp() {
166 // Arrange to run |message_loop_| until no components depend on it.
167 task_runner_ = new AutoThreadTaskRunner(
168 message_loop_.message_loop_proxy(), main_run_loop_.QuitClosure());
169
170 scoped_refptr<AutoThreadTaskRunner> io_task_runner =
171 AutoThread::CreateWithType("IPC thread", task_runner_,
172 MessageLoop::TYPE_IO);
173
174 // Set expectation that the DaemonProcess will send DesktopAttached message
175 // once it is ready.
176 EXPECT_CALL(daemon_listener_, OnChannelConnected(_));
177 EXPECT_CALL(daemon_listener_, OnDesktopAttached(_))
178 .WillOnce(Invoke(this, &IpcDesktopEnvironmentTest::OnDesktopAttached));
179 EXPECT_CALL(daemon_listener_, OnChannelError())
180 .Times(AnyNumber())
181 .WillOnce(Invoke(this,
182 &IpcDesktopEnvironmentTest::OnDesktopSessionClosed));
183
184 // Create the daemon end of the daemon-to-desktop channel.
185 daemon_channel_name_ = IPC::Channel::GenerateUniqueRandomChannelID();
186 daemon_channel_.reset(new IPC::ChannelProxy(
187 IPC::ChannelHandle(daemon_channel_name_),
188 IPC::Channel::MODE_SERVER,
189 &daemon_listener_,
190 io_task_runner));
191
192 // Create an IpcDesktopEnvironment instance.
193 desktop_environment_.reset(new IpcDesktopEnvironment(
194 task_runner_, io_task_runner, "user@domain/rest-of-jid",
195 base::Bind(&IpcDesktopEnvironmentTest::OnDisconnectCallback,
196 base::Unretained(this)),
197 connector_factory_.GetWeakPtr()));
198
199 // Create the event executor.
200 event_executor_ =
201 desktop_environment_->CreateEventExecutor(task_runner_, task_runner_);
202
203 // Create the screen capturer.
204 video_capturer_ =
205 desktop_environment_->CreateVideoCapturer(task_runner_, task_runner_);
206 }
207
208 void IpcDesktopEnvironmentTest::ConnectTerminal(
209 scoped_refptr<DesktopSessionProxy> desktop_session_proxy) {
210 EXPECT_TRUE(!desktop_process_);
211 EXPECT_TRUE(!desktop_session_proxy_.get());
212 EXPECT_TRUE(task_runner_.get());
213
214 desktop_session_proxy_ = desktop_session_proxy;
215
216 // Create and start the desktop process.
217 desktop_process_.reset(new DesktopProcess(task_runner_,
218 daemon_channel_name_));
219
220 scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory(
221 new MockDesktopEnvironmentFactory());
222 EXPECT_CALL(*desktop_environment_factory, CreatePtr())
223 .Times(AnyNumber())
224 .WillRepeatedly(Invoke(
225 this, &IpcDesktopEnvironmentTest::CreateDesktopEnvironment));
226 EXPECT_CALL(*desktop_environment_factory, SupportsAudioCapture())
227 .Times(AnyNumber())
228 .WillRepeatedly(Return(false));
229
230 // TODO(alexeypa): Fix DesktopProcess to use the desktop environment
231 // to create the disconnect window instead of directly calling
232 // DisconnectWindow::Create(). This will take care of "Uninteresting mock
233 // function call" warnings printed when DisconnectWindow::Show() and
234 // DisconnectWindow::Hide() are called.
235 EXPECT_TRUE(desktop_process_->Start(desktop_environment_factory.Pass()));
236 }
237
238 void IpcDesktopEnvironmentTest::DisconnectTerminal(
239 scoped_refptr<DesktopSessionProxy> desktop_session_proxy) {
240 EXPECT_TRUE(desktop_session_proxy_.get());
241 EXPECT_EQ(desktop_session_proxy_.get(), desktop_session_proxy.get());
242
243 desktop_session_proxy_ = NULL;
244 }
245
246 void IpcDesktopEnvironmentTest::OnDesktopSessionAgentAttached(
247 int terminal_id,
248 base::ProcessHandle desktop_process,
249 IPC::PlatformFileForTransit desktop_pipe) {
250 NOTIMPLEMENTED();
251 }
252
253 void IpcDesktopEnvironmentTest::OnTerminalDisconnected(int terminal_id) {
254 NOTIMPLEMENTED();
255 }
256
257 DesktopEnvironment* IpcDesktopEnvironmentTest::CreateDesktopEnvironment() {
258 MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment();
259 EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr(_))
260 .Times(0);
261 EXPECT_CALL(*desktop_environment, CreateEventExecutorPtr(_, _))
262 .Times(AnyNumber())
263 .WillRepeatedly(
264 InvokeWithoutArgs(this,
265 &IpcDesktopEnvironmentTest::CreateEventExecutor));
266 EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr(_, _))
267 .Times(AnyNumber())
268 .WillRepeatedly(
269 InvokeWithoutArgs(this,
270 &IpcDesktopEnvironmentTest::CreateVideoCapturer));
271
272 return desktop_environment;
273 }
274
275 EventExecutor* IpcDesktopEnvironmentTest::CreateEventExecutor() {
276 MockEventExecutor* event_executor = new MockEventExecutor();
277 EXPECT_CALL(*event_executor, StartPtr(_));
278 return event_executor;
279 }
280
281 media::ScreenCapturer* IpcDesktopEnvironmentTest::CreateVideoCapturer() {
282 return new media::ScreenCapturerFake();
283 }
284
285 void IpcDesktopEnvironmentTest::DeleteDesktopEnvironment() {
286 desktop_environment_.reset();
287 event_executor_.reset();
288 video_capturer_.reset();
289 }
290
291 void IpcDesktopEnvironmentTest::OnDisconnectCallback() {
292 NOTIMPLEMENTED();
293 }
294
295 void IpcDesktopEnvironmentTest::OnDesktopAttached(
296 IPC::PlatformFileForTransit desktop_pipe) {
297 // Instruct DesktopSessionProxy to connect to the network-to-desktop pipe.
298 EXPECT_TRUE(desktop_session_proxy_->AttachToDesktop(
299 base::GetCurrentProcessHandle(), desktop_pipe));
300
301 // Let the test know that |desktop_session_proxy_| is attahced to the desktop.
302 setup_run_loop_.Quit();
303 }
304
305 void IpcDesktopEnvironmentTest::OnDesktopSessionClosed() {
306 daemon_channel_.reset();
307 desktop_process_.reset();
308 }
309
310 TEST_F(IpcDesktopEnvironmentTest, Basic) {
311 scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
312 new protocol::MockClipboardStub());
313 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
314 .Times(0);
315
316 // Start the event executor and screen capturer.
317 event_executor_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
318 video_capturer_->Start(&screen_capturer_delegate_);
319
320 // Run the message loop until the desktop is attached.
321 setup_run_loop_.Run();
322
323 // Stop the test.
324 DeleteDesktopEnvironment();
325
326 task_runner_ = NULL;
327 main_run_loop_.Run();
328 }
329
330 TEST_F(IpcDesktopEnvironmentTest, CaptureFrame) {
331 scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
332 new protocol::MockClipboardStub());
333 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
334 .Times(0);
335
336 // Start the event executor and screen capturer.
337 event_executor_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
338 video_capturer_->Start(&screen_capturer_delegate_);
339
340 // Run the message loop until the desktop is attached.
341 setup_run_loop_.Run();
342
343 // Stop the test when the first frame is captured.
344 EXPECT_CALL(screen_capturer_delegate_, OnCaptureCompleted(_))
345 .WillOnce(InvokeWithoutArgs(
346 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
347
348 // Capture a single frame.
349 video_capturer_->CaptureFrame();
350
351 task_runner_ = NULL;
352 main_run_loop_.Run();
353 }
354
355 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698