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

Side by Side Diff: third_party/twisted_8_1/twisted/words/test/test_jabberxmlstream.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2001-2008 Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4 """
5 Tests for L{twisted.words.protocols.jabber.xmlstream}.
6 """
7
8 from twisted.trial import unittest
9
10 from zope.interface.verify import verifyObject
11
12 from twisted.internet import defer, task
13 from twisted.internet.error import ConnectionLost
14 from twisted.test import proto_helpers
15 from twisted.words.xish import domish
16 from twisted.words.protocols.jabber import error, ijabber, jid, xmlstream
17
18
19
20 NS_XMPP_TLS = 'urn:ietf:params:xml:ns:xmpp-tls'
21
22
23
24 class IQTest(unittest.TestCase):
25 """
26 Tests both IQ and the associated IIQResponseTracker callback.
27 """
28
29 def setUp(self):
30 authenticator = xmlstream.ConnectAuthenticator('otherhost')
31 authenticator.namespace = 'testns'
32 self.xmlstream = xmlstream.XmlStream(authenticator)
33 self.clock = task.Clock()
34 self.xmlstream._callLater = self.clock.callLater
35 self.xmlstream.makeConnection(proto_helpers.StringTransport())
36 self.xmlstream.dataReceived(
37 "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
38 "xmlns='testns' from='otherhost' version='1.0'>")
39 self.iq = xmlstream.IQ(self.xmlstream, 'get')
40
41
42 def testBasic(self):
43 self.assertEquals(self.iq['type'], 'get')
44 self.assertTrue(self.iq['id'])
45
46
47 def testSend(self):
48 self.xmlstream.transport.clear()
49 self.iq.send()
50 self.assertEquals("<iq type='get' id='%s'/>" % self.iq['id'],
51 self.xmlstream.transport.value())
52
53
54 def testResultResponse(self):
55 def cb(result):
56 self.assertEquals(result['type'], 'result')
57
58 d = self.iq.send()
59 d.addCallback(cb)
60
61 xs = self.xmlstream
62 xs.dataReceived("<iq type='result' id='%s'/>" % self.iq['id'])
63 return d
64
65
66 def testErrorResponse(self):
67 d = self.iq.send()
68 self.assertFailure(d, error.StanzaError)
69
70 xs = self.xmlstream
71 xs.dataReceived("<iq type='error' id='%s'/>" % self.iq['id'])
72 return d
73
74
75 def testNonTrackedResponse(self):
76 """
77 Test that untracked iq responses don't trigger any action.
78
79 Untracked means that the id of the incoming response iq is not
80 in the stream's C{iqDeferreds} dictionary.
81 """
82 xs = self.xmlstream
83 xmlstream.upgradeWithIQResponseTracker(xs)
84
85 # Make sure we aren't tracking any iq's.
86 self.failIf(xs.iqDeferreds)
87
88 # Set up a fallback handler that checks the stanza's handled attribute.
89 # If that is set to True, the iq tracker claims to have handled the
90 # response.
91 def cb(iq):
92 self.failIf(getattr(iq, 'handled', False))
93
94 xs.addObserver("/iq", cb, -1)
95
96 # Receive an untracked iq response
97 xs.dataReceived("<iq type='result' id='test'/>")
98
99
100 def testCleanup(self):
101 """
102 Test if the deferred associated with an iq request is removed
103 from the list kept in the L{XmlStream} object after it has
104 been fired.
105 """
106
107 d = self.iq.send()
108 xs = self.xmlstream
109 xs.dataReceived("<iq type='result' id='%s'/>" % self.iq['id'])
110 self.assertNotIn(self.iq['id'], xs.iqDeferreds)
111 return d
112
113
114 def testDisconnectCleanup(self):
115 """
116 Test if deferreds for iq's that haven't yet received a response
117 have their errback called on stream disconnect.
118 """
119
120 d = self.iq.send()
121 xs = self.xmlstream
122 xs.connectionLost("Closed by peer")
123 self.assertFailure(d, ConnectionLost)
124 return d
125
126
127 def testNoModifyingDict(self):
128 """
129 Test to make sure the errbacks cannot cause the iteration of the
130 iqDeferreds to blow up in our face.
131 """
132
133 def eb(failure):
134 d = xmlstream.IQ(self.xmlstream).send()
135 d.addErrback(eb)
136
137 d = self.iq.send()
138 d.addErrback(eb)
139 self.xmlstream.connectionLost("Closed by peer")
140 return d
141
142
143 def testRequestTimingOut(self):
144 """
145 Test that an iq request with a defined timeout times out.
146 """
147 self.iq.timeout = 60
148 d = self.iq.send()
149 self.assertFailure(d, xmlstream.TimeoutError)
150
151 self.clock.pump([1, 60])
152 self.failIf(self.clock.calls)
153 self.failIf(self.xmlstream.iqDeferreds)
154 return d
155
156
157 def testRequestNotTimingOut(self):
158 """
159 Test that an iq request with a defined timeout does not time out
160 when a response was received before the timeout period elapsed.
161 """
162 self.iq.timeout = 60
163 d = self.iq.send()
164 self.clock.callLater(1, self.xmlstream.dataReceived,
165 "<iq type='result' id='%s'/>" % self.iq['id'])
166 self.clock.pump([1, 1])
167 self.failIf(self.clock.calls)
168 return d
169
170
171 def testDisconnectTimeoutCancellation(self):
172 """
173 Test if timeouts for iq's that haven't yet received a response
174 are cancelled on stream disconnect.
175 """
176
177 self.iq.timeout = 60
178 d = self.iq.send()
179
180 xs = self.xmlstream
181 xs.connectionLost("Closed by peer")
182 self.assertFailure(d, ConnectionLost)
183 self.failIf(self.clock.calls)
184 return d
185
186
187
188 class XmlStreamTest(unittest.TestCase):
189
190 def onStreamStart(self, obj):
191 self.gotStreamStart = True
192
193
194 def onStreamEnd(self, obj):
195 self.gotStreamEnd = True
196
197
198 def onStreamError(self, obj):
199 self.gotStreamError = True
200
201
202 def setUp(self):
203 """
204 Set up XmlStream and several observers.
205 """
206 self.gotStreamStart = False
207 self.gotStreamEnd = False
208 self.gotStreamError = False
209 xs = xmlstream.XmlStream(xmlstream.Authenticator())
210 xs.addObserver('//event/stream/start', self.onStreamStart)
211 xs.addObserver('//event/stream/end', self.onStreamEnd)
212 xs.addObserver('//event/stream/error', self.onStreamError)
213 xs.makeConnection(proto_helpers.StringTransportWithDisconnection())
214 xs.transport.protocol = xs
215 xs.namespace = 'testns'
216 xs.version = (1, 0)
217 self.xmlstream = xs
218
219
220 def test_sendHeaderBasic(self):
221 """
222 Basic test on the header sent by sendHeader.
223 """
224 xs = self.xmlstream
225 xs.sendHeader()
226 splitHeader = self.xmlstream.transport.value()[0:-1].split(' ')
227 self.assertIn("<stream:stream", splitHeader)
228 self.assertIn("xmlns:stream='http://etherx.jabber.org/streams'",
229 splitHeader)
230 self.assertIn("xmlns='testns'", splitHeader)
231 self.assertIn("version='1.0'", splitHeader)
232 self.assertTrue(xs._headerSent)
233
234
235 def test_sendHeaderAdditionalNamespaces(self):
236 """
237 Test for additional namespace declarations.
238 """
239 xs = self.xmlstream
240 xs.prefixes['jabber:server:dialback'] = 'db'
241 xs.sendHeader()
242 splitHeader = self.xmlstream.transport.value()[0:-1].split(' ')
243 self.assertIn("<stream:stream", splitHeader)
244 self.assertIn("xmlns:stream='http://etherx.jabber.org/streams'",
245 splitHeader)
246 self.assertIn("xmlns:db='jabber:server:dialback'", splitHeader)
247 self.assertIn("xmlns='testns'", splitHeader)
248 self.assertIn("version='1.0'", splitHeader)
249 self.assertTrue(xs._headerSent)
250
251
252 def test_sendHeaderInitiating(self):
253 """
254 Test addressing when initiating a stream.
255 """
256 xs = self.xmlstream
257 xs.thisEntity = jid.JID('thisHost')
258 xs.otherEntity = jid.JID('otherHost')
259 xs.initiating = True
260 xs.sendHeader()
261 splitHeader = xs.transport.value()[0:-1].split(' ')
262 self.assertIn("to='otherhost'", splitHeader)
263 self.assertIn("from='thishost'", splitHeader)
264
265
266 def test_sendHeaderReceiving(self):
267 """
268 Test addressing when receiving a stream.
269 """
270 xs = self.xmlstream
271 xs.thisEntity = jid.JID('thisHost')
272 xs.otherEntity = jid.JID('otherHost')
273 xs.initiating = False
274 xs.sid = 'session01'
275 xs.sendHeader()
276 splitHeader = xs.transport.value()[0:-1].split(' ')
277 self.assertIn("to='otherhost'", splitHeader)
278 self.assertIn("from='thishost'", splitHeader)
279 self.assertIn("id='session01'", splitHeader)
280
281
282 def test_receiveStreamError(self):
283 """
284 Test events when a stream error is received.
285 """
286 xs = self.xmlstream
287 xs.dataReceived("<stream:stream xmlns='jabber:client' "
288 "xmlns:stream='http://etherx.jabber.org/streams' "
289 "from='example.com' id='12345' version='1.0'>")
290 xs.dataReceived("<stream:error/>")
291 self.assertTrue(self.gotStreamError)
292 self.assertTrue(self.gotStreamEnd)
293
294
295 def test_sendStreamErrorInitiating(self):
296 """
297 Test sendStreamError on an initiating xmlstream with a header sent.
298
299 An error should be sent out and the connection lost.
300 """
301 xs = self.xmlstream
302 xs.initiating = True
303 xs.sendHeader()
304 xs.transport.clear()
305 xs.sendStreamError(error.StreamError('version-unsupported'))
306 self.assertNotEqual('', xs.transport.value())
307 self.assertTrue(self.gotStreamEnd)
308
309
310 def test_sendStreamErrorInitiatingNoHeader(self):
311 """
312 Test sendStreamError on an initiating xmlstream without having sent a
313 header.
314
315 In this case, no header should be generated. Also, the error should
316 not be sent out on the stream. Just closing the connection.
317 """
318 xs = self.xmlstream
319 xs.initiating = True
320 xs.transport.clear()
321 xs.sendStreamError(error.StreamError('version-unsupported'))
322 self.assertNot(xs._headerSent)
323 self.assertEqual('', xs.transport.value())
324 self.assertTrue(self.gotStreamEnd)
325
326
327 def test_sendStreamErrorReceiving(self):
328 """
329 Test sendStreamError on a receiving xmlstream with a header sent.
330
331 An error should be sent out and the connection lost.
332 """
333 xs = self.xmlstream
334 xs.initiating = False
335 xs.sendHeader()
336 xs.transport.clear()
337 xs.sendStreamError(error.StreamError('version-unsupported'))
338 self.assertNotEqual('', xs.transport.value())
339 self.assertTrue(self.gotStreamEnd)
340
341
342 def test_sendStreamErrorReceivingNoHeader(self):
343 """
344 Test sendStreamError on a receiving xmlstream without having sent a
345 header.
346
347 In this case, a header should be generated. Then, the error should
348 be sent out on the stream followed by closing the connection.
349 """
350 xs = self.xmlstream
351 xs.initiating = False
352 xs.transport.clear()
353 xs.sendStreamError(error.StreamError('version-unsupported'))
354 self.assertTrue(xs._headerSent)
355 self.assertNotEqual('', xs.transport.value())
356 self.assertTrue(self.gotStreamEnd)
357
358
359 def test_reset(self):
360 """
361 Test resetting the XML stream to start a new layer.
362 """
363 xs = self.xmlstream
364 xs.sendHeader()
365 stream = xs.stream
366 xs.reset()
367 self.assertNotEqual(stream, xs.stream)
368 self.assertNot(xs._headerSent)
369
370
371 def test_send(self):
372 """
373 Test send with various types of objects.
374 """
375 xs = self.xmlstream
376 xs.send('<presence/>')
377 self.assertEqual(xs.transport.value(), '<presence/>')
378
379 xs.transport.clear()
380 el = domish.Element(('testns', 'presence'))
381 xs.send(el)
382 self.assertEqual(xs.transport.value(), '<presence/>')
383
384 xs.transport.clear()
385 el = domish.Element(('http://etherx.jabber.org/streams', 'features'))
386 xs.send(el)
387 self.assertEqual(xs.transport.value(), '<stream:features/>')
388
389
390 def test_authenticator(self):
391 """
392 Test that the associated authenticator is correctly called.
393 """
394 connectionMadeCalls = []
395 streamStartedCalls = []
396 associateWithStreamCalls = []
397
398 class TestAuthenticator:
399 def connectionMade(self):
400 connectionMadeCalls.append(None)
401
402 def streamStarted(self, rootElement):
403 streamStartedCalls.append(rootElement)
404
405 def associateWithStream(self, xs):
406 associateWithStreamCalls.append(xs)
407
408 a = TestAuthenticator()
409 xs = xmlstream.XmlStream(a)
410 self.assertEqual([xs], associateWithStreamCalls)
411 xs.connectionMade()
412 self.assertEqual([None], connectionMadeCalls)
413 xs.dataReceived("<stream:stream xmlns='jabber:client' "
414 "xmlns:stream='http://etherx.jabber.org/streams' "
415 "from='example.com' id='12345'>")
416 self.assertEqual(1, len(streamStartedCalls))
417 xs.reset()
418 self.assertEqual([None], connectionMadeCalls)
419
420
421
422 class TestError(Exception):
423 pass
424
425
426
427 class AuthenticatorTest(unittest.TestCase):
428 def setUp(self):
429 self.authenticator = xmlstream.ListenAuthenticator()
430 self.xmlstream = xmlstream.XmlStream(self.authenticator)
431
432
433 def test_streamStart(self):
434 """
435 Test streamStart to fill the appropriate attributes from the
436 stream header.
437 """
438 xs = self.xmlstream
439 xs.makeConnection(proto_helpers.StringTransport())
440 xs.dataReceived("<stream:stream xmlns='jabber:client' "
441 "xmlns:stream='http://etherx.jabber.org/streams' "
442 "from='example.org' to='example.com' id='12345' "
443 "version='1.0'>")
444 self.assertEqual((1, 0), xs.version)
445 self.assertIdentical(None, xs.sid)
446 self.assertEqual('jabber:client', xs.namespace)
447 self.assertIdentical(None, xs.otherEntity)
448 self.assertEqual('example.com', xs.thisEntity.host)
449
450
451 def test_streamStartLegacy(self):
452 """
453 Test streamStart to fill the appropriate attributes from the
454 stream header for a pre-XMPP-1.0 header.
455 """
456 xs = self.xmlstream
457 xs.makeConnection(proto_helpers.StringTransport())
458 xs.dataReceived("<stream:stream xmlns='jabber:client' "
459 "xmlns:stream='http://etherx.jabber.org/streams' "
460 "from='example.com' id='12345'>")
461 self.assertEqual((0, 0), xs.version)
462
463
464 def test_streamBadVersionOneDigit(self):
465 """
466 Test streamStart to fill the appropriate attributes from the
467 stream header for a version with only one digit.
468 """
469 xs = self.xmlstream
470 xs.makeConnection(proto_helpers.StringTransport())
471 xs.dataReceived("<stream:stream xmlns='jabber:client' "
472 "xmlns:stream='http://etherx.jabber.org/streams' "
473 "from='example.com' id='12345' version='1'>")
474 self.assertEqual((0, 0), xs.version)
475
476
477 def test_streamBadVersionNoNumber(self):
478 """
479 Test streamStart to fill the appropriate attributes from the
480 stream header for a malformed version.
481 """
482 xs = self.xmlstream
483 xs.makeConnection(proto_helpers.StringTransport())
484 xs.dataReceived("<stream:stream xmlns='jabber:client' "
485 "xmlns:stream='http://etherx.jabber.org/streams' "
486 "from='example.com' id='12345' version='blah'>")
487 self.assertEqual((0, 0), xs.version)
488
489
490
491 class ConnectAuthenticatorTest(unittest.TestCase):
492
493 def setUp(self):
494 self.gotAuthenticated = False
495 self.initFailure = None
496 self.authenticator = xmlstream.ConnectAuthenticator('otherHost')
497 self.xmlstream = xmlstream.XmlStream(self.authenticator)
498 self.xmlstream.addObserver('//event/stream/authd', self.onAuthenticated)
499 self.xmlstream.addObserver('//event/xmpp/initfailed', self.onInitFailed)
500
501
502 def onAuthenticated(self, obj):
503 self.gotAuthenticated = True
504
505
506 def onInitFailed(self, failure):
507 self.initFailure = failure
508
509
510 def testSucces(self):
511 """
512 Test successful completion of an initialization step.
513 """
514 class Initializer:
515 def initialize(self):
516 pass
517
518 init = Initializer()
519 self.xmlstream.initializers = [init]
520
521 self.authenticator.initializeStream()
522 self.assertEqual([], self.xmlstream.initializers)
523 self.assertTrue(self.gotAuthenticated)
524
525
526 def testFailure(self):
527 """
528 Test failure of an initialization step.
529 """
530 class Initializer:
531 def initialize(self):
532 raise TestError
533
534 init = Initializer()
535 self.xmlstream.initializers = [init]
536
537 self.authenticator.initializeStream()
538 self.assertEqual([init], self.xmlstream.initializers)
539 self.assertFalse(self.gotAuthenticated)
540 self.assertNotIdentical(None, self.initFailure)
541 self.assertTrue(self.initFailure.check(TestError))
542
543
544 def test_streamStart(self):
545 """
546 Test streamStart to fill the appropriate attributes from the
547 stream header.
548 """
549 self.authenticator.namespace = 'testns'
550 xs = self.xmlstream
551 xs.makeConnection(proto_helpers.StringTransport())
552 xs.dataReceived("<stream:stream xmlns='jabber:client' "
553 "xmlns:stream='http://etherx.jabber.org/streams' "
554 "from='example.com' to='example.org' id='12345' "
555 "version='1.0'>")
556 self.assertEqual((1, 0), xs.version)
557 self.assertEqual('12345', xs.sid)
558 self.assertEqual('testns', xs.namespace)
559 self.assertEqual('example.com', xs.otherEntity.host)
560 self.assertIdentical(None, xs.thisEntity)
561 self.assertNot(self.gotAuthenticated)
562 xs.dataReceived("<stream:features>"
563 "<test xmlns='testns'/>"
564 "</stream:features>")
565 self.assertIn(('testns', 'test'), xs.features)
566 self.assertTrue(self.gotAuthenticated)
567
568
569
570 class ListenAuthenticatorTest(unittest.TestCase):
571 def setUp(self):
572 self.authenticator = xmlstream.ListenAuthenticator()
573 self.xmlstream = xmlstream.XmlStream(self.authenticator)
574
575
576 def test_streamStart(self):
577 """
578 Test streamStart to fill the appropriate attributes from the
579 stream header.
580 """
581 xs = self.xmlstream
582 xs.makeConnection(proto_helpers.StringTransport())
583 xs.dataReceived("<stream:stream xmlns='jabber:client' "
584 "xmlns:stream='http://etherx.jabber.org/streams' "
585 "from='example.org' to='example.com' id='12345' "
586 "version='1.0'>")
587 self.assertEqual((1, 0), xs.version)
588 self.assertIdentical(None, xs.sid)
589 self.assertEqual('jabber:client', xs.namespace)
590 self.assertIdentical(None, xs.otherEntity)
591 self.assertEqual('example.com', xs.thisEntity.host)
592
593
594
595 class TLSInitiatingInitializerTest(unittest.TestCase):
596 def setUp(self):
597 self.output = []
598 self.done = []
599
600 self.savedSSL = xmlstream.ssl
601
602 self.authenticator = xmlstream.Authenticator()
603 self.xmlstream = xmlstream.XmlStream(self.authenticator)
604 self.xmlstream.send = self.output.append
605 self.xmlstream.connectionMade()
606 self.xmlstream.dataReceived("<stream:stream xmlns='jabber:client' "
607 "xmlns:stream='http://etherx.jabber.org/streams' "
608 "from='example.com' id='12345' version='1.0'>")
609 self.init = xmlstream.TLSInitiatingInitializer(self.xmlstream)
610
611
612 def tearDown(self):
613 xmlstream.ssl = self.savedSSL
614
615
616 def testWantedSupported(self):
617 """
618 Test start when TLS is wanted and the SSL library available.
619 """
620 self.xmlstream.transport = proto_helpers.StringTransport()
621 self.xmlstream.transport.startTLS = lambda ctx: self.done.append('TLS')
622 self.xmlstream.reset = lambda: self.done.append('reset')
623 self.xmlstream.sendHeader = lambda: self.done.append('header')
624
625 d = self.init.start()
626 d.addCallback(self.assertEquals, xmlstream.Reset)
627 starttls = self.output[0]
628 self.assertEquals('starttls', starttls.name)
629 self.assertEquals(NS_XMPP_TLS, starttls.uri)
630 self.xmlstream.dataReceived("<proceed xmlns='%s'/>" % NS_XMPP_TLS)
631 self.assertEquals(['TLS', 'reset', 'header'], self.done)
632
633 return d
634
635 if not xmlstream.ssl:
636 testWantedSupported.skip = "SSL not available"
637
638
639 def testWantedNotSupportedNotRequired(self):
640 """
641 Test start when TLS is wanted and the SSL library available.
642 """
643 xmlstream.ssl = None
644
645 d = self.init.start()
646 d.addCallback(self.assertEquals, None)
647 self.assertEquals([], self.output)
648
649 return d
650
651
652 def testWantedNotSupportedRequired(self):
653 """
654 Test start when TLS is wanted and the SSL library available.
655 """
656 xmlstream.ssl = None
657 self.init.required = True
658
659 d = self.init.start()
660 self.assertFailure(d, xmlstream.TLSNotSupported)
661 self.assertEquals([], self.output)
662
663 return d
664
665
666 def testNotWantedRequired(self):
667 """
668 Test start when TLS is not wanted, but required by the server.
669 """
670 tls = domish.Element(('urn:ietf:params:xml:ns:xmpp-tls', 'starttls'))
671 tls.addElement('required')
672 self.xmlstream.features = {(tls.uri, tls.name): tls}
673 self.init.wanted = False
674
675 d = self.init.start()
676 self.assertEquals([], self.output)
677 self.assertFailure(d, xmlstream.TLSRequired)
678
679 return d
680
681
682 def testNotWantedNotRequired(self):
683 """
684 Test start when TLS is not wanted, but required by the server.
685 """
686 tls = domish.Element(('urn:ietf:params:xml:ns:xmpp-tls', 'starttls'))
687 self.xmlstream.features = {(tls.uri, tls.name): tls}
688 self.init.wanted = False
689
690 d = self.init.start()
691 d.addCallback(self.assertEqual, None)
692 self.assertEquals([], self.output)
693 return d
694
695
696 def testFailed(self):
697 """
698 Test failed TLS negotiation.
699 """
700 # Pretend that ssl is supported, it isn't actually used when the
701 # server starts out with a failure in response to our initial
702 # C{starttls} stanza.
703 xmlstream.ssl = 1
704
705 d = self.init.start()
706 self.assertFailure(d, xmlstream.TLSFailed)
707 self.xmlstream.dataReceived("<failure xmlns='%s'/>" % NS_XMPP_TLS)
708 return d
709
710
711
712 class TestFeatureInitializer(xmlstream.BaseFeatureInitiatingInitializer):
713 feature = ('testns', 'test')
714
715 def start(self):
716 return defer.succeed(None)
717
718
719
720 class BaseFeatureInitiatingInitializerTest(unittest.TestCase):
721
722 def setUp(self):
723 self.xmlstream = xmlstream.XmlStream(xmlstream.Authenticator())
724 self.init = TestFeatureInitializer(self.xmlstream)
725
726
727 def testAdvertized(self):
728 """
729 Test that an advertized feature results in successful initialization.
730 """
731 self.xmlstream.features = {self.init.feature:
732 domish.Element(self.init.feature)}
733 return self.init.initialize()
734
735
736 def testNotAdvertizedRequired(self):
737 """
738 Test that when the feature is not advertized, but required by the
739 initializer, an exception is raised.
740 """
741 self.init.required = True
742 self.assertRaises(xmlstream.FeatureNotAdvertized, self.init.initialize)
743
744
745 def testNotAdvertizedNotRequired(self):
746 """
747 Test that when the feature is not advertized, and not required by the
748 initializer, the initializer silently succeeds.
749 """
750 self.init.required = False
751 self.assertIdentical(None, self.init.initialize())
752
753
754
755 class ToResponseTest(unittest.TestCase):
756
757 def test_toResponse(self):
758 """
759 Test that a response stanza is generated with addressing swapped.
760 """
761 stanza = domish.Element(('jabber:client', 'iq'))
762 stanza['type'] = 'get'
763 stanza['to'] = 'user1@example.com'
764 stanza['from'] = 'user2@example.com/resource'
765 stanza['id'] = 'stanza1'
766 response = xmlstream.toResponse(stanza, 'result')
767 self.assertNotIdentical(stanza, response)
768 self.assertEqual(response['from'], 'user1@example.com')
769 self.assertEqual(response['to'], 'user2@example.com/resource')
770 self.assertEqual(response['type'], 'result')
771 self.assertEqual(response['id'], 'stanza1')
772
773
774 def test_toResponseNoFrom(self):
775 """
776 Test that a response is generated from a stanza without a from address.
777 """
778 stanza = domish.Element(('jabber:client', 'iq'))
779 stanza['type'] = 'get'
780 stanza['to'] = 'user1@example.com'
781 response = xmlstream.toResponse(stanza)
782 self.assertEqual(response['from'], 'user1@example.com')
783 self.failIf(response.hasAttribute('to'))
784
785
786 def test_toResponseNoTo(self):
787 """
788 Test that a response is generated from a stanza without a to address.
789 """
790 stanza = domish.Element(('jabber:client', 'iq'))
791 stanza['type'] = 'get'
792 stanza['from'] = 'user2@example.com/resource'
793 response = xmlstream.toResponse(stanza)
794 self.failIf(response.hasAttribute('from'))
795 self.assertEqual(response['to'], 'user2@example.com/resource')
796
797
798 def test_toResponseNoAddressing(self):
799 """
800 Test that a response is generated from a stanza without any addressing.
801 """
802 stanza = domish.Element(('jabber:client', 'message'))
803 stanza['type'] = 'chat'
804 response = xmlstream.toResponse(stanza)
805 self.failIf(response.hasAttribute('to'))
806 self.failIf(response.hasAttribute('from'))
807
808
809 def test_noID(self):
810 """
811 Test that a proper response is generated without id attribute.
812 """
813 stanza = domish.Element(('jabber:client', 'message'))
814 response = xmlstream.toResponse(stanza)
815 self.failIf(response.hasAttribute('id'))
816
817
818
819 class DummyFactory(object):
820 """
821 Dummy XmlStream factory that only registers bootstrap observers.
822 """
823 def __init__(self):
824 self.callbacks = {}
825
826
827 def addBootstrap(self, event, callback):
828 self.callbacks[event] = callback
829
830
831
832 class DummyXMPPHandler(xmlstream.XMPPHandler):
833 """
834 Dummy XMPP subprotocol handler to count the methods are called on it.
835 """
836 def __init__(self):
837 self.doneMade = 0
838 self.doneInitialized = 0
839 self.doneLost = 0
840
841
842 def makeConnection(self, xs):
843 self.connectionMade()
844
845
846 def connectionMade(self):
847 self.doneMade += 1
848
849
850 def connectionInitialized(self):
851 self.doneInitialized += 1
852
853
854 def connectionLost(self, reason):
855 self.doneLost += 1
856
857
858
859 class XMPPHandlerTest(unittest.TestCase):
860 """
861 Tests for L{xmlstream.XMPPHandler}.
862 """
863
864 def test_interface(self):
865 """
866 L{xmlstream.XMPPHandler} implements L{ijabber.IXMPPHandler}.
867 """
868 verifyObject(ijabber.IXMPPHandler, xmlstream.XMPPHandler())
869
870
871 def test_send(self):
872 """
873 Test that data is passed on for sending by the stream manager.
874 """
875 class DummyStreamManager(object):
876 def __init__(self):
877 self.outlist = []
878
879 def send(self, data):
880 self.outlist.append(data)
881
882 handler = xmlstream.XMPPHandler()
883 handler.parent = DummyStreamManager()
884 handler.send('<presence/>')
885 self.assertEquals(['<presence/>'], handler.parent.outlist)
886
887
888 def test_makeConnection(self):
889 """
890 Test that makeConnection saves the XML stream and calls connectionMade.
891 """
892 class TestXMPPHandler(xmlstream.XMPPHandler):
893 def connectionMade(self):
894 self.doneMade = True
895
896 handler = TestXMPPHandler()
897 xs = xmlstream.XmlStream(xmlstream.Authenticator())
898 handler.makeConnection(xs)
899 self.assertTrue(handler.doneMade)
900 self.assertIdentical(xs, handler.xmlstream)
901
902
903 def test_connectionLost(self):
904 """
905 Test that connectionLost forgets the XML stream.
906 """
907 handler = xmlstream.XMPPHandler()
908 xs = xmlstream.XmlStream(xmlstream.Authenticator())
909 handler.makeConnection(xs)
910 handler.connectionLost(Exception())
911 self.assertIdentical(None, handler.xmlstream)
912
913
914
915 class XMPPHandlerCollectionTest(unittest.TestCase):
916 """
917 Tests for L{xmlstream.XMPPHandlerCollection}.
918 """
919
920 def setUp(self):
921 self.collection = xmlstream.XMPPHandlerCollection()
922
923
924 def test_interface(self):
925 """
926 L{xmlstream.StreamManager} implements L{ijabber.IXMPPHandlerCollection}.
927 """
928 verifyObject(ijabber.IXMPPHandlerCollection, self.collection)
929
930
931 def test_addHandler(self):
932 """
933 Test the addition of a protocol handler.
934 """
935 handler = DummyXMPPHandler()
936 handler.setHandlerParent(self.collection)
937 self.assertIn(handler, self.collection)
938 self.assertIdentical(self.collection, handler.parent)
939
940
941 def test_removeHandler(self):
942 """
943 Test removal of a protocol handler.
944 """
945 handler = DummyXMPPHandler()
946 handler.setHandlerParent(self.collection)
947 handler.disownHandlerParent(self.collection)
948 self.assertNotIn(handler, self.collection)
949 self.assertIdentical(None, handler.parent)
950
951
952
953 class StreamManagerTest(unittest.TestCase):
954 """
955 Tests for L{xmlstream.StreamManager}.
956 """
957
958 def setUp(self):
959 factory = DummyFactory()
960 self.streamManager = xmlstream.StreamManager(factory)
961
962
963 def test_basic(self):
964 """
965 Test correct initialization and setup of factory observers.
966 """
967 sm = self.streamManager
968 self.assertIdentical(None, sm.xmlstream)
969 self.assertEquals([], sm.handlers)
970 self.assertEquals(sm._connected,
971 sm.factory.callbacks['//event/stream/connected'])
972 self.assertEquals(sm._authd,
973 sm.factory.callbacks['//event/stream/authd'])
974 self.assertEquals(sm._disconnected,
975 sm.factory.callbacks['//event/stream/end'])
976 self.assertEquals(sm.initializationFailed,
977 sm.factory.callbacks['//event/xmpp/initfailed'])
978
979
980 def test_connected(self):
981 """
982 Test that protocol handlers have their connectionMade method called
983 when the XML stream is connected.
984 """
985 sm = self.streamManager
986 handler = DummyXMPPHandler()
987 handler.setHandlerParent(sm)
988 xs = xmlstream.XmlStream(xmlstream.Authenticator())
989 sm._connected(xs)
990 self.assertEquals(1, handler.doneMade)
991 self.assertEquals(0, handler.doneInitialized)
992 self.assertEquals(0, handler.doneLost)
993
994
995 def test_connectedLogTrafficFalse(self):
996 """
997 Test raw data functions unset when logTraffic is set to False.
998 """
999 sm = self.streamManager
1000 handler = DummyXMPPHandler()
1001 handler.setHandlerParent(sm)
1002 xs = xmlstream.XmlStream(xmlstream.Authenticator())
1003 sm._connected(xs)
1004 self.assertIdentical(None, xs.rawDataInFn)
1005 self.assertIdentical(None, xs.rawDataOutFn)
1006
1007
1008 def test_connectedLogTrafficTrue(self):
1009 """
1010 Test raw data functions set when logTraffic is set to True.
1011 """
1012 sm = self.streamManager
1013 sm.logTraffic = True
1014 handler = DummyXMPPHandler()
1015 handler.setHandlerParent(sm)
1016 xs = xmlstream.XmlStream(xmlstream.Authenticator())
1017 sm._connected(xs)
1018 self.assertNotIdentical(None, xs.rawDataInFn)
1019 self.assertNotIdentical(None, xs.rawDataOutFn)
1020
1021
1022 def test_authd(self):
1023 """
1024 Test that protocol handlers have their connectionInitialized method
1025 called when the XML stream is initialized.
1026 """
1027 sm = self.streamManager
1028 handler = DummyXMPPHandler()
1029 handler.setHandlerParent(sm)
1030 xs = xmlstream.XmlStream(xmlstream.Authenticator())
1031 sm._authd(xs)
1032 self.assertEquals(0, handler.doneMade)
1033 self.assertEquals(1, handler.doneInitialized)
1034 self.assertEquals(0, handler.doneLost)
1035
1036
1037 def test_disconnected(self):
1038 """
1039 Test that protocol handlers have their connectionLost method
1040 called when the XML stream is disconnected.
1041 """
1042 sm = self.streamManager
1043 handler = DummyXMPPHandler()
1044 handler.setHandlerParent(sm)
1045 xs = xmlstream.XmlStream(xmlstream.Authenticator())
1046 sm._disconnected(xs)
1047 self.assertEquals(0, handler.doneMade)
1048 self.assertEquals(0, handler.doneInitialized)
1049 self.assertEquals(1, handler.doneLost)
1050
1051
1052 def test_addHandler(self):
1053 """
1054 Test the addition of a protocol handler while not connected.
1055 """
1056 sm = self.streamManager
1057 handler = DummyXMPPHandler()
1058 handler.setHandlerParent(sm)
1059
1060 self.assertEquals(0, handler.doneMade)
1061 self.assertEquals(0, handler.doneInitialized)
1062 self.assertEquals(0, handler.doneLost)
1063
1064
1065 def test_addHandlerInitialized(self):
1066 """
1067 Test the addition of a protocol handler after the stream
1068 have been initialized.
1069
1070 Make sure that the handler will have the connected stream
1071 passed via C{makeConnection} and have C{connectionInitialized}
1072 called.
1073 """
1074 sm = self.streamManager
1075 xs = xmlstream.XmlStream(xmlstream.Authenticator())
1076 sm._connected(xs)
1077 sm._authd(xs)
1078 handler = DummyXMPPHandler()
1079 handler.setHandlerParent(sm)
1080
1081 self.assertEquals(1, handler.doneMade)
1082 self.assertEquals(1, handler.doneInitialized)
1083 self.assertEquals(0, handler.doneLost)
1084
1085
1086 def test_sendInitialized(self):
1087 """
1088 Test send when the stream has been initialized.
1089
1090 The data should be sent directly over the XML stream.
1091 """
1092 factory = xmlstream.XmlStreamFactory(xmlstream.Authenticator())
1093 sm = xmlstream.StreamManager(factory)
1094 xs = factory.buildProtocol(None)
1095 xs.transport = proto_helpers.StringTransport()
1096 xs.connectionMade()
1097 xs.dataReceived("<stream:stream xmlns='jabber:client' "
1098 "xmlns:stream='http://etherx.jabber.org/streams' "
1099 "from='example.com' id='12345'>")
1100 xs.dispatch(xs, "//event/stream/authd")
1101 sm.send("<presence/>")
1102 self.assertEquals("<presence/>", xs.transport.value())
1103
1104
1105 def test_sendNotConnected(self):
1106 """
1107 Test send when there is no established XML stream.
1108
1109 The data should be cached until an XML stream has been established and
1110 initialized.
1111 """
1112 factory = xmlstream.XmlStreamFactory(xmlstream.Authenticator())
1113 sm = xmlstream.StreamManager(factory)
1114 handler = DummyXMPPHandler()
1115 sm.addHandler(handler)
1116
1117 xs = factory.buildProtocol(None)
1118 xs.transport = proto_helpers.StringTransport()
1119 sm.send("<presence/>")
1120 self.assertEquals("", xs.transport.value())
1121 self.assertEquals("<presence/>", sm._packetQueue[0])
1122
1123 xs.connectionMade()
1124 self.assertEquals("", xs.transport.value())
1125 self.assertEquals("<presence/>", sm._packetQueue[0])
1126
1127 xs.dataReceived("<stream:stream xmlns='jabber:client' "
1128 "xmlns:stream='http://etherx.jabber.org/streams' "
1129 "from='example.com' id='12345'>")
1130 xs.dispatch(xs, "//event/stream/authd")
1131
1132 self.assertEquals("<presence/>", xs.transport.value())
1133 self.failIf(sm._packetQueue)
1134
1135
1136 def test_sendNotInitialized(self):
1137 """
1138 Test send when the stream is connected but not yet initialized.
1139
1140 The data should be cached until the XML stream has been initialized.
1141 """
1142 factory = xmlstream.XmlStreamFactory(xmlstream.Authenticator())
1143 sm = xmlstream.StreamManager(factory)
1144 xs = factory.buildProtocol(None)
1145 xs.transport = proto_helpers.StringTransport()
1146 xs.connectionMade()
1147 xs.dataReceived("<stream:stream xmlns='jabber:client' "
1148 "xmlns:stream='http://etherx.jabber.org/streams' "
1149 "from='example.com' id='12345'>")
1150 sm.send("<presence/>")
1151 self.assertEquals("", xs.transport.value())
1152 self.assertEquals("<presence/>", sm._packetQueue[0])
1153
1154
1155 def test_sendDisconnected(self):
1156 """
1157 Test send after XML stream disconnection.
1158
1159 The data should be cached until a new XML stream has been established
1160 and initialized.
1161 """
1162 factory = xmlstream.XmlStreamFactory(xmlstream.Authenticator())
1163 sm = xmlstream.StreamManager(factory)
1164 handler = DummyXMPPHandler()
1165 sm.addHandler(handler)
1166
1167 xs = factory.buildProtocol(None)
1168 xs.connectionMade()
1169 xs.transport = proto_helpers.StringTransport()
1170 xs.connectionLost(None)
1171
1172 sm.send("<presence/>")
1173 self.assertEquals("", xs.transport.value())
1174 self.assertEquals("<presence/>", sm._packetQueue[0])
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698