def test_distributed_tracing_policy_solo():
    """Test policy with no other policy and happy path"""
    settings.tracing_implementation.set_value(FakeSpan)
    with FakeSpan(name="parent") as root_span:
        policy = DistributedTracingPolicy()

        request = HttpRequest("GET", "http://127.0.0.1/temp?query=query")
        request.headers["x-ms-client-request-id"] = "some client request id"

        pipeline_request = PipelineRequest(request, PipelineContext(None))
        policy.on_request(pipeline_request)

        response = HttpResponse(request, None)
        response.headers = request.headers
        response.status_code = 202
        response.headers["x-ms-request-id"] = "some request id"

        assert request.headers.get("traceparent") == '123456789'

        policy.on_response(
            pipeline_request,
            PipelineResponse(request, response, PipelineContext(None)))
        time.sleep(0.001)
        policy.on_request(pipeline_request)
        try:
            raise ValueError("Transport trouble")
        except:
            policy.on_exception(pipeline_request)

    # Check on_response
    network_span = root_span.children[0]
    assert network_span.name == "/temp"
    assert network_span.attributes.get("http.method") == "GET"
    assert network_span.attributes.get("component") == "http"
    assert network_span.attributes.get(
        "http.url") == "http://127.0.0.1/temp?query=query"
    assert network_span.attributes.get("http.user_agent") is None
    assert network_span.attributes.get("x-ms-request-id") == "some request id"
    assert network_span.attributes.get(
        "x-ms-client-request-id") == "some client request id"
    assert network_span.attributes.get("http.status_code") == 202

    # Check on_exception
    network_span = root_span.children[1]
    assert network_span.name == "/temp"
    assert network_span.attributes.get("http.method") == "GET"
    assert network_span.attributes.get("component") == "http"
    assert network_span.attributes.get(
        "http.url") == "http://127.0.0.1/temp?query=query"
    assert network_span.attributes.get(
        "x-ms-client-request-id") == "some client request id"
    assert network_span.attributes.get("http.user_agent") is None
    assert network_span.attributes.get("x-ms-request-id") == None
    assert network_span.attributes.get("http.status_code") == 504
Beispiel #2
0
            def parse_responses(response):
                http_request = response.request
                context = PipelineContext(None)
                pipeline_request = PipelineRequest(http_request, context)
                pipeline_response = PipelineResponse(http_request,
                                                     response,
                                                     context=context)

                for policy in policies:
                    _await_result(policy.on_response, pipeline_request,
                                  pipeline_response)
Beispiel #3
0
    def build_response(body, content_type=None):
        class MockResponse(HttpResponse):
            def __init__(self, body, content_type):
                super(MockResponse, self).__init__(None, None)
                self._body = body
                self.content_type = content_type

            def body(self):
                return self._body

        return PipelineResponse(request, MockResponse(body, content_type),
                                context)
    def send(self, request):
        """HTTP transport send method.

        :param request: The PipelineRequest object.
        :type request: ~azure.core.pipeline.PipelineRequest
        :return: The PipelineResponse object.
        :rtype: ~azure.core.pipeline.PipelineResponse
        """
        return PipelineResponse(request.http_request,
                                self._sender.send(request.http_request,
                                                  **request.context.options),
                                context=request.context)
