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

Side by Side Diff: third_party/libjingle_xmpp/xmpp/xmppengine_unittest.cc

Issue 2443903004: Add xmllite and xmpp sources to third_party/ (Closed)
Patch Set: Explicitly use webrtc_overrides/webrtc/base/logging.h Created 3 years, 11 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
OLDNEW
(Empty)
1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <iostream>
12 #include <memory>
13 #include <sstream>
14 #include <string>
15
16 #include "third_party/libjingle_xmpp/xmllite/xmlelement.h"
17 #include "third_party/libjingle_xmpp/xmpp/constants.h"
18 #include "third_party/libjingle_xmpp/xmpp/plainsaslhandler.h"
19 #include "third_party/libjingle_xmpp/xmpp/saslplainmechanism.h"
20 #include "third_party/libjingle_xmpp/xmpp/util_unittest.h"
21 #include "third_party/libjingle_xmpp/xmpp/xmppengine.h"
22 #include "third_party/webrtc/base/common.h"
23 #include "third_party/webrtc/base/gunit.h"
24
25 using buzz::Jid;
26 using buzz::QName;
27 using buzz::XmlElement;
28 using buzz::XmppEngine;
29 using buzz::XmppIqCookie;
30 using buzz::XmppIqHandler;
31 using buzz::XmppTestHandler;
32 using buzz::QN_ID;
33 using buzz::QN_IQ;
34 using buzz::QN_TYPE;
35 using buzz::QN_ROSTER_QUERY;
36 using buzz::XMPP_RETURN_OK;
37 using buzz::XMPP_RETURN_BADARGUMENT;
38
39 // XmppEngineTestIqHandler
40 // This class grabs the response to an IQ stanza and stores it in a string.
41 class XmppEngineTestIqHandler : public XmppIqHandler {
42 public:
43 virtual void IqResponse(XmppIqCookie, const XmlElement * stanza) {
44 ss_ << stanza->Str();
45 }
46
47 std::string IqResponseActivity() {
48 std::string result = ss_.str();
49 ss_.str("");
50 return result;
51 }
52
53 private:
54 std::stringstream ss_;
55 };
56
57 class XmppEngineTest : public testing::Test {
58 public:
59 XmppEngine* engine() { return engine_.get(); }
60 XmppTestHandler* handler() { return handler_.get(); }
61 virtual void SetUp() {
62 engine_.reset(XmppEngine::Create());
63 handler_.reset(new XmppTestHandler(engine_.get()));
64
65 Jid jid("david@my-server");
66 rtc::InsecureCryptStringImpl pass;
67 pass.password() = "david";
68 engine_->SetSessionHandler(handler_.get());
69 engine_->SetOutputHandler(handler_.get());
70 engine_->AddStanzaHandler(handler_.get());
71 engine_->SetUser(jid);
72 engine_->SetSaslHandler(
73 new buzz::PlainSaslHandler(jid, rtc::CryptString(pass), true));
74 }
75 virtual void TearDown() {
76 handler_.reset();
77 engine_.reset();
78 }
79 void RunLogin();
80
81 private:
82 std::unique_ptr<XmppEngine> engine_;
83 std::unique_ptr<XmppTestHandler> handler_;
84 };
85
86 void XmppEngineTest::RunLogin() {
87 // Connect
88 EXPECT_EQ(XmppEngine::STATE_START, engine()->GetState());
89 engine()->Connect();
90 EXPECT_EQ(XmppEngine::STATE_OPENING, engine()->GetState());
91
92 EXPECT_EQ("[OPENING]", handler_->SessionActivity());
93
94 EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" "
95 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
96 "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
97
98 std::string input =
99 "<stream:stream id=\"a5f2d8c9\" version=\"1.0\" "
100 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
101 "xmlns=\"jabber:client\">";
102 engine()->HandleInput(input.c_str(), input.length());
103
104 input =
105 "<stream:features>"
106 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>"
107 "<required/>"
108 "</starttls>"
109 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
110 "<mechanism>DIGEST-MD5</mechanism>"
111 "<mechanism>PLAIN</mechanism>"
112 "</mechanisms>"
113 "</stream:features>";
114 engine()->HandleInput(input.c_str(), input.length());
115 EXPECT_EQ("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>",
116 handler_->OutputActivity());
117
118 EXPECT_EQ("", handler_->SessionActivity());
119 EXPECT_EQ("", handler_->StanzaActivity());
120
121 input = "<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>";
122 engine()->HandleInput(input.c_str(), input.length());
123 EXPECT_EQ("[START-TLS my-server]"
124 "<stream:stream to=\"my-server\" xml:lang=\"*\" "
125 "version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\" "
126 "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
127
128 EXPECT_EQ("", handler_->SessionActivity());
129 EXPECT_EQ("", handler_->StanzaActivity());
130
131 input = "<stream:stream id=\"01234567\" version=\"1.0\" "
132 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
133 "xmlns=\"jabber:client\">";
134 engine()->HandleInput(input.c_str(), input.length());
135
136 input =
137 "<stream:features>"
138 "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"
139 "<mechanism>DIGEST-MD5</mechanism>"
140 "<mechanism>PLAIN</mechanism>"
141 "</mechanisms>"
142 "</stream:features>";
143 engine()->HandleInput(input.c_str(), input.length());
144 EXPECT_EQ("<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" "
145 "mechanism=\"PLAIN\" "
146 "auth:allow-non-google-login=\"true\" "
147 "auth:client-uses-full-bind-result=\"true\" "
148 "xmlns:auth=\"http://www.google.com/talk/protocol/auth\""
149 ">AGRhdmlkAGRhdmlk</auth>",
150 handler_->OutputActivity());
151
152 EXPECT_EQ("", handler_->SessionActivity());
153 EXPECT_EQ("", handler_->StanzaActivity());
154
155 input = "<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>";
156 engine()->HandleInput(input.c_str(), input.length());
157 EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" "
158 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
159 "xmlns=\"jabber:client\">\r\n", handler_->OutputActivity());
160
161 EXPECT_EQ("", handler_->SessionActivity());
162 EXPECT_EQ("", handler_->StanzaActivity());
163
164 input = "<stream:stream id=\"01234567\" version=\"1.0\" "
165 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
166 "xmlns=\"jabber:client\">";
167 engine()->HandleInput(input.c_str(), input.length());
168
169 input = "<stream:features>"
170 "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>"
171 "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>"
172 "</stream:features>";
173 engine()->HandleInput(input.c_str(), input.length());
174 EXPECT_EQ("<iq type=\"set\" id=\"0\">"
175 "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/></iq>",
176 handler_->OutputActivity());
177
178 EXPECT_EQ("", handler_->SessionActivity());
179 EXPECT_EQ("", handler_->StanzaActivity());
180
181 input = "<iq type='result' id='0'>"
182 "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><jid>"
183 "david@my-server/test</jid></bind></iq>";
184 engine()->HandleInput(input.c_str(), input.length());
185
186 EXPECT_EQ("<iq type=\"set\" id=\"1\">"
187 "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/></iq>",
188 handler_->OutputActivity());
189
190 EXPECT_EQ("", handler_->SessionActivity());
191 EXPECT_EQ("", handler_->StanzaActivity());
192
193 input = "<iq type='result' id='1'/>";
194 engine()->HandleInput(input.c_str(), input.length());
195
196 EXPECT_EQ("[OPEN]", handler_->SessionActivity());
197 EXPECT_EQ("", handler_->StanzaActivity());
198 EXPECT_EQ(Jid("david@my-server/test"), engine()->FullJid());
199 }
200
201 // TestSuccessfulLogin()
202 // This function simply tests to see if a login works. This includes
203 // encryption and authentication
204 TEST_F(XmppEngineTest, TestSuccessfulLoginAndDisconnect) {
205 RunLogin();
206 engine()->Disconnect();
207 EXPECT_EQ("</stream:stream>[CLOSED]", handler()->OutputActivity());
208 EXPECT_EQ("[CLOSED]", handler()->SessionActivity());
209 EXPECT_EQ("", handler()->StanzaActivity());
210 }
211
212 TEST_F(XmppEngineTest, TestSuccessfulLoginAndConnectionClosed) {
213 RunLogin();
214 engine()->ConnectionClosed(0);
215 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
216 EXPECT_EQ("[CLOSED][ERROR-CONNECTION-CLOSED]", handler()->SessionActivity());
217 EXPECT_EQ("", handler()->StanzaActivity());
218 }
219
220
221 // TestNotXmpp()
222 // This tests the error case when connecting to a non XMPP service
223 TEST_F(XmppEngineTest, TestNotXmpp) {
224 // Connect
225 engine()->Connect();
226 EXPECT_EQ("<stream:stream to=\"my-server\" xml:lang=\"*\" version=\"1.0\" "
227 "xmlns:stream=\"http://etherx.jabber.org/streams\" "
228 "xmlns=\"jabber:client\">\r\n", handler()->OutputActivity());
229
230 // Send garbage response (courtesy of apache)
231 std::string input = "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">";
232 engine()->HandleInput(input.c_str(), input.length());
233
234 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
235 EXPECT_EQ("[OPENING][CLOSED][ERROR-XML]", handler()->SessionActivity());
236 EXPECT_EQ("", handler()->StanzaActivity());
237 }
238
239 // TestPassthrough()
240 // This tests that arbitrary stanzas can be passed to the server through
241 // the engine.
242 TEST_F(XmppEngineTest, TestPassthrough) {
243 // Queue up an app stanza
244 XmlElement application_stanza(QName("test", "app-stanza"));
245 application_stanza.AddText("this-is-a-test");
246 engine()->SendStanza(&application_stanza);
247
248 // Do the whole login handshake
249 RunLogin();
250
251 EXPECT_EQ("<test:app-stanza xmlns:test=\"test\">this-is-a-test"
252 "</test:app-stanza>", handler()->OutputActivity());
253
254 // do another stanza
255 XmlElement roster_get(QN_IQ);
256 roster_get.AddAttr(QN_TYPE, "get");
257 roster_get.AddAttr(QN_ID, engine()->NextId());
258 roster_get.AddElement(new XmlElement(QN_ROSTER_QUERY, true));
259 engine()->SendStanza(&roster_get);
260 EXPECT_EQ("<iq type=\"get\" id=\"2\"><query xmlns=\"jabber:iq:roster\"/>"
261 "</iq>", handler()->OutputActivity());
262
263 // now say the server ends the stream
264 engine()->HandleInput("</stream:stream>", 16);
265 EXPECT_EQ("[CLOSED][ERROR-DOCUMENT-CLOSED]", handler()->SessionActivity());
266 EXPECT_EQ("[CLOSED]", handler()->OutputActivity());
267 EXPECT_EQ("", handler()->StanzaActivity());
268 }
269
270 // TestIqCallback()
271 // This tests the routing of Iq stanzas and responses.
272 TEST_F(XmppEngineTest, TestIqCallback) {
273 XmppEngineTestIqHandler iq_response;
274 XmppIqCookie cookie;
275
276 // Do the whole login handshake
277 RunLogin();
278
279 // Build an iq request
280 XmlElement roster_get(QN_IQ);
281 roster_get.AddAttr(QN_TYPE, "get");
282 roster_get.AddAttr(QN_ID, engine()->NextId());
283 roster_get.AddElement(new XmlElement(QN_ROSTER_QUERY, true));
284 engine()->SendIq(&roster_get, &iq_response, &cookie);
285 EXPECT_EQ("<iq type=\"get\" id=\"2\"><query xmlns=\"jabber:iq:roster\"/>"
286 "</iq>", handler()->OutputActivity());
287 EXPECT_EQ("", handler()->SessionActivity());
288 EXPECT_EQ("", handler()->StanzaActivity());
289 EXPECT_EQ("", iq_response.IqResponseActivity());
290
291 // now say the server responds to the iq
292 std::string input = "<iq type='result' id='2'>"
293 "<query xmlns='jabber:iq:roster'><item>foo</item>"
294 "</query></iq>";
295 engine()->HandleInput(input.c_str(), input.length());
296 EXPECT_EQ("", handler()->OutputActivity());
297 EXPECT_EQ("", handler()->SessionActivity());
298 EXPECT_EQ("", handler()->StanzaActivity());
299 EXPECT_EQ("<cli:iq type=\"result\" id=\"2\" xmlns:cli=\"jabber:client\">"
300 "<query xmlns=\"jabber:iq:roster\"><item>foo</item></query>"
301 "</cli:iq>", iq_response.IqResponseActivity());
302
303 EXPECT_EQ(XMPP_RETURN_BADARGUMENT, engine()->RemoveIqHandler(cookie, NULL));
304
305 // Do it again with another id to test cancel
306 roster_get.SetAttr(QN_ID, engine()->NextId());
307 engine()->SendIq(&roster_get, &iq_response, &cookie);
308 EXPECT_EQ("<iq type=\"get\" id=\"3\"><query xmlns=\"jabber:iq:roster\"/>"
309 "</iq>", handler()->OutputActivity());
310 EXPECT_EQ("", handler()->SessionActivity());
311 EXPECT_EQ("", handler()->StanzaActivity());
312 EXPECT_EQ("", iq_response.IqResponseActivity());
313
314 // cancel the handler this time
315 EXPECT_EQ(XMPP_RETURN_OK, engine()->RemoveIqHandler(cookie, NULL));
316
317 // now say the server responds to the iq: the iq handler should not get it.
318 input = "<iq type='result' id='3'><query xmlns='jabber:iq:roster'><item>bar"
319 "</item></query></iq>";
320 engine()->HandleInput(input.c_str(), input.length());
321 EXPECT_EQ("<cli:iq type=\"result\" id=\"3\" xmlns:cli=\"jabber:client\">"
322 "<query xmlns=\"jabber:iq:roster\"><item>bar</item></query>"
323 "</cli:iq>", handler()->StanzaActivity());
324 EXPECT_EQ("", iq_response.IqResponseActivity());
325 EXPECT_EQ("", handler()->OutputActivity());
326 EXPECT_EQ("", handler()->SessionActivity());
327 }
OLDNEW
« no previous file with comments | « third_party/libjingle_xmpp/xmpp/xmppengine.h ('k') | third_party/libjingle_xmpp/xmpp/xmppengineimpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698