async def test_servers_cache_failure(client, protocol_client, backend_client, servers_cache): servers_cache.get.return_value = async_raise(AccessDenied()) await client.run() servers_cache.get.assert_called_once_with() backend_client.get_authentication_data.assert_not_called() protocol_client.authenticate.assert_not_called() protocol_client.run.assert_not_called() @pytest.mark.asyncio @pytest.mark.parametrize("exception", [ asyncio.TimeoutError(), IOError(), websockets.InvalidURI("wss://websocket_1"), websockets.InvalidHandshake() ]) async def test_connect_error(client, backend_client, protocol_client, servers_cache, mocker, exception): servers_cache.get.side_effect = [ async_return_value(["wss://websocket_1", "wss://websocket_2"]), ] connect = mocker.patch( "protocol.websocket_client.websockets.connect", side_effect=[async_raise(exception), async_return_value(MagicMock())]) backend_client.get_authentication_data.return_value = STEAM_ID, ACCOUNT_NAME, TOKEN protocol_client.authenticate.return_value = async_return_value(None) protocol_client.run.return_value = async_raise( websockets.ConnectionClosedOK(1000, ""), 10) await client.run()
def handshake(self, origins=None, subprotocols=None, extra_headers=None): # Read handshake request. try: path, headers = yield from websockets.http.read_request( self.reader) except Exception as exc: raise websockets.InvalidHandshake( "Malformed HTTP message") from exc self.request_headers = headers self.raw_request_headers = list(headers.raw_items()) get_header = lambda k: headers.get(k, '') try: key = websockets.handshake.check_request(get_header) except websockets.InvalidHandshake as exc: raise TryFilesError(path) if origins is not None: origin = get_header('Origin') if not set(origin.split() or ['']) <= set(origins): raise websockets.InvalidOrigin( "Origin not allowed: {}".format(origin)) if subprotocols is not None: protocol = get_header('Sec-WebSocket-Protocol') if protocol: client_subprotocols = [p.strip() for p in protocol.split(',')] self.subprotocol = self.select_subprotocol( client_subprotocols, subprotocols) headers = [] set_header = lambda k, v: headers.append((k, v)) set_header('Server', websockets.http.USER_AGENT) if self.subprotocol: set_header('Sec-WebSocket-Protocol', self.subprotocol) if extra_headers is not None: if callable(extra_headers): extra_headers = extra_headers(path, self.raw_request_headers) if isinstance(extra_headers, collections.abc.Mapping): extra_headers = extra_headers.items() for name, value in extra_headers: set_header(name, value) websockets.handshake.build_response(set_header, key) self.response_headers = email.message.Message() for name, value in headers: self.response_headers[name] = value self.raw_response_headers = headers # Send handshake response. Since the status line and headers only # contain ASCII characters, we can keep this simple. response = ['HTTP/1.1 101 Switching Protocols'] response.extend('{}: {}'.format(k, v) for k, v in headers) response.append('\r\n') response = '\r\n'.join(response).encode() self.writer.write(response) assert self.state == websockets.protocol.CONNECTING self.state = websockets.protocol.OPEN self.opening_handshake.set_result(True) return path
from persistent_cache_state import PersistentCacheState async def async_raise(error, loop_iterations_delay=0): if loop_iterations_delay > 0: await skip_loop(loop_iterations_delay) raise error def wrap_address(addr): return "wss://{}/cmsocket/".format(addr) @pytest.mark.asyncio @pytest.mark.parametrize("exception", [ TimeoutError(), IOError(), websockets.InvalidURI(wrap_address("address_1")), websockets.InvalidHandshake() ]) async def test_no_cache_all_connect_failure(backend_client, mocker, exception): addresses = [ "address_1" ] persistent_cache = {} persistent_cache_state = PersistentCacheState() cache = ServersCache(backend_client, MagicMock(), persistent_cache, persistent_cache_state) backend_client.get_servers.return_value = addresses connect = mocker.patch( "protocol.websocket_client.websockets.connect", return_value=async_raise(exception)
await client.run() sleep.assert_any_call(RECONNECT_INTERVAL_SECONDS) @pytest.mark.asyncio async def test_servers_cache_failure(client, protocol_client, backend_client, servers_cache): servers_cache.get.return_value = async_raise(AccessDenied()) await client.run() servers_cache.get.assert_called_once_with() backend_client.get_authentication_data.assert_not_called() protocol_client.authenticate.assert_not_called() protocol_client.run.assert_not_called() @pytest.mark.asyncio @pytest.mark.parametrize("exception", [ asyncio.TimeoutError(), IOError(), websockets.InvalidURI("wss://websocket_1"), websockets.InvalidHandshake() ]) async def test_connect_error(client, backend_client, protocol_client, servers_cache, mocker, exception): servers_cache.get.side_effect = [ async_return_value(["wss://websocket_1", "wss://websocket_2"]), ] connect = mocker.patch( "protocol.websocket_client.websockets.connect", side_effect=[ async_raise(exception), async_return_value(MagicMock()) ] ) backend_client.get_authentication_data.return_value = STEAM_ID, ACCOUNT_NAME, TOKEN protocol_client.authenticate.return_value = async_return_value(None) protocol_client.run.return_value = async_raise(websockets.ConnectionClosedOK(1000, ""), 10)