Beispiel #5
0
def test_distributed_tracing_policy_solo(should_set_sdk_context):
    """Test policy with no other policy and happy path"""
    with ContextHelper():
        exporter = MockExporter()
        trace = tracer_module.Tracer(sampler=AlwaysOnSampler(), exporter=exporter)
        with trace.span("parent"):
            if should_set_sdk_context:
                tracing_context.current_span.set(OpenCensusSpan(trace.current_span()))
            policy = DistributedTracingPolicy()

            request = HttpRequest("GET", "http://127.0.0.1/temp?query=query")
            request.headers["x-ms-client-request-id"] = "some client request id"

            pipeline_request = PipelineRequest(request, PipelineContext(None))
            policy.on_request(pipeline_request)

            response = HttpResponse(request, None)
            response.headers = request.headers
            response.status_code = 202
            response.headers["x-ms-request-id"] = "some request id"

            ctx = trace.span_context
            header = trace.propagator.to_headers(ctx)
            assert request.headers.get("traceparent") == header.get("traceparent")

            policy.on_response(pipeline_request, PipelineResponse(request, response, PipelineContext(None)))
            time.sleep(0.001)
            policy.on_request(pipeline_request)
            policy.on_exception(pipeline_request)

        trace.finish()
        exporter.build_tree()
        parent = exporter.root
        network_span = parent.children[0]
        assert network_span.span_data.name == "/temp"
        assert network_span.span_data.attributes.get("http.method") == "GET"
        assert network_span.span_data.attributes.get("component") == "http"
        assert network_span.span_data.attributes.get("http.url") == "http://127.0.0.1/temp?query=query"
        assert network_span.span_data.attributes.get("http.user_agent") is None
        assert network_span.span_data.attributes.get("x-ms-request-id") == "some request id"
        assert network_span.span_data.attributes.get("x-ms-client-request-id") == "some client request id"
        assert network_span.span_data.attributes.get("http.status_code") == 202

        network_span = parent.children[1]
        assert network_span.span_data.name == "/temp"
        assert network_span.span_data.attributes.get("http.method") == "GET"
        assert network_span.span_data.attributes.get("component") == "http"
        assert network_span.span_data.attributes.get("http.url") == "http://127.0.0.1/temp?query=query"
        assert network_span.span_data.attributes.get("x-ms-client-request-id") == "some client request id"
        assert network_span.span_data.attributes.get("http.user_agent") is None
        assert network_span.span_data.attributes.get("x-ms-request-id") == None
        assert network_span.span_data.attributes.get("http.status_code") == 504
    def build_response(body, content_type=None):
        class MockResponse(HttpResponse):
            def __init__(self):
                super(MockResponse, self).__init__(None, None)
                self._body = 'test'

            def body(self):
                return self._body

        data = BytesIO(b"Lots of dataaaa")
        universal_request = HttpRequest('GET', 'http://127.0.0.1/', data=data)
        universal_request.set_streamed_data_body(data)
        return PipelineResponse(universal_request, MockResponse(), PipelineContext(None, stream=True))
Beispiel #7
0
def test_update_cached_sync_token():
    test_sync_token = "syncToken1=val1;sn=6"
    header = {"Sync-Token": test_sync_token}
    request = HttpRequest("GET", "https://bing.com/")
    response = HttpResponse(request, None)
    response.headers = header
    pipeline_response = PipelineResponse(request, response, None)
    sync_token_policy = SyncTokenPolicy()
    sync_token_policy.on_response(None, pipeline_response)
    sync_token = sync_token_policy._sync_tokens['syncToken1']
    assert sync_token.token_id == 'syncToken1'
    assert sync_token.value == 'val1'
    assert sync_token.sequence_number == 6
    test_new_sync_token = "syncToken1=val2;sn=10"
    header["Sync-Token"] = test_new_sync_token
    response.headers = header
    pipeline_response = PipelineResponse(request, response, None)
    sync_token_policy.on_response(None, pipeline_response)
    sync_token = sync_token_policy._sync_tokens['syncToken1']
    assert sync_token.token_id == 'syncToken1'
    assert sync_token.value == 'val2'
    assert sync_token.sequence_number == 10
Beispiel #8
0
def test_save_sync_token():
    test_sync_token = "jtqGc1I4=MDoyOA==;sn=28"
    header = {"Sync-Token": test_sync_token}
    request = HttpRequest("GET", "https://bing.com/")
    response = HttpResponse(request, None)
    response.headers = header
    pipeline_response = PipelineResponse(request, response, None)
    sync_token_policy = SyncTokenPolicy()
    sync_token_policy.on_response(None, pipeline_response)
    sync_token = sync_token_policy._sync_tokens['jtqGc1I4']
    assert sync_token.token_id == 'jtqGc1I4'
    assert sync_token.value == 'MDoyOA=='
    assert sync_token.sequence_number == 28
Beispiel #9
0
def test_set_sync_token():
    test_sync_token = "jtqGc1I4=MDoyOA==;sn=28"
    header = {"Sync-Token": test_sync_token}
    request = HttpRequest("GET", "https://bing.com/")
    response = HttpResponse(request, None)
    response.headers = header
    pipeline_response = PipelineResponse(request, response, None)
    pipeline_request = PipelineRequest(request, None)
    sync_token_policy = SyncTokenPolicy()
    sync_token_policy.on_response(None, pipeline_response)
    sync_token_policy.on_request(pipeline_request)
    sync_token_header = pipeline_request.http_request.headers.get("Sync-Token")
    assert sync_token_header == 'jtqGc1I4=MDoyOA=='
    def mock_send(http_request,
                  http_response,
                  method,
                  status,
                  headers=None,
                  body=RESPONSE_BODY):
        if headers is None:
            headers = {}
        response = Response()
        response._content_consumed = True
        response._content = json.dumps(body).encode(
            'ascii') if body is not None else None
        response.request = Request()
        response.request.method = method
        response.request.url = RESOURCE_URL
        response.request.headers = {
            'x-ms-client-request-id': '67f4dd4e-6262-45e1-8bed-5c45cf23b6d9'
        }
        response.status_code = status
        response.headers = headers
        response.headers.update(
            {"content-type": "application/json; charset=utf8"})
        response.reason = "OK"

        if is_rest(http_request):
            request = http_request(
                response.request.method,
                response.request.url,
                headers=response.request.headers,
                content=body,
            )
        else:
            request = CLIENT._request(
                response.request.method,
                response.request.url,
                None,  # params
                response.request.headers,
                body,
                None,  # form_content
                None  # stream_content
            )
        response = create_transport_response(
            http_response,
            request,
            response,
        )
        return PipelineResponse(
            request,
            response,
            None  # context
        )
