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

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: 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) 2012 The Chromium Authors. All rights reserved.
Sergey Ulanov 2013/02/04 21:04:41 2013 please
alexeypa (please no reviews) 2013/02/04 23:45:58 Done.
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 virtual void TearDown() OVERRIDE;
81
82 // DesktopSessionConnector implementation.
83 virtual void ConnectTerminal(
84 scoped_refptr<DesktopSessionProxy> desktop_session_proxy) OVERRIDE;
85 virtual void DisconnectTerminal(
86 scoped_refptr<DesktopSessionProxy> desktop_session_proxy) OVERRIDE;
87 virtual void OnDesktopSessionAgentAttached(
88 int terminal_id,
89 base::ProcessHandle desktop_process,
90 IPC::PlatformFileForTransit desktop_pipe) OVERRIDE;
91 virtual void OnTerminalDisconnected(int terminal_id) OVERRIDE;
92
93 // Creates a DesktopEnvironment with a fake media::ScreenCapturer, to mock
94 // DesktopEnvironmentFactory::Create().
95 DesktopEnvironment* CreateDesktopEnvironment();
96
97 // Creates a dummy EventExecutor, to mock
98 // DesktopEnvironment::CreateEventExecutor().
99 EventExecutor* CreateEventExecutor();
100
101 // Creates a fake media::ScreenCapturer, to mock
102 // DesktopEnvironment::CreateVideoCapturer().
103 media::ScreenCapturer* CreateVideoCapturer();
104
105 void DeleteDesktopEnvironment();
106
107 protected:
108 void OnDisconnectCallback();
109
110 // Invoked when ChromotingDesktopDaemonMsg_DesktopAttached message is
111 // received.
112 void OnDesktopAttached(IPC::PlatformFileForTransit desktop_pipe);
113
114 // Invoked when the daemon-to-desktop channel is closed.
115 void OnDesktopSessionClosed();
116
117 MessageLoop message_loop_;
118 base::RunLoop run_loop_;
119 scoped_refptr<AutoThreadTaskRunner> task_runner_;
120
121 // Factory for weak pointers to DesktopSessionConnector interface.
122 base::WeakPtrFactory<DesktopSessionConnector> connector_factory_;
123
124 // The daemons's end of the daemon-to-desktop channel.
125 scoped_ptr<IPC::ChannelProxy> daemon_channel_;
126
127 // Name of the daemon-to-desktop channel.
128 std::string daemon_channel_name_;
129
130 // Delegate that is passed to |daemon_channel_|.
131 MockDaemonListener daemon_listener_;
132
133 scoped_ptr<IpcDesktopEnvironment> desktop_environment_;
134
135 // Event executor created by |desktop_environment_|.
136 scoped_ptr<EventExecutor> event_executor_;
137
138 // Screen capturer created by |desktop_environment_|.
139 scoped_ptr<media::ScreenCapturer> video_capturer_;
140
141 // Represents the desktop process running in a user session.
142 scoped_ptr<DesktopProcess> desktop_process_;
143
144 // Points to the DesktopSessionProxy instance created by
145 // IpdDesktopEnvironment.
146 scoped_refptr<DesktopSessionProxy> desktop_session_proxy_;
147
148 media::MockScreenCapturerDelegate screen_capturer_delegate_;
149 };
150
151 IpcDesktopEnvironmentTest::IpcDesktopEnvironmentTest()
152 : message_loop_(MessageLoop::TYPE_UI),
153 connector_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
154 }
155
156 IpcDesktopEnvironmentTest::~IpcDesktopEnvironmentTest() {
157 }
158
159 void IpcDesktopEnvironmentTest::SetUp() {
160 // Arrange to run |message_loop_| until no components depend on it.
161 task_runner_ = new AutoThreadTaskRunner(
162 message_loop_.message_loop_proxy(), run_loop_.QuitClosure());
163
164 scoped_refptr<AutoThreadTaskRunner> io_task_runner =
165 AutoThread::CreateWithType("IPC thread", task_runner_,
166 MessageLoop::TYPE_IO);
167
168 // Set expectation that the DaemonProcess will send DesktopAttached message
169 // once it is ready.
170 EXPECT_CALL(daemon_listener_, OnChannelConnected(_));
171 EXPECT_CALL(daemon_listener_, OnDesktopAttached(_))
172 .WillOnce(Invoke(this, &IpcDesktopEnvironmentTest::OnDesktopAttached));
173 EXPECT_CALL(daemon_listener_, OnChannelError())
174 .Times(AnyNumber())
175 .WillOnce(Invoke(this,
176 &IpcDesktopEnvironmentTest::OnDesktopSessionClosed));
177
178 // Create the daemon end of the daemon-to-desktop channel.
179 daemon_channel_name_ = IPC::Channel::GenerateUniqueRandomChannelID();
180 daemon_channel_.reset(new IPC::ChannelProxy(
181 IPC::ChannelHandle(daemon_channel_name_),
182 IPC::Channel::MODE_SERVER,
183 &daemon_listener_,
184 io_task_runner));
185
186 // Create an IpcDesktopEnvironment instance.
187 desktop_environment_.reset(new IpcDesktopEnvironment(
188 task_runner_, io_task_runner, "user@domain/rest-of-jid",
189 base::Bind(&IpcDesktopEnvironmentTest::OnDisconnectCallback,
190 base::Unretained(this)),
191 connector_factory_.GetWeakPtr()));
192
193 // Create the event executor.
194 scoped_ptr<protocol::MockClipboardStub> clipboard_stub(
195 new protocol::MockClipboardStub());
196 EXPECT_CALL(*clipboard_stub, InjectClipboardEvent(_))
197 .Times(0);
198
199 event_executor_ =
200 desktop_environment_->CreateEventExecutor(task_runner_, task_runner_);
201 event_executor_->Start(clipboard_stub.PassAs<protocol::ClipboardStub>());
202
203 // Create the screen capturer.
204 video_capturer_ =
205 desktop_environment_->CreateVideoCapturer(task_runner_, task_runner_);
206 video_capturer_->Start(&screen_capturer_delegate_);
Sergey Ulanov 2013/02/04 21:04:41 It looks wrong that all this code is in SetUp() me
alexeypa (please no reviews) 2013/02/04 23:45:58 Done.
207 }
208
209 void IpcDesktopEnvironmentTest::TearDown() {
Sergey Ulanov 2013/02/04 21:04:41 nit: No need to override this method if it's empty
alexeypa (please no reviews) 2013/02/04 23:45:58 Done.
210 }
211
212 void IpcDesktopEnvironmentTest::ConnectTerminal(
213 scoped_refptr<DesktopSessionProxy> desktop_session_proxy) {
214 EXPECT_TRUE(!desktop_process_);
215 EXPECT_TRUE(!desktop_session_proxy_.get());
216 EXPECT_TRUE(task_runner_.get());
217
218 desktop_session_proxy_ = desktop_session_proxy;
219
220 // Create and start the desktop process.
221 desktop_process_.reset(new DesktopProcess(task_runner_,
222 daemon_channel_name_));
223
224 scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory(
225 new MockDesktopEnvironmentFactory());
226 EXPECT_CALL(*desktop_environment_factory, CreatePtr())
227 .Times(AnyNumber())
228 .WillRepeatedly(Invoke(
229 this, &IpcDesktopEnvironmentTest::CreateDesktopEnvironment));
230 EXPECT_CALL(*desktop_environment_factory, SupportsAudioCapture())
231 .Times(AnyNumber())
232 .WillRepeatedly(Return(false));
233
234 // TODO(alexeypa): Fix DesktopProcess to use the desktop environment
235 // to create the disconnect window instead of directly calling
236 // DisconnectWindow::Create(). This will take care of "Uninteresting mock
237 // function call" warnings printed when DisconnectWindow::Show() and
238 // DisconnectWindow::Hide() are called.
239 EXPECT_TRUE(desktop_process_->Start(desktop_environment_factory.Pass()));
240 }
241
242 void IpcDesktopEnvironmentTest::DisconnectTerminal(
243 scoped_refptr<DesktopSessionProxy> desktop_session_proxy) {
244 EXPECT_TRUE(desktop_session_proxy_.get());
245 EXPECT_EQ(desktop_session_proxy_.get(), desktop_session_proxy.get());
246
247 desktop_session_proxy_ = NULL;
248 }
249
250 void IpcDesktopEnvironmentTest::OnDesktopSessionAgentAttached(
251 int terminal_id,
252 base::ProcessHandle desktop_process,
253 IPC::PlatformFileForTransit desktop_pipe) {
254 NOTIMPLEMENTED();
255 }
256
257 void IpcDesktopEnvironmentTest::OnTerminalDisconnected(int terminal_id) {
258 NOTIMPLEMENTED();
259 }
260
261 DesktopEnvironment* IpcDesktopEnvironmentTest::CreateDesktopEnvironment() {
262 MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment();
263 EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr(_))
264 .Times(0);
265 EXPECT_CALL(*desktop_environment, CreateEventExecutorPtr(_, _))
266 .Times(AnyNumber())
267 .WillRepeatedly(
268 InvokeWithoutArgs(this,
269 &IpcDesktopEnvironmentTest::CreateEventExecutor));
270 EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr(_, _))
271 .Times(AnyNumber())
272 .WillRepeatedly(
273 InvokeWithoutArgs(this,
274 &IpcDesktopEnvironmentTest::CreateVideoCapturer));
275
276 return desktop_environment;
277 }
278
279 EventExecutor* IpcDesktopEnvironmentTest::CreateEventExecutor() {
280 MockEventExecutor* event_executor = new MockEventExecutor();
281 EXPECT_CALL(*event_executor, StartPtr(_));
282 return event_executor;
283 }
284
285 media::ScreenCapturer* IpcDesktopEnvironmentTest::CreateVideoCapturer() {
286 return new media::ScreenCapturerFake();
287 }
288
289 void IpcDesktopEnvironmentTest::DeleteDesktopEnvironment() {
290 desktop_environment_.reset();
291 event_executor_.reset();
292 video_capturer_.reset();
293 }
294
295 void IpcDesktopEnvironmentTest::OnDisconnectCallback() {
296 NOTIMPLEMENTED();
297 }
298
299 void IpcDesktopEnvironmentTest::OnDesktopAttached(
300 IPC::PlatformFileForTransit desktop_pipe) {
301 // Instruct DesktopSessionProxy to connect to the network-to-desktop pipe.
302 EXPECT_TRUE(desktop_session_proxy_->AttachToDesktop(
303 base::GetCurrentProcessHandle(), desktop_pipe));
304
305 // Once |desktop_session_proxy_| is attahced to the desktop, request a single
306 // frame to be captured.
307 video_capturer_->CaptureFrame();
Sergey Ulanov 2013/02/04 21:04:41 I think it's better to move this call to the body
alexeypa (please no reviews) 2013/02/04 23:45:58 Done.
308 }
309
310 void IpcDesktopEnvironmentTest::OnDesktopSessionClosed() {
311 daemon_channel_.reset();
312 desktop_process_.reset();
313 }
314
315 TEST_F(IpcDesktopEnvironmentTest, Basic) {
316 // Wait for the first frame to be captured and exit.
317 EXPECT_CALL(screen_capturer_delegate_, OnCaptureCompleted(_))
318 .WillOnce(InvokeWithoutArgs(
319 this, &IpcDesktopEnvironmentTest::DeleteDesktopEnvironment));
320
321 task_runner_ = NULL;
322 run_loop_.Run();
323 }
324
325 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698