~landscape/zope3/newer-from-ztk

« back to all changes in this revision

Viewing changes to src/twisted/words/test/test_jabberxmlstream.py

  • Committer: Thomas Hervé
  • Date: 2009-07-08 13:52:04 UTC
  • Revision ID: thomas@canonical.com-20090708135204-df5eesrthifpylf8
Remove twisted copy

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
from twisted.trial import unittest
2
 
 
3
 
from twisted.internet import defer, task
4
 
from twisted.internet.error import ConnectionLost
5
 
from twisted.test import proto_helpers
6
 
from twisted.words.xish import domish
7
 
from twisted.words.protocols.jabber import error, xmlstream
8
 
 
9
 
NS_XMPP_TLS = 'urn:ietf:params:xml:ns:xmpp-tls'
10
 
 
11
 
class IQTest(unittest.TestCase):
12
 
    """
13
 
    Tests both IQ and the associated IIQResponseTracker callback.
14
 
    """
15
 
 
16
 
    def setUp(self):
17
 
        authenticator = xmlstream.ConnectAuthenticator('otherhost')
18
 
        authenticator.namespace = 'testns'
19
 
        self.xmlstream = xmlstream.XmlStream(authenticator)
20
 
        self.clock = task.Clock()
21
 
        self.xmlstream._callLater = self.clock.callLater
22
 
        self.xmlstream.makeConnection(proto_helpers.StringTransport())
23
 
        self.xmlstream.dataReceived(
24
 
           "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
25
 
                          "xmlns='testns' from='otherhost' version='1.0'>")
26
 
        self.iq = xmlstream.IQ(self.xmlstream, type='get')
27
 
 
28
 
    def testBasic(self):
29
 
        self.assertEquals(self.iq['type'], 'get')
30
 
        self.assert_(self.iq['id'])
31
 
 
32
 
    def testSend(self):
33
 
        self.xmlstream.transport.clear()
34
 
        self.iq.send()
35
 
        self.assertEquals("<iq type='get' id='%s'/>" % self.iq['id'],
36
 
                          self.xmlstream.transport.value())
37
 
 
38
 
    def testResultResponse(self):
39
 
        def cb(result):
40
 
            self.assertEquals(result['type'], 'result')
41
 
 
42
 
        d = self.iq.send()
43
 
        d.addCallback(cb)
44
 
 
45
 
        xs = self.xmlstream
46
 
        xs.dataReceived("<iq type='result' id='%s'/>" % self.iq['id'])
47
 
        return d
48
 
 
49
 
    def testErrorResponse(self):
50
 
        d = self.iq.send()
51
 
        self.assertFailure(d, error.StanzaError)
52
 
 
53
 
        xs = self.xmlstream
54
 
        xs.dataReceived("<iq type='error' id='%s'/>" % self.iq['id'])
55
 
        return d
56
 
 
57
 
    def testNonTrackedResponse(self):
58
 
        """
59
 
        Test that untracked iq responses don't trigger any action.
60
 
 
61
 
        Untracked means that the id of the incoming response iq is not
62
 
        in the stream's C{iqDeferreds} dictionary.
63
 
        """
64
 
        xs = self.xmlstream
65
 
        xmlstream.upgradeWithIQResponseTracker(xs)
66
 
 
67
 
        # Make sure we aren't tracking any iq's.
68
 
        self.failIf(xs.iqDeferreds)
69
 
 
70
 
        # Set up a fallback handler that checks the stanza's handled attribute.
71
 
        # If that is set to True, the iq tracker claims to have handled the
72
 
        # response.
73
 
        def cb(iq):
74
 
            self.failIf(getattr(iq, 'handled', False))
75
 
 
76
 
        xs.addObserver("/iq", cb, -1)
77
 
 
78
 
        # Receive an untracked iq response
79
 
        xs.dataReceived("<iq type='result' id='test'/>")
80
 
 
81
 
    def testCleanup(self):
82
 
        """
83
 
        Test if the deferred associated with an iq request is removed
84
 
        from the list kept in the L{XmlStream} object after it has
85
 
        been fired.
86
 
        """
87
 
 
88
 
        d = self.iq.send()
89
 
        xs = self.xmlstream
90
 
        xs.dataReceived("<iq type='result' id='%s'/>" % self.iq['id'])
91
 
        self.assertNotIn(self.iq['id'], xs.iqDeferreds)
