Do not create the NativeViewport PlatformEventSource when headless.
[chromium-blink-merge.git] / remoting / signaling / xmpp_signal_strategy_unittest.cc
blob219398238b6f1b8ffb555d2e1915552cdd4b0ccb
1 // Copyright 2015 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 "remoting/signaling/xmpp_signal_strategy.h"
7 #include "base/base64.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "net/socket/socket_test_util.h"
11 #include "net/url_request/url_request_test_util.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
15 namespace remoting {
17 namespace {
19 class XmppSocketDataProvider: public net::SocketDataProvider {
20 public:
21 net::MockRead OnRead() override {
22 return net::MockRead(net::ASYNC, net::ERR_IO_PENDING);
25 net::MockWriteResult OnWrite(const std::string& data) override {
26 written_data_.append(data);
27 return net::MockWriteResult(net::SYNCHRONOUS, data.size());
30 void Reset() override {}
32 bool AllReadDataConsumed() const override {
33 return true;
36 bool AllWriteDataConsumed() const override {
37 return true;
40 void ReceiveData(const std::string& text) {
41 socket()->OnReadComplete(
42 net::MockRead(net::ASYNC, text.data(), text.size()));
45 void Close() {
46 ReceiveData(std::string());
49 void SimulateNetworkError() {
50 socket()->OnReadComplete(
51 net::MockRead(net::ASYNC, net::ERR_CONNECTION_RESET));
54 std::string GetAndClearWrittenData() {
55 std::string data;
56 data.swap(written_data_);
57 return data;
60 private:
61 std::string written_data_;
64 } // namespace
66 const char kTestUsername[] = "test_username@example.com";
67 const char kTestAuthToken[] = "test_auth_token";
69 class XmppSignalStrategyTest : public testing::Test,
70 public SignalStrategy::Listener {
71 public:
72 XmppSignalStrategyTest() : message_loop_(base::MessageLoop::TYPE_IO) {}
74 void SetUp() override {
75 scoped_ptr<net::TestURLRequestContext> context(
76 new net::TestURLRequestContext());
77 request_context_getter_ = new net::TestURLRequestContextGetter(
78 message_loop_.task_runner(), context.Pass());
80 XmppSignalStrategy::XmppServerConfig config;
81 config.host = "talk.google.com";
82 config.port = 443;
83 config.username = kTestUsername;
84 config.auth_token = kTestAuthToken;
85 signal_strategy_.reset(new XmppSignalStrategy(
86 &client_socket_factory_, request_context_getter_, config));
87 signal_strategy_->AddListener(this);
90 void TearDown() override {
91 signal_strategy_->RemoveListener(this);
92 signal_strategy_.reset();
93 base::RunLoop().RunUntilIdle();
96 void OnSignalStrategyStateChange(SignalStrategy::State state) override {
97 state_history_.push_back(state);
100 bool OnSignalStrategyIncomingStanza(const buzz::XmlElement* stanza) override {
101 received_messages_.push_back(
102 make_scoped_ptr(new buzz::XmlElement(*stanza)));
103 return true;
106 void Connect(bool success);
108 protected:
109 base::MessageLoop message_loop_;
110 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
111 net::MockClientSocketFactory client_socket_factory_;
112 scoped_ptr<XmppSocketDataProvider> socket_data_provider_;
113 scoped_ptr<net::SSLSocketDataProvider> ssl_socket_data_provider_;
114 scoped_ptr<XmppSignalStrategy> signal_strategy_;
116 std::vector<SignalStrategy::State> state_history_;
117 ScopedVector<buzz::XmlElement> received_messages_;
120 void XmppSignalStrategyTest::Connect(bool success) {
121 EXPECT_EQ(SignalStrategy::DISCONNECTED, signal_strategy_->GetState());
122 state_history_.clear();
124 socket_data_provider_.reset(new XmppSocketDataProvider());
125 socket_data_provider_->set_connect_data(
126 net::MockConnect(net::ASYNC, net::OK));
127 client_socket_factory_.AddSocketDataProvider(socket_data_provider_.get());
129 ssl_socket_data_provider_.reset(
130 new net::SSLSocketDataProvider(net::ASYNC, net::OK));
131 client_socket_factory_.AddSSLSocketDataProvider(
132 ssl_socket_data_provider_.get());
134 signal_strategy_->Connect();
136 EXPECT_EQ(SignalStrategy::CONNECTING, signal_strategy_->GetState());
137 EXPECT_EQ(1U, state_history_.size());
138 EXPECT_EQ(SignalStrategy::CONNECTING, state_history_[0]);
140 // No data written before TLS.
141 EXPECT_EQ("", socket_data_provider_->GetAndClearWrittenData());
143 base::RunLoop().RunUntilIdle();
145 socket_data_provider_->ReceiveData(
146 "<stream:stream from=\"google.com\" id=\"DCDDE5171CB2154A\" "
147 "version=\"1.0\" "
148 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
149 "xmlns=\"jabber:client\">"
150 "<stream:features>"
151 "<mechanisms xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"
152 "<mechanism>X-OAUTH2</mechanism>"
153 "<mechanism>X-GOOGLE-TOKEN</mechanism>"
154 "<mechanism>PLAIN</mechanism>"
155 "</mechanisms>"
156 "</stream:features>");
158 base::RunLoop().RunUntilIdle();
160 std::string cookie;
161 base::Base64Encode(std::string("\0", 1) + kTestUsername +
162 std::string("\0", 1) + kTestAuthToken,
163 &cookie);
164 // Expect auth message.
165 EXPECT_EQ(
166 "<stream:stream to=\"google.com\" version=\"1.0\" "
167 "xmlns=\"jabber:client\" "
168 "xmlns:stream=\"http://etherx.jabber.org/streams\">"
169 "<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"X-OAUTH2\" "
170 "auth:service=\"oauth2\" auth:allow-generated-jid=\"true\" "
171 "auth:client-uses-full-bind-result=\"true\" "
172 "auth:allow-non-google-login=\"true\" "
173 "xmlns:auth=\"http://www.google.com/talk/protocol/auth\">" + cookie +
174 "</auth>", socket_data_provider_->GetAndClearWrittenData());
176 if (!success) {
177 socket_data_provider_->ReceiveData(
178 "<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"
179 "<not-authorized/></failure>");
180 EXPECT_EQ(2U, state_history_.size());
181 EXPECT_EQ(SignalStrategy::DISCONNECTED, state_history_[1]);
182 EXPECT_EQ(SignalStrategy::AUTHENTICATION_FAILED,
183 signal_strategy_->GetError());
184 return;
187 socket_data_provider_->ReceiveData(
188 "<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"/>");
190 base::RunLoop().RunUntilIdle();
192 EXPECT_EQ(
193 "<stream:stream to=\"google.com\" version=\"1.0\" "
194 "xmlns=\"jabber:client\" "
195 "xmlns:stream=\"http://etherx.jabber.org/streams\">"
196 "<iq type=\"set\" id=\"0\">"
197 "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\">"
198 "<resource>chromoting</resource>"
199 "</bind>"
200 "</iq>"
201 "<iq type=\"set\" id=\"1\">"
202 "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>"
203 "</iq>",
204 socket_data_provider_->GetAndClearWrittenData());
205 socket_data_provider_->ReceiveData(
206 "<stream:stream from=\"google.com\" id=\"104FA10576E2AA80\" "
207 "version=\"1.0\" "
208 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
209 "xmlns=\"jabber:client\">"
210 "<stream:features>"
211 "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/>"
212 "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>"
213 "</stream:features>"
214 "<iq id=\"0\" type=\"result\">"
215 "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\">"
216 "<jid>" + std::string(kTestUsername) + "/chromoting52B4920E</jid>"
217 "</bind>"
218 "</iq>"
219 "<iq type=\"result\" id=\"1\"/>");
221 EXPECT_EQ(2U, state_history_.size());
222 EXPECT_EQ(SignalStrategy::CONNECTED, state_history_[1]);
225 TEST_F(XmppSignalStrategyTest, SendAndReceive) {
226 Connect(true);
228 EXPECT_TRUE(signal_strategy_->SendStanza(make_scoped_ptr(
229 new buzz::XmlElement(buzz::QName(std::string(), "hello")))));
230 EXPECT_EQ("<hello/>", socket_data_provider_->GetAndClearWrittenData());
232 socket_data_provider_->ReceiveData("<hi xmlns=\"hello\"/>");
233 EXPECT_EQ(1U, received_messages_.size());
234 EXPECT_EQ("<hi xmlns=\"hello\"/>", received_messages_[0]->Str());
237 TEST_F(XmppSignalStrategyTest, AuthError) {
238 Connect(false);
241 TEST_F(XmppSignalStrategyTest, ConnectionClosed) {
242 Connect(true);
244 socket_data_provider_->Close();
246 EXPECT_EQ(3U, state_history_.size());
247 EXPECT_EQ(SignalStrategy::DISCONNECTED, state_history_[2]);
248 EXPECT_EQ(SignalStrategy::DISCONNECTED, signal_strategy_->GetState());
249 EXPECT_EQ(SignalStrategy::OK, signal_strategy_->GetError());
251 // Can't send messages anymore.
252 EXPECT_FALSE(signal_strategy_->SendStanza(make_scoped_ptr(
253 new buzz::XmlElement(buzz::QName(std::string(), "hello")))));
255 // Try connecting again.
256 Connect(true);
259 TEST_F(XmppSignalStrategyTest, NetworkError) {
260 Connect(true);
262 socket_data_provider_->SimulateNetworkError();
264 EXPECT_EQ(3U, state_history_.size());
265 EXPECT_EQ(SignalStrategy::DISCONNECTED, state_history_[2]);
266 EXPECT_EQ(SignalStrategy::NETWORK_ERROR, signal_strategy_->GetError());
268 // Can't send messages anymore.
269 EXPECT_FALSE(signal_strategy_->SendStanza(make_scoped_ptr(
270 new buzz::XmlElement(buzz::QName(std::string(), "hello")))));
272 // Try connecting again.
273 Connect(true);
276 } // namespace remoting