Beispiel #11
0
    def mock_update(url, headers=None):
        response = Response()
        response._content_consumed = True
        response.request = mock.create_autospec(Request)
        response.request.method = 'GET'
        response.headers = headers or {}
        response.headers.update(
            {"content-type": "application/json; charset=utf8"})
        response.reason = "OK"

        if url == ASYNC_URL:
            response.request.url = url
            response.status_code = POLLING_STATUS
            response._content = ASYNC_BODY.encode('ascii')
            response.randomFieldFromPollAsyncOpHeader = None

        elif url == LOCATION_URL:
            response.request.url = url
            response.status_code = POLLING_STATUS
            response._content = LOCATION_BODY.encode('ascii')
            response.randomFieldFromPollLocationHeader = None

        elif url == ERROR:
            raise BadEndpointError("boom")

        elif url == RESOURCE_URL:
            response.request.url = url
            response.status_code = POLLING_STATUS
            response._content = RESOURCE_BODY.encode('ascii')

        else:
            raise Exception('URL does not match')

        request = CLIENT._request(
            response.request.method,
            response.request.url,
            None,  # params
            {},  # request has no headers
            None,  # Request has no body
            None,  # form_content
            None  # stream_content
        )

        return PipelineResponse(
            request,
            AsyncioRequestsTransportResponse(
                request,
                response,
            ),
            None  # context
        )
    def build_response(body, content_type=None):
        class MockResponse(HttpResponse):
            def __init__(self, body, content_type):
                super(MockResponse, self).__init__(None, None)
                self._body = body
                self.content_type = None
                if content_type:
                    self.content_type = [content_type]

            def body(self):
                return self._body

        return PipelineResponse(None, MockResponse(body, content_type),
                                PipelineContext(None, stream=False))
Beispiel #13
0
def test_set_multi_sync_token():
    test_sync_token = "syncToken1=val1;sn=6,syncToken2=val2;sn=10"
    header = {"Sync-Token": test_sync_token}
    request = HttpRequest("GET", "https://bing.com/")
    response = HttpResponse(request, None)
    response.headers = header
    pipeline_response = PipelineResponse(request, response, None)
    pipeline_request = PipelineRequest(request, None)
    sync_token_policy = SyncTokenPolicy()
    sync_token_policy.on_response(None, pipeline_response)
    sync_token_policy.on_request(pipeline_request)
    sync_token_header = pipeline_request.http_request.headers.get("Sync-Token")
    assert 'syncToken1=val1' in sync_token_header
    assert 'syncToken2=val2' in sync_token_header
Beispiel #14
0
def polling_response():
    polling = LROBasePolling()
    headers = {}

    response = Response()
    response.headers = headers
    response.status_code = 200

    polling._pipeline_response = PipelineResponse(
        None, RequestsTransportResponse(
            None,
            response,
        ), PipelineContext(None))
    polling._initial_response = polling._pipeline_response
    return polling, headers
Beispiel #15
0
def test_x_ms_retry_after(retry_after_input):
    retry_policy = RetryPolicy()
    request = HttpRequest("GET", "https://bing.com")
    response = HttpResponse(request, None)
    response.headers["x-ms-retry-after-ms"] = retry_after_input
    pipeline_response = PipelineResponse(request, response, None)
    retry_after = retry_policy.get_retry_after(pipeline_response)
    seconds = float(retry_after_input)
    assert retry_after == seconds/1000.0
    response.headers.pop("x-ms-retry-after-ms")
    response.headers["Retry-After"] = retry_after_input
    retry_after = retry_policy.get_retry_after(pipeline_response)
    assert retry_after == float(retry_after_input)
    response.headers["x-ms-retry-after-ms"] = 500
    retry_after = retry_policy.get_retry_after(pipeline_response)
    assert retry_after == float(retry_after_input)
