Changeset 45:125f9d902a20 for wokkel
- Timestamp:
- Nov 1, 2008, 7:18:50 PM (14 years ago)
- Branch:
- default
- Convert:
- svn:b33ecbfc-034c-dc11-8662-000475d9059e/trunk@134
- Location:
- wokkel
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
wokkel/iwokkel.py
r43 r45 16 16 """ 17 17 18 manager = Attribute("""XML stream manager""")18 parent = Attribute("""XML stream manager for this handler""") 19 19 xmlstream = Attribute("""The managed XML stream""") 20 20 … … 26 26 """ 27 27 28 28 29 def disownHandlerParent(parent): 29 30 """ … … 32 33 @type parent: L{IXMPPHandlerCollection} 33 34 """ 35 34 36 35 37 def makeConnection(xs): … … 45 47 @type xs: L{XmlStream<twisted.words.protocols.jabber.XmlStream>} 46 48 """ 49 47 50 48 51 def connectionMade(): … … 55 58 """ 56 59 60 57 61 def connectionInitialized(): 58 62 """ … … 64 68 """ 65 69 70 66 71 def connectionLost(reason): 67 72 """ … … 75 80 76 81 82 77 83 class IXMPPHandlerCollection(Interface): 78 84 """ … … 87 93 """ 88 94 95 89 96 def addHandler(handler): 90 97 """ … … 94 101 """ 95 102 103 96 104 def removeHandler(handler): 97 105 """ … … 100 108 @type handler: L{IXMPPHandler} 101 109 """ 110 102 111 103 112 -
wokkel/subprotocols.py
r22 r45 24 24 25 25 class XMPPHandler(object): 26 """ 27 XMPP protocol handler. 28 29 Classes derived from this class implement (part of) one or more XMPP 30 extension protocols, and are referred to as a subprotocol implementation. 31 """ 32 26 33 implements(IXMPPHandler) 34 35 def __init__(self): 36 self.parent = None 37 self.xmlstream = None 38 27 39 28 40 def setHandlerParent(self, parent): … … 30 42 self.parent.addHandler(self) 31 43 44 32 45 def disownHandlerParent(self, parent): 33 46 self.parent.removeHandler(self) 34 47 self.parent = None 35 48 49 36 50 def makeConnection(self, xs): 37 51 self.xmlstream = xs 38 52 self.connectionMade() 39 53 54 40 55 def connectionMade(self): 41 pass 56 """ 57 Called after a connection has been established. 58 59 Can be overridden to perform work before stream initialization. 60 """ 61 42 62 43 63 def connectionInitialized(self): 44 pass 64 """ 65 The XML stream has been initialized. 66 67 Can be overridden to perform work after stream initialization, e.g. to 68 set up observers and start exchanging XML stanzas. 69 """ 70 45 71 46 72 def connectionLost(self, reason): 73 """ 74 The XML stream has been closed. 75 76 This method can be extended to inspect the C{reason} argument and 77 act on it. 78 """ 47 79 self.xmlstream = None 80 48 81 49 82 def send(self, obj): … … 65 98 66 99 100 67 101 class XMPPHandlerCollection(object): 68 102 """ … … 72 106 L{XMPPHandler} itself, so this is not recursive. 73 107 74 @ivar xmlstream: Currently managed XML stream.75 @type xmlstream: L{XmlStream}76 108 @ivar handlers: List of protocol handlers. 77 109 @type handlers: L{list} of objects providing … … 83 115 def __init__(self): 84 116 self.handlers = [] 85 self.xmlstream = None 86 self._initialized = False 117 87 118 88 119 def __iter__(self): … … 92 123 return iter(self.handlers) 93 124 125 94 126 def addHandler(self, handler): 95 127 """ … … 97 129 98 130 Protocol handlers are expected to provide L{IXMPPHandler}. 99 100 When an XML stream has already been established, the handler's 101 C{connectionInitialized} will be called to get it up to speed. 102 """ 103 131 """ 104 132 self.handlers.append(handler) 105 133 106 # get protocol handler up to speed when a connection has already107 # been established108 if self.xmlstream and self._initialized:109 handler.makeConnection(self.xmlstream)110 handler.connectionInitialized()111 134 112 135 def removeHandler(self, handler): … … 114 137 Remove protocol handler. 115 138 """ 116 117 139 self.handlers.remove(handler) 140 141 118 142 119 143 class StreamManager(XMPPHandlerCollection): … … 126 150 using L{addHandler}. 127 151 152 @ivar xmlstream: currently managed XML stream 153 @type xmlstream: L{XmlStream} 128 154 @ivar logTraffic: if true, log all traffic. 129 155 @type logTraffic: L{bool} 156 @ivar _initialized: Whether the stream represented by L{xmlstream} has 157 been initialized. This is used when caching outgoing 158 stanzas. 159 @type _initialized: C{bool} 130 160 @ivar _packetQueue: internal buffer of unsent data. See L{send} for details. 131 161 @type _packetQueue: L{list} … … 135 165 136 166 def __init__(self, factory): 137 self.handlers = []167 XMPPHandlerCollection.__init__(self) 138 168 self.xmlstream = None 139 169 self._packetQueue = [] … … 147 177 self.factory = factory 148 178 179 180 def addHandler(self, handler): 181 """ 182 Add protocol handler. 183 184 When an XML stream has already been established, the handler's 185 C{connectionInitialized} will be called to get it up to speed. 186 """ 187 XMPPHandlerCollection.addHandler(self, handler) 188 189 # get protocol handler up to speed when a connection has already 190 # been established 191 if self.xmlstream and self._initialized: 192 handler.makeConnection(self.xmlstream) 193 handler.connectionInitialized() 194 195 149 196 def _connected(self, xs): 197 """ 198 Called when the transport connection has been established. 199 200 Here we optionally set up traffic logging (depending on L{logTraffic}) 201 and call each handler's C{makeConnection} method with the L{XmlStream} 202 instance. 203 """ 150 204 def logDataIn(buf): 151 205 log.msg("RECV: %r" % buf) … … 163 217 e.makeConnection(xs) 164 218 219 165 220 def _authd(self, xs): 221 """ 222 Called when the stream has been initialized. 223 224 Send out cached stanzas and call each handler's 225 C{connectionInitialized} method. 226 """ 166 227 # Flush all pending packets 167 228 for p in self._packetQueue: … … 175 236 e.connectionInitialized() 176 237 238 177 239 def initializationFailed(self, reason): 178 240 """ … … 188 250 """ 189 251 252 190 253 def _disconnected(self, _): 254 """ 255 Called when the stream has been closed. 256 257 From this point on, the manager doesn't interact with the 258 L{XmlStream} anymore and notifies each handler that the connection 259 was lost by calling its C{connectionLost} method. 260 """ 191 261 self.xmlstream = None 192 262 self._initialized = False … … 195 265 # the IService interface 196 266 for e in self: 197 e.xmlstream = None198 267 e.connectionLost(None) 268 199 269 200 270 def send(self, obj): … … 208 278 L{xmlstream.XmlStream.send} for details. 209 279 """ 210 211 280 if self._initialized: 212 281 self.xmlstream.send(obj) 213 282 else: 214 283 self._packetQueue.append(obj) 284 215 285 216 286 -
wokkel/test/test_subprotocols.py
r4 r45 5 5 Tests for L{wokkel.subprotocols} 6 6 """ 7 8 from zope.interface.verify import verifyObject 7 9 8 10 from twisted.trial import unittest … … 12 14 from twisted.words.protocols.jabber import error, xmlstream 13 15 14 from wokkel import subprotocols16 from wokkel import iwokkel, subprotocols 15 17 16 18 class DummyFactory(object): 19 """ 20 Dummy XmlStream factory that only registers bootstrap observers. 21 """ 17 22 def __init__(self): 18 23 self.callbacks = {} 19 24 25 20 26 def addBootstrap(self, event, callback): 21 27 self.callbacks[event] = callback 22 28 23 29 30 24 31 class DummyXMPPHandler(subprotocols.XMPPHandler): 32 """ 33 Dummy XMPP subprotocol handler to count the methods are called on it. 34 """ 25 35 def __init__(self): 26 36 self.doneMade = 0 … … 28 38 self.doneLost = 0 29 39 40 30 41 def makeConnection(self, xs): 31 42 self.connectionMade() 32 43 44 33 45 def connectionMade(self): 34 46 self.doneMade += 1 35 47 48 36 49 def connectionInitialized(self): 37 50 self.doneInitialized += 1 38 51 52 39 53 def connectionLost(self, reason): 40 54 self.doneLost += 1 41 55 42 56 57 43 58 class XMPPHandlerTest(unittest.TestCase): 59 """ 60 Tests for L{subprotocols.XMPPHandler}. 61 """ 62 63 def test_interface(self): 64 """ 65 L{xmlstream.XMPPHandler} implements L{iwokkel.IXMPPHandler}. 66 """ 67 verifyObject(iwokkel.IXMPPHandler, subprotocols.XMPPHandler()) 68 44 69 45 70 def test_send(self): … … 47 72 Test that data is passed on for sending by the stream manager. 48 73 """ 49 50 74 class DummyStreamManager(object): 51 75 def __init__(self): … … 61 85 62 86 87 def test_makeConnection(self): 88 """ 89 Test that makeConnection saves the XML stream and calls connectionMade. 90 """ 91 class TestXMPPHandler(subprotocols.XMPPHandler): 92 def connectionMade(self): 93 self.doneMade = True 94 95 handler = TestXMPPHandler() 96 xs = xmlstream.XmlStream(xmlstream.Authenticator()) 97 handler.makeConnection(xs) 98 self.assertTrue(handler.doneMade) 99 self.assertIdentical(xs, handler.xmlstream) 100 101 102 def test_connectionLost(self): 103 """ 104 Test that connectionLost forgets the XML stream. 105 """ 106 handler = subprotocols.XMPPHandler() 107 xs = xmlstream.XmlStream(xmlstream.Authenticator()) 108 handler.makeConnection(xs) 109 handler.connectionLost(Exception()) 110 self.assertIdentical(None, handler.xmlstream) 111 112 113 114 class XMPPHandlerCollectionTest(unittest.TestCase): 115 """ 116 Tests for L{subprotocols.XMPPHandlerCollection}. 117 """ 118 119 def setUp(self): 120 self.collection = subprotocols.XMPPHandlerCollection() 121 122 123 def test_interface(self): 124 """ 125 L{subprotocols.StreamManager} implements L{iwokkel.IXMPPHandlerCollection}. 126 """ 127 verifyObject(iwokkel.IXMPPHandlerCollection, self.collection) 128 129 130 def test_addHandler(self): 131 """ 132 Test the addition of a protocol handler. 133 """ 134 handler = DummyXMPPHandler() 135 handler.setHandlerParent(self.collection) 136 self.assertIn(handler, self.collection) 137 self.assertIdentical(self.collection, handler.parent) 138 139 140 def test_removeHandler(self): 141 """ 142 Test removal of a protocol handler. 143 """ 144 handler = DummyXMPPHandler() 145 handler.setHandlerParent(self.collection) 146 handler.disownHandlerParent(self.collection) 147 self.assertNotIn(handler, self.collection) 148 self.assertIdentical(None, handler.parent) 149 150 151 63 152 class StreamManagerTest(unittest.TestCase): 153 """ 154 Tests for L{subprotocols.StreamManager}. 155 """ 64 156 65 157 def setUp(self): … … 83 175 sm.factory.callbacks['//event/xmpp/initfailed']) 84 176 85 def test__connected(self): 177 178 def test_connected(self): 86 179 """ 87 180 Test that protocol handlers have their connectionMade method called … … 97 190 self.assertEquals(0, handler.doneLost) 98 191 99 def test__authd(self): 192 193 def test_connectedLogTrafficFalse(self): 194 """ 195 Test raw data functions unset when logTraffic is set to False. 196 """ 197 sm = self.streamManager 198 handler = DummyXMPPHandler() 199 handler.setHandlerParent(sm) 200 xs = xmlstream.XmlStream(xmlstream.Authenticator()) 201 sm._connected(xs) 202 self.assertIdentical(None, xs.rawDataInFn) 203 self.assertIdentical(None, xs.rawDataOutFn) 204 205 206 def test_connectedLogTrafficTrue(self): 207 """ 208 Test raw data functions set when logTraffic is set to True. 209 """ 210 sm = self.streamManager 211 sm.logTraffic = True 212 handler = DummyXMPPHandler() 213 handler.setHandlerParent(sm) 214 xs = xmlstream.XmlStream(xmlstream.Authenticator()) 215 sm._connected(xs) 216 self.assertNotIdentical(None, xs.rawDataInFn) 217 self.assertNotIdentical(None, xs.rawDataOutFn) 218 219 220 def test_authd(self): 100 221 """ 101 222 Test that protocol handlers have their connectionInitialized method … … 111 232 self.assertEquals(0, handler.doneLost) 112 233 113 def test__disconnected(self): 234 235 def test_disconnected(self): 114 236 """ 115 237 Test that protocol handlers have their connectionLost method … … 125 247 self.assertEquals(1, handler.doneLost) 126 248 249 127 250 def test_addHandler(self): 128 251 """ … … 132 255 handler = DummyXMPPHandler() 133 256 handler.setHandlerParent(sm) 134 self.assertIn(handler, sm)135 self.assertIdentical(sm, handler.parent)136 257 137 258 self.assertEquals(0, handler.doneMade) 138 259 self.assertEquals(0, handler.doneInitialized) 139 260 self.assertEquals(0, handler.doneLost) 261 140 262 141 263 def test_addHandlerInitialized(self): … … 188 310 self.assertEquals("<presence/>", xs.transport.value()) 189 311 312 190 313 def test_sendNotConnected(self): 191 314 """ … … 216 339 217 340 self.assertEquals("<presence/>", xs.transport.value()) 218 self.failIf(sm._packetQueue) 341 self.assertFalse(sm._packetQueue) 342 219 343 220 344 def test_sendNotInitialized(self): … … 236 360 self.assertEquals("<presence/>", sm._packetQueue[0]) 237 361 362 238 363 def test_sendDisconnected(self): 239 364 """ … … 258 383 259 384 385 260 386 class DummyIQHandler(subprotocols.IQHandlerMixin): 261 387 iqHandlers = {'/iq[@type="get"]': 'onGet'}
Note: See TracChangeset
for help on using the changeset viewer.