示例#1
0
def test_max_span_batch_size(default_trace_id_generator):
    settings = {
        'zipkin.tracing_percent': 0,
        'zipkin.trace_id_generator': default_trace_id_generator,
        'zipkin.max_span_batch_size': 1,
    }
    app_main, normal_transport, firehose_transport = generate_app_main(
        settings,
        firehose=True,
    )

    WebTestApp(app_main).get('/decorator_context', status=200)

    # Assert the expected number of batches for two spans
    assert len(normal_transport.output) == 0
    assert len(firehose_transport.output) == 2

    # Assert proper hierarchy
    batch_one = decode_thrift(firehose_transport.output[0])
    assert len(batch_one) == 1
    child_span = batch_one[0]

    batch_two = decode_thrift(firehose_transport.output[1])
    assert len(batch_two) == 1
    server_span = batch_two[0]

    assert child_span.parent_id == server_span.id
    assert child_span.name == 'my_span'
示例#2
0
def test_upstream_zipkin_headers_sampled(default_trace_id_generator):
    settings = {'zipkin.trace_id_generator': default_trace_id_generator}
    app_main, transport, _ = generate_app_main(settings)

    trace_hex = 'aaaaaaaaaaaaaaaa'
    span_hex = 'bbbbbbbbbbbbbbbb'
    parent_hex = 'cccccccccccccccc'

    def validate(span_objs):
        assert len(span_objs) == 1
        span = span_objs[0]
        assert span.trace_id == unsigned_hex_to_signed_int(trace_hex)
        assert span.id == unsigned_hex_to_signed_int(span_hex)
        assert span.parent_id == unsigned_hex_to_signed_int(parent_hex)
        # Since Zipkin headers are passed in, the span in assumed to be the
        # server part of a span started by an upstream client, so doesn't have
        # to log timestamp/duration.
        assert span.timestamp is None
        assert span.duration is None

    WebTestApp(app_main).get(
        '/sample',
        status=200,
        headers={
            'X-B3-TraceId': trace_hex,
            'X-B3-SpanId': span_hex,
            'X-B3-ParentSpanId': parent_hex,
            'X-B3-Flags': '0',
            'X-B3-Sampled': '1',
        },
    )

    validate(decode_thrift(transport.output[0]))
示例#3
0
def test_binary_annotations_404(default_trace_id_generator):
    settings = {
        'zipkin.tracing_percent': 100,
        'zipkin.trace_id_generator': default_trace_id_generator,
    }
    app_main, transport, _ = generate_app_main(settings)

    def validate_span(span_objs):
        assert len(span_objs) == 1
        span_obj = span_objs[0]
        # Assert that the only present binary_annotations are ones we expect
        expected_annotations = {
            'http.uri': '/abcd',
            'http.uri.qs': '/abcd?test=1',
            'http.route': '',
            'response_status_code': '404',
        }
        result_span = test_helper.massage_result_span(span_obj)
        for ann in result_span['binary_annotations']:
            assert ann['value'] == expected_annotations.pop(ann['key'])
        assert len(expected_annotations) == 0

    WebTestApp(app_main).get('/abcd?test=1', status=404)

    assert len(transport.output) == 1
    validate_span(decode_thrift(transport.output[0]))
示例#4
0
def test_binary_annotations(default_trace_id_generator):
    def set_extra_binary_annotations(dummy_request, response):
        return {'other': dummy_request.registry.settings['other_attr']}

    settings = {
        'zipkin.tracing_percent': 100,
        'zipkin.trace_id_generator': default_trace_id_generator,
        'zipkin.set_extra_binary_annotations': set_extra_binary_annotations,
        'other_attr': '42',
    }
    app_main, transport, _ = generate_app_main(settings)

    def validate_span(span_objs):
        assert len(span_objs) == 1
        span_obj = span_objs[0]
        # Assert that the only present binary_annotations are ones we expect
        expected_annotations = {
            'http.uri': '/pet/123',
            'http.uri.qs': '/pet/123?test=1',
            'http.route': '/pet/{petId}',
            'response_status_code': '200',
            'other': '42',
        }
        result_span = test_helper.massage_result_span(span_obj)
        for ann in result_span['binary_annotations']:
            assert ann['value'] == expected_annotations.pop(ann['key'])
        assert len(expected_annotations) == 0

    WebTestApp(app_main).get('/pet/123?test=1', status=200)

    assert len(transport.output) == 1
    validate_span(decode_thrift(transport.output[0]))