92
 
        return d
93
 
 
94
 
    def testDisconnectCleanup(self):
95
 
        """
96
 
        Test if deferreds for iq's that haven't yet received a response
97
 
        have their errback called on stream disconnect.
98
 
        """
99
 
 
100
 
        d = self.iq.send()
101
 
        xs = self.xmlstream
102
 
        xs.connectionLost("Closed by peer")
103
 
        self.assertFailure(d, ConnectionLost)
104
 
        return d
105
 
 
106
 
    def testNoModifyingDict(self):
107
 
        """
108
 
        Test to make sure the errbacks cannot cause the iteration of the
109
 
        iqDeferreds to blow up in our face.
110
 
        """
111
 
 
112
 
        def eb(failure):
113
 
            d = xmlstream.IQ(self.xmlstream).send()
114
 
            d.addErrback(eb)
115
 
 
116
 
        d = self.iq.send()
117
 
        d.addErrback(eb)
118
 
        self.xmlstream.connectionLost("Closed by peer")
119
 
        return d
120
 
 
121
 
    def testRequestTimingOut(self):
122
 
        """
123
 
        Test that an iq request with a defined timeout times out.
124
 
        """
125
 
        self.iq.timeout = 60
126
 
        d = self.iq.send()
127
 
        self.assertFailure(d, xmlstream.TimeoutError)
128
 
 
129
 
        self.clock.pump([1, 60])
130
 
        self.failIf(self.clock.calls)
131
 
        self.failIf(self.xmlstream.iqDeferreds)
132
 
        return d
133
 
 
134
 
    def testRequestNotTimingOut(self):
135
 
        """
136
 
        Test that an iq request with a defined timeout does not time out
137
 
        when a response was received before the timeout period elapsed.
138
 
        """
139
 
        self.iq.timeout = 60
140
 
        d = self.iq.send()
141
 
        self.clock.callLater(1, self.xmlstream.dataReceived,
142
 
                             "<iq type='result' id='%s'/>" % self.iq['id'])
143
 
        self.clock.pump([1, 1])
144
 
        self.failIf(self.clock.calls)
145
 
        return d
146
 
 
147
 
    def testDisconnectTimeoutCancellation(self):
148
 
        """
149
 
        Test if timeouts for iq's that haven't yet received a response
150
 
        are cancelled on stream disconnect.
151
 
        """
152
 
 
153
 
        self.iq.timeout = 60
154
 
        d = self.iq.send()
155
 
        
156
 
        xs = self.xmlstream
157
 
        xs.connectionLost("Closed by peer")
158
 
        self.assertFailure(d, ConnectionLost)
159
 
        self.failIf(self.clock.calls)
160
 
        return d
161
 
 
162
 
class XmlStreamTest(unittest.TestCase):
163
 
 
164
 
    def onStreamStart(self, obj):
165
 
        self.gotStreamStart = True
166
 
 
167
 
 
168
 
    def onStreamEnd(self, obj):
169
 
        self.gotStreamEnd = True
170
 
 
171
 
 
172
 
    def onStreamError(self, obj):
173
 
        self.gotStreamError = True
174
 
 
175
 
 
176
 
    def setUp(self):
177
 
        """
178
 
        Set up XmlStream and several observers.
179
 
        """
180
 
        self.gotStreamStart = False
181
 
        self.gotStreamEnd = False
182
 
        self.gotStreamError = False
183
 
        xs = xmlstream.XmlStream(xmlstream.Authenticator())
184
 
        xs.addObserver('//event/stream/start', self.onStreamStart)
185
 
        xs.addObserver('//event/stream/end', self.onStreamEnd)
186
 
        xs.addObserver('//event/stream/error', self.onStreamError)
187
 
        xs.makeConnection(proto_helpers.StringTransportWithDisconnection())
188
 
        xs.transport.protocol = xs
189
 
        xs.namespace = 'testns'
190
 
        xs.version = (1, 0)
191
 
        self.xmlstream = xs
192
 
 
193
 
 
194
 
    def testSendHeaderBasic(self):
195
 
        """
196
 
        Basic test on the header sent by sendHeader.
197
 
        """
198
 
        xs = self.xmlstream
199
 
        xs.sendHeader()
200
 
        splitHeader = self.xmlstream.transport.value()[0:-1].split(' ')
