def test_write_loop_websocket_bad_connection(self): c = client.Client() c.state = 'connected' c.ping_interval = 1 c.ping_timeout = 2 c.current_transport = 'websocket' c.queue = mock.MagicMock() c.queue.Empty = RuntimeError c.queue.get.side_effect = [ packet.Packet(packet.MESSAGE, {'foo': 'bar'}), RuntimeError, RuntimeError ] c.ws = mock.MagicMock() c.ws.send.side_effect = websocket.WebSocketConnectionClosedException c._write_loop() self.assertEqual(c.state, 'disconnected')
def test_write_loop_websocket_one_packet(self): c = client.Client() c.state = 'connected' c.current_transport = 'websocket' c.queue = mock.MagicMock() c.queue_empty = RuntimeError c.queue.get.side_effect = [ packet.Packet(packet.MESSAGE, {'foo': 'bar'}), RuntimeError, RuntimeError ] c.ws = mock.MagicMock() c._write_loop() self.assertEqual(c.queue.task_done.call_count, 1) self.assertEqual(c.ws.send.call_count, 1) c.ws.send.assert_called_once_with(b'4{"foo":"bar"}')
def test_read_loop_polling_no_response(self, _time): c = client.Client() c.state = 'connected' c.base_url = 'http://foo' c.queue = mock.MagicMock() c._send_request = mock.MagicMock(return_value=None) c._trigger_event = mock.MagicMock() c.write_loop_task = mock.MagicMock() c.ping_loop_task = mock.MagicMock() c._read_loop_polling() self.assertEqual(c.state, 'disconnected') c.queue.put.assert_called_once_with(None) c.write_loop_task.join.assert_called_once_with() c.ping_loop_task.join.assert_called_once_with() c._send_request.assert_called_once_with('GET', 'http://foo&t=123.456') c._trigger_event.assert_called_once_with('disconnect', run_async=False)
def test_read_loop_polling_bad_packet(self, _time): c = client.Client() c.state = 'connected' c.base_url = 'http://foo' c.queue = mock.MagicMock() c._send_request = mock.MagicMock() c._send_request.return_value.status_code = 200 c._send_request.return_value.content = b'foo' c.write_loop_task = mock.MagicMock() c.ping_loop_task = mock.MagicMock() c._read_loop_polling() self.assertEqual(c.state, 'disconnected') c.queue.put.assert_called_once_with(None) c.write_loop_task.join.assert_called_once_with() c.ping_loop_task.join.assert_called_once_with() c._send_request.assert_called_once_with('GET', 'http://foo&t=123.456')
def test_ping_loop_disconnect(self): c = client.Client() c.state = 'connected' c.ping_interval = 10 c._send_packet = mock.MagicMock() states = [('disconnecting', True)] def fake_wait(timeout): self.assertEqual(timeout, 10) c.state, c.pong_received = states.pop(0) c.ping_loop_event = c.create_event() c.ping_loop_event.wait = fake_wait c._ping_loop() self.assertEqual(c._send_packet.call_args_list[0][0][0].encode(), b'2')
def test_read_loop_websocket(self): c = client.Client() c.state = 'connected' c.queue = mock.MagicMock() c.ws = mock.MagicMock() c.ws.recv.side_effect = [packet.Packet(packet.PING).encode(), ValueError] c.write_loop_task = mock.MagicMock() c.ping_loop_task = mock.MagicMock() c._receive_packet = mock.MagicMock() c._read_loop_websocket() self.assertEqual(c.state, 'disconnected') c.queue.put.assert_called_once_with(None) c.write_loop_task.join.assert_called_once_with() c.ping_loop_task.join.assert_called_once_with() self.assertEqual(c._receive_packet.call_args_list[0][0][0].encode(), b'2')
def test_ping_loop_missing_pong(self): c = client.Client() c.state = 'connected' c.ping_interval = 10 c._send_packet = mock.MagicMock() c.queue = mock.MagicMock() states = [('connected', False)] def fake_wait(timeout): self.assertEqual(timeout, 10) c.state, c.pong_received = states.pop(0) c.ping_loop_event.wait = fake_wait c._ping_loop() self.assertEqual(c.state, 'disconnected') c.queue.put.assert_called_once_with(None)
def test_write_loop_websocket_one_packet_binary(self): c = client.Client() c.state = 'connected' c.ping_interval = 1 c.ping_timeout = 2 c.current_transport = 'websocket' c.queue = mock.MagicMock() c.queue.Empty = RuntimeError c.queue.get.side_effect = [ packet.Packet(packet.MESSAGE, b'foo'), RuntimeError, RuntimeError ] c.ws = mock.MagicMock() c._write_loop() self.assertEqual(c.queue.task_done.call_count, 1) self.assertEqual(c.ws.send.call_count, 0) self.assertEqual(c.ws.send_binary.call_count, 1) c.ws.send_binary.assert_called_once_with(b'\x04foo')
def test_ping_loop_disconnect(self): c = client.Client() c.state = 'connected' c.ping_interval = 10 c._send_packet = mock.MagicMock() states = [ ('disconnecting', True) ] def fake_sleep(interval): self.assertEqual(interval, 10) c.state, c.pong_received = states.pop(0) c.sleep = fake_sleep c._ping_loop() self.assertEqual( c._send_packet.call_args_list[0][0][0].encode(), b'2')
def test_send(self): c = client.Client() saved_packets = [] def fake_send_packet(pkt): saved_packets.append(pkt) c._send_packet = fake_send_packet c.send('foo') c.send('foo', binary=False) c.send(b'foo', binary=True) self.assertEqual(saved_packets[0].packet_type, packet.MESSAGE) self.assertEqual(saved_packets[0].data, 'foo') self.assertEqual(saved_packets[0].binary, False if six.PY3 else True) self.assertEqual(saved_packets[1].packet_type, packet.MESSAGE) self.assertEqual(saved_packets[1].data, 'foo') self.assertEqual(saved_packets[1].binary, False) self.assertEqual(saved_packets[2].packet_type, packet.MESSAGE) self.assertEqual(saved_packets[2].data, b'foo') self.assertEqual(saved_packets[2].binary, True)
def test_write_loop_websocket_three_packets(self): c = client.Client() c.state = 'connected' c.ping_interval = 1 c.ping_timeout = 2 c.current_transport = 'websocket' c.queue = mock.MagicMock() c.queue.Empty = RuntimeError c.queue.get.side_effect = [ packet.Packet(packet.MESSAGE, {'foo': 'bar'}), packet.Packet(packet.PING), packet.Packet(packet.NOOP), RuntimeError, RuntimeError ] c.ws = mock.MagicMock() c._write_loop() self.assertEqual(c.queue.task_done.call_count, 3) self.assertEqual(c.ws.send.call_count, 3) self.assertEqual(c.ws.send.call_args_list[0][0][0], b'4{"foo":"bar"}') self.assertEqual(c.ws.send.call_args_list[1][0][0], b'2') self.assertEqual(c.ws.send.call_args_list[2][0][0], b'6')
def test_trigger_event(self): c = client.Client() f = {} @c.on('connect') def foo(): return 'foo' @c.on('message') def bar(data): f['bar'] = data return 'bar' r = c._trigger_event('connect', run_async=False) self.assertEqual(r, 'foo') r = c._trigger_event('message', 123, run_async=True) r.join() self.assertEqual(f['bar'], 123) r = c._trigger_event('message', 321) self.assertEqual(r, 'bar')
def test_websocket_https_noverify_connection_successful( self, create_connection): create_connection.return_value.recv.return_value = packet.Packet( packet.OPEN, { 'sid': '123', 'upgrades': [], 'pingInterval': 1000, 'pingTimeout': 2000 }).encode() c = client.Client(ssl_verify=False) c._ping_loop = mock.MagicMock() c._read_loop_polling = mock.MagicMock() c._read_loop_websocket = mock.MagicMock() c._write_loop = mock.MagicMock() on_connect = mock.MagicMock() c.on('connect', on_connect) c.connect('wss://foo', transports=['websocket']) time.sleep(0.1) c._ping_loop.assert_called_once_with() c._read_loop_polling.assert_not_called() c._read_loop_websocket.assert_called_once_with() c._write_loop.assert_called_once_with() on_connect.assert_called_once_with() self.assertIn(c, client.connected_clients) self.assertEqual(c.base_url, 'wss://foo/engine.io/?transport=websocket&EIO=3') self.assertEqual(c.sid, '123') self.assertEqual(c.ping_interval, 1) self.assertEqual(c.ping_timeout, 2) self.assertEqual(c.upgrades, []) self.assertEqual(c.transport(), 'websocket') self.assertEqual(c.ws, create_connection.return_value) self.assertEqual(len(create_connection.call_args_list), 1) self.assertEqual(create_connection.call_args[1], { 'header': {}, 'cookie': None, 'sslopt': { 'cert_reqs': ssl.CERT_NONE } })
def test_engineio_url(self): c = client.Client() self.assertEqual(c._get_engineio_url('http://foo', 'bar', 'polling'), 'http://foo/bar/?transport=polling&EIO=3') self.assertEqual(c._get_engineio_url('http://foo', 'bar', 'websocket'), 'ws://foo/bar/?transport=websocket&EIO=3') self.assertEqual(c._get_engineio_url('ws://foo', 'bar', 'polling'), 'http://foo/bar/?transport=polling&EIO=3') self.assertEqual(c._get_engineio_url('ws://foo', 'bar', 'websocket'), 'ws://foo/bar/?transport=websocket&EIO=3') self.assertEqual(c._get_engineio_url('https://foo', 'bar', 'polling'), 'https://foo/bar/?transport=polling&EIO=3') self.assertEqual( c._get_engineio_url('https://foo', 'bar', 'websocket'), 'wss://foo/bar/?transport=websocket&EIO=3') self.assertEqual( c._get_engineio_url('http://foo?baz=1', 'bar', 'polling'), 'http://foo/bar/?baz=1&transport=polling&EIO=3') self.assertEqual( c._get_engineio_url('http://foo#baz', 'bar', 'polling'), 'http://foo/bar/?transport=polling&EIO=3')
def test_ping_loop_missing_pong_websocket(self): c = client.Client() c.state = 'connected' c.ping_interval = 10 c._send_packet = mock.MagicMock() c.queue = mock.MagicMock() c.ws = mock.MagicMock() states = [ ('connected', False) ] def fake_sleep(interval): self.assertEqual(interval, 10) c.state, c.pong_received = states.pop(0) c.sleep = fake_sleep c._ping_loop() self.assertEqual(c.state, 'disconnected') c.queue.put.assert_called_once_with(None) c.ws.close.assert_called_once_with()
def test_write_loop_polling_bad_status(self): c = client.Client() c.base_url = 'http://foo' c.state = 'connected' c.current_transport = 'polling' c.queue = mock.MagicMock() c.queue_empty = RuntimeError c.queue.get.side_effect = [ packet.Packet(packet.MESSAGE, {'foo': 'bar'}), RuntimeError, ] c._send_request = mock.MagicMock() c._send_request.return_value.status = 500 c._write_loop() self.assertEqual(c.queue.task_done.call_count, 1) p = payload.Payload( packets=[packet.Packet(packet.MESSAGE, {'foo': 'bar'})]) c._send_request.assert_called_once_with( 'POST', 'http://foo', body=p.encode(), headers={'Content-Type': 'application/octet-stream'}) self.assertEqual(c.state, 'disconnected')
def test_polling_connection_with_more_packets(self, _send_request): _send_request.return_value.status_code = 200 _send_request.return_value.content = payload.Payload(packets=[ packet.Packet(packet.OPEN, { 'sid': '123', 'upgrades': [], 'pingInterval': 1000, 'pingTimeout': 2000 }), packet.Packet(packet.NOOP) ]).encode() c = client.Client() c._ping_loop = mock.MagicMock() c._read_loop_polling = mock.MagicMock() c._read_loop_websocket = mock.MagicMock() c._write_loop = mock.MagicMock() c._receive_packet = mock.MagicMock() on_connect = mock.MagicMock() c.on('connect', on_connect) c.connect('http://foo') time.sleep(0.1) self.assertEqual(c._receive_packet.call_count, 1) self.assertEqual( c._receive_packet.call_args_list[0][0][0].packet_type, packet.NOOP)
def test_read_loop_polling(self): c = client.Client() c.state = 'connected' c.base_url = 'http://foo' c.queue = mock.MagicMock() c._send_request = mock.MagicMock() c._send_request.side_effect = [ mock.MagicMock(status=200, data=payload.Payload(packets=[ packet.Packet(packet.PING), packet.Packet(packet.NOOP)]).encode()), None ] c.write_loop_task = mock.MagicMock() c._receive_packet = mock.MagicMock() c._read_loop_polling() self.assertEqual(c.state, 'disconnected') c.queue.put.assert_called_once_with(None) self.assertEqual(c._send_request.call_count, 2) self.assertEqual(c._receive_packet.call_count, 2) self.assertEqual(c._receive_packet.call_args_list[0][0][0].encode(), b'2') self.assertEqual(c._receive_packet.call_args_list[1][0][0].encode(), b'6')
def test_websocket_upgrade_no_pong(self, create_connection): create_connection.return_value.recv.return_value = packet.Packet( packet.OPEN, { 'sid': '123', 'upgrades': [], 'pingInterval': 1000, 'pingTimeout': 2000 }).encode() c = client.Client() c.sid = '123' c.current_transport = 'polling' c._ping_loop = mock.MagicMock() c._read_loop_polling = mock.MagicMock() c._read_loop_websocket = mock.MagicMock() c._write_loop = mock.MagicMock() on_connect = mock.MagicMock() c.on('connect', on_connect) self.assertFalse(c.connect('ws://foo', transports=['websocket'])) c._ping_loop.assert_not_called() c._read_loop_polling.assert_not_called() c._read_loop_websocket.assert_not_called() c._write_loop.assert_not_called() on_connect.assert_not_called() self.assertEqual(c.transport(), 'polling')
def test_trigger_unknown_event(self): c = client.Client() c._trigger_event('connect', run_async=False) c._trigger_event('message', 123, run_async=True)
def test_on_event_invalid(self): c = client.Client() self.assertRaises(ValueError, c.on, 'invalid')
def test_send_packet_disconnected(self): c = client.Client() c.queue = c.create_queue() c.state = 'disconnected' c._send_packet(packet.Packet(packet.NOOP)) self.assertTrue(c.queue.empty())
def test_invalid_transports(self): c = client.Client() self.assertRaises(ValueError, c.connect, 'http://foo', transports=['foo', 'bar'])
def test_receive_pong_packet(self): c = client.Client() c.pong_received = False c._receive_packet(packet.Packet(packet.PONG)) self.assertTrue(c.pong_received)
def test_receive_noop_packet(self): c = client.Client() c._receive_packet(packet.Packet(packet.NOOP))
def test_already_connected(self): c = client.Client() c.state = 'connected' self.assertRaises(ValueError, c.connect, 'http://foo')
def test_ping_loop_disconnected(self): c = client.Client() c.state = 'disconnected' c._ping_loop()
def test_receive_message_packet(self): c = client.Client() c._trigger_event = mock.MagicMock() c._receive_packet(packet.Packet(packet.MESSAGE, {'foo': 'bar'})) c._trigger_event.assert_called_once_with('message', {'foo': 'bar'}, run_async=True)
def test_some_invalid_transports(self): c = client.Client() c._connect_websocket = mock.MagicMock() c.connect('http://foo', transports=['foo', 'websocket', 'bar']) self.assertEqual(c.transports, ['websocket'])
def test_receive_close_packet(self): c = client.Client() c.disconnect = mock.MagicMock() c._receive_packet(packet.Packet(packet.CLOSE)) c.disconnect.assert_called_once_with(abort=True)