async def test_send_payload_final_payload_client_error(self): resp_data = [{"channel": "test/channel3", "data": {}, "id": 4}] response_mock = mock.MagicMock() response_mock.json = mock.CoroutineMock(return_value=resp_data) session = mock.MagicMock() post_exception = client_exceptions.ClientError("client error") session.post = mock.CoroutineMock(side_effect=post_exception) self.transport._get_http_session = \ mock.CoroutineMock(return_value=session) self.transport._http_semaphore = mock.MagicMock() payload = [object(), object()] self.transport.ssl = object() self.transport._consume_payload = \ mock.CoroutineMock(return_value=resp_data[0]) headers = dict(key="value") with self.assertLogs(LongPollingTransport.__module__, level="DEBUG") as log: with self.assertRaisesRegex(TransportError, str(post_exception)): await self.transport._send_final_payload(payload, headers=headers) log_message = "WARNING:{}:Failed to send payload, {}"\ .format(LongPollingTransport.__module__, post_exception) self.assertEqual(log.output, [log_message]) self.transport._http_semaphore.__aenter__.assert_called() self.transport._http_semaphore.__aexit__.assert_called() session.post.assert_called_with(self.transport._url, json=payload, ssl=self.transport.ssl, headers=headers, timeout=self.transport.request_timeout) self.transport._consume_payload.assert_not_called()
def test_cloud_unable_to_connect(mock_client, caplog, mock_cloud): """Test unable to connect error.""" conn = iot.CloudIoT(mock_cloud) mock_client.receive.side_effect = client_exceptions.ClientError(None, None) yield from conn.connect() assert 'Unable to connect:' in caplog.text
async def test_cloud_unable_to_connect(mock_client, caplog, cloud_mock_iot): """Test unable to connect error.""" conn = iot.CloudIoT(cloud_mock_iot) mock_client.receive.side_effect = client_exceptions.ClientError(None, None) await conn.connect() assert "Unable to connect:" in caplog.text
async def test_send_final_payload_transport_error(self): payload = object() socket = object() exception = client_exceptions.ClientError("message") self.transport._get_socket = mock.CoroutineMock(return_value=socket) self.transport._send_socket_payload = \ mock.CoroutineMock(side_effect=exception) headers = object() with self.assertLogs(WebSocketTransport.__module__, level="DEBUG") as log: with self.assertRaisesRegex(TransportError, str(exception)): await self.transport._send_final_payload(payload, headers=headers) log_message = "WARNING:{}:Failed to send payload, {}"\ .format(WebSocketTransport.__module__, exception) self.assertEqual(log.output, [log_message]) self.transport._get_socket.assert_called_with(headers) self.transport._send_socket_payload.assert_called_with(socket, payload)
def _build_digest_header(self, method, url): """ :rtype: str """ realm = self.challenge['realm'] nonce = self.challenge['nonce'] qop = self.challenge.get('qop') algorithm = self.challenge.get('algorithm', 'MD5').upper() opaque = self.challenge.get('opaque') if qop and not (qop == 'auth' or 'auth' in qop.split(',')): raise client_exceptions.ClientError('Unsupported qop value: %s' % qop) # lambdas assume digest modules are imported at the top level if algorithm == 'MD5' or algorithm == 'MD5-SESS': hash_fn = hashlib.md5 elif algorithm == 'SHA': hash_fn = hashlib.sha1 else: return '' def H(x): return hash_fn(x.encode()).hexdigest() def KD(s, d): return H('%s:%s' % (s, d)) path = URL(url).path_qs A1 = '%s:%s:%s' % (self.username, realm, self.password) A2 = '%s:%s' % (method, path) HA1 = H(A1) HA2 = H(A2) if nonce == self.last_nonce: self.nonce_count += 1 else: self.nonce_count = 1 self.last_nonce = nonce ncvalue = '%08x' % self.nonce_count # cnonce is just a random string generated by the client. cnonce_data = ''.join([ str(self.nonce_count), nonce, time.ctime(), os.urandom(8).decode(errors='ignore'), ]).encode() cnonce = hashlib.sha1(cnonce_data).hexdigest()[:16] if algorithm == 'MD5-SESS': HA1 = H('%s:%s:%s' % (HA1, nonce, cnonce)) # This assumes qop was validated to be 'auth' above. If 'auth-int' # support is added this will need to change. if qop: noncebit = ':'.join([nonce, ncvalue, cnonce, 'auth', HA2]) response_digest = KD(HA1, noncebit) else: response_digest = KD(HA1, '%s:%s' % (nonce, HA2)) base = ', '.join([ 'username="******"' % self.username, 'realm="%s"' % realm, 'nonce="%s"' % nonce, 'uri="%s"' % path, 'response="%s"' % response_digest, 'algorithm="%s"' % algorithm, ]) if opaque: base += ', opaque="%s"' % opaque if qop: base += ', qop="auth", nc=%s, cnonce="%s"' % (ncvalue, cnonce) return 'Digest %s' % base