def test_deflate_compression(self, import_module): a = self.get_async_mock({ 'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo', 'HTTP_ACCEPT_ENCODING': 'deflate;q=1,gzip', }) import_module.side_effect = [a] s = asyncio_server.AsyncServer(compression_threshold=0) s.sockets['foo'] = mock_socket = self._get_mock_socket() mock_socket.handle_get_request.mock.return_value = [ packet.Packet(packet.MESSAGE, data='hello') ] _run(s.handle_request('request')) headers = a._async['make_response'].call_args[0][1] assert ('Content-Encoding', 'deflate') in headers zlib.decompress(a._async['make_response'].call_args[0][2])
def test_polling_connection_no_open_packet(self): c = asyncio_client.AsyncClient() c._send_request = AsyncMock() c._send_request.mock.return_value.status = 200 c._send_request.mock.return_value.read = AsyncMock( return_value=payload.Payload(packets=[ packet.Packet( packet.CLOSE, { 'sid': '123', 'upgrades': [], 'pingInterval': 10, 'pingTimeout': 20 }) ]).encode()) self.assertRaises(exceptions.ConnectionError, _run, c.connect('http://foo'))
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_deflate_compression(self): s = server.Server(compression_threshold=0) mock_socket = self._get_mock_socket() mock_socket.handle_get_request = mock.MagicMock( return_value=[packet.Packet(packet.MESSAGE, data='hello')]) s.sockets['foo'] = mock_socket environ = { 'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo', 'ACCEPT_ENCODING': 'deflate;q=1,gzip' } start_response = mock.MagicMock() r = s.handle_request(environ, start_response) self.assertIn(('Content-Encoding', 'deflate'), start_response.call_args[0][1]) zlib.decompress(r[0])
def test_compression_no_encoding(self): s = server.Server(compression_threshold=0) mock_socket = self._get_mock_socket() mock_socket.handle_get_request = mock.MagicMock( return_value=[packet.Packet(packet.MESSAGE, data='hello')]) s.sockets['foo'] = mock_socket environ = { 'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo', 'ACCEPT_ENCODING': '' } start_response = mock.MagicMock() r = s.handle_request(environ, start_response) for header, value in start_response.call_args[0][1]: self.assertNotEqual(header, 'Content-Encoding') self.assertRaises(IOError, self._gzip_decompress, r[0])
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, 'connected')
def test_get_request(self, import_module): a = self.get_async_mock({ 'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo' }) import_module.side_effect = [a] s = asyncio_server.AsyncServer() s.sockets['foo'] = mock_socket = self._get_mock_socket() mock_socket.handle_get_request.mock.return_value = \ [packet.Packet(packet.MESSAGE, data='hello')] _run(s.handle_request('request')) self.assertEqual(a._async['make_response'].call_args[0][0], '200 OK') packets = payload.Payload( encoded_payload=a._async['make_response'].call_args[0][2]).packets self.assertEqual(len(packets), 1) self.assertEqual(packets[0].packet_type, packet.MESSAGE)
def test_compression_disabled(self, import_module): a = self.get_async_mock({'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo', 'HTTP_ACCEPT_ENCODING': 'gzip'}) import_module.side_effect = [a] s = asyncio_server.AsyncServer(http_compression=False, compression_threshold=0) s.sockets['foo'] = mock_socket = self._get_mock_socket() mock_socket.handle_get_request.mock.return_value = \ [packet.Packet(packet.MESSAGE, data='hello')] _run(s.handle_request('request')) headers = a._async['make_response'].call_args[0][1] for header, value in headers: self.assertNotEqual(header, 'Content-Encoding') self.assertRaises(IOError, self._gzip_decompress, a._async['make_response'].call_args[0][2])
def test_read_loop_websocket(self): c = asyncio_client.AsyncClient() c.base_url = 'ws://foo' c.state = 'connected' c.queue = mock.MagicMock() c.queue.put = AsyncMock() c.ws = mock.MagicMock() c.ws.recv = AsyncMock( side_effect=[packet.Packet(packet.PING).encode(), ValueError]) c.write_loop_task = AsyncMock()() c._receive_packet = AsyncMock() _run(c._read_loop_websocket()) self.assertEqual(c.state, 'disconnected') self.assertEqual( c._receive_packet.mock.call_args_list[0][0][0].encode(), b'2') c.queue.put.mock.assert_called_once_with(None)
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_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_compression_unknown(self): s = server.Server(compression_threshold=0) mock_socket = self._get_mock_socket() mock_socket.handle_get_request = mock.MagicMock( return_value=[packet.Packet(packet.MESSAGE, data='hello')]) s.sockets['foo'] = mock_socket environ = { 'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'EIO=4&sid=foo', 'HTTP_ACCEPT_ENCODING': 'rar', } start_response = mock.MagicMock() r = s.handle_request(environ, start_response) for header, value in start_response.call_args[0][1]: assert header != 'Content-Encoding' with pytest.raises(IOError): self._gzip_decompress(r[0])
def test_write_loop_websocket_bad_connection(self): c = asyncio_client.AsyncClient() 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 = AsyncMock(side_effect=[ packet.Packet(packet.MESSAGE, {'foo': 'bar'}), RuntimeError ]) c.queue.get_nowait = mock.MagicMock(side_effect=[RuntimeError]) c.ws = mock.MagicMock() c.ws.send = AsyncMock( side_effect=websockets.exceptions.ConnectionClosed(1, 'foo')) _run(c._write_loop()) self.assertEqual(c.state, 'disconnected')
def test_write_loop_websocket_one_packet(self): c = asyncio_client.AsyncClient() 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 = AsyncMock(side_effect=[ packet.Packet(packet.MESSAGE, {'foo': 'bar'}), RuntimeError ]) c.queue.get_nowait = mock.MagicMock(side_effect=[RuntimeError]) c.ws = mock.MagicMock() c.ws.send = AsyncMock() _run(c._write_loop()) self.assertEqual(c.queue.task_done.call_count, 1) self.assertEqual(c.ws.send.mock.call_count, 1) c.ws.send.mock.assert_called_once_with('4{"foo":"bar"}')
def test_compression_no_encoding(self, import_module): a = self.get_async_mock({ 'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=foo', 'HTTP_ACCEPT_ENCODING': '', }) import_module.side_effect = [a] s = asyncio_server.AsyncServer(compression_threshold=0) s.sockets['foo'] = mock_socket = self._get_mock_socket() mock_socket.handle_get_request.mock.return_value = [ packet.Packet(packet.MESSAGE, data='hello') ] _run(s.handle_request('request')) headers = a._async['make_response'].call_args[0][1] for header, value in headers: assert header != 'Content-Encoding' with pytest.raises(IOError): self._gzip_decompress(a._async['make_response'].call_args[0][2])
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_websocket_https_noverify_connection_successful(self, _time): c = asyncio_client.AsyncClient(ssl_verify=False) c.http = mock.MagicMock(closed=False) c.http.ws_connect = AsyncMock() ws = c.http.ws_connect.mock.return_value ws.receive = AsyncMock() ws.receive.mock.return_value.data = packet.Packet( packet.OPEN, { 'sid': '123', 'upgrades': [], 'pingInterval': 1000, 'pingTimeout': 2000 }).encode() c._ping_loop = AsyncMock() c._read_loop_polling = AsyncMock() c._read_loop_websocket = AsyncMock() c._write_loop = AsyncMock() on_connect = mock.MagicMock() c.on('connect', on_connect) _run(c.connect('wss://foo', transports=['websocket'])) time.sleep(0.1) c._ping_loop.mock.assert_called_once_with() c._read_loop_polling.mock.assert_not_called() c._read_loop_websocket.mock.assert_called_once_with() c._write_loop.mock.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, ws) _, kwargs = c.http.ws_connect.mock.call_args self.assertTrue('ssl' in kwargs) self.assertTrue(isinstance(kwargs['ssl'], ssl.SSLContext)) self.assertEqual(kwargs['ssl'].verify_mode, ssl.CERT_NONE)
def test_websocket_connection_successful(self, _time): c = asyncio_client.AsyncClient() c.http = mock.MagicMock(closed=False) c.http.ws_connect = AsyncMock() ws = c.http.ws_connect.mock.return_value ws.receive = AsyncMock() ws.receive.mock.return_value.data = packet.Packet( packet.OPEN, { 'sid': '123', 'upgrades': [], 'pingInterval': 1000, 'pingTimeout': 2000 }).encode() c._ping_loop = AsyncMock() c._read_loop_polling = AsyncMock() c._read_loop_websocket = AsyncMock() c._write_loop = AsyncMock() on_connect = mock.MagicMock() c.on('connect', on_connect) _run(c.connect('ws://foo', transports=['websocket'])) time.sleep(0.1) c._ping_loop.mock.assert_called_once_with() c._read_loop_polling.mock.assert_not_called() c._read_loop_websocket.mock.assert_called_once_with() c._write_loop.mock.assert_called_once_with() on_connect.assert_called_once_with() self.assertIn(c, client.connected_clients) self.assertEqual(c.base_url, 'ws://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, ws) c.http.ws_connect.mock.assert_called_once_with( 'ws://foo/engine.io/?transport=websocket&EIO=3&t=123.456', headers={})
def test_websocket_upgrade_successful(self): c = asyncio_client.AsyncClient() c.http = mock.MagicMock(closed=False) c.http.ws_connect = AsyncMock() ws = c.http.ws_connect.mock.return_value ws.receive = AsyncMock() ws.receive.mock.return_value.data = packet.Packet( packet.PONG, 'probe').encode() ws.send_str = AsyncMock() c.sid = '123' c.base_url = 'http://foo' c.current_transport = 'polling' c._ping_loop = AsyncMock() c._read_loop_polling = AsyncMock() c._read_loop_websocket = AsyncMock() c._write_loop = AsyncMock() on_connect = mock.MagicMock() c.on('connect', on_connect) self.assertTrue(_run(c.connect('ws://foo', transports=['websocket']))) time.sleep(0.1) c._ping_loop.mock.assert_called_once_with() c._read_loop_polling.mock.assert_not_called() c._read_loop_websocket.mock.assert_called_once_with() c._write_loop.mock.assert_called_once_with() on_connect.assert_not_called() # was called by polling self.assertNotIn(c, client.connected_clients) # was added by polling self.assertEqual(c.base_url, 'http://foo') # not changed self.assertEqual(c.sid, '123') # not changed self.assertEqual(c.transport(), 'websocket') self.assertEqual(c.ws, ws) self.assertEqual( ws.send_str.mock.call_args_list[0], (('2probe',),)) # ping self.assertEqual( ws.send_str.mock.call_args_list[1], (('5',),)) # upgrade
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_polling_connection_successful(self): c = asyncio_client.AsyncClient() c._send_request = AsyncMock() c._send_request.mock.return_value.status = 200 c._send_request.mock.return_value.read = AsyncMock( return_value=payload.Payload(packets=[ packet.Packet( packet.OPEN, { 'sid': '123', 'upgrades': [], 'pingInterval': 1000, 'pingTimeout': 2000 }) ]).encode()) c._ping_loop = AsyncMock() c._read_loop_polling = AsyncMock() c._read_loop_websocket = AsyncMock() c._write_loop = AsyncMock() on_connect = AsyncMock() c.on('connect', on_connect) _run(c.connect('http://foo')) time.sleep(0.1) c._ping_loop.mock.assert_called_once_with() c._read_loop_polling.mock.assert_called_once_with() c._read_loop_websocket.mock.assert_not_called() c._write_loop.mock.assert_called_once_with() on_connect.mock.assert_called_once_with() self.assertIn(c, client.connected_clients) self.assertEqual( c.base_url, 'http://foo/engine.io/?transport=polling&EIO=3&sid=123') 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(), 'polling')
def test_websocket_connection_no_open_packet(self): asyncio_client.websockets.connect.mock.return_value.recv = AsyncMock( return_value=packet.Packet(packet.CLOSE).encode()) c = asyncio_client.AsyncClient() self.assertRaises(exceptions.ConnectionError, _run, c.connect('http://foo', transports=['websocket']))
def test_receive_pong_packet(self): c = asyncio_client.AsyncClient() c.pong_received = False _run(c._receive_packet(packet.Packet(packet.PONG))) self.assertTrue(c.pong_received)
def test_invalid_packet_type(self): mock_server = self._get_mock_server() s = socket.Socket(mock_server, 'sid') pkt = packet.Packet(packet_type=99) self.assertRaises(exceptions.UnknownPacketError, s.receive, pkt)
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)
def test_receive_unknown_packet(self): c = asyncio_client.AsyncClient() _run(c._receive_packet(packet.Packet(encoded_packet=b'9')))
def test_receive_noop_packet(self): c = asyncio_client.AsyncClient() _run(c._receive_packet(packet.Packet(packet.NOOP)))
def test_send_after_close(self): mock_server = self._get_mock_server() s = socket.Socket(mock_server, 'sid') s.close(wait=False) self.assertRaises(IOError, s.send, packet.Packet(packet.NOOP))
def test_send_packet_disconnected(self): c = asyncio_client.AsyncClient() c.queue = c.create_queue() c.state = 'disconnected' _run(c._send_packet(packet.Packet(packet.NOOP))) self.assertTrue(c.queue.empty())
def test_invalid_packet(self): mock_server = self._get_mock_server() s = socket.Socket(mock_server, 'sid') self.assertRaises(ValueError, s.receive, packet.Packet(packet.OPEN))