201
 
        self.assertIn("<stream:stream", splitHeader)
202
 
        self.assertIn("xmlns:stream='http://etherx.jabber.org/streams'",
203
 
                      splitHeader)
204
 
        self.assertIn("xmlns='testns'", splitHeader)
205
 
        self.assertIn("version='1.0'", splitHeader)
206
 
        self.assertEquals(True, xs._headerSent)
207
 
 
208
 
 
209
 
    def testSendHeaderInitiating(self):
210
 
        """
211
 
        Test addressing when initiating a stream.
212
 
        """
213
 
        xs = self.xmlstream
214
 
        xs.thisHost = 'thisHost'
215
 
        xs.otherHost = 'otherHost'
216
 
        xs.initiating = True
217
 
        xs.sendHeader()
218
 
        splitHeader = xs.transport.value()[0:-1].split(' ')
219
 
        self.assertIn("to='otherHost'", splitHeader)
220
 
        self.assertNotIn("from='thisHost'", splitHeader)
221
 
 
222
 
 
223
 
    def testSendHeaderReceiving(self):
224
 
        """
225
 
        Test addressing when receiving a stream.
226
 
        """
227
 
        xs = self.xmlstream
228
 
        xs.thisHost = 'thisHost'
229
 
        xs.otherHost = 'otherHost'
230
 
        xs.initiating = False
231
 
        xs.sid = 'session01'
232
 
        xs.sendHeader()
233
 
        splitHeader = xs.transport.value()[0:-1].split(' ')
234
 
        self.assertNotIn("to='otherHost'", splitHeader)
235
 
        self.assertIn("from='thisHost'", splitHeader)
236
 
        self.assertIn("id='session01'", splitHeader)
237
 
 
238
 
 
239
 
    def testReceiveStreamError(self):
240
 
        """
241
 
        Test events when a stream error is received.
242
 
        """
243
 
        xs = self.xmlstream
244
 
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
245
 
                        "xmlns:stream='http://etherx.jabber.org/streams' "
246
 
                        "from='example.com' id='12345' version='1.0'>")
247
 
        xs.dataReceived("<stream:error/>")
248
 
        self.assert_(self.gotStreamError)
249
 
        self.assert_(self.gotStreamEnd)
250
 
 
251
 
 
252
 
    def testSendStreamErrorInitiating(self):
253
 
        """
254
 
        Test sendStreamError on an initiating xmlstream with a header sent.
255
 
 
256
 
        An error should be sent out and the connection lost.
257
 
        """
258
 
        xs = self.xmlstream
259
 
        xs.initiating = True
260
 
        xs.sendHeader()
261
 
        xs.transport.clear()
262
 
        xs.sendStreamError(error.StreamError('version-unsupported'))
263
 
        self.assertNotEqual('', xs.transport.value())
264
 
        self.assert_(self.gotStreamEnd)
265
 
 
266
 
 
267
 
    def testSendStreamErrorInitiatingNoHeader(self):
268
 
        """
269
 
        Test sendStreamError on an initiating xmlstream without having sent a
270
 
        header.
271
 
 
272
 
        In this case, no header should be generated. Also, the error should
273
 
        not be sent out on the stream. Just closing the connection.
274
 
        """
275
 
        xs = self.xmlstream
276
 
        xs.initiating = True
277
 
        xs.transport.clear()
278
 
        xs.sendStreamError(error.StreamError('version-unsupported'))
279
 
        self.assertNot(xs._headerSent)
280
 
        self.assertEqual('', xs.transport.value())
281
 
        self.assert_(self.gotStreamEnd)
282
 
 
283
 
 
284
 
    def testSendStreamErrorReceiving(self):
285
 
        """
286
 
        Test sendStreamError on a receiving xmlstream with a header sent.
287
 
 
288
 
        An error should be sent out and the connection lost.
289
 
        """
290
 
        xs = self.xmlstream
291
 
        xs.initiating = False
292
 
        xs.sendHeader()
293
 
        xs.transport.clear()
294
 
        xs.sendStreamError(error.StreamError('version-unsupported'))
295
 
        self.assertNotEqual('', xs.transport.value())
296
 
        self.assert_(self.gotStreamEnd)
297
 
 
298
 
 
299
 
    def testSendStreamErrorReceivingNoHeader(self):
