async def _get_request(self, session: aiohttp.ClientSession, url, params={}, retries=0) -> str: try: async with session.get(url, allow_redirects=True, params=params) as query: if query.status != 200: print(f'try: {retries}') if query.status == 503: if retries > 100: raise ClientConnectionError( 'Слишком много неудачных попыток') await asyncio.sleep(retries + random.randint(1, 3)) return await self._get_request(session, url, params, retries=retries + 1) elif query.status == 404: raise ClientConnectionError( f'Страница: {url} не найдена') else: return ClientConnectionError( f'{url}: code {query.status}') return await query.text() except aiohttp.ServerDisconnectedError: await asyncio.sleep(retries + random.randint(1, 3)) print(f'tryd: {retries}') if retries > 100: raise ClientConnectionError('Слишком много неудачных попыток') return await self._get_request(session, url, params, retries=retries + 1)
async def _request_mock(self, orig_self: ClientSession, method: str, url: 'Union[URL, str]', *args: Tuple, **kwargs: Dict) -> 'ClientResponse': """Return mocked response object or raise connection error.""" url = normalize_url(merge_params(url, kwargs.get('params'))) url_str = str(url) for prefix in self._passthrough: if url_str.startswith(prefix): return (await self.patcher.temp_original(orig_self, method, url, *args, **kwargs)) response = await self.match(method, url, **kwargs) if response is None: raise ClientConnectionError('Connection refused: {} {}'.format( method, url)) self._responses.append(response) key = (method, url) self.requests.setdefault(key, []) self.requests[key].append(RequestCall(args, kwargs)) # Automatically call response.raise_for_status() on a request if the # request was initialized with raise_for_status=True. Also call # response.raise_for_status() if the client session was initialized # with raise_for_status=True, unless the request was called with # raise_for_status=False. raise_for_status = kwargs.get('raise_for_status') if raise_for_status is None: raise_for_status = getattr(orig_self, '_raise_for_status', False) if raise_for_status: response.raise_for_status() return response
async def test_connection_errors_raise_not_ready(hass, config_entry, smartthings_mock): """Test config entry not ready raised for connection errors.""" config_entry.add_to_hass(hass) smartthings_mock.app.side_effect = ClientConnectionError() with pytest.raises(ConfigEntryNotReady): await smartthings.async_setup_entry(hass, config_entry)
def test_exception_handling(self): def test_exception_handling(to_raise, to_catch): with self.assertRaises(to_catch): with self.cloudstack_adapter.handle_exceptions(): raise to_raise matrix = [ (CloudStackClientException(message="Quota Exceeded", error_code=535, error_text="Quota Exceeded"), TardisQuotaExceeded), (asyncio.TimeoutError(), TardisTimeout), (ClientConnectionError(), TardisResourceStatusUpdateFailed), (CloudStackClientException( message="Timeout", error_code=500, response={'message': 'timed out after 1000.0 ms'}), TardisTimeout), (CloudStackClientException(message="Timeout", error_code=500, response={ 'message': 'connection was closed' }), TardisResourceStatusUpdateFailed), (CloudStackClientException(message="Something else", error_code=500, response={'message': 'Something else'}), TardisError), (CloudStackClientException(message="Something Else", error_code=666, error_text="Something Else"), TardisError) ] for to_raise, to_catch in matrix: test_exception_handling(to_raise, to_catch)
def test_exception_handling(self): def test_exception_handling(to_raise, to_catch): with self.assertRaises(to_catch): with self.assertLogs(level=logging.WARNING): with self.openstack_adapter.handle_exceptions(): raise to_raise matrix = [ (asyncio.TimeoutError(), TardisTimeout), (AuthError(message="Test_Error", response="Not Allowed"), TardisAuthError), ( ContentTypeError(request_info=AttributeDict(real_url="Test"), history="Test"), TardisResourceStatusUpdateFailed, ), ( ClientError(message="Test_Error", response="Internal Server Error"), TardisDroneCrashed, ), (ClientConnectionError(), TardisResourceStatusUpdateFailed), (Exception, TardisError), ] for to_raise, to_catch in matrix: test_exception_handling(to_raise, to_catch)
async def readcontent(self, n: int = -1) -> bytes: """Read up to 'n' bytes of the response payload. If 'n' is -1 (default), read the entire payload. """ if self._body is None: try: if n == -1: self._body = await self.content.read() else: chunks = [] i = 0 while i < n: chunk = await self.content.read(n=n - i) if not chunk: break chunks.append(chunk) i += len(chunk) self._body = b''.join(chunks) for trace in self._traces: await trace.send_response_chunk_received(self._body) except BaseException: self.close() raise elif self._released: raise ClientConnectionError('Connection closed') return self._body
def _request_mock(self, method: str, url: str, *args: Tuple, **kwargs: Dict) -> 'ClientResponse': """Return mocked response object or raise connection error.""" response = self.match(method, url) if response is None: raise ClientConnectionError('Connection refused: {} {}'.format( method, url)) return response
async def test_connection_errors_raise_not_ready(hass, config_entry, smartthings_mock): """Test config entry not ready raised for connection errors.""" setattr(hass.config_entries, '_entries', [config_entry]) api = smartthings_mock.return_value api.app.return_value = mock_coro(exception=ClientConnectionError()) with pytest.raises(ConfigEntryNotReady): await smartthings.async_setup_entry(hass, config_entry)
def match(self, method: str, url: str) -> Tuple[Callable[..., dict], int]: try: i, handler, status = next((i, r.handler, r.status) for i, r in enumerate(self._responses) if r.method.lower() == method.lower() and url == f'{r.hostname}{r.path}') del self._responses[i] return handler, status except StopIteration: raise ClientConnectionError(f'No response for {method} {url}')
async def test_async_setup_raises_entry_not_ready(opp: OpenPeerPower): """Test that it throws ConfigEntryNotReady when exception occurs during setup.""" config_entry = MockConfigEntry( domain=DOMAIN, data={CONF_HOST: "some host", CONF_ACCESS_TOKEN: "test-token"}, ) config_entry.add_to_opp(opp) with patch_bond_version(side_effect=ClientConnectionError()): await opp.config_entries.async_setup(config_entry.entry_id) assert config_entry.state is ConfigEntryState.SETUP_RETRY
async def test_async_setup_raises_entry_not_ready(hass: HomeAssistant): """Test that it throws ConfigEntryNotReady when exception occurs during setup.""" config_entry = MockConfigEntry( domain=DOMAIN, data={CONF_HOST: "some host", CONF_ACCESS_TOKEN: "test-token"}, ) config_entry.add_to_hass(hass) with patch_bond_version(side_effect=ClientConnectionError()): await hass.config_entries.async_setup(config_entry.entry_id) assert config_entry.state == ENTRY_STATE_SETUP_RETRY
async def test_options_flow_network_failure(hass): """Test options flow with connectivity failure.""" entry = await setup_platform(hass) with patch("aussiebb.asyncio.AussieBB.get_services", side_effect=ClientConnectionError()): result1 = await hass.config_entries.options.async_init(entry.entry_id) assert result1["type"] == RESULT_TYPE_ABORT assert result1["reason"] == "cannot_connect"
def test_exception_handling(self): def test_exception_handling(to_raise, to_catch): with self.assertRaises(to_catch): with self.assertLogs(level=logging.WARNING): with self.cloudstack_adapter.handle_exceptions(): raise to_raise matrix = [ ( CloudStackClientException( message="Quota Exceeded", error_code=535, error_text="Quota Exceeded", ), TardisQuotaExceeded, ), (asyncio.TimeoutError(), TardisTimeout), (ClientConnectionError(), TardisResourceStatusUpdateFailed), ( CloudStackClientException( message="Timeout", error_code=500, response={"message": "timed out after 1000.0 ms"}, ), TardisTimeout, ), ( CloudStackClientException( message="Timeout", error_code=500, response={"message": "connection was closed"}, ), TardisResourceStatusUpdateFailed, ), ( CloudStackClientException( message="Something else", error_code=500, response={"message": "Something else"}, ), TardisError, ), ( CloudStackClientException( message="Something Else", error_code=666, error_text="Something Else", ), TardisError, ), ] for to_raise, to_catch in matrix: test_exception_handling(to_raise, to_catch)
async def test_form_network_issue(hass: HomeAssistant) -> None: """Test network issues are handled.""" result1 = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}) with patch("aussiebb.asyncio.AussieBB.__init__", return_value=None), patch("aussiebb.asyncio.AussieBB.login", side_effect=ClientConnectionError()): result2 = await hass.config_entries.flow.async_configure( result1["flow_id"], FAKE_DATA, ) assert result2["type"] == FlowResultType.FORM assert result2["errors"] == {"base": "cannot_connect"}
async def test_user_form_cannot_connect(opp): """Test we handle cannot connect error.""" result = await opp.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}) with patch( "openpeerpower.components.nightscout.NightscoutAPI.get_server_status", side_effect=ClientConnectionError(), ): result2 = await opp.config_entries.flow.async_configure( result["flow_id"], {CONF_URL: "https://some.url:1234"}, ) assert result2["type"] == data_entry_flow.RESULT_TYPE_FORM assert result2["errors"] == {"base": "cannot_connect"}
async def test_user_form_cannot_connect(hass: core.HomeAssistant): """Test we handle cannot connect error.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} ) with patch_bond_version( side_effect=ClientConnectionError() ), patch_bond_bridge(), patch_bond_device_ids(): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_HOST: "some host", CONF_ACCESS_TOKEN: "test-token"}, ) assert result2["type"] == "form" assert result2["errors"] == {"base": "cannot_connect"}
def test_lock_catalog_error_on_preventing(self, m): def callback_prevent(url, **kwargs): self.assertDictEqual( kwargs['json'], { 'scope': 'CATALOG', 'applicant': [ str(Server.get_current().id), str(self.n1.id), str(self.n2.id) ] }) return CallbackResult("{'message': 'Preventing lock acquired'}", status=200) def callback_unlock(url, **kwargs): self.assertDictEqual( kwargs['json'], { 'scope': 'CATALOG', 'action': 'UNLOCK', 'applicant': [ str(Server.get_current().id), str(self.n1.id), str(self.n2.id) ] }) return CallbackResult("{'message': 'UnLocked'}", status=200) m.post(Server.get_current().url('api_1_0.locker_prevent'), callback=callback_prevent) m.post(self.n1.url('api_1_0.locker_prevent'), exception=ClientConnectionError()) m.post(self.n2.url('api_1_0.locker_prevent'), callback=callback_prevent) m.post(Server.get_current().url('api_1_0.locker_unlock'), callback=callback_unlock) m.post(self.n2.url('api_1_0.locker_unlock'), callback=callback_unlock) with self.assertRaises(errors.LockError): lock(Scope.CATALOG, [Server.get_current(), self.n1, self.n2], identity=ROOT) c = Locker.query.get(Scope.CATALOG) self.assertEqual(State.UNLOCKED, c.state)
def _request_mock(self, orig_self: client.ClientSession, method: str, url: str, *args: Tuple, **kwargs: Dict) -> 'ClientResponse': """Return mocked response object or raise connection error.""" for prefix in self._passthrough: if url.startswith(prefix): return self.patcher.temp_original(orig_self, method, url, *args, **kwargs) response = self.match(method, url) if response is None: raise ClientConnectionError('Connection refused: {} {}'.format( method, url)) key = (method, url) self.requests.setdefault(key, list()) self.requests[key].append(self.method_call(args, kwargs)) return response
async def _request_mock(self, orig_self: ClientSession, method: str, url: 'Union[URL, str]', *args: Tuple, **kwargs: Any) -> 'ClientResponse': """Return mocked response object or raise connection error.""" if orig_self.closed: raise RuntimeError('Session is closed') url_origin = url url = normalize_url(merge_params(url, kwargs.get('params'))) url_str = str(url) for prefix in self._passthrough: if url_str.startswith(prefix): return (await self.patcher.temp_original(orig_self, method, url_origin, *args, **kwargs)) key = (method, url) self.requests.setdefault(key, []) try: kwargs_copy = copy.deepcopy(kwargs) except (TypeError, ValueError): # Handle the fact that some values cannot be deep copied kwargs_copy = kwargs self.requests[key].append(RequestCall(args, kwargs_copy)) response = await self.match(method, url, **kwargs) if response is None: raise ClientConnectionError('Connection refused: {} {}'.format( method, url)) self._responses.append(response) # Automatically call response.raise_for_status() on a request if the # request was initialized with raise_for_status=True. Also call # response.raise_for_status() if the client session was initialized # with raise_for_status=True, unless the request was called with # raise_for_status=False. raise_for_status = kwargs.get('raise_for_status') if raise_for_status is None: raise_for_status = getattr(orig_self, '_raise_for_status', False) if raise_for_status: response.raise_for_status() return response
async def users_profile_get(self, *, user: str) -> SlackResponse: step = self._step self._step = (self._step + 1) % 4 if step == 0: raise ClientConnectionError() elif step == 1: return await super().users_profile_get(user=user) elif step == 2: response = self.build_slack_response({ "ok": False, "error": "ratelimited" }) raise SlackApiError("test exception", response) elif step == 3: return await super().users_profile_get(user=user) else: raise NotImplementedError("invalid step number")
async def init_integration_unavailable(hass) -> MockConfigEntry: """Set up the Nightscout integration in Home Assistant.""" entry = MockConfigEntry( domain=DOMAIN, data={CONF_URL: "https://some.url:1234"}, ) with patch( "homeassistant.components.nightscout.NightscoutAPI.get_sgvs", side_effect=ClientConnectionError(), ), patch( "homeassistant.components.nightscout.NightscoutAPI.get_server_status", return_value=SERVER_STATUS, ): entry.add_to_hass(hass) await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() return entry
async def run(self, login: str, password: str, session: aiohttp.ClientSession): auth = aiohttp.BasicAuth(login, password) async with session.post(self.token_uri, data={}, auth=auth) as response: try: self.auth_token = response.headers["X-Cisco-CMS-Auth-Token"] except KeyError: raise ClientConnectionError('X-Cisco-CMS-Auth-Token missing from response headers') # noinspection PyTypeChecker async with connect(self.event_uri, ping_interval=None) as ws: self.ws = ws await self._subscribe() while True: msg = await ws.recv() msg_dict = json.loads(msg) msg_id = await self.process_message(msg_dict) if msg_id: await ws.send(json.dumps(ack(msg_id))) # acknowledge
async def _request_mock(self, orig_self: ClientSession, method: str, url: 'Union[URL, str]', *args: Tuple, **kwargs: Dict) -> 'ClientResponse': """Return mocked response object or raise connection error.""" url = normalize_url(merge_params(url, kwargs.get('params'))) url_str = str(url) for prefix in self._passthrough: if url_str.startswith(prefix): return (await self.patcher.temp_original(orig_self, method, url, *args, **kwargs)) response = await self.match(method, url) if response is None: raise ClientConnectionError('Connection refused: {} {}'.format( method, url)) self._responses.append(response) key = (method, url) self.requests.setdefault(key, []) self.requests[key].append(RequestCall(args, kwargs)) return response
async def read_http_content(self: ClientResponse, n: int = -1) -> bytes: """ # https://github.com/aio-libs/aiohttp/issues/2638 Read up to 'n' bytes of the response payload. If 'n' is -1 (default), read the entire payload. """ if self._body is None: try: if n == -1: self._body = await self.content.read() else: chunks = [] i = 0 while i < n: chunk = await self.content.read(n=n - i) if not chunk: break chunks.append(chunk) i += len(chunk) self._body = b''.join(chunks) try: for trace in self._traces: await trace.send_response_chunk_received(method=self.method, url=self.url, chunk=self._body) except: pass except BaseException: self.close() raise elif self._released: raise ClientConnectionError('Connection closed') return self._body
async def test_net_failure(hass: HomeAssistant) -> None: """Test init with a network failure.""" entry = await setup_platform(hass, side_effect=ClientConnectionError()) assert entry.state is ConfigEntryState.SETUP_RETRY