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

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

Powered by Google App Engine
This is Rietveld 408576698