Revert 207377 "Disable TabCaptureApiTest.EndToEnd for Linux (non..."
[chromium-blink-merge.git] / remoting / host / daemon_process_unittest.cc
blob1e49cf4ecae91f9e361130ad62bce4fa6cd08231
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
3 // found in the LICENSE file.
5 #include "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/location.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/process.h"
10 #include "ipc/ipc_message.h"
11 #include "ipc/ipc_message_macros.h"
12 #include "ipc/ipc_platform_file.h"
13 #include "remoting/base/auto_thread_task_runner.h"
14 #include "remoting/host/chromoting_messages.h"
15 #include "remoting/host/daemon_process.h"
16 #include "remoting/host/desktop_session.h"
17 #include "testing/gmock_mutant.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 using testing::_;
22 using testing::AnyNumber;
23 using testing::InSequence;
25 namespace remoting {
27 namespace {
29 enum Messages {
30 kMessageCrash = ChromotingDaemonMsg_Crash::ID,
31 kMessageConfiguration = ChromotingDaemonNetworkMsg_Configuration::ID,
32 kMessageConnectTerminal = ChromotingNetworkHostMsg_ConnectTerminal::ID,
33 kMessageDisconnectTerminal = ChromotingNetworkHostMsg_DisconnectTerminal::ID,
34 kMessageTerminalDisconnected =
35 ChromotingDaemonNetworkMsg_TerminalDisconnected::ID
38 // Provides a public constructor allowing the test to create instances of
39 // DesktopSession directly.
40 class FakeDesktopSession : public DesktopSession {
41 public:
42 FakeDesktopSession(DaemonProcess* daemon_process, int id);
43 virtual ~FakeDesktopSession();
45 virtual void SetScreenResolution(
46 const ScreenResolution& resolution) OVERRIDE {}
48 private:
49 DISALLOW_COPY_AND_ASSIGN(FakeDesktopSession);
52 class MockDaemonProcess : public DaemonProcess {
53 public:
54 MockDaemonProcess(
55 scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
56 scoped_refptr<AutoThreadTaskRunner> io_task_runner,
57 const base::Closure& stopped_callback);
58 virtual ~MockDaemonProcess();
60 virtual scoped_ptr<DesktopSession> DoCreateDesktopSession(
61 int terminal_id,
62 const ScreenResolution& resolution,
63 bool virtual_terminal) OVERRIDE;
65 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
66 virtual void SendToNetwork(IPC::Message* message) OVERRIDE;
68 MOCK_METHOD1(Received, void(const IPC::Message&));
69 MOCK_METHOD1(Sent, void(const IPC::Message&));
71 MOCK_METHOD3(OnDesktopSessionAgentAttached,
72 bool(int, base::ProcessHandle, IPC::PlatformFileForTransit));
74 MOCK_METHOD1(DoCreateDesktopSessionPtr, DesktopSession*(int));
75 MOCK_METHOD1(DoCrashNetworkProcess, void(const tracked_objects::Location&));
76 MOCK_METHOD0(LaunchNetworkProcess, void());
78 private:
79 DISALLOW_COPY_AND_ASSIGN(MockDaemonProcess);
82 FakeDesktopSession::FakeDesktopSession(DaemonProcess* daemon_process, int id)
83 : DesktopSession(daemon_process, id) {
86 FakeDesktopSession::~FakeDesktopSession() {
89 MockDaemonProcess::MockDaemonProcess(
90 scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
91 scoped_refptr<AutoThreadTaskRunner> io_task_runner,
92 const base::Closure& stopped_callback)
93 : DaemonProcess(caller_task_runner, io_task_runner, stopped_callback) {
96 MockDaemonProcess::~MockDaemonProcess() {
99 scoped_ptr<DesktopSession> MockDaemonProcess::DoCreateDesktopSession(
100 int terminal_id,
101 const ScreenResolution& resolution,
102 bool virtual_terminal) {
103 return scoped_ptr<DesktopSession>(DoCreateDesktopSessionPtr(terminal_id));
106 bool MockDaemonProcess::OnMessageReceived(const IPC::Message& message) {
107 // Notify the mock method.
108 Received(message);
110 // Call the actual handler.
111 return DaemonProcess::OnMessageReceived(message);
114 void MockDaemonProcess::SendToNetwork(IPC::Message* message) {
115 // Notify the mock method.
116 Sent(*message);
117 delete message;
120 } // namespace
122 class DaemonProcessTest : public testing::Test {
123 public:
124 DaemonProcessTest();
125 virtual ~DaemonProcessTest();
127 virtual void SetUp() OVERRIDE;
128 virtual void TearDown() OVERRIDE;
130 // DaemonProcess mocks
131 DesktopSession* DoCreateDesktopSession(int terminal_id);
132 void DoCrashNetworkProcess(const tracked_objects::Location& location);
133 void LaunchNetworkProcess();
135 // Deletes |daemon_process_|.
136 void DeleteDaemonProcess();
138 // Quits |message_loop_|.
139 void QuitMessageLoop();
141 void StartDaemonProcess();
143 const DaemonProcess::DesktopSessionList& desktop_sessions() const {
144 return daemon_process_->desktop_sessions();
147 protected:
148 base::MessageLoop message_loop_;
150 scoped_ptr<MockDaemonProcess> daemon_process_;
151 int terminal_id_;
154 DaemonProcessTest::DaemonProcessTest()
155 : message_loop_(base::MessageLoop::TYPE_IO), terminal_id_(0) {
158 DaemonProcessTest::~DaemonProcessTest() {
161 void DaemonProcessTest::SetUp() {
162 scoped_refptr<AutoThreadTaskRunner> task_runner = new AutoThreadTaskRunner(
163 message_loop_.message_loop_proxy(),
164 base::Bind(&DaemonProcessTest::QuitMessageLoop,
165 base::Unretained(this)));
166 daemon_process_.reset(
167 new MockDaemonProcess(task_runner, task_runner,
168 base::Bind(&DaemonProcessTest::DeleteDaemonProcess,
169 base::Unretained(this))));
171 // Set up daemon process mocks.
172 EXPECT_CALL(*daemon_process_, DoCreateDesktopSessionPtr(_))
173 .Times(AnyNumber())
174 .WillRepeatedly(Invoke(this, &DaemonProcessTest::DoCreateDesktopSession));
175 EXPECT_CALL(*daemon_process_, DoCrashNetworkProcess(_))
176 .Times(AnyNumber())
177 .WillRepeatedly(Invoke(this, &DaemonProcessTest::DoCrashNetworkProcess));
178 EXPECT_CALL(*daemon_process_, LaunchNetworkProcess())
179 .Times(AnyNumber())
180 .WillRepeatedly(Invoke(this, &DaemonProcessTest::LaunchNetworkProcess));
183 void DaemonProcessTest::TearDown() {
184 daemon_process_->Stop();
185 message_loop_.Run();
188 DesktopSession* DaemonProcessTest::DoCreateDesktopSession(int terminal_id) {
189 return new FakeDesktopSession(daemon_process_.get(), terminal_id);
192 void DaemonProcessTest::DoCrashNetworkProcess(
193 const tracked_objects::Location& location) {
194 daemon_process_->SendToNetwork(
195 new ChromotingDaemonMsg_Crash(location.function_name(),
196 location.file_name(),
197 location.line_number()));
200 void DaemonProcessTest::LaunchNetworkProcess() {
201 terminal_id_ = 0;
202 daemon_process_->OnChannelConnected(0);
205 void DaemonProcessTest::DeleteDaemonProcess() {
206 daemon_process_.reset();
209 void DaemonProcessTest::QuitMessageLoop() {
210 message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
213 void DaemonProcessTest::StartDaemonProcess() {
214 // DaemonProcess::Initialize() sets up the config watcher that this test does
215 // not support. Launch the process directly.
216 daemon_process_->LaunchNetworkProcess();
219 MATCHER_P(Message, type, "") {
220 return arg.type() == static_cast<uint32>(type);
223 TEST_F(DaemonProcessTest, OpenClose) {
224 InSequence s;
225 EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));
226 EXPECT_CALL(*daemon_process_, Received(Message(kMessageConnectTerminal)));
227 EXPECT_CALL(*daemon_process_, Received(Message(kMessageDisconnectTerminal)));
228 EXPECT_CALL(*daemon_process_, Sent(Message(kMessageTerminalDisconnected)));
230 StartDaemonProcess();
232 int id = terminal_id_++;
233 ScreenResolution resolution;
235 EXPECT_TRUE(daemon_process_->OnMessageReceived(
236 ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false)));
237 EXPECT_EQ(1u, desktop_sessions().size());
238 EXPECT_EQ(id, desktop_sessions().front()->id());
240 EXPECT_TRUE(daemon_process_->OnMessageReceived(
241 ChromotingNetworkHostMsg_DisconnectTerminal(id)));
242 EXPECT_TRUE(desktop_sessions().empty());
245 TEST_F(DaemonProcessTest, CallCloseDesktopSession) {
246 InSequence s;
247 EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));
248 EXPECT_CALL(*daemon_process_, Received(Message(kMessageConnectTerminal)));
249 EXPECT_CALL(*daemon_process_, Sent(Message(kMessageTerminalDisconnected)));
251 StartDaemonProcess();
253 int id = terminal_id_++;
254 ScreenResolution resolution;
256 EXPECT_TRUE(daemon_process_->OnMessageReceived(
257 ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false)));
258 EXPECT_EQ(1u, desktop_sessions().size());
259 EXPECT_EQ(id, desktop_sessions().front()->id());
261 daemon_process_->CloseDesktopSession(id);
262 EXPECT_TRUE(desktop_sessions().empty());
265 // Sends two CloseDesktopSession messages and expects the second one to be
266 // ignored.
267 TEST_F(DaemonProcessTest, DoubleDisconnectTerminal) {
268 InSequence s;
269 EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));
270 EXPECT_CALL(*daemon_process_, Received(Message(kMessageConnectTerminal)));
271 EXPECT_CALL(*daemon_process_, Received(Message(kMessageDisconnectTerminal)));
272 EXPECT_CALL(*daemon_process_, Sent(Message(kMessageTerminalDisconnected)));
273 EXPECT_CALL(*daemon_process_, Received(Message(kMessageDisconnectTerminal)));
275 StartDaemonProcess();
277 int id = terminal_id_++;
278 ScreenResolution resolution;
280 EXPECT_TRUE(daemon_process_->OnMessageReceived(
281 ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false)));
282 EXPECT_EQ(1u, desktop_sessions().size());
283 EXPECT_EQ(id, desktop_sessions().front()->id());
285 EXPECT_TRUE(daemon_process_->OnMessageReceived(
286 ChromotingNetworkHostMsg_DisconnectTerminal(id)));
287 EXPECT_TRUE(desktop_sessions().empty());
289 EXPECT_TRUE(daemon_process_->OnMessageReceived(
290 ChromotingNetworkHostMsg_DisconnectTerminal(id)));
291 EXPECT_TRUE(desktop_sessions().empty());
294 // Tries to close an invalid terminal ID and expects the network process to be
295 // restarted.
296 TEST_F(DaemonProcessTest, InvalidDisconnectTerminal) {
297 InSequence s;
298 EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));
299 EXPECT_CALL(*daemon_process_, Received(Message(kMessageDisconnectTerminal)));
300 EXPECT_CALL(*daemon_process_, Sent(Message(kMessageCrash)))
301 .WillOnce(InvokeWithoutArgs(this,
302 &DaemonProcessTest::LaunchNetworkProcess));
303 EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));
305 StartDaemonProcess();
307 int id = terminal_id_++;
309 EXPECT_TRUE(daemon_process_->OnMessageReceived(
310 ChromotingNetworkHostMsg_DisconnectTerminal(id)));
311 EXPECT_TRUE(desktop_sessions().empty());
312 EXPECT_EQ(0, terminal_id_);
315 // Tries to open an invalid terminal ID and expects the network process to be
316 // restarted.
317 TEST_F(DaemonProcessTest, InvalidConnectTerminal) {
318 InSequence s;
319 EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));
320 EXPECT_CALL(*daemon_process_, Received(Message(kMessageConnectTerminal)));
321 EXPECT_CALL(*daemon_process_, Received(Message(kMessageConnectTerminal)));
322 EXPECT_CALL(*daemon_process_, Sent(Message(kMessageCrash)))
323 .WillOnce(InvokeWithoutArgs(this,
324 &DaemonProcessTest::LaunchNetworkProcess));
325 EXPECT_CALL(*daemon_process_, Sent(Message(kMessageConfiguration)));
327 StartDaemonProcess();
329 int id = terminal_id_++;
330 ScreenResolution resolution;
332 EXPECT_TRUE(daemon_process_->OnMessageReceived(
333 ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false)));
334 EXPECT_EQ(1u, desktop_sessions().size());
335 EXPECT_EQ(id, desktop_sessions().front()->id());
337 EXPECT_TRUE(daemon_process_->OnMessageReceived(
338 ChromotingNetworkHostMsg_ConnectTerminal(id, resolution, false)));
339 EXPECT_TRUE(desktop_sessions().empty());
340 EXPECT_EQ(0, terminal_id_);
343 } // namespace remoting