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 "base/message_loop/message_loop.h" | 5 #include "base/message_loop/message_loop.h" |
6 #include "base/strings/string_util.h" | |
6 #include "base/test/test_simple_task_runner.h" | 7 #include "base/test/test_simple_task_runner.h" |
7 #include "remoting/base/auto_thread_task_runner.h" | 8 #include "remoting/base/auto_thread_task_runner.h" |
8 #include "remoting/base/constants.h" | 9 #include "remoting/base/constants.h" |
9 #include "remoting/host/audio_capturer.h" | 10 #include "remoting/host/audio_capturer.h" |
10 #include "remoting/host/client_session.h" | 11 #include "remoting/host/client_session.h" |
11 #include "remoting/host/desktop_environment.h" | 12 #include "remoting/host/desktop_environment.h" |
13 #include "remoting/host/extension.h" | |
12 #include "remoting/host/host_mock_objects.h" | 14 #include "remoting/host/host_mock_objects.h" |
13 #include "remoting/host/screen_capturer_fake.h" | 15 #include "remoting/host/screen_capturer_fake.h" |
14 #include "remoting/protocol/protocol_mock_objects.h" | 16 #include "remoting/protocol/protocol_mock_objects.h" |
15 #include "testing/gmock/include/gmock/gmock-matchers.h" | 17 #include "testing/gmock/include/gmock/gmock-matchers.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
17 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" | 19 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" |
18 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h" | 20 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h" |
19 #include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_object s.h" | 21 #include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_object s.h" |
20 | 22 |
21 namespace remoting { | 23 namespace remoting { |
22 | 24 |
23 using protocol::MockConnectionToClient; | 25 using protocol::MockConnectionToClient; |
24 using protocol::MockClientStub; | 26 using protocol::MockClientStub; |
25 using protocol::MockHostStub; | 27 using protocol::MockHostStub; |
26 using protocol::MockInputStub; | 28 using protocol::MockInputStub; |
27 using protocol::MockSession; | 29 using protocol::MockSession; |
28 using protocol::MockVideoStub; | 30 using protocol::MockVideoStub; |
29 using protocol::SessionConfig; | 31 using protocol::SessionConfig; |
30 | 32 |
31 using testing::_; | 33 using testing::_; |
32 using testing::AnyNumber; | 34 using testing::AnyNumber; |
33 using testing::AtMost; | 35 using testing::AtMost; |
34 using testing::DeleteArg; | 36 using testing::DeleteArg; |
35 using testing::DoAll; | 37 using testing::DoAll; |
36 using testing::Expectation; | 38 using testing::Expectation; |
39 using testing::Invoke; | |
37 using testing::Return; | 40 using testing::Return; |
38 using testing::ReturnRef; | 41 using testing::ReturnRef; |
39 using testing::Sequence; | 42 using testing::Sequence; |
40 using testing::StrEq; | 43 using testing::StrEq; |
41 using testing::StrictMock; | 44 using testing::StrictMock; |
42 | 45 |
43 namespace { | 46 namespace { |
44 | 47 |
48 const char kDefaultTestCapability[] = "default"; | |
49 | |
45 ACTION_P2(InjectClipboardEvent, connection, event) { | 50 ACTION_P2(InjectClipboardEvent, connection, event) { |
46 connection->clipboard_stub()->InjectClipboardEvent(event); | 51 connection->clipboard_stub()->InjectClipboardEvent(event); |
47 } | 52 } |
48 | 53 |
49 ACTION_P2(InjectKeyEvent, connection, event) { | 54 ACTION_P2(InjectKeyEvent, connection, event) { |
50 connection->input_stub()->InjectKeyEvent(event); | 55 connection->input_stub()->InjectKeyEvent(event); |
51 } | 56 } |
52 | 57 |
53 ACTION_P2(InjectMouseEvent, connection, event) { | 58 ACTION_P2(InjectMouseEvent, connection, event) { |
54 connection->input_stub()->InjectMouseEvent(event); | 59 connection->input_stub()->InjectMouseEvent(event); |
55 } | 60 } |
56 | 61 |
57 ACTION_P2(LocalMouseMoved, client_session, event) { | 62 ACTION_P2(LocalMouseMoved, client_session, event) { |
58 client_session->OnLocalMouseMoved( | 63 client_session->OnLocalMouseMoved( |
59 webrtc::DesktopVector(event.x(), event.y())); | 64 webrtc::DesktopVector(event.x(), event.y())); |
60 } | 65 } |
61 | 66 |
62 ACTION_P2(SetGnubbyAuthHandlerForTesting, client_session, gnubby_auth_handler) { | 67 ACTION_P2(SetGnubbyAuthHandlerForTesting, client_session, gnubby_auth_handler) { |
63 client_session->SetGnubbyAuthHandlerForTesting(gnubby_auth_handler); | 68 client_session->SetGnubbyAuthHandlerForTesting(gnubby_auth_handler); |
64 } | 69 } |
65 | 70 |
66 ACTION_P2(DeliverClientMessage, client_session, message) { | 71 ACTION_P2(DeliverClientMessage, client_session, message) { |
67 client_session->DeliverClientMessage(message); | 72 client_session->DeliverClientMessage(message); |
68 } | 73 } |
69 | 74 |
75 // Matches a |protocol::Capabilities| argument against a list of capabilities | |
76 // formatted as a space-separated string. | |
77 MATCHER_P(EqCapabilities, expected_capabilities, "") { | |
78 if (!arg.has_capabilities()) | |
79 return false; | |
80 | |
81 std::vector<std::string> words_args; | |
82 std::vector<std::string> words_expected; | |
83 Tokenize(arg.capabilities(), " ", &words_args); | |
84 Tokenize(expected_capabilities, " ", &words_expected); | |
85 std::sort(words_args.begin(), words_args.end()); | |
86 std::sort(words_expected.begin(), words_expected.end()); | |
87 return words_args == words_expected; | |
88 } | |
89 | |
90 // |Extension| implementation that can handle an extension message type and | |
91 // provide capabilities. | |
92 class FakeExtension : public Extension { | |
93 public: | |
94 FakeExtension(const std::string& message_type, | |
95 const std::string& capabilities); | |
96 virtual ~FakeExtension(); | |
97 | |
98 virtual std::string GetCapabilities() OVERRIDE; | |
99 virtual scoped_ptr<ExtensionSession> CreateExtensionSession( | |
100 ClientSession* client_session) OVERRIDE; | |
101 | |
102 bool message_handled() { | |
103 return message_handled_; | |
104 } | |
105 | |
106 private: | |
107 class FakeExtensionSession : public ExtensionSession { | |
108 public: | |
109 FakeExtensionSession(FakeExtension* extension); | |
110 virtual ~FakeExtensionSession(); | |
111 | |
112 virtual bool OnExtensionMessage( | |
113 ClientSession* client_session, | |
114 const protocol::ExtensionMessage& message) OVERRIDE; | |
115 | |
116 private: | |
117 FakeExtension* extension_; | |
118 }; | |
119 | |
120 std::string message_type_; | |
121 std::string capabilities_; | |
122 bool message_handled_; | |
123 }; | |
124 | |
70 } | 125 } |
71 | 126 |
72 class ClientSessionTest : public testing::Test { | 127 class ClientSessionTest : public testing::Test { |
73 public: | 128 public: |
74 ClientSessionTest() : client_jid_("user@domain/rest-of-jid") {} | 129 ClientSessionTest() : client_jid_("user@domain/rest-of-jid") {} |
75 | 130 |
76 virtual void SetUp() OVERRIDE; | 131 virtual void SetUp() OVERRIDE; |
77 virtual void TearDown() OVERRIDE; | 132 virtual void TearDown() OVERRIDE; |
78 | 133 |
79 // Disconnects the client session. | 134 // Disconnects the client session. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 MockClientStub client_stub_; | 176 MockClientStub client_stub_; |
122 MockVideoStub video_stub_; | 177 MockVideoStub video_stub_; |
123 | 178 |
124 // DesktopEnvironment owns |input_injector_|, but input injection tests need | 179 // DesktopEnvironment owns |input_injector_|, but input injection tests need |
125 // to express expectations on it. | 180 // to express expectations on it. |
126 scoped_ptr<MockInputInjector> input_injector_; | 181 scoped_ptr<MockInputInjector> input_injector_; |
127 | 182 |
128 // ClientSession owns |connection_| but tests need it to inject fake events. | 183 // ClientSession owns |connection_| but tests need it to inject fake events. |
129 MockConnectionToClient* connection_; | 184 MockConnectionToClient* connection_; |
130 | 185 |
186 ExtensionList extensions_; | |
187 | |
131 scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory_; | 188 scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory_; |
132 }; | 189 }; |
133 | 190 |
191 FakeExtension::FakeExtension(const std::string& message_type, | |
192 const std::string& capabilities) | |
193 : message_type_(message_type), | |
194 capabilities_(capabilities), | |
195 message_handled_(false) { | |
196 } | |
197 | |
198 FakeExtension::~FakeExtension() {} | |
199 | |
200 std::string FakeExtension::GetCapabilities() { | |
201 return capabilities_; | |
202 } | |
203 | |
204 scoped_ptr<ExtensionSession> FakeExtension::CreateExtensionSession( | |
205 ClientSession* client_session) { | |
206 return scoped_ptr<ExtensionSession>(new FakeExtensionSession(this)); | |
207 } | |
208 | |
209 FakeExtension::FakeExtensionSession::FakeExtensionSession( | |
210 FakeExtension* extension) | |
211 : extension_(extension) { | |
212 } | |
213 | |
214 FakeExtension::FakeExtensionSession::~FakeExtensionSession() {} | |
215 | |
216 bool FakeExtension::FakeExtensionSession::OnExtensionMessage( | |
217 ClientSession* client_session, | |
218 const protocol::ExtensionMessage& message) { | |
219 if (message.type() == extension_->message_type_) { | |
220 extension_->message_handled_ = true; | |
221 return true; | |
222 } | |
223 return false; | |
224 } | |
225 | |
134 void ClientSessionTest::SetUp() { | 226 void ClientSessionTest::SetUp() { |
135 // Arrange to run |message_loop_| until no components depend on it. | 227 // Arrange to run |message_loop_| until no components depend on it. |
136 scoped_refptr<AutoThreadTaskRunner> ui_task_runner = new AutoThreadTaskRunner( | 228 scoped_refptr<AutoThreadTaskRunner> ui_task_runner = new AutoThreadTaskRunner( |
137 message_loop_.message_loop_proxy(), | 229 message_loop_.message_loop_proxy(), |
138 base::Bind(&ClientSessionTest::QuitMainMessageLoop, | 230 base::Bind(&ClientSessionTest::QuitMainMessageLoop, |
139 base::Unretained(this))); | 231 base::Unretained(this))); |
140 | 232 |
141 desktop_environment_factory_.reset(new MockDesktopEnvironmentFactory()); | 233 desktop_environment_factory_.reset(new MockDesktopEnvironmentFactory()); |
142 EXPECT_CALL(*desktop_environment_factory_, CreatePtr()) | 234 EXPECT_CALL(*desktop_environment_factory_, CreatePtr()) |
143 .Times(AnyNumber()) | 235 .Times(AnyNumber()) |
(...skipping 28 matching lines...) Expand all Loading... | |
172 &session_event_handler_, | 264 &session_event_handler_, |
173 ui_task_runner, // Audio thread. | 265 ui_task_runner, // Audio thread. |
174 ui_task_runner, // Input thread. | 266 ui_task_runner, // Input thread. |
175 ui_task_runner, // Capture thread. | 267 ui_task_runner, // Capture thread. |
176 ui_task_runner, // Encode thread. | 268 ui_task_runner, // Encode thread. |
177 ui_task_runner, // Network thread. | 269 ui_task_runner, // Network thread. |
178 ui_task_runner, // UI thread. | 270 ui_task_runner, // UI thread. |
179 connection.PassAs<protocol::ConnectionToClient>(), | 271 connection.PassAs<protocol::ConnectionToClient>(), |
180 desktop_environment_factory_.get(), | 272 desktop_environment_factory_.get(), |
181 base::TimeDelta(), | 273 base::TimeDelta(), |
182 NULL)); | 274 NULL, |
275 &extensions_)); | |
276 | |
277 // By default, client will report the same capabilities as the host. | |
278 EXPECT_CALL(client_stub_, SetCapabilities(_)) | |
279 .Times(AtMost(1)) | |
280 .WillOnce(Invoke(client_session_.get(), &ClientSession::SetCapabilities)); | |
183 } | 281 } |
184 | 282 |
185 void ClientSessionTest::TearDown() { | 283 void ClientSessionTest::TearDown() { |
186 // Verify that the client session has been stopped. | 284 // Verify that the client session has been stopped. |
187 EXPECT_TRUE(!client_session_); | 285 EXPECT_TRUE(!client_session_); |
188 } | 286 } |
189 | 287 |
190 void ClientSessionTest::DisconnectClientSession() { | 288 void ClientSessionTest::DisconnectClientSession() { |
191 client_session_->DisconnectSession(); | 289 client_session_->DisconnectSession(); |
192 // MockSession won't trigger OnConnectionClosed, so fake it. | 290 // MockSession won't trigger OnConnectionClosed, so fake it. |
(...skipping 11 matching lines...) Expand all Loading... | |
204 MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment(); | 302 MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment(); |
205 EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr()) | 303 EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr()) |
206 .Times(0); | 304 .Times(0); |
207 EXPECT_CALL(*desktop_environment, CreateInputInjectorPtr()) | 305 EXPECT_CALL(*desktop_environment, CreateInputInjectorPtr()) |
208 .WillOnce(Invoke(this, &ClientSessionTest::CreateInputInjector)); | 306 .WillOnce(Invoke(this, &ClientSessionTest::CreateInputInjector)); |
209 EXPECT_CALL(*desktop_environment, CreateScreenControlsPtr()) | 307 EXPECT_CALL(*desktop_environment, CreateScreenControlsPtr()) |
210 .Times(AtMost(1)); | 308 .Times(AtMost(1)); |
211 EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr()) | 309 EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr()) |
212 .WillOnce(Invoke(this, &ClientSessionTest::CreateVideoCapturer)); | 310 .WillOnce(Invoke(this, &ClientSessionTest::CreateVideoCapturer)); |
213 EXPECT_CALL(*desktop_environment, GetCapabilities()) | 311 EXPECT_CALL(*desktop_environment, GetCapabilities()) |
214 .Times(AtMost(1)); | 312 .Times(AtMost(1)) |
313 .WillOnce(Return(kDefaultTestCapability)); | |
215 EXPECT_CALL(*desktop_environment, SetCapabilities(_)) | 314 EXPECT_CALL(*desktop_environment, SetCapabilities(_)) |
216 .Times(AtMost(1)); | 315 .Times(AtMost(1)); |
217 | 316 |
218 return desktop_environment; | 317 return desktop_environment; |
219 } | 318 } |
220 | 319 |
221 InputInjector* ClientSessionTest::CreateInputInjector() { | 320 InputInjector* ClientSessionTest::CreateInputInjector() { |
222 EXPECT_TRUE(input_injector_); | 321 EXPECT_TRUE(input_injector_); |
223 return input_injector_.release(); | 322 return input_injector_.release(); |
224 } | 323 } |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
592 DeliverClientMessage(client_session_.get(), message), | 691 DeliverClientMessage(client_session_.get(), message), |
593 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession), | 692 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession), |
594 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession))); | 693 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession))); |
595 EXPECT_CALL(*gnubby_auth_handler, DeliverClientMessage(_)); | 694 EXPECT_CALL(*gnubby_auth_handler, DeliverClientMessage(_)); |
596 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); | 695 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); |
597 | 696 |
598 ConnectClientSession(); | 697 ConnectClientSession(); |
599 message_loop_.Run(); | 698 message_loop_.Run(); |
600 } | 699 } |
601 | 700 |
701 // Verifies that messages can be handled by extensions. | |
702 TEST_F(ClientSessionTest, ExtensionMessages_MessageHandled) { | |
703 FakeExtension extension1("ext1", "cap1"); | |
704 FakeExtension extension2("ext2", "cap2"); | |
705 FakeExtension extension3("ext3", "cap3"); | |
706 extensions_.push_back(&extension1); | |
707 extensions_.push_back(&extension2); | |
708 extensions_.push_back(&extension3); | |
709 | |
710 protocol::ExtensionMessage message; | |
711 message.set_type("ext2"); | |
712 message.set_data("test"); | |
713 | |
714 Expectation authenticated = | |
715 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)) | |
716 .WillOnce(Return(true)); | |
717 EXPECT_CALL(*input_injector_, StartPtr(_)).After(authenticated); | |
718 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)) | |
719 .After(authenticated) | |
720 .WillOnce(DoAll( | |
721 DeliverClientMessage(client_session_.get(), message), | |
722 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession), | |
723 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession))); | |
Wez
2014/05/28 01:05:59
This chunk of work is unrelated to the test, aside
dcaiafa
2014/05/28 22:44:58
Done.
| |
724 | |
725 ConnectClientSession(); | |
726 message_loop_.Run(); | |
727 | |
728 EXPECT_FALSE(extension1.message_handled()); | |
729 EXPECT_TRUE(extension2.message_handled()); | |
730 EXPECT_FALSE(extension3.message_handled()); | |
731 } | |
732 | |
733 // Verifies that extension messages not handled by extensions don't result in a | |
734 // crash. | |
735 TEST_F(ClientSessionTest, ExtensionMessages_MessageNotHandled) { | |
736 FakeExtension extension1("ext1", "cap1"); | |
737 extensions_.push_back(&extension1); | |
738 | |
739 protocol::ExtensionMessage message; | |
740 message.set_type("extX"); | |
741 message.set_data("test"); | |
742 | |
743 Expectation authenticated = | |
744 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)) | |
745 .WillOnce(Return(true)); | |
746 EXPECT_CALL(*input_injector_, StartPtr(_)).After(authenticated); | |
747 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)) | |
748 .After(authenticated) | |
749 .WillOnce(DoAll( | |
750 DeliverClientMessage(client_session_.get(), message), | |
751 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession), | |
752 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession))); | |
753 | |
754 ConnectClientSession(); | |
755 message_loop_.Run(); | |
756 | |
757 EXPECT_FALSE(extension1.message_handled()); | |
758 } | |
759 | |
760 // Verifies that host factors in extension capabilties when reporting | |
Wez
2014/05/28 01:05:59
typo:
dcaiafa
2014/05/28 22:44:58
Done.
| |
761 // capabilities to the client. | |
Wez
2014/05/28 01:05:59
These lines look to be wrongly indented?
dcaiafa
2014/05/28 22:44:58
Done.
| |
762 TEST_F(ClientSessionTest, ExtensionMessages_Capabilities) { | |
763 FakeExtension extension1("ext1", ""); | |
764 FakeExtension extension2("ext2", "capX capZ"); | |
765 FakeExtension extension3("ext3", "capY"); | |
766 extensions_.push_back(&extension1); | |
767 extensions_.push_back(&extension2); | |
768 extensions_.push_back(&extension3); | |
769 | |
770 Expectation authenticated = | |
771 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)) | |
772 .WillOnce(Return(true)); | |
773 EXPECT_CALL(*input_injector_, StartPtr(_)).After(authenticated); | |
774 EXPECT_CALL(client_stub_, | |
775 SetCapabilities(EqCapabilities("capX capY capZ default"))) | |
776 .After(authenticated); | |
777 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)) | |
778 .After(authenticated) | |
779 .WillOnce(DoAll( | |
780 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession), | |
781 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession))); | |
782 | |
783 ConnectClientSession(); | |
784 message_loop_.Run(); | |
785 } | |
786 | |
602 } // namespace remoting | 787 } // namespace remoting |
OLD | NEW |