~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-17 14:52:35 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20070117145235-btmig6qfmqfen0om
Tags: 2.5.0-0ubuntu1
New upstream version, compatible with python2.5.

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())