def test_connect_transport_websocket_closed(self, import_module, AsyncSocket): a = self.get_async_mock({'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'transport=websocket'}) import_module.side_effect = [a] AsyncSocket.return_value = self._get_mock_socket() s = asyncio_server.AsyncServer() s._generate_id = mock.MagicMock(return_value='123') # this mock handler just closes the socket, as it would happen on a # real websocket exchange async def mock_handle(environ): s.sockets['123'].closed = True AsyncSocket().handle_get_request = mock_handle _run(s.handle_request('request')) self.assertNotIn('123', s.sockets) # socket should close on its own
def test_connect(self, import_module): a = self.get_async_mock() import_module.side_effect = [a] s = asyncio_server.AsyncServer() _run(s.handle_request('request')) self.assertEqual(len(s.sockets), 1) self.assertEqual(a._async['make_response'].call_count, 1) self.assertEqual(a._async['make_response'].call_args[0][0], '200 OK') self.assertIn(('Content-Type', 'application/octet-stream'), a._async['make_response'].call_args[0][1]) 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.OPEN) self.assertIn('upgrades', packets[0].data) self.assertEqual(packets[0].data['upgrades'], ['websocket']) self.assertIn('sid', packets[0].data)
def test_connect_b64_with_0(self, import_module): a = self.get_async_mock({'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'b64=0'}) import_module.side_effect = [a] s = asyncio_server.AsyncServer(allow_upgrades=False) s._generate_id = mock.MagicMock(return_value='1') _run(s.handle_request('request')) self.assertEqual(a._async['make_response'].call_count, 1) self.assertEqual(a._async['make_response'].call_args[0][0], '200 OK') self.assertIn(('Content-Type', 'application/octet-stream'), a._async['make_response'].call_args[0][1]) _run(s.send('1', b'\x00\x01\x02', binary=True)) a._async['translate_request'].return_value = { 'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=1&b64=0'} _run(s.handle_request('request')) self.assertEqual(a._async['make_response'].call_args[0][2], b'\x01\x04\xff\x04\x00\x01\x02')
def test_post_request_error(self, import_module): a = self.get_async_mock({ 'REQUEST_METHOD': 'POST', 'QUERY_STRING': 'sid=foo' }) import_module.side_effect = [a] s = asyncio_server.AsyncServer() s.sockets['foo'] = mock_socket = self._get_mock_socket() @asyncio.coroutine def mock_post_request(*args, **kwargs): raise exceptions.ContentTooLongError() mock_socket.handle_post_request.mock.return_value = mock_post_request() _run(s.handle_request('request')) self.assertEqual(a._async['make_response'].call_args[0][0], '400 BAD REQUEST')
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: self.assertNotEqual(header, 'Content-Encoding') self.assertRaises(IOError, self._gzip_decompress, a._async['make_response'].call_args[0][2])
def test_get_request_closes_socket(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() async def mock_get_request(*args, **kwargs): mock_socket.closed = True return 'resp' mock_socket.handle_get_request = mock_get_request r = _run(s.handle_request('request')) self.assertEqual(r, 'resp') self.assertNotIn('foo', s.sockets)
def test_get_request_error(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() async def mock_get_request(*args, **kwargs): raise exceptions.QueueEmpty() mock_socket.handle_get_request = mock_get_request _run(s.handle_request('request')) self.assertEqual(a._async['make_response'].call_args[0][0], '400 BAD REQUEST') self.assertEqual(len(s.sockets), 0)
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')) assert a._async['make_response'].call_args[0][0] == '200 OK' packets = payload.Payload( encoded_payload=a._async['make_response'].call_args[0][2]).packets assert len(packets) == 1 assert packets[0].packet_type == packet.MESSAGE
def test_connect_cors_not_allowed_origin_async_response( self, import_module): a = self.get_async_mock({ 'REQUEST_METHOD': 'GET', 'QUERY_STRING': '', 'HTTP_ORIGIN': 'c' }) a._async['make_response'] = AsyncMock( return_value=a._async['make_response'].return_value) import_module.side_effect = [a] s = asyncio_server.AsyncServer(cors_allowed_origins=['a', 'b']) _run(s.handle_request('request')) assert (a._async['make_response'].mock.call_args[0][0] == '400 BAD REQUEST') headers = a._async['make_response'].mock.call_args[0][1] assert ('Access-Control-Allow-Origin', 'c') not in headers assert ('Access-Control-Allow-Origin', '*') not in headers
def test_connect(self, import_module): a = self.get_async_mock() import_module.side_effect = [a] s = asyncio_server.AsyncServer() _run(s.handle_request('request')) assert len(s.sockets) == 1 assert a._async['make_response'].call_count == 1 assert a._async['make_response'].call_args[0][0] == '200 OK' assert ('Content-Type', 'application/octet-stream' ) in a._async['make_response'].call_args[0][1] packets = payload.Payload( encoded_payload=a._async['make_response'].call_args[0][2]).packets assert len(packets) == 1 assert packets[0].packet_type == packet.OPEN assert 'upgrades' in packets[0].data assert packets[0].data['upgrades'] == ['websocket'] assert 'sid' in packets[0].data
def test_jsonp_index(self, import_module): a = self.get_async_mock( {'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'j=233'} ) import_module.side_effect = [a] s = asyncio_server.AsyncServer() response = _run(s.handle_request('request')) assert response == 'response' a._async['translate_request'].assert_called_once_with('request') assert a._async['make_response'].call_count == 1 assert a._async['make_response'].call_args[0][0] == '200 OK' assert ( a._async['make_response'] .call_args[0][2] .startswith(b'___eio[233]("') ) assert a._async['make_response'].call_args[0][2].endswith(b'");')
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_cookie_dict(self, import_module): def get_path(): return '/a' a = self.get_async_mock() import_module.side_effect = [a] s = asyncio_server.AsyncServer(cookie={ 'name': 'test', 'path': get_path, 'SameSite': 'None', 'Secure': True, 'HttpOnly': True }) s._generate_id = mock.MagicMock(return_value='123') _run(s.handle_request('request')) headers = a._async['make_response'].call_args[0][1] assert ('Set-Cookie', 'test=123; path=/a; SameSite=None; Secure; ' 'HttpOnly') in headers
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: assert header != 'Content-Encoding' with pytest.raises(IOError): self._gzip_decompress(a._async['make_response'].call_args[0][2])
def test_connect_transport_websocket(self, import_module, AsyncSocket): a = self.get_async_mock( { 'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'transport=websocket', 'HTTP_UPGRADE': 'websocket', } ) import_module.side_effect = [a] AsyncSocket.return_value = self._get_mock_socket() s = asyncio_server.AsyncServer() s._generate_id = mock.MagicMock(return_value='123') # force socket to stay open, so that we can check it later AsyncSocket().closed = False _run(s.handle_request('request')) assert ( s.sockets['123'].send.mock.call_args[0][0].packet_type == packet.OPEN )
def test_connect_b64_with_true(self, import_module): a = self.get_async_mock({ 'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'b64=true' }) import_module.side_effect = [a] s = asyncio_server.AsyncServer(allow_upgrades=False) s._generate_id = mock.MagicMock(return_value='1') _run(s.handle_request('request')) assert a._async['make_response'].call_count == 1 assert a._async['make_response'].call_args[0][0] == '200 OK' assert ('Content-Type', 'text/plain; charset=UTF-8' ) in a._async['make_response'].call_args[0][1] _run(s.send('1', b'\x00\x01\x02', binary=True)) a._async['translate_request'].return_value = { 'REQUEST_METHOD': 'GET', 'QUERY_STRING': 'sid=1&b64=true', } _run(s.handle_request('request')) assert a._async['make_response'].call_args[0][2] == b'6:b4AAEC'
def test_custom_json(self): # Warning: this test cannot run in parallel with other tests, as it # changes the JSON encoding/decoding functions class CustomJSON(object): @staticmethod def dumps(*args, **kwargs): return '*** encoded ***' @staticmethod def loads(*args, **kwargs): return '+++ decoded +++' asyncio_server.AsyncServer(json=CustomJSON) pkt = packet.Packet(packet.MESSAGE, data={'foo': 'bar'}) self.assertEqual(pkt.encode(), b'4*** encoded ***') pkt2 = packet.Packet(encoded_packet=pkt.encode()) self.assertEqual(pkt2.data, '+++ decoded +++') # restore the default JSON module packet.Packet.json = json
def test_async_modes(self): s = asyncio_server.AsyncServer() self.assertEqual(s.async_modes(), ['aiohttp', 'sanic', 'tornado', 'asgi'])
def test_is_asyncio_based(self): s = asyncio_server.AsyncServer() self.assertEqual(s.is_asyncio_based(), True)
def test_send_unknown_socket(self, import_module): a = self.get_async_mock() import_module.side_effect = [a] s = asyncio_server.AsyncServer() # just ensure no exceptions are raised _run(s.send('foo', 'hello'))
def test_create_event(self): s = asyncio_server.AsyncServer() e = s.create_event() self.assertFalse(e.is_set()) e.set() self.assertTrue(e.is_set())
def test_create_queue(self): s = asyncio_server.AsyncServer() q = s.create_queue() empty = s.get_queue_empty_exception() self.assertRaises(empty, q.get_nowait)
def test_async_mode_auto_aiohttp(self, import_module): import_module.side_effect = [self.get_async_mock()] s = asyncio_server.AsyncServer() self.assertEqual(s.async_mode, 'aiohttp')
def test_attach(self, import_module): a = self.get_async_mock() import_module.side_effect = [a] s = asyncio_server.AsyncServer() s.attach('app', engineio_path='path') a._async['create_route'].assert_called_with('app', s, '/path/')
def test_async_modes(self): s = asyncio_server.AsyncServer() assert s.async_modes() == ['aiohttp', 'sanic', 'tornado', 'asgi']
def test_is_asyncio_based(self): s = asyncio_server.AsyncServer() assert s.is_asyncio_based()
def test_create_event(self): s = asyncio_server.AsyncServer() e = s.create_event() assert not e.is_set() e.set() assert e.is_set()
def test_sleep(self): s = asyncio_server.AsyncServer() _run(s.sleep(0))
def test_create_queue(self): s = asyncio_server.AsyncServer() q = s.create_queue() empty = s.get_queue_empty_exception() with pytest.raises(empty): q.get_nowait()