예제 #1
0
def test_distributed_tracing_policy_badurl(caplog):
    """Test policy with a bad url that will throw, and be sure policy ignores it"""
    with ContextHelper():
        exporter = MockExporter()
        trace = tracer_module.Tracer(sampler=AlwaysOnSampler(), exporter=exporter)
        with trace.span("parent"):
            policy = DistributedTracingPolicy()

            request = HttpRequest("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 = 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") 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)
            policy.on_exception(pipeline_request)

        trace.finish()
        exporter.build_tree()
        parent = exporter.root
        assert len(parent.children) == 0
예제 #2
0
 def send(self, request, **kwargs):  # type: (PipelineRequest, Any) -> PipelineResponse
     self._count += 1
     response = HttpResponse(request, None)
     response.status_code = 201
     headers = {"Retry-After": "1"}
     response.headers = headers
     return response
예제 #3
0
def test_distributed_tracing_policy_badurl(caplog):
    """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 = HttpRequest("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 = 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") 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
def test_span_namer():
    settings.tracing_implementation.set_value(FakeSpan)
    with FakeSpan(name="parent") as root_span:

        request = HttpRequest("GET", "http://127.0.0.1/temp?query=query")
        pipeline_request = PipelineRequest(request, PipelineContext(None))

        def fixed_namer(http_request):
            assert http_request is request
            return "overridenname"

        policy = DistributedTracingPolicy(network_span_namer=fixed_namer)

        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)))

        def operation_namer(http_request):
            assert http_request is request
            return "operation level name"

        pipeline_request.context.options[
            'network_span_namer'] = operation_namer

        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 init kwargs
    network_span = root_span.children[0]
    assert network_span.name == "overridenname"

    # Check operation kwargs
    network_span = root_span.children[1]
    assert network_span.name == "operation level name"
예제 #5
0
def test_distributed_tracing_policy_with_user_agent():
    """Test policy working with user agent."""
    with ContextHelper(environ={"AZURE_HTTP_USER_AGENT": "mytools"}):
        exporter = MockExporter()
        trace = tracer_module.Tracer(sampler=AlwaysOnSampler(), exporter=exporter)
        with trace.span("parent"):
            tracing_context.current_span.set(OpenCensusSpan(trace.current_span()))
            policy = DistributedTracingPolicy()

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

            pipeline_request = PipelineRequest(request, PipelineContext(None))

            user_agent = UserAgentPolicy()
            user_agent.on_request(pipeline_request)
            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"
            pipeline_response = PipelineResponse(request, response, PipelineContext(None))

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

            policy.on_response(pipeline_request, pipeline_response)

            time.sleep(0.001)
            policy.on_request(pipeline_request)
            policy.on_exception(pipeline_request)

            user_agent.on_response(pipeline_request, pipeline_response)

        trace.finish()
        exporter.build_tree()
        parent = exporter.root
        network_span = parent.children[0]
        assert network_span.span_data.name == "/"
        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"
        assert network_span.span_data.attributes.get("http.user_agent").endswith("mytools")
        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 == "/"
        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"
        assert network_span.span_data.attributes.get("http.user_agent").endswith("mytools")
        assert network_span.span_data.attributes.get("x-ms-client-request-id") == "some client request id"
        assert network_span.span_data.attributes.get("x-ms-request-id") is None
        assert network_span.span_data.attributes.get("http.status_code") == 504
예제 #6
0
def test_distributed_tracing_policy_with_user_agent():
    """Test policy working with user agent."""
    settings.tracing_implementation.set_value(FakeSpan)
    with mock.patch.dict('os.environ', {"AZURE_HTTP_USER_AGENT": "mytools"}):
        with FakeSpan(name="parent") as root_span:
            policy = DistributedTracingPolicy()

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

            pipeline_request = PipelineRequest(request, PipelineContext(None))

            user_agent = UserAgentPolicy()
            user_agent.on_request(pipeline_request)
            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"
            pipeline_response = PipelineResponse(request, response, PipelineContext(None))

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

            policy.on_response(pipeline_request, pipeline_response)

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

            user_agent.on_response(pipeline_request, pipeline_response)

        network_span = root_span.children[0]
        assert network_span.name == "/"
        assert network_span.attributes.get("http.method") == "GET"
        assert network_span.attributes.get("component") == "http"
        assert network_span.attributes.get("http.url") == "http://localhost"
        assert network_span.attributes.get("http.user_agent").endswith("mytools")
        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

        network_span = root_span.children[1]
        assert network_span.name == "/"
        assert network_span.attributes.get("http.method") == "GET"
        assert network_span.attributes.get("component") == "http"
        assert network_span.attributes.get("http.url") == "http://localhost"
        assert network_span.attributes.get("http.user_agent").endswith("mytools")
        assert network_span.attributes.get("x-ms-client-request-id") == "some client request id"
        assert network_span.attributes.get("x-ms-request-id") is None
        assert network_span.attributes.get("http.status_code") == 504
        # Exception should propagate status for Opencensus
        assert network_span.status == 'Transport trouble'
예제 #7
0
def test_distributed_tracing_policy_solo():
    """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"):
            tracing_context.current_span.set(
                OpenCensusSpan(trace.current_span()))
            policy = DistributedTracingPolicy()

            request = HttpRequest("GET", "http://127.0.0.1/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
            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("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("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 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
예제 #9
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
예제 #10
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=='
예제 #11
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
예제 #12
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
예제 #13
0
 def test_transmit_http_error_redirect(self):
     response = HttpResponse(None, None)
     response.status_code = 307
     response.headers = {"location":"https://example.com"}
     prev_redirects = self._base.client._config.redirect_policy.max_redirects
     self._base.client._config.redirect_policy.max_redirects = 2
     prev_host = self._base.client._config.host
     error = HttpResponseError(response=response)
     with mock.patch.object(AzureMonitorClient, 'track') as post:
         post.side_effect = error
         result = self._base._transmit(self._envelopes_to_export)
         self.assertEqual(result, ExportResult.FAILED_NOT_RETRYABLE)
         self.assertEqual(post.call_count, 2)
         self.assertEqual(self._base.client._config.host, "https://example.com")
     self._base.client._config.redirect_policy.max_redirects = prev_redirects
     self._base.client._config.host = prev_host
예제 #14
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"
예제 #15
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()