def test_x_ms_retry_after(retry_after_input, http_request, http_response):
    retry_policy = RetryPolicy()
    request = http_request("GET", "http://localhost")
    response = create_http_response(http_response, request, None)
    response.headers["x-ms-retry-after-ms"] = retry_after_input
    pipeline_response = PipelineResponse(request, response, None)
    retry_after = retry_policy.get_retry_after(pipeline_response)
    seconds = float(retry_after_input)
    assert retry_after == seconds / 1000.0
    response.headers.pop("x-ms-retry-after-ms")
    response.headers["Retry-After"] = retry_after_input
    retry_after = retry_policy.get_retry_after(pipeline_response)
    assert retry_after == float(retry_after_input)
    response.headers["x-ms-retry-after-ms"] = 500
    retry_after = retry_policy.get_retry_after(pipeline_response)
    assert retry_after == float(retry_after_input)
Beispiel #17
0
def test_retry_after(retry_after_input):
    retry_policy = AsyncRetryPolicy()
    request = HttpRequest("GET", "http://localhost")
    response = HttpResponse(request, None)
    response.headers["retry-after-ms"] = retry_after_input
    pipeline_response = PipelineResponse(request, response, None)
    retry_after = retry_policy.get_retry_after(pipeline_response)
    seconds = float(retry_after_input)
    assert retry_after == seconds / 1000.0
    response.headers.pop("retry-after-ms")
    response.headers["Retry-After"] = retry_after_input
    retry_after = retry_policy.get_retry_after(pipeline_response)
    assert retry_after == float(retry_after_input)
    response.headers["retry-after-ms"] = 500
    retry_after = retry_policy.get_retry_after(pipeline_response)
    assert retry_after == float(retry_after_input)
    def _callback(http_response, headers={}):
        polling = LROBasePolling()

        response = Response()
        response.headers = headers
        response.status_code = 200

        response = create_transport_response(
            http_response,
            None,
            response,
        )
        polling._pipeline_response = PipelineResponse(None, response,
                                                      PipelineContext(None))
        polling._initial_response = polling._pipeline_response
        return polling
def polling_response():
    polling = LROBasePolling()
    headers = {}

    response = Response()
    response.headers = headers

    polling._pipeline_response = PipelineResponse(
        None,
        RequestsTransportResponse(
            None,
            response,
        ),
        None  # context
    )
    return polling, headers
    def mock_update(http_request, http_response, url, headers=None):
        response = Response()
        response._content_consumed = True
        response.request = mock.create_autospec(Request)
        response.request.method = 'GET'
        response.headers = headers or {}
        response.headers.update({"content-type": "application/json; charset=utf8"})
        response.reason = "OK"

        if url == ASYNC_URL:
            response.request.url = url
            response.status_code = POLLING_STATUS
            response._content = ASYNC_BODY.encode('ascii')
            response.randomFieldFromPollAsyncOpHeader = None

        elif url == LOCATION_URL:
            response.request.url = url
            response.status_code = POLLING_STATUS
            response._content = LOCATION_BODY.encode('ascii')
            response.randomFieldFromPollLocationHeader = None

        elif url == ERROR:
            raise BadEndpointError("boom")

        elif url == RESOURCE_URL:
            response.request.url = url
            response.status_code = POLLING_STATUS
            response._content = RESOURCE_BODY.encode('ascii')

        else:
            raise Exception('URL does not match')

        request = http_request(
            response.request.method,
            response.request.url,
        )

        response = create_transport_response(http_response, request, response)
        if is_rest(http_response):
            response.body()

        return PipelineResponse(
            request,
            response,
            None  # context
        )
Beispiel #21
0
def test_http_logger_with_generator_body(http_request, http_response):
    class MockHandler(logging.Handler):
        def __init__(self):
            super(MockHandler, self).__init__()
            self.messages = []

        def reset(self):
            self.messages = []

        def emit(self, record):
            self.messages.append(record)

    mock_handler = MockHandler()

    logger = logging.getLogger("testlogger")
    logger.addHandler(mock_handler)
    logger.setLevel(logging.DEBUG)

    policy = HttpLoggingPolicy(logger=logger)

    universal_request = http_request('GET', 'http://localhost/')
    mock = Mock()
    mock.__class__ = types.AsyncGeneratorType
    universal_request.body = mock
    http_response = create_http_response(http_response, universal_request,
                                         None)
    http_response.status_code = 202
    request = PipelineRequest(universal_request, PipelineContext(None))

    policy.on_request(request)
    response = PipelineResponse(request, http_response, request.context)
    policy.on_response(request, response)

    assert all(m.levelname == 'INFO' for m in mock_handler.messages)
    assert len(mock_handler.messages) == 2
    messages_request = mock_handler.messages[0].message.split("\n")
    messages_response = mock_handler.messages[1].message.split("\n")
    assert messages_request[0] == "Request URL: 'http://localhost/'"
    assert messages_request[1] == "Request method: 'GET'"
    assert messages_request[2] == 'Request headers:'
    assert messages_request[3] == 'File upload'
    assert messages_response[0] == 'Response status: 202'
    assert messages_response[1] == 'Response headers:'

    mock_handler.reset()
