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 |