300
 
        """
301
 
        Test sendStreamError on a receiving xmlstream without having sent a
302
 
        header.
303
 
 
304
 
        In this case, a header should be generated. Then, the error should
305
 
        be sent out on the stream followed by closing the connection.
306
 
        """
307
 
        xs = self.xmlstream
308
 
        xs.initiating = False
309
 
        xs.transport.clear()
310
 
        xs.sendStreamError(error.StreamError('version-unsupported'))
311
 
        self.assert_(xs._headerSent)
312
 
        self.assertNotEqual('', xs.transport.value())
313
 
        self.assert_(self.gotStreamEnd)
314
 
 
315
 
 
316
 
    def testOnDocumentStart(self):
317
 
        """
318
 
        Test onDocumentStart to fill the appropriate attributes from the
319
 
        stream header and stream start event.
320
 
        """
321
 
        xs = self.xmlstream
322
 
        xs.initiating = True
323
 
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
324
 
                         "xmlns:stream='http://etherx.jabber.org/streams' "
325
 
                         "from='example.com' id='12345' version='1.0'>")
326
 
        self.assert_(self.gotStreamStart)
327
 
        self.assertEqual((1, 0), xs.version)
328
 
        self.assertEqual('12345', xs.sid)
329
 
        xs.dataReceived("<stream:features>"
330
 
                          "<test xmlns='testns'/>"
331
 
                        "</stream:features>")
332
 
        self.assertIn(('testns', 'test'), xs.features)
333
 
 
334
 
 
335
 
    def testOnDocumentStartLegacy(self):
336
 
        """
337
 
        Test onDocumentStart to fill the appropriate attributes from the
338
 
        stream header and stream start event for a pre-XMPP-1.0 header.
339
 
        """
340
 
        xs = self.xmlstream
341
 
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
342
 
                        "xmlns:stream='http://etherx.jabber.org/streams' "
343
 
                        "from='example.com' id='12345'>")
344
 
        self.assert_(self.gotStreamStart)
345
 
        self.assertEqual((0, 0), xs.version)
346
 
 
347
 
 
348
 
    def testReset(self):
349
 
        """
350
 
        Test resetting the XML stream to start a new layer.
351
 
        """
352
 
        xs = self.xmlstream
353
 
        xs.sendHeader()
354
 
        stream = xs.stream
355
 
        xs.reset()
356
 
        self.assertNotEqual(stream, xs.stream)
357
 
        self.assertNot(xs._headerSent)
358
 
 
359
 
 
360
 
    def testSend(self):
361
 
        """
362
 
        Test send with various types of objects.
363
 
        """
364
 
        xs = self.xmlstream
365
 
        xs.send('<presence/>')
366
 
        self.assertEqual(xs.transport.value(), '<presence/>')
367
 
 
368
 
        xs.transport.clear()
369
 
        el = domish.Element(('testns', 'presence'))
370
 
        xs.send(el)
371
 
        self.assertEqual(xs.transport.value(), '<presence/>')
372
 
 
373
 
        xs.transport.clear()
374
 
        el = domish.Element(('http://etherx.jabber.org/streams', 'features'))
375
 
        xs.send(el)
376
 
        self.assertEqual(xs.transport.value(), '<stream:features/>')
377
 
 
378
 
 
379
 
    def testAuthenticator(self):
380
 
        """
381
 
        Test that the associated authenticator is correctly called.
382
 
        """
383
 
        connectionMade = []
384
 
        streamStarted = []
385
 
        associateWithStream = []
386
 
 
387
 
        class TestAuthenticator:
388
 
            def connectionMade(self):
389
 
                connectionMade.append(None)
390
 
 
391
 
            def streamStarted(self):
392
 
                streamStarted.append(None)
393
 
 
394
 
            def associateWithStream(self, xs):
395
 
                associateWithStream.append(xs)
396
 
 
397
 
        a = TestAuthenticator()
398
 
        xs = xmlstream.XmlStream(a)
399
 
        self.assertEqual([xs], associateWithStream)
400
 
        xs.connectionMade()
401
 
        self.assertEqual([None], connectionMade)
402
 
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
403
 
                        "xmlns:stream='http://etherx.jabber.org/streams' "
404
 
                        "from='example.com' id='12345'>")
405
 
        self.assertEqual([None], streamStarted)
406
 
        xs.reset()
407
 
        self.assertEqual([None], connectionMade)