def test_http_logger_with_body():
    class MockHandler(logging.Handler):
        def __init__(self):
            super(MockHandler, self).__init__()
            self.messages = []

        def reset(self):
            self.messages = []

        def emit(self, record):
            self.messages.append(record)

    mock_handler = MockHandler()

    logger = logging.getLogger("testlogger")
    logger.addHandler(mock_handler)
    logger.setLevel(logging.DEBUG)

    policy = HttpLoggingPolicy(logger=logger)

    universal_request = HttpRequest('GET', 'http://127.0.0.1/')
    universal_request.body = "testbody"
    http_response = HttpResponse(universal_request, None)
    http_response.status_code = 202
    request = PipelineRequest(universal_request, PipelineContext(None))

    policy.on_request(request)
    response = PipelineResponse(request, http_response, request.context)
    policy.on_response(request, response)

    assert all(m.levelname == 'INFO' for m in mock_handler.messages)
    assert len(mock_handler.messages) == 6
    assert mock_handler.messages[
        0].message == "Request URL: 'http://127.0.0.1/'"
    assert mock_handler.messages[1].message == "Request method: 'GET'"
    assert mock_handler.messages[2].message == 'Request headers:'
    assert mock_handler.messages[
        3].message == 'A body is sent with the request'
    assert mock_handler.messages[4].message == 'Response status: 202'
    assert mock_handler.messages[5].message == 'Response headers:'

    mock_handler.reset()
Beispiel #23
0
def test_distributed_tracing_policy_attributes():
    """Test policy with no other policy and happy path"""
    settings.tracing_implementation.set_value(FakeSpan)
    with FakeSpan(name="parent") as root_span:
        policy = DistributedTracingPolicy(tracing_attributes={
            'myattr': 'myvalue'
        })

        request = HttpRequest("GET", "http://localhost/temp?query=query")

        pipeline_request = PipelineRequest(request, PipelineContext(None))
        policy.on_request(pipeline_request)

        response = HttpResponse(request, None)
        response.headers = request.headers
        response.status_code = 202

        policy.on_response(pipeline_request, PipelineResponse(request, response, PipelineContext(None)))

    # Check on_response
    network_span = root_span.children[0]
    assert network_span.attributes.get("myattr") == "myvalue"
Beispiel #24
0
    def build_response(body, content_type=None):
        if is_rest(http_response):

            class MockResponse(http_response):
                def __init__(self, body, content_type):
                    super(MockResponse, self).__init__(
                        request=None,
                        internal_response=None,
                        status_code=400,
                        reason="Bad Request",
                        content_type="application/json",
                        headers={},
                        stream_download_generator=None,
                    )
                    self._body = body
                    self.content_type = content_type

                def body(self):
                    return self._body

                def read(self):
                    self._content = self._body
                    return self.content

        else:

            class MockResponse(http_response):
                def __init__(self, body, content_type):
                    super(MockResponse, self).__init__(None, None)
                    self._body = body
                    self.content_type = content_type

                def body(self):
                    return self._body

        return PipelineResponse(request, MockResponse(body, content_type),
                                context)
    def mock_send(method, status, headers=None, body=None):
        if headers is None:
            headers = {}
        response = mock.create_autospec(Response)
        response.request = mock.create_autospec(Request)
        response.request.method = method
        response.request.url = RESOURCE_URL
        response.request.headers = {
            'x-ms-client-request-id': '67f4dd4e-6262-45e1-8bed-5c45cf23b6d9'
        }
        response.status_code = status
        response.headers = headers
        response.headers.update(
            {"content-type": "application/json; charset=utf8"})
        response.reason = "OK"
        content = body if body is not None else RESPONSE_BODY
        response.text = json.dumps(content)
        response.json = lambda: json.loads(response.text)

        request = CLIENT._request(
            response.request.method,
            response.request.url,
            None,  # params
            response.request.headers,
            content,
            None,  # form_content
            None  # stream_content
        )

        return PipelineResponse(
            request,
            RequestsTransportResponse(
                request,
                response,
            ),
            None  # context
        )