示例#5
0
def test_defaults_at_using_raw_url_path(default_trace_id_generator):
    settings = {
        'zipkin.tracing_percent': 100,
        'zipkin.trace_id_generator': default_trace_id_generator,
        'other_attr': '42',
    }
    app_main, transport, _ = generate_app_main(settings)

    def validate_span(span_objs):
        assert len(span_objs) == 1
        result_span = test_helper.massage_result_span(span_objs[0])
        # Check that the span name is the raw url by default
        assert result_span['name'] == 'GET /pet/123'

    WebTestApp(app_main).get('/pet/123?test=1', status=200)

    assert len(transport.output) == 1
    validate_span(decode_thrift(transport.output[0]))
示例#6
0
def test_report_root_timestamp():
    settings = {
        'zipkin.report_root_timestamp': True,
        'zipkin.tracing_percent': 100.0,
    }
    app_main, transport, _ = generate_app_main(settings)

    old_time = time.time() * 1000000

    def check_for_timestamp_and_duration(span_objs):
        span_obj = span_objs[0]
        assert span_obj.timestamp > old_time
        assert span_obj.duration > 0

    WebTestApp(app_main).get('/sample', status=200)

    assert len(transport.output) == 1
    check_for_timestamp_and_duration(decode_thrift(transport.output[0]))
def test_add_logging_annotation():
    settings = {
        'zipkin.tracing_percent': 100,
        'zipkin.add_logging_annotation': True,
    }
    app_main, transport, _ = generate_app_main(settings)

    WebTestApp(app_main).get('/sample', status=200)

    assert len(transport.output) == 1
    span_list = decode_thrift(transport.output[0])
    assert len(span_list) == 1
    server_span = span_list[0]

    # Just make sure py-zipkin added an annotation for when logging started
    assert any(
        annotation.value == 'py_zipkin.logging_end'
        for annotation in server_span.annotations
    )
示例#8
0
def test_use_pattern_as_span_name(default_trace_id_generator):
    settings = {
        'zipkin.tracing_percent': 100,
        'zipkin.trace_id_generator': default_trace_id_generator,
        'other_attr': '42',
        'zipkin.use_pattern_as_span_name': True,
    }
    app_main, transport, _ = generate_app_main(settings)

    def validate_span(span_objs):
        assert len(span_objs) == 1
        result_span = test_helper.massage_result_span(span_objs[0])
        # Check that the span name is the pyramid pattern and not the raw url
        assert result_span['name'] == 'GET /pet/{petId}'

    WebTestApp(app_main).get('/pet/123?test=1', status=200)

    assert len(transport.output) == 1
    validate_span(decode_thrift(transport.output[0]))
示例#9
0
def test_host_and_port_in_span():
    settings = {
        'zipkin.tracing_percent': 100,
        'zipkin.host': '1.2.2.1',
        'zipkin.port': 1231,
    }
    app_main, transport, _ = generate_app_main(settings)

    def validate_span(span_objs):
        assert len(span_objs) == 1
        span_obj = span_objs[0]
        # Assert ipv4 and port match what we expect
        expected_ipv4 = (1 << 24) | (2 << 16) | (2 << 8) | 1
        assert expected_ipv4 == span_obj.annotations[0].host.ipv4
        assert 1231 == span_obj.annotations[0].host.port

    WebTestApp(app_main).get('/sample?test=1', status=200)

    assert len(transport.output) == 1
    validate_span(decode_thrift(transport.output[0]))