408
 
 
409
 
 
410
 
 
411
 
class TestError(Exception):
412
 
    pass
413
 
 
414
 
 
415
 
 
416
 
class ConnectAuthenticatorTest(unittest.TestCase):
417
 
 
418
 
    def setUp(self):
419
 
        self.gotAuthenticated = False
420
 
        self.initFailure = None
421
 
        self.authenticator = xmlstream.ConnectAuthenticator('otherHost')
422
 
        self.xmlstream = xmlstream.XmlStream(self.authenticator)
423
 
        self.xmlstream.addObserver('//event/stream/authd', self.onAuthenticated)
424
 
        self.xmlstream.addObserver('//event/xmpp/initfailed', self.onInitFailed)
425
 
 
426
 
 
427
 
    def onAuthenticated(self, obj):
428
 
        self.gotAuthenticated = True
429
 
 
430
 
 
431
 
    def onInitFailed(self, failure):
432
 
        self.initFailure = failure
433
 
 
434
 
 
435
 
    def testSucces(self):
436
 
        """
437
 
        Test successful completion of an initialization step.
438
 
        """
439
 
        class Initializer:
440
 
            def initialize(self):
441
 
                pass
442
 
 
443
 
        init = Initializer()
444
 
        self.xmlstream.initializers = [init]
445
 
 
446
 
        self.authenticator.initializeStream()
447
 
        self.assertEqual([], self.xmlstream.initializers)
448
 
        self.assert_(self.gotAuthenticated)
449
 
 
450
 
 
451
 
    def testFailure(self):
452
 
        """
453
 
        Test failure of an initialization step.
454
 
        """
455
 
        class Initializer:
456
 
            def initialize(self):
457
 
                raise TestError
458
 
 
459
 
        init = Initializer()
460
 
        self.xmlstream.initializers = [init]
461
 
 
462
 
        self.authenticator.initializeStream()
463
 
        self.assertEqual([init], self.xmlstream.initializers)
464
 
        self.assertFalse(self.gotAuthenticated)
465
 
        self.assertNotIdentical(None, self.initFailure)
466
 
        self.assert_(self.initFailure.check(TestError))
467
 
 
468
 
 
469
 
 
470
 
class TLSInitiatingInitializerTest(unittest.TestCase):
471
 
    def setUp(self):
472
 
        self.output = []
473
 
        self.done = []
474
 
 
475
 
        self.savedSSL = xmlstream.ssl
476
 
 
477
 
        self.authenticator = xmlstream.Authenticator()
478
 
        self.xmlstream = xmlstream.XmlStream(self.authenticator)
479
 
        self.xmlstream.send = self.output.append
480
 
        self.xmlstream.connectionMade()
481
 
        self.xmlstream.dataReceived("<stream:stream xmlns='jabber:client' "
482
 
                        "xmlns:stream='http://etherx.jabber.org/streams' "
483
 
                        "from='example.com' id='12345' version='1.0'>")
484
 
        self.init = xmlstream.TLSInitiatingInitializer(self.xmlstream)
485
 
 
486
 
 
487
 
    def tearDown(self):
488
 
        xmlstream.ssl = self.savedSSL
489
 
 
490
 
 
491
 
    def testWantedSupported(self):
492
 
        """
493
 
        Test start when TLS is wanted and the SSL library available.
494
 
        """
495
 
        self.xmlstream.transport = proto_helpers.StringTransport()
496
 
        self.xmlstream.transport.startTLS = lambda ctx: self.done.append('TLS')
497
 
        self.xmlstream.reset = lambda: self.done.append('reset')
498
 
        self.xmlstream.sendHeader = lambda: self.done.append('header')
499
 
 
500
 
        d = self.init.start()
501
 
        d.addCallback(self.assertEquals, xmlstream.Reset)
502
 
        starttls = self.output[0]
503
 
        self.assertEquals('starttls', starttls.name)
504
 
        self.assertEquals(NS_XMPP_TLS, starttls.uri)
505
 
        self.xmlstream.dataReceived("<proceed xmlns='%s'/>" % NS_XMPP_TLS)
506
 
        self.assertEquals(['TLS', 'reset', 'header'], self.done)
507
 
 
508
 
        return d
509
 
 
510
 
    if not xmlstream.ssl:
511
 
        testWantedSupported.skip = "SSL not available"
