| OLD | NEW |
| 1 #!/usr/bin/python2.4 | 1 #!/usr/bin/python2.4 |
| 2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Tests exercising the various classes in xmppserver.py.""" | 6 """Tests exercising the various classes in xmppserver.py.""" |
| 7 | 7 |
| 8 import unittest | 8 import unittest |
| 9 | 9 |
| 10 import base64 | 10 import base64 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 self.DoHandshake('resource_prefix', 'resource', | 157 self.DoHandshake('resource_prefix', 'resource', |
| 158 'foo', 'bar.com', 'baz.com', 'quux.com') | 158 'foo', 'bar.com', 'baz.com', 'quux.com') |
| 159 self.DoHandshake('resource_prefix', 'resource', | 159 self.DoHandshake('resource_prefix', 'resource', |
| 160 'foo', 'bar.com', 'baz.com', '') | 160 'foo', 'bar.com', 'baz.com', '') |
| 161 self.DoHandshake('resource_prefix', 'resource', | 161 self.DoHandshake('resource_prefix', 'resource', |
| 162 'foo', 'bar.com', '', '') | 162 'foo', 'bar.com', '', '') |
| 163 self.DoHandshake('resource_prefix', 'resource', | 163 self.DoHandshake('resource_prefix', 'resource', |
| 164 'foo', '', '', '') | 164 'foo', '', '', '') |
| 165 | 165 |
| 166 | 166 |
| 167 class XmppConnectionTest(unittest.TestCase): | 167 class FakeSocket(object): |
| 168 """A fake socket object used for testing. |
| 169 """ |
| 168 | 170 |
| 169 def setUp(self): | 171 def __init__(self): |
| 170 self.connections = set() | 172 self._sent_data = [] |
| 171 self.data = [] | 173 |
| 174 def GetSentData(self): |
| 175 return self._sent_data |
| 172 | 176 |
| 173 # socket-like methods. | 177 # socket-like methods. |
| 174 def fileno(self): | 178 def fileno(self): |
| 175 return 0 | 179 return 0 |
| 176 | 180 |
| 177 def setblocking(self, int): | 181 def setblocking(self, int): |
| 178 pass | 182 pass |
| 179 | 183 |
| 180 def getpeername(self): | 184 def getpeername(self): |
| 181 return ('', 0) | 185 return ('', 0) |
| 182 | 186 |
| 183 def send(self, data): | 187 def send(self, data): |
| 184 self.data.append(data) | 188 self._sent_data.append(data) |
| 185 pass | 189 pass |
| 186 | 190 |
| 187 def close(self): | 191 def close(self): |
| 188 pass | 192 pass |
| 189 | 193 |
| 194 |
| 195 class XmppConnectionTest(unittest.TestCase): |
| 196 |
| 197 def setUp(self): |
| 198 self.connections = set() |
| 199 self.fake_socket = FakeSocket() |
| 200 |
| 190 # XmppConnection delegate methods. | 201 # XmppConnection delegate methods. |
| 191 def OnXmppHandshakeDone(self, xmpp_connection): | 202 def OnXmppHandshakeDone(self, xmpp_connection): |
| 192 self.connections.add(xmpp_connection) | 203 self.connections.add(xmpp_connection) |
| 193 | 204 |
| 194 def OnXmppConnectionClosed(self, xmpp_connection): | 205 def OnXmppConnectionClosed(self, xmpp_connection): |
| 195 self.connections.discard(xmpp_connection) | 206 self.connections.discard(xmpp_connection) |
| 196 | 207 |
| 197 def ForwardNotification(self, unused_xmpp_connection, notification_stanza): | 208 def ForwardNotification(self, unused_xmpp_connection, notification_stanza): |
| 198 for connection in self.connections: | 209 for connection in self.connections: |
| 199 connection.ForwardNotification(notification_stanza) | 210 connection.ForwardNotification(notification_stanza) |
| 200 | 211 |
| 201 def testBasic(self): | 212 def testBasic(self): |
| 202 socket_map = {} | 213 socket_map = {} |
| 203 xmpp_connection = xmppserver.XmppConnection( | 214 xmpp_connection = xmppserver.XmppConnection( |
| 204 self, socket_map, self, ('', 0)) | 215 self.fake_socket, socket_map, self, ('', 0)) |
| 205 self.assertEqual(len(socket_map), 1) | 216 self.assertEqual(len(socket_map), 1) |
| 206 self.assertEqual(len(self.connections), 0) | 217 self.assertEqual(len(self.connections), 0) |
| 207 xmpp_connection.HandshakeDone(xmppserver.Jid('foo', 'bar')) | 218 xmpp_connection.HandshakeDone(xmppserver.Jid('foo', 'bar')) |
| 208 self.assertEqual(len(socket_map), 1) | 219 self.assertEqual(len(socket_map), 1) |
| 209 self.assertEqual(len(self.connections), 1) | 220 self.assertEqual(len(self.connections), 1) |
| 210 | 221 |
| 222 sent_data = self.fake_socket.GetSentData() |
| 223 |
| 211 # Test subscription request. | 224 # Test subscription request. |
| 212 self.assertEqual(len(self.data), 0) | 225 self.assertEqual(len(sent_data), 0) |
| 213 xmpp_connection.collect_incoming_data( | 226 xmpp_connection.collect_incoming_data( |
| 214 '<iq><subscribe xmlns="google:push"></subscribe></iq>') | 227 '<iq><subscribe xmlns="google:push"></subscribe></iq>') |
| 215 self.assertEqual(len(self.data), 1) | 228 self.assertEqual(len(sent_data), 1) |
| 216 | 229 |
| 217 # Test acks. | 230 # Test acks. |
| 218 xmpp_connection.collect_incoming_data('<iq type="result"/>') | 231 xmpp_connection.collect_incoming_data('<iq type="result"/>') |
| 219 self.assertEqual(len(self.data), 1) | 232 self.assertEqual(len(sent_data), 1) |
| 220 | 233 |
| 221 # Test notification. | 234 # Test notification. |
| 222 xmpp_connection.collect_incoming_data( | 235 xmpp_connection.collect_incoming_data( |
| 223 '<message><push xmlns="google:push"/></message>') | 236 '<message><push xmlns="google:push"/></message>') |
| 224 self.assertEqual(len(self.data), 2) | 237 self.assertEqual(len(sent_data), 2) |
| 225 | 238 |
| 226 # Test unexpected stanza. | 239 # Test unexpected stanza. |
| 227 def SendUnexpectedStanza(): | 240 def SendUnexpectedStanza(): |
| 228 xmpp_connection.collect_incoming_data('<foo/>') | 241 xmpp_connection.collect_incoming_data('<foo/>') |
| 229 self.assertRaises(xmppserver.UnexpectedXml, SendUnexpectedStanza) | 242 self.assertRaises(xmppserver.UnexpectedXml, SendUnexpectedStanza) |
| 230 | 243 |
| 231 # Test unexpected notifier command. | 244 # Test unexpected notifier command. |
| 232 def SendUnexpectedNotifierCommand(): | 245 def SendUnexpectedNotifierCommand(): |
| 233 xmpp_connection.collect_incoming_data( | 246 xmpp_connection.collect_incoming_data( |
| 234 '<iq><foo xmlns="google:notifier"/></iq>') | 247 '<iq><foo xmlns="google:notifier"/></iq>') |
| 235 self.assertRaises(xmppserver.UnexpectedXml, | 248 self.assertRaises(xmppserver.UnexpectedXml, |
| 236 SendUnexpectedNotifierCommand) | 249 SendUnexpectedNotifierCommand) |
| 237 | 250 |
| 238 # Test close | 251 # Test close |
| 239 xmpp_connection.close() | 252 xmpp_connection.close() |
| 240 self.assertEqual(len(socket_map), 0) | 253 self.assertEqual(len(socket_map), 0) |
| 241 self.assertEqual(len(self.connections), 0) | 254 self.assertEqual(len(self.connections), 0) |
| 242 | 255 |
| 256 |
| 257 class FakeXmppServer(xmppserver.XmppServer): |
| 258 """A fake XMPP server object used for testing. |
| 259 """ |
| 260 |
| 261 def __init__(self): |
| 262 self._socket_map = {} |
| 263 self._fake_sockets = set() |
| 264 self._next_jid_suffix = 1 |
| 265 xmppserver.XmppServer.__init__(self, self._socket_map, ('', 0)) |
| 266 |
| 267 def GetSocketMap(self): |
| 268 return self._socket_map |
| 269 |
| 270 def GetFakeSockets(self): |
| 271 return self._fake_sockets |
| 272 |
| 273 def AddHandshakeCompletedConnection(self): |
| 274 """Creates a new XMPP connection and completes its handshake. |
| 275 """ |
| 276 xmpp_connection = self.handle_accept() |
| 277 jid = xmppserver.Jid('user%s' % self._next_jid_suffix, 'domain.com') |
| 278 self._next_jid_suffix += 1 |
| 279 xmpp_connection.HandshakeDone(jid) |
| 280 |
| 281 # XmppServer overrides. |
| 282 def accept(self): |
| 283 fake_socket = FakeSocket() |
| 284 self._fake_sockets.add(fake_socket) |
| 285 return (fake_socket, ('', 0)) |
| 286 |
| 287 def close(self): |
| 288 self._fake_sockets.clear() |
| 289 xmppserver.XmppServer.close(self) |
| 290 |
| 291 |
| 243 class XmppServerTest(unittest.TestCase): | 292 class XmppServerTest(unittest.TestCase): |
| 244 | 293 |
| 245 # socket-like methods. | 294 def setUp(self): |
| 246 def fileno(self): | 295 self.xmpp_server = FakeXmppServer() |
| 247 return 0 | |
| 248 | 296 |
| 249 def setblocking(self, int): | 297 def AssertSentDataLength(self, expected_length): |
| 250 pass | 298 for fake_socket in self.xmpp_server.GetFakeSockets(): |
| 251 | 299 self.assertEqual(len(fake_socket.GetSentData()), expected_length) |
| 252 def getpeername(self): | |
| 253 return ('', 0) | |
| 254 | |
| 255 def close(self): | |
| 256 pass | |
| 257 | 300 |
| 258 def testBasic(self): | 301 def testBasic(self): |
| 259 class FakeXmppServer(xmppserver.XmppServer): | 302 socket_map = self.xmpp_server.GetSocketMap() |
| 260 def accept(self2): | 303 self.assertEqual(len(socket_map), 1) |
| 261 return (self, ('', 0)) | 304 self.xmpp_server.AddHandshakeCompletedConnection() |
| 305 self.assertEqual(len(socket_map), 2) |
| 306 self.xmpp_server.close() |
| 307 self.assertEqual(len(socket_map), 0) |
| 262 | 308 |
| 263 socket_map = {} | 309 def testMakeNotification(self): |
| 264 self.assertEqual(len(socket_map), 0) | 310 notification = self.xmpp_server.MakeNotification('channel', 'data') |
| 265 xmpp_server = FakeXmppServer(socket_map, ('', 0)) | 311 expected_xml = ( |
| 266 self.assertEqual(len(socket_map), 1) | 312 '<message>' |
| 267 xmpp_server.handle_accept() | 313 ' <push channel="channel" xmlns="google:push">' |
| 268 self.assertEqual(len(socket_map), 2) | 314 ' <data>%s</data>' |
| 269 xmpp_server.close() | 315 ' </push>' |
| 270 self.assertEqual(len(socket_map), 0) | 316 '</message>' % base64.b64encode('data')) |
| 317 self.assertEqual(notification.toxml(), expected_xml) |
| 318 |
| 319 def testSendNotification(self): |
| 320 # Add a few connections. |
| 321 for _ in xrange(0, 7): |
| 322 self.xmpp_server.AddHandshakeCompletedConnection() |
| 323 |
| 324 self.assertEqual(len(self.xmpp_server.GetFakeSockets()), 7) |
| 325 |
| 326 self.AssertSentDataLength(0) |
| 327 self.xmpp_server.SendNotification('channel', 'data') |
| 328 self.AssertSentDataLength(1) |
| 329 |
| 330 def testEnableDisableNotifications(self): |
| 331 # Add a few connections. |
| 332 for _ in xrange(0, 5): |
| 333 self.xmpp_server.AddHandshakeCompletedConnection() |
| 334 |
| 335 self.assertEqual(len(self.xmpp_server.GetFakeSockets()), 5) |
| 336 |
| 337 self.AssertSentDataLength(0) |
| 338 self.xmpp_server.SendNotification('channel', 'data') |
| 339 self.AssertSentDataLength(1) |
| 340 |
| 341 self.xmpp_server.EnableNotifications() |
| 342 self.xmpp_server.SendNotification('channel', 'data') |
| 343 self.AssertSentDataLength(2) |
| 344 |
| 345 self.xmpp_server.DisableNotifications() |
| 346 self.xmpp_server.SendNotification('channel', 'data') |
| 347 self.AssertSentDataLength(2) |
| 348 |
| 349 self.xmpp_server.DisableNotifications() |
| 350 self.xmpp_server.SendNotification('channel', 'data') |
| 351 self.AssertSentDataLength(2) |
| 352 |
| 353 self.xmpp_server.EnableNotifications() |
| 354 self.xmpp_server.SendNotification('channel', 'data') |
| 355 self.AssertSentDataLength(3) |
| 271 | 356 |
| 272 | 357 |
| 273 if __name__ == '__main__': | 358 if __name__ == '__main__': |
| 274 unittest.main() | 359 unittest.main() |
| OLD | NEW |