示例#10
0
def test_span_context(default_trace_id_generator):
    # Tests that log lines with 'service_name' keys are logged as
    # new client spans.
    settings = {
        'zipkin.tracing_percent': 100,
        'zipkin.trace_id_generator': default_trace_id_generator,
    }
    app_main, transport, _ = generate_app_main(settings)

    WebTestApp(app_main).get('/span_context', status=200)

    # Spans are batched
    # The order of span logging goes from innermost (grandchild) up.
    assert len(transport.output) == 1
    span_list = decode_thrift(transport.output[0])
    assert len(span_list) == 3
    grandchild_span = span_list[0]
    child_span = span_list[1]
    server_span = span_list[2]

    # Assert proper hierarchy
    assert child_span.parent_id == server_span.id
    assert grandchild_span.parent_id == child_span.id
    # Assert annotations are properly assigned
    assert_extra_annotations(child_span, {'child_annotation': 1000000})
    assert_extra_binary_annotations(
        child_span, {'foo': 'bar', 'child': 'true'})
    assert_extra_annotations(
        grandchild_span, {'grandchild_annotation': 1000000})
    assert_extra_binary_annotations(grandchild_span, {'grandchild': 'true'})

    # For the span produced by SpanContext, assert cs==sr and ss==cr
    # Initialize them all so the equalities won't be true.
    annotations = {
        'cs': 0, 'sr': 1, 'ss': 2, 'cr': 3
    }
    for annotation in child_span.annotations:
        if annotation.value in annotations:
            annotations[annotation.value] = annotation.timestamp
    assert annotations['cs'] == annotations['sr']
    assert annotations['ss'] == annotations['cr']
示例#11
0
def test_decorator(default_trace_id_generator):
    # Tests that log lines with 'service_name' keys are logged as
    # new client spans.
    settings = {
        'zipkin.tracing_percent': 100,
        'zipkin.trace_id_generator': default_trace_id_generator,
    }
    app_main, transport, _ = generate_app_main(settings)

    WebTestApp(app_main).get('/decorator_context', status=200)

    # Two spans are logged - child span, then server span
    assert len(transport.output) == 1
    span_list = decode_thrift(transport.output[0])
    assert len(span_list) == 2
    child_span = span_list[0]
    server_span = span_list[1]

    # Assert proper hierarchy and annotations
    assert child_span.parent_id == server_span.id
    assert_extra_binary_annotations(child_span, {'a': '1'})
    assert child_span.name == 'my_span'
示例#12
0
def test_sample_server_span_with_firehose_tracing(default_trace_id_generator,
                                                  get_span):
    settings = {
        'zipkin.tracing_percent': 0,
        'zipkin.trace_id_generator': default_trace_id_generator,
        'zipkin.firehose_handler': default_trace_id_generator,
    }
    app_main, normal_transport, firehose_transport = generate_app_main(
        settings,
        firehose=True,
    )

    old_time = time.time() * 1000000

    def validate_span(span_objs):
        assert len(span_objs) == 1
        span_obj = span_objs[0]
        result_span = test_helper.massage_result_span(span_obj)
        timestamps = test_helper.get_timestamps(result_span)
        get_span['trace_id'] = unsigned_hex_to_signed_int(
            default_trace_id_generator(span_obj), )
        # The request to this service had no incoming Zipkin headers, so it's
        # assumed to be the root span of a trace, which means it logs
        # timestamp and duration.
        assert result_span.pop('timestamp') > old_time
        assert result_span.pop('duration') > 0
        assert get_span == result_span
        assert old_time <= timestamps['sr']
        assert timestamps['sr'] <= timestamps['ss']

    with mock.patch(
            'pyramid_zipkin.request_helper.generate_random_64bit_string'
    ) as mock_generate_random_64bit_string:
        mock_generate_random_64bit_string.return_value = '1'
        WebTestApp(app_main).get('/sample', status=200)

    assert len(normal_transport.output) == 0
    assert len(firehose_transport.output) == 1
    validate_span(decode_thrift(firehose_transport.output[0]))
示例#13
0
def test_log_new_client_spans(default_trace_id_generator):
    # Tests that log lines with 'service_name' keys are logged as
    # new client spans.
    settings = {
        'zipkin.tracing_percent': 100,
        'zipkin.trace_id_generator': default_trace_id_generator,
    }
    app_main, transport, _ = generate_app_main(settings)

    WebTestApp(app_main).get('/sample_v2_client', status=200)

    assert len(transport.output) == 1
    span_list = decode_thrift(transport.output[0])
    assert len(span_list) == 3
    foo_span = span_list[0]
    bar_span = span_list[1]
    server_span = span_list[2]

    # Some sanity checks on the new client spans
    for client_span in (foo_span, bar_span):
        assert client_span.parent_id == server_span.id
    assert foo_span.id != bar_span.id
    assert_extra_annotations(foo_span, {'foo_client': 2000000})
    assert_extra_annotations(bar_span, {'bar_client': 1000000})