Ejemplo n.º 1
0
    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()
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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