def test_distributed_tracing_policy_badurl(caplog, http_request,
                                           http_response):
    """Test policy with a bad url that will throw, and be sure policy ignores it"""
    settings.tracing_implementation.set_value(FakeSpan)
    with FakeSpan(name="parent") as root_span:
        policy = DistributedTracingPolicy()

        request = http_request("GET", "http://[[[")
        request.headers["x-ms-client-request-id"] = "some client request id"

        pipeline_request = PipelineRequest(request, PipelineContext(None))
        with caplog.at_level(
                logging.WARNING,
                logger="azure.core.pipeline.policies.distributed_tracing"):
            policy.on_request(pipeline_request)
        assert "Unable to start network span" in caplog.text

        response = create_http_response(http_response, request, None)
        response.headers = request.headers
        response.status_code = 202
        response.headers["x-ms-request-id"] = "some request id"

        assert request.headers.get(
            "traceparent") is None  # Got not network trace

        policy.on_response(
            pipeline_request,
            PipelineResponse(request, response, PipelineContext(None)))
        time.sleep(0.001)

        policy.on_request(pipeline_request)
        try:
            raise ValueError("Transport trouble")
        except:
            policy.on_exception(pipeline_request)

    assert len(root_span.children) == 0
Beispiel #27
0
def test_no_log(mock_http_logger):
    universal_request = HttpRequest('GET', 'http://127.0.0.1/')
    request = PipelineRequest(universal_request, PipelineContext(None))
    http_logger = NetworkTraceLoggingPolicy()
    response = PipelineResponse(request, HttpResponse(universal_request, None),
                                request.context)

    # By default, no log handler for HTTP
    http_logger.on_request(request)
    mock_http_logger.debug.assert_not_called()
    http_logger.on_response(request, response)
    mock_http_logger.debug.assert_not_called()
    mock_http_logger.reset_mock()

    # I can enable it per request
    request.context.options['logging_enable'] = True
    http_logger.on_request(request)
    assert mock_http_logger.debug.call_count >= 1
    mock_http_logger.reset_mock()
    request.context.options['logging_enable'] = True
    http_logger.on_response(request, response)
    assert mock_http_logger.debug.call_count >= 1
    mock_http_logger.reset_mock()

    # I can enable it per request (bool value should be honored)
    request.context.options['logging_enable'] = False
    http_logger.on_request(request)
    mock_http_logger.debug.assert_not_called()
    request.context.options['logging_enable'] = False
    http_logger.on_response(request, response)
    mock_http_logger.debug.assert_not_called()
    mock_http_logger.reset_mock()

    # I can enable it globally
    request.context.options = {}
    http_logger.enable_http_logger = True
    http_logger.on_request(request)
    assert mock_http_logger.debug.call_count >= 1
    http_logger.on_response(request, response)
    assert mock_http_logger.debug.call_count >= 1
    mock_http_logger.reset_mock()

    # I can enable it globally and override it locally
    http_logger.enable_http_logger = True
    request.context.options['logging_enable'] = False
    http_logger.on_request(request)
    mock_http_logger.debug.assert_not_called()
    response.context['logging_enable'] = False
    http_logger.on_response(request, response)
    mock_http_logger.debug.assert_not_called()
    mock_http_logger.reset_mock()

    # Let's make this request a failure, retried twice
    request.context.options['logging_enable'] = True
    http_logger.on_request(request)
    http_logger.on_response(request, response)

    first_count = mock_http_logger.debug.call_count
    assert first_count >= 1

    http_logger.on_request(request)
    http_logger.on_response(request, response)

    second_count = mock_http_logger.debug.call_count
    assert second_count == first_count * 2
Beispiel #28
0
def test_http_logger_operation_level():
    class MockHandler(logging.Handler):
        def __init__(self):
            super(MockHandler, self).__init__()
            self.messages = []

        def reset(self):
            self.messages = []

        def emit(self, record):
            self.messages.append(record)

    mock_handler = MockHandler()

    logger = logging.getLogger("testlogger")
    logger.addHandler(mock_handler)
    logger.setLevel(logging.DEBUG)

    policy = HttpLoggingPolicy()
    kwargs = {'logger': logger}

    universal_request = HttpRequest('GET', 'http://127.0.0.1/')
    http_response = HttpResponse(universal_request, None)
    http_response.status_code = 202
    request = PipelineRequest(universal_request,
                              PipelineContext(None, **kwargs))

    # Basics

    policy.on_request(request)
    response = PipelineResponse(request, http_response, request.context)
    policy.on_response(request, response)

    assert all(m.levelname == 'INFO' for m in mock_handler.messages)
    assert len(mock_handler.messages) == 5
    assert mock_handler.messages[
        0].message == "Request URL: 'http://127.0.0.1/'"
    assert mock_handler.messages[1].message == "Request method: 'GET'"
    assert mock_handler.messages[2].message == 'Request headers:'
    assert mock_handler.messages[3].message == 'Response status: 202'
    assert mock_handler.messages[4].message == 'Response headers:'

    mock_handler.reset()

    # Let's make this request a failure, retried twice

    request = PipelineRequest(universal_request,
                              PipelineContext(None, **kwargs))

    policy.on_request(request)
    response = PipelineResponse(request, http_response, request.context)
    policy.on_response(request, response)

    policy.on_request(request)
    response = PipelineResponse(request, http_response, request.context)
    policy.on_response(request, response)

    assert all(m.levelname == 'INFO' for m in mock_handler.messages)
    assert len(mock_handler.messages) == 10
    assert mock_handler.messages[
        0].message == "Request URL: 'http://127.0.0.1/'"
    assert mock_handler.messages[1].message == "Request method: 'GET'"
    assert mock_handler.messages[2].message == 'Request headers:'
    assert mock_handler.messages[3].message == 'Response status: 202'
    assert mock_handler.messages[4].message == 'Response headers:'
    assert mock_handler.messages[
        0].message == "Request URL: 'http://127.0.0.1/'"
    assert mock_handler.messages[1].message == "Request method: 'GET'"
    assert mock_handler.messages[2].message == 'Request headers:'
    assert mock_handler.messages[3].message == 'Response status: 202'
    assert mock_handler.messages[4].message == 'Response headers:'

    mock_handler.reset()
