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

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: Fix posix #2 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
« no previous file with comments | « remoting/host/ipc_desktop_environment.cc ('k') | remoting/host/remoting_me2me_host.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "ipc/ipc_channel.h"
16 #include "ipc/ipc_channel_proxy.h"
17 #include "ipc/ipc_listener.h"
18 #include "ipc/ipc_message.h"
19 #include "ipc/ipc_platform_file.h"
20 #include "media/video/capture/screen/screen_capturer_fake.h"
21 #include "media/video/capture/screen/screen_capturer_mock_objects.h"
22 #include "remoting/base/auto_thread.h"
23 #include "remoting/base/auto_thread_task_runner.h"
24 #include "remoting/host/chromoting_messages.h"
25 #include "remoting/host/desktop_process.h"
26 #include "remoting/host/desktop_session_connector.h"
27 #include "remoting/host/desktop_session_proxy.h"
28 #include "remoting/host/host_mock_objects.h"
29 #include "remoting/host/ipc_desktop_environment.h"
30 #include "remoting/protocol/protocol_mock_objects.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33
34 using testing::_;
35 using testing::AnyNumber;
36 using testing::Return;
37
38 namespace remoting {
39
40 namespace {
41
42 class MockDaemonListener : public IPC::Listener {
43 public:
44 MockDaemonListener() {}
45 virtual ~MockDaemonListener() {}
46
47 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
48
49 MOCK_METHOD1(OnDesktopAttached, void(IPC::PlatformFileForTransit));
50 MOCK_METHOD1(OnChannelConnected, void(int32));
51 MOCK_METHOD0(OnChannelError, void());
52
53 private:
54 DISALLOW_COPY_AND_ASSIGN(MockDaemonListener);
55 };
56
57 bool MockDaemonListener::OnMessageReceived(const IPC::Message& message) {
58 bool handled = true;
59 IPC_BEGIN_MESSAGE_MAP(MockDaemonListener, message)
60 IPC_MESSAGE_HANDLER(ChromotingDesktopDaemonMsg_DesktopAttached,
61 OnDesktopAttached)
62 IPC_MESSAGE_UNHANDLED(handled = false)
63 IPC_END_MESSAGE_MAP()
64
65 EXPECT_TRUE(handled);
66 return handled;
67 }
68
69 } // namespace
70
71 class IpcDesktopEnvironmentTest
72 : public testing::Test,
73 public DesktopSessionConnector {
74 public:
75 IpcDesktopEnvironmentTest();
76 virtual ~IpcDesktopEnvironmentTest();
77
78 virtual void SetUp() OVERRIDE;
79
80 // DesktopSessionConnector implementation.
81 virtual void ConnectTerminal(
82 scoped_refptr<DesktopSessionProxy> desktop_session_proxy) OVERRIDE;
83 virtual void DisconnectTerminal(
84 scoped_refptr<DesktopSessionProxy> desktop_session_proxy) OVERRIDE;
85 virtual void OnDesktopSessionAgentAttached(
86 int terminal_id,
87 base::ProcessHandle desktop_process,
88 IPC::PlatformFileForTransit desktop_pipe) OVERRIDE;
89 virtual void OnTerminalDisconnected(int terminal_id) OVERRIDE;
90
91 // Creates a DesktopEnvironment with a fake media::ScreenCapturer, to mock
92 // DesktopEnvironmentFactory::Create().
93 DesktopEnvironment* CreateDesktopEnvironment();
94
95 // Creates a dummy EventExecutor, to mock
96 // DesktopEnvironment::CreateEventExecutor().
97 EventExecutor* CreateEventExecutor();
98
99 // Creates a fake media::ScreenCapturer, to mock
100 // DesktopEnvironment::CreateVideoCapturer().
101 media::ScreenCapturer* CreateVideoCapturer();
102
103 void DeleteDesktopEnvironment();
104
105 protected:
106 void OnDisconnectCallback();
107
108 // Invoked when ChromotingDesktopDaemonMsg_DesktopAttached message is
109 // received.
110 void OnDesktopAttached(IPC::PlatformFileForTransit desktop_pipe);
111
112 // Invoked when the daemon-to-desktop channel is closed.
113 void OnDesktopSessionClosed();
114
115 // The main message loop.
116 MessageLoop message_loop_;
117
118 // Runs until |desktop_session_proxy_| is connected to the desktop.
119 base::RunLoop setup_run_loop_;
120
121 // Runs until there are references to |task_runner_|.
122 base::RunLoop main_run_loop_;
123
124 scoped_refptr<AutoThreadTaskRunner> task_runner_;
125
126 // Factory for weak pointers to DesktopSessionConnector interface.
127 base::WeakPtrFactory<DesktopSessionConnector> connector_factory_;
128
129 // The daemons's end of the daemon-to-desktop channel.
130 scoped_ptr<IPC::ChannelProxy> daemon_channel_;
131
132 // Name of the daemon-to-desktop channel.
133 std::string daemon_channel_name_;
134
135 // Delegate that is passed to |daemon_channel_|.
136 MockDaemonListener daemon_listener_;
137
138 scoped_ptr<IpcDesktopEnvironment> desktop_environment_;
139
140 // Event executor created by |desktop_environment_|.
141 scoped_ptr<EventExecutor> event_executor_;
142
143 // Screen capturer created by |desktop_environment_|.
144 scoped_ptr<media::ScreenCapturer> video_capturer_;
145
146 // Represents the desktop process running in a user session.
147 scoped_ptr<DesktopProcess> desktop_process_;
148
149 // Points to the DesktopSessionProxy instance created by
150 // IpdDesktopEnvironment.
151 scoped_refptr<DesktopSessionProxy> desktop_session_proxy_;
152
153 media::MockScreenCapturerDelegate screen_capturer_delegate_;
154 };
155
156 IpcDesktopEnvironmentTest::IpcDesktopEnvironmentTest()
157 : message_loop_(MessageLoop::TYPE_UI),
158 connector_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
159 }
160
161 IpcDesktopEnvironmentTest::~IpcDesktopEnvironmentTest() {
162 }
163
164 void IpcDesktopEnvironmentTest::SetUp() {
165 // Arrange to run |message_loop_| until no components depend on it.
166 task_runner_ = new AutoThreadTaskRunner(
167 message_loop_.message_loop_proxy(), main_run_loop_.QuitClosure());
168
169 scoped_refptr<AutoThreadTaskRunner> io_task_runner =
170 AutoThread::CreateWithType("IPC thread", task_runner_,
171 MessageLoop::TYPE_IO);
172
173 // Set expectation that the DaemonProcess will send DesktopAttached message
174 // once it is ready.
175 EXPECT_CALL(daemon_listener_, OnChannelConnected(_));
176 EXPECT_CALL(daemon_listener_, OnDesktopAttached(_))
177 .WillOnce(Invoke(this, &IpcDesktopEnvironmentTest::OnDesktopAttached));
178 EXPECT_CALL(daemon_listener_, OnChannelError())
179 .Times(AnyNumber())
180 .WillOnce(Invoke(this,
181 &IpcDesktopEnvironmentTest::OnDesktopSessionClosed));
182
183 // Create the daemon end of the daemon-to-desktop channel.
184 daemon_channel_name_ = IPC::Channel::GenerateUniqueRandomChannelID();
185 daemon_channel_.reset(new IPC::ChannelProxy(
186 IPC::ChannelHandle(daemon_channel_name_),
187 IPC::Channel::MODE_SERVER,
188 &daemon_listener_,
189 io_task_runner));
190
191 // Create an IpcDesktopEnvironment instance.
192 desktop_environment_.reset(new IpcDesktopEnvironment(
193 task_runner_, io_task_runner, "user@domain/rest-of-jid",
194 base::Bind(&IpcDesktopEnvironmentTest::OnDisconnectCallback,
195 base::Unretained(this)),
196 connector_factory_.GetWeakPtr()));
197
198 // Create the event executor.
199 event_executor_ =
200 desktop_environment_->CreateEventExecutor(task_runner_, task_runner_);
201
202 // Create the screen capturer.
203 video_capturer_ =
204 desktop_environment_->CreateVideoCapturer(task_runner_, task_runner_);
205 }
206
207 void IpcDesktopEnvironmentTest::ConnectTerminal(
208 scoped_refptr<DesktopSessionProxy> desktop_session_proxy) {
209 EXPECT_TRUE(!desktop_process_);
210 EXPECT_TRUE(!desktop_session_proxy_.get());
211 EXPECT_TRUE(task_runner_.get());
212
213 desktop_session_proxy_ = desktop_session_proxy;
214
215 // Create and start the desktop process.
216 desktop_process_.reset(new DesktopProcess(task_runner_,
217 daemon_channel_name_));
218
219 scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory(
220 new MockDesktopEnvironmentFactory());
221 EXPECT_CALL(*desktop_environment_factory, CreatePtr())
222 .Times(AnyNumber())
223 .WillRepeatedly(Invoke(
224 this, &IpcDesktopEnvironmentTest::CreateDesktopEnvironment));
225 EXPECT_CALL(*desktop_environment_factory, SupportsAudioCapture())
226 .Times(AnyNumber())
227 .WillRepeatedly(Return(false));
228
229 // TODO(alexeypa): Fix DesktopProcess to use the desktop environment
230 // to create the disconnect window instead of directly calling
231 // DisconnectWindow::Create(). This will take care of "Uninteresting mock
232 // function call" warnings printed when DisconnectWindow::Show() and
233 // DisconnectWindow::Hide() are called.
234 EXPECT_TRUE(desktop_process_->Start(
235 desktop_environment_factory.PassAs<DesktopEnvironmentFactory>()));
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
« no previous file with comments | « remoting/host/ipc_desktop_environment.cc ('k') | remoting/host/remoting_me2me_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698