512
 
 
513
 
    def testWantedNotSupportedNotRequired(self):
514
 
        """
515
 
        Test start when TLS is wanted and the SSL library available.
516
 
        """
517
 
        xmlstream.ssl = None
518
 
 
519
 
        d = self.init.start()
520
 
        d.addCallback(self.assertEquals, None)
521
 
        self.assertEquals([], self.output)
522
 
 
523
 
        return d
524
 
 
525
 
 
526
 
    def testWantedNotSupportedRequired(self):
527
 
        """
528
 
        Test start when TLS is wanted and the SSL library available.
529
 
        """
530
 
        xmlstream.ssl = None
531
 
        self.init.required = True
532
 
 
533
 
        d = self.init.start()
534
 
        self.assertFailure(d, xmlstream.TLSNotSupported)
535
 
        self.assertEquals([], self.output)
536
 
 
537
 
        return d
538
 
 
539
 
 
540
 
    def testNotWantedRequired(self):
541
 
        """
542
 
        Test start when TLS is not wanted, but required by the server.
543
 
        """
544
 
        tls = domish.Element(('urn:ietf:params:xml:ns:xmpp-tls', 'starttls'))
545
 
        tls.addElement('required')
546
 
        self.xmlstream.features = {(tls.uri, tls.name): tls}
547
 
        self.init.wanted = False
548
 
 
549
 
        d = self.init.start()
550
 
        self.assertEquals([], self.output)
551
 
        self.assertFailure(d, xmlstream.TLSRequired)
552
 
 
553
 
        return d
554
 
 
555
 
 
556
 
    def testNotWantedNotRequired(self):
557
 
        """
558
 
        Test start when TLS is not wanted, but required by the server.
559
 
        """
560
 
        tls = domish.Element(('urn:ietf:params:xml:ns:xmpp-tls', 'starttls'))
561
 
        self.xmlstream.features = {(tls.uri, tls.name): tls}
562
 
        self.init.wanted = False
563
 
 
564
 
        d = self.init.start()
565
 
        d.addCallback(self.assertEqual, None)
566
 
        self.assertEquals([], self.output)
567
 
        return d
568
 
 
569
 
 
570
 
    def testFailed(self):
571
 
        """
572
 
        Test failed TLS negotiation.
573
 
        """
574
 
        # Pretend that ssl is supported, it isn't actually used when the
575
 
        # server starts out with a failure in response to our initial
576
 
        # C{starttls} stanza.
577
 
        xmlstream.ssl = 1
578
 
 
579
 
        d = self.init.start()
580
 
        self.assertFailure(d, xmlstream.TLSFailed)
581
 
        self.xmlstream.dataReceived("<failure xmlns='%s'/>" % NS_XMPP_TLS)
582
 
        return d
583
 
 
584
 
 
585
 
 
586
 
class TestFeatureInitializer(xmlstream.BaseFeatureInitiatingInitializer):
587
 
    feature = ('testns', 'test')
588
 
 
589
 
    def start(self):
590
 
        return defer.succeed(None)
591
 
 
592
 
 
593
 
 
594
 
class BaseFeatureInitiatingInitializerTest(unittest.TestCase):
595
 
 
596
 
    def setUp(self):
597
 
        self.xmlstream = xmlstream.XmlStream(xmlstream.Authenticator())
598
 
        self.init = TestFeatureInitializer(self.xmlstream)
599
 
 
600
 
 
601
 
    def testAdvertized(self):
602
 
        """
603
 
        Test that an advertized feature results in successful initialization.
604
 
        """
605
 
        self.xmlstream.features = {self.init.feature:
606
 
                                   domish.Element(self.init.feature)}
607
 
        return self.init.initialize()
608
 
 
609
 
 
610
 
    def testNotAdvertizedRequired(self):
611
 
        """
612
 
        Test that when the feature is not advertized, but required by the
613
 
        initializer, an exception is raised.
614
 
        """
615
 
        self.init.required = True
616
 
        self.assertRaises(xmlstream.FeatureNotAdvertized, self.init.initialize)
617
 
 
618
 
 
619
 
    def testNotAdvertizedNotRequired(self):
620
 
        """
621
 
        Test that when the feature is not advertized, and not required by the
622
 
        initializer, the initializer silently succeeds.
623
 
        """
624
 
        self.init.required = False
625
 
        self.assertIdentical(None, self.init.initialize())