Beispiel #29
0
def test_http_logger():
    class MockHandler(logging.Handler):
        def __init__(self):
            super(MockHandler, self).__init__()
            self.messages = []

        def reset(self):
            self.messages = []

        def emit(self, record):
            self.messages.append(record)

    mock_handler = MockHandler()

    logger = logging.getLogger("testlogger")
    logger.addHandler(mock_handler)
    logger.setLevel(logging.DEBUG)

    policy = HttpLoggingPolicy(logger=logger)

    universal_request = HttpRequest('GET', 'http://127.0.0.1/')
    http_response = HttpResponse(universal_request, None)
    http_response.status_code = 202
    request = PipelineRequest(universal_request, PipelineContext(None))

    # Basics

    policy.on_request(request)
    response = PipelineResponse(request, http_response, request.context)
    policy.on_response(request, response)

    assert all(m.levelname == 'INFO' for m in mock_handler.messages)
    assert len(mock_handler.messages) == 5
    assert mock_handler.messages[
        0].message == "Request URL: 'http://127.0.0.1/'"
    assert mock_handler.messages[1].message == "Request method: 'GET'"
    assert mock_handler.messages[2].message == 'Request headers:'
    assert mock_handler.messages[3].message == 'Response status: 202'
    assert mock_handler.messages[4].message == 'Response headers:'

    mock_handler.reset()

    # Let's make this request a failure, retried twice

    policy.on_request(request)
    response = PipelineResponse(request, http_response, request.context)
    policy.on_response(request, response)

    policy.on_request(request)
    response = PipelineResponse(request, http_response, request.context)
    policy.on_response(request, response)

    assert all(m.levelname == 'INFO' for m in mock_handler.messages)
    assert len(mock_handler.messages) == 10
    assert mock_handler.messages[
        0].message == "Request URL: 'http://127.0.0.1/'"
    assert mock_handler.messages[1].message == "Request method: 'GET'"
    assert mock_handler.messages[2].message == 'Request headers:'
    assert mock_handler.messages[3].message == 'Response status: 202'
    assert mock_handler.messages[4].message == 'Response headers:'
    assert mock_handler.messages[
        0].message == "Request URL: 'http://127.0.0.1/'"
    assert mock_handler.messages[1].message == "Request method: 'GET'"
    assert mock_handler.messages[2].message == 'Request headers:'
    assert mock_handler.messages[3].message == 'Response status: 202'
    assert mock_handler.messages[4].message == 'Response headers:'

    mock_handler.reset()

    # Headers and query parameters

    policy.allowed_query_params = ['country']

    universal_request.headers = {
        "Accept": "Caramel",
        "Hate": "Chocolat",
    }
    http_response.headers = {
        "Content-Type": "Caramel",
        "HateToo": "Chocolat",
    }
    universal_request.url = "http://127.0.0.1/?country=france&city=aix"

    policy.on_request(request)
    response = PipelineResponse(request, http_response, request.context)
    policy.on_response(request, response)

    assert all(m.levelname == 'INFO' for m in mock_handler.messages)
    assert len(mock_handler.messages) == 9
    assert mock_handler.messages[
        0].message == "Request URL: 'http://127.0.0.1/?country=france&city=REDACTED'"
    assert mock_handler.messages[1].message == "Request method: 'GET'"
    assert mock_handler.messages[2].message == "Request headers:"
    # Dict not ordered in Python, exact logging order doesn't matter
    assert set([
        mock_handler.messages[3].message, mock_handler.messages[4].message
    ]) == set(["    'Accept': 'Caramel'", "    'Hate': 'REDACTED'"])
    assert mock_handler.messages[5].message == "Response status: 202"
    assert mock_handler.messages[6].message == "Response headers:"
    # Dict not ordered in Python, exact logging order doesn't matter
    assert set([
        mock_handler.messages[7].message, mock_handler.messages[8].message
    ]) == set(["    'Content-Type': 'Caramel'", "    'HateToo': 'REDACTED'"])

    mock_handler.reset()
Beispiel #30
0
def test_raw_deserializer():
    raw_deserializer = ContentDecodePolicy()
    context = PipelineContext(None, stream=False)
    universal_request = HttpRequest('GET', 'http://127.0.0.1/')
    request = PipelineRequest(universal_request, context)

    def build_response(body, content_type=None):
        class MockResponse(HttpResponse):
            def __init__(self, body, content_type):
                super(MockResponse, self).__init__(None, None)
                self._body = body
                self.content_type = content_type

            def body(self):
                return self._body

        return PipelineResponse(request, MockResponse(body, content_type),
                                context)

    response = build_response(b"<groot/>", content_type="application/xml")
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result.tag == "groot"

    response = build_response(b"\xef\xbb\xbf<utf8groot/>",
                              content_type="application/xml")
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result.tag == "utf8groot"

    # The basic deserializer works with unicode XML
    response = build_response(u'<groot language="français"/>'.encode('utf-8'),
                              content_type="application/xml")
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result.attrib["language"] == u"français"

    # Catch some weird situation where content_type is XML, but content is JSON
    response = build_response(b'{"ugly": true}',
                              content_type="application/xml")
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result["ugly"] is True

    # Be sure I catch the correct exception if it's neither XML nor JSON
    response = build_response(b'gibberish', content_type="application/xml")
    with pytest.raises(DecodeError) as err:
        raw_deserializer.on_response(request, response)
    assert err.value.response is response.http_response

    response = build_response(b'{{gibberish}}', content_type="application/xml")
    with pytest.raises(DecodeError) as err:
        raw_deserializer.on_response(request, response)
    assert err.value.response is response.http_response

    # Simple JSON
    response = build_response(b'{"success": true}',
                              content_type="application/json")
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result["success"] is True

    # Simple JSON with BOM
    response = build_response(b'\xef\xbb\xbf{"success": true}',
                              content_type="application/json")
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result["success"] is True

    # Simple JSON with complex content_type
    response = build_response(
        b'{"success": true}',
        content_type="application/vnd.microsoft.appconfig.kv.v1+json")
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result["success"] is True

    # Simple JSON with complex content_type, v2
    response = build_response(
        b'{"success": true}',
        content_type="text/vnd.microsoft.appconfig.kv.v1+json")
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result["success"] is True

    # For compat, if no content-type, decode JSON
    response = build_response(b'"data"')
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result == "data"

    # Let text/plain let through
    response = build_response(b'I am groot', content_type="text/plain")
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result == "I am groot"

    # Let text/plain let through + BOM
    response = build_response(b'\xef\xbb\xbfI am groot',
                              content_type="text/plain")
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result == "I am groot"

    # Try with a mock of requests

    req_response = requests.Response()
    req_response.headers["content-type"] = "application/json"
    req_response._content = b'{"success": true}'
    req_response._content_consumed = True
    response = PipelineResponse(None,
                                RequestsTransportResponse(None, req_response),
                                PipelineContext(None, stream=False))

    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result["success"] is True

    # I can enable it per request
    request.context.options['response_encoding'] = 'utf-8'
    response = build_response(b'\xc3\xa9', content_type="text/plain")
    raw_deserializer.on_request(request)
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result == u"é"
    assert response.context["response_encoding"] == "utf-8"
    del request.context['response_encoding']

    # I can enable it globally
    raw_deserializer = ContentDecodePolicy(response_encoding="utf-8")
    response = build_response(b'\xc3\xa9', content_type="text/plain")
    raw_deserializer.on_request(request)
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result == u"é"
    assert response.context["response_encoding"] == "utf-8"
    del request.context['response_encoding']

    # Per request is more important
    request.context.options['response_encoding'] = 'utf-8-sig'
    response = build_response(b'\xc3\xa9', content_type="text/plain")
    raw_deserializer.on_request(request)
    raw_deserializer.on_response(request, response)
    result = response.context["deserialized_data"]
    assert result == u"é"
    assert response.context["response_encoding"] == "utf-8-sig"
    del request.context['response_encoding']