Exemplo n.º 1
0
def test_batch_sender_add_span_not_sampled_with_firehose(
        add_span_mock, flush_mock, time_mock):
    attr = ZipkinAttrs(
        trace_id='0000000000000001',
        span_id='0000000000000002',
        parent_span_id=None,
        flags=None,
        is_sampled=False,
    )
    span_storage = SpanStorage()
    transport_handler = mock.Mock()
    firehose_handler = mock.Mock()

    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=create_endpoint(80, 'test_server', '127.0.0.1'),
        span_name='span_name',
        transport_handler=transport_handler,
        report_root_timestamp=False,
        span_storage=span_storage,
        firehose_handler=firehose_handler,
        service_name='test_server',
        encoding=Encoding.V1_JSON,
    )
    context.start_timestamp = 24
    context.response_status_code = 200

    context.binary_annotations_dict = {'k': 'v'}
    time_mock.return_value = 42

    context.emit_spans()
    assert add_span_mock.call_count == 1
    assert flush_mock.call_count == 1
Exemplo n.º 2
0
def test_batch_sender_add_span_not_sampled_with_firehose(
        add_span_mock, flush_mock, time_mock):
    attr = ZipkinAttrs(
        trace_id='0000000000000001',
        span_id='0000000000000002',
        parent_span_id=None,
        flags=None,
        is_sampled=False,
    )
    log_handler = logging_helper.ZipkinLoggerHandler(attr)
    transport_handler = mock.Mock()
    firehose_handler = mock.Mock()
    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        thrift_endpoint='thrift_endpoint',
        log_handler=log_handler,
        span_name='span_name',
        transport_handler=transport_handler,
        report_root_timestamp=False,
        firehose_handler=firehose_handler,
    )
    context.start_timestamp = 24
    context.response_status_code = 200

    context.binary_annotations_dict = {'k': 'v'}
    time_mock.return_value = 42

    context.log_spans()
    assert add_span_mock.call_count == 1
    assert flush_mock.call_count == 1
Exemplo n.º 3
0
def test_batch_sender_add_span_not_called_if_not_sampled(
        add_span_mock, flush_mock):
    attr = ZipkinAttrs(
        trace_id='0000000000000001',
        span_id='0000000000000002',
        parent_span_id=None,
        flags=None,
        is_sampled=False,
    )
    span_storage = SpanStorage()
    transport_handler = mock.Mock()

    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=create_endpoint(80, 'test_server', '127.0.0.1'),
        span_name='span_name',
        transport_handler=transport_handler,
        report_root_timestamp=False,
        span_storage=span_storage,
        service_name='test_server',
        encoding=Encoding.V1_JSON,
    )
    context.emit_spans()
    assert add_span_mock.call_count == 0
    assert flush_mock.call_count == 0
Exemplo n.º 4
0
def test_batch_sender_add_span_not_sampled_with_firehose(
    add_span_mock, flush_mock, time_mock
):
    attr = ZipkinAttrs(
        trace_id="0000000000000001",
        span_id="0000000000000002",
        parent_span_id=None,
        flags=None,
        is_sampled=False,
    )
    tracer = MockTracer()
    transport_handler = mock.Mock()
    firehose_handler = mock.Mock()

    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=create_endpoint(80, "test_server", "127.0.0.1"),
        span_name="span_name",
        transport_handler=transport_handler,
        report_root_timestamp=False,
        get_tracer=lambda: tracer,
        firehose_handler=firehose_handler,
        service_name="test_server",
        encoding=Encoding.V1_JSON,
    )
    context.start_timestamp = 24
    context.response_status_code = 200

    context.tags = {"k": "v"}
    time_mock.return_value = 42

    context.emit_spans()
    assert add_span_mock.call_count == 1
    assert flush_mock.call_count == 1
Exemplo n.º 5
0
def test_zipkin_logging_client_context_log_spans(copy_endpoint_mock,
                                                 bin_ann_list_builder,
                                                 ann_list_builder,
                                                 add_span_mock, flush_mock,
                                                 time_mock):
    # This lengthy function tests that the logging context properly
    # logs root client span
    trace_id = '000000000000000f'
    client_span_id = '0000000000000003'
    attr = ZipkinAttrs(
        trace_id=trace_id,
        span_id=client_span_id,
        parent_span_id=None,
        flags=None,
        is_sampled=True,
    )
    handler = logging_helper.ZipkinLoggerHandler(attr)
    handler.client_spans = []

    # Each of the thrift annotation helpers just reflects its first arg
    # so the annotation dicts can be checked.
    ann_list_builder.side_effect = lambda x, y: x
    bin_ann_list_builder.side_effect = lambda x, y: x

    transport_handler = mock.Mock()

    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        thrift_endpoint='thrift_endpoint',
        log_handler=handler,
        span_name='GET /foo',
        transport_handler=transport_handler,
        report_root_timestamp=True,
        client_context=True)

    context.start_timestamp = 24
    context.response_status_code = 200

    context.binary_annotations_dict = {'k': 'v'}
    time_mock.return_value = 42

    expected_server_annotations = {'cs': 24, 'cr': 42}
    expected_server_bin_annotations = {'k': 'v'}

    context.log_spans()
    log_call = add_span_mock.call_args_list[0]
    assert log_call[1] == {
        'span_id': client_span_id,
        'parent_span_id': None,
        'trace_id': trace_id,
        'span_name': 'GET /foo',
        'annotations': expected_server_annotations,
        'binary_annotations': expected_server_bin_annotations,
        'duration_s': 18,
        'timestamp_s': 24,
    }
    assert flush_mock.call_count == 1
Exemplo n.º 6
0
def test_zipkin_logging_client_context_emit_spans(add_span_mock, flush_mock,
                                                  time_mock, fake_endpoint):
    # This lengthy function tests that the logging context properly
    # logs root client span
    trace_id = '000000000000000f'
    client_span_id = '0000000000000003'
    attr = ZipkinAttrs(
        trace_id=trace_id,
        span_id=client_span_id,
        parent_span_id=None,
        flags=None,
        is_sampled=True,
    )

    span_storage = SpanStorage()
    transport_handler = mock.Mock()

    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=fake_endpoint,
        span_name='GET /foo',
        transport_handler=transport_handler,
        report_root_timestamp=True,
        span_storage=span_storage,
        client_context=True,
        service_name='test_server',
        encoding=Encoding.V1_JSON,
    )

    context.start_timestamp = 24
    context.response_status_code = 200

    context.binary_annotations_dict = {'k': 'v'}
    time_mock.return_value = 42

    context.emit_spans()
    log_call = add_span_mock.call_args_list[0]
    assert log_call[0][1].build_v1_span() == SpanBuilder(
        trace_id=trace_id,
        name='GET /foo',
        parent_id=None,
        span_id=client_span_id,
        timestamp=24.0,
        duration=18.0,
        annotations={
            'cs': 24,
            'cr': 42
        },
        tags={
            'k': 'v'
        },
        kind=Kind.CLIENT,
        service_name='test_server',
        local_endpoint=fake_endpoint,
    ).build_v1_span()
    assert flush_mock.call_count == 1
Exemplo n.º 7
0
def context():
    attr = ZipkinAttrs(None, None, None, None, False)
    log_handler = logging_helper.ZipkinLoggerHandler(attr)
    transport_handler = mock.Mock()
    return logging_helper.ZipkinLoggingContext(
        attr,
        'thrift_endpoint',
        log_handler,
        'span_name',
        transport_handler,
    )
Exemplo n.º 8
0
def context():
    attr = ZipkinAttrs(None, None, None, None, False)
    log_handler = logging_helper.ZipkinLoggerHandler(attr)
    return logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        thrift_endpoint='thrift_endpoint',
        log_handler=log_handler,
        span_name='span_name',
        transport_handler=mock_transport_handler,
        report_root_timestamp=False,
    )
Exemplo n.º 9
0
def test_zipkin_logging_client_context_emit_spans(
    add_span_mock, flush_mock, time_mock, fake_endpoint
):
    # This lengthy function tests that the logging context properly
    # logs root client span
    trace_id = "000000000000000f"
    client_span_id = "0000000000000003"
    attr = ZipkinAttrs(
        trace_id=trace_id,
        span_id=client_span_id,
        parent_span_id=None,
        flags=None,
        is_sampled=True,
    )

    tracer = MockTracer()
    transport_handler = mock.Mock()

    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=fake_endpoint,
        span_name="GET /foo",
        transport_handler=transport_handler,
        report_root_timestamp=True,
        get_tracer=lambda: tracer,
        client_context=True,
        service_name="test_server",
        encoding=Encoding.V1_JSON,
    )

    context.start_timestamp = 24
    context.response_status_code = 200

    context.tags = {"k": "v"}
    time_mock.return_value = 42

    context.emit_spans()
    log_call = add_span_mock.call_args_list[0]
    assert (
        log_call[0][1].build_v1_span()
        == Span(
            trace_id=trace_id,
            name="GET /foo",
            parent_id=None,
            span_id=client_span_id,
            kind=Kind.CLIENT,
            timestamp=24.0,
            duration=18.0,
            local_endpoint=fake_endpoint,
            annotations={"cs": 24, "cr": 42},
            tags={"k": "v"},
        ).build_v1_span()
    )
    assert flush_mock.call_count == 1
Exemplo n.º 10
0
def context():
    attr = ZipkinAttrs(None, None, None, None, False)
    return logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=create_endpoint(80, 'test_server', '127.0.0.1'),
        span_name='span_name',
        transport_handler=MockTransportHandler(),
        report_root_timestamp=False,
        span_storage=SpanStorage(),
        service_name='test_server',
        encoding=Encoding.V1_JSON,
    )
Exemplo n.º 11
0
def context():
    attr = ZipkinAttrs(None, None, None, None, False)
    log_handler = logging_helper.ZipkinLoggerHandler(attr)
    return logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=_encoding_helpers.create_endpoint(80, 'test_server',
                                                   '127.0.0.1'),
        log_handler=log_handler,
        span_name='span_name',
        transport_handler=MockTransportHandler(),
        report_root_timestamp=False,
    )
Exemplo n.º 12
0
def test_zipkin_logging_client_context_log_spans(add_span_mock, flush_mock,
                                                 time_mock, fake_endpoint):
    # This lengthy function tests that the logging context properly
    # logs root client span
    trace_id = '000000000000000f'
    client_span_id = '0000000000000003'
    attr = ZipkinAttrs(
        trace_id=trace_id,
        span_id=client_span_id,
        parent_span_id=None,
        flags=None,
        is_sampled=True,
    )
    handler = logging_helper.ZipkinLoggerHandler(attr)
    handler.client_spans = []

    transport_handler = mock.Mock()

    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=fake_endpoint,
        log_handler=handler,
        span_name='GET /foo',
        transport_handler=transport_handler,
        report_root_timestamp=True,
        client_context=True)

    context.start_timestamp = 24
    context.response_status_code = 200

    context.binary_annotations_dict = {'k': 'v'}
    time_mock.return_value = 42

    expected_server_annotations = {'cs': 24, 'cr': 42}
    expected_server_bin_annotations = {'k': 'v'}

    context.log_spans()
    log_call = add_span_mock.call_args_list[0]
    assert log_call[1] == {
        'span_id': client_span_id,
        'parent_span_id': None,
        'trace_id': trace_id,
        'span_name': 'GET /foo',
        'annotations': expected_server_annotations,
        'binary_annotations': expected_server_bin_annotations,
        'duration_s': 18,
        'timestamp_s': 24,
        'endpoint': fake_endpoint,
        'sa_endpoint': None,
    }
    assert flush_mock.call_count == 1
Exemplo n.º 13
0
def test_log_span_not_called_if_not_sampled(log_span_mock):
    attr = ZipkinAttrs(
        trace_id='0000000000000001',
        span_id='0000000000000002',
        parent_span_id=None,
        flags=None,
        is_sampled=False,
    )
    log_handler = logging_helper.ZipkinLoggerHandler(attr)
    transport_handler = mock.Mock()
    context = logging_helper.ZipkinLoggingContext(attr, 'thrift_endpoint',
                                                  log_handler, 'span_name',
                                                  transport_handler)
    context.log_spans()
    assert log_span_mock.call_count == 0
Exemplo n.º 14
0
def test_batch_sender_add_span_not_called_if_not_sampled(
        add_span_mock, flush_mock):
    attr = ZipkinAttrs(
        trace_id='0000000000000001',
        span_id='0000000000000002',
        parent_span_id=None,
        flags=None,
        is_sampled=False,
    )
    log_handler = logging_helper.ZipkinLoggerHandler(attr)
    transport_handler = mock.Mock()
    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        thrift_endpoint='thrift_endpoint',
        log_handler=log_handler,
        span_name='span_name',
        transport_handler=transport_handler,
        report_root_timestamp=False,
    )
    context.log_spans()
    assert add_span_mock.call_count == 0
    assert flush_mock.call_count == 0
Exemplo n.º 15
0
def test_zipkin_logging_context(time_mock):
    # Tests the context manager aspects of the ZipkinLoggingContext
    time_mock.return_value = 42
    attr = ZipkinAttrs(None, None, None, None, False)
    tracer = MockTracer()
    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=create_endpoint(80, "test_server", "127.0.0.1"),
        span_name="span_name",
        transport_handler=MockTransportHandler(),
        report_root_timestamp=False,
        get_tracer=lambda: tracer,
        service_name="test_server",
        encoding=Encoding.V1_JSON,
    )
    # Ignore the actual logging part
    with mock.patch.object(context, "emit_spans"):
        context.start()
        assert context.start_timestamp == 42
        context.stop()
        # Make sure the handler and the zipkin attrs are gone
        assert context.emit_spans.call_count == 1
Exemplo n.º 16
0
def test_batch_sender_add_span_not_called_if_not_sampled(add_span_mock, flush_mock):
    attr = ZipkinAttrs(
        trace_id="0000000000000001",
        span_id="0000000000000002",
        parent_span_id=None,
        flags=None,
        is_sampled=False,
    )
    tracer = MockTracer()
    transport_handler = mock.Mock()

    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=create_endpoint(80, "test_server", "127.0.0.1"),
        span_name="span_name",
        transport_handler=transport_handler,
        report_root_timestamp=False,
        get_tracer=lambda: tracer,
        service_name="test_server",
        encoding=Encoding.V1_JSON,
    )
    context.emit_spans()
    assert add_span_mock.call_count == 0
    assert flush_mock.call_count == 0
Exemplo n.º 17
0
def test_zipkin_logging_server_context_log_spans(copy_endpoint_mock,
                                                 bin_ann_list_builder,
                                                 ann_list_builder,
                                                 log_span_mock, time_mock):
    # This lengthy function tests that the logging context properly
    # logs both client and server spans, while attaching extra annotations
    # logged throughout the context of the trace.
    trace_id = '000000000000000f'
    parent_span_id = '0000000000000001'
    server_span_id = '0000000000000002'
    client_span_id = '0000000000000003'
    client_span_name = 'breadcrumbs'
    client_svc_name = 'svc'
    attr = ZipkinAttrs(
        trace_id=trace_id,
        span_id=server_span_id,
        parent_span_id=parent_span_id,
        flags=None,
        is_sampled=True,
    )
    handler = logging_helper.ZipkinLoggerHandler(attr)
    extra_server_annotations = {
        'parent_span_id': None,
        'annotations': {
            'foo': 1
        },
        'binary_annotations': {
            'what': 'whoa'
        },
    }
    extra_client_annotations = {
        'parent_span_id': client_span_id,
        'annotations': {
            'ann1': 1
        },
        'binary_annotations': {
            'bann1': 'aww'
        },
    }
    handler.extra_annotations = [
        extra_server_annotations,
        extra_client_annotations,
    ]
    handler.client_spans = [{
        'span_id': client_span_id,
        'parent_span_id': None,
        'span_name': client_span_name,
        'service_name': client_svc_name,
        'annotations': {
            'ann2': 2,
            'cs': 26,
            'cr': 30
        },
        'binary_annotations': {
            'bann2': 'yiss'
        },
    }]

    # Each of the thrift annotation helpers just reflects its first arg
    # so the annotation dicts can be checked.
    ann_list_builder.side_effect = lambda x, y: x
    bin_ann_list_builder.side_effect = lambda x, y: x

    transport_handler = mock.Mock()

    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        thrift_endpoint='thrift_endpoint',
        log_handler=handler,
        span_name='GET /foo',
        transport_handler=transport_handler,
        report_root_timestamp=True,
    )

    context.start_timestamp = 24
    context.response_status_code = 200

    context.binary_annotations_dict = {'k': 'v'}
    time_mock.return_value = 42

    expected_server_annotations = {'foo': 1, 'sr': 24, 'ss': 42}
    expected_server_bin_annotations = {'k': 'v', 'what': 'whoa'}

    expected_client_annotations = {'ann1': 1, 'ann2': 2, 'cs': 26, 'cr': 30}
    expected_client_bin_annotations = {'bann1': 'aww', 'bann2': 'yiss'}

    context.log_spans()
    client_log_call, server_log_call = log_span_mock.call_args_list
    assert server_log_call[1] == {
        'span_id': server_span_id,
        'parent_span_id': parent_span_id,
        'trace_id': trace_id,
        'span_name': 'GET /foo',
        'annotations': expected_server_annotations,
        'binary_annotations': expected_server_bin_annotations,
        'transport_handler': transport_handler,
        'duration_s': 18,
        'timestamp_s': 24,
    }
    assert client_log_call[1] == {
        'span_id': client_span_id,
        'parent_span_id': server_span_id,
        'trace_id': trace_id,
        'span_name': client_span_name,
        'annotations': expected_client_annotations,
        'binary_annotations': expected_client_bin_annotations,
        'transport_handler': transport_handler,
        'duration_s': 4,
        'timestamp_s': 26,
    }
Exemplo n.º 18
0
def test_zipkin_logging_server_context_log_spans(add_span_mock, flush_mock,
                                                 time_mock, fake_endpoint):
    # This lengthy function tests that the logging context properly
    # logs both client and server spans, while attaching extra annotations
    # logged throughout the context of the trace.
    trace_id = '000000000000000f'
    parent_span_id = '0000000000000001'
    server_span_id = '0000000000000002'
    client_span_id = '0000000000000003'
    client_span_name = 'breadcrumbs'
    client_svc_name = 'svc'
    attr = ZipkinAttrs(
        trace_id=trace_id,
        span_id=server_span_id,
        parent_span_id=parent_span_id,
        flags=None,
        is_sampled=True,
    )
    handler = logging_helper.ZipkinLoggerHandler(attr)
    extra_server_annotations = {
        'parent_span_id': None,
        'annotations': {
            'foo': 1
        },
        'binary_annotations': {
            'what': 'whoa'
        },
    }
    extra_client_annotations = {
        'parent_span_id': client_span_id,
        'annotations': {
            'ann1': 1
        },
        'binary_annotations': {
            'bann1': 'aww'
        },
    }
    handler.extra_annotations = [
        extra_server_annotations,
        extra_client_annotations,
    ]
    handler.client_spans = [{
        'span_id': client_span_id,
        'parent_span_id': None,
        'span_name': client_span_name,
        'service_name': client_svc_name,
        'annotations': {
            'ann2': 2,
            'cs': 26,
            'cr': 30
        },
        'binary_annotations': {
            'bann2': 'yiss'
        },
    }]

    transport_handler = mock.Mock()

    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=fake_endpoint,
        log_handler=handler,
        span_name='GET /foo',
        transport_handler=transport_handler,
        report_root_timestamp=True,
    )

    context.start_timestamp = 24
    context.response_status_code = 200

    context.binary_annotations_dict = {'k': 'v'}
    time_mock.return_value = 42

    expected_server_annotations = {'foo': 1, 'sr': 24, 'ss': 42}
    expected_server_bin_annotations = {'k': 'v', 'what': 'whoa'}

    expected_client_annotations = {'ann1': 1, 'ann2': 2, 'cs': 26, 'cr': 30}
    expected_client_bin_annotations = {'bann1': 'aww', 'bann2': 'yiss'}

    context.log_spans()
    client_log_call, server_log_call = add_span_mock.call_args_list
    assert server_log_call[1] == {
        'span_id': server_span_id,
        'parent_span_id': parent_span_id,
        'trace_id': trace_id,
        'span_name': 'GET /foo',
        'annotations': expected_server_annotations,
        'binary_annotations': expected_server_bin_annotations,
        'duration_s': 18,
        'timestamp_s': 24,
        'endpoint': fake_endpoint,
        'sa_endpoint': None,
    }
    assert client_log_call[1] == {
        'span_id': client_span_id,
        'parent_span_id': server_span_id,
        'trace_id': trace_id,
        'span_name': client_span_name,
        'annotations': expected_client_annotations,
        'binary_annotations': expected_client_bin_annotations,
        'duration_s': 4,
        'timestamp_s': 26,
        'endpoint': _encoding_helpers.create_endpoint(80, 'svc', '127.0.0.1'),
        'sa_endpoint': None,
    }
    assert flush_mock.call_count == 1
Exemplo n.º 19
0
def test_zipkin_logging_server_context_emit_spans(
    add_span_mock, flush_mock, time_mock, fake_endpoint
):
    # This lengthy function tests that the logging context properly
    # logs both client and server spans.
    trace_id = "000000000000000f"
    parent_span_id = "0000000000000001"
    server_span_id = "0000000000000002"
    client_span_id = "0000000000000003"
    client_span_name = "breadcrumbs"
    attr = ZipkinAttrs(
        trace_id=trace_id,
        span_id=server_span_id,
        parent_span_id=parent_span_id,
        flags=None,
        is_sampled=True,
    )
    tracer = MockTracer()

    client_span = Span(
        trace_id=trace_id,
        name=client_span_name,
        parent_id=server_span_id,
        span_id=client_span_id,
        kind=Kind.CLIENT,
        timestamp=26.0,
        duration=4.0,
        local_endpoint=create_endpoint(service_name="test_server"),
        annotations={"ann2": 2, "cs": 26, "cr": 30},
        tags={"bann2": "yiss"},
    )
    tracer.get_spans().append(client_span)

    transport_handler = mock.Mock()

    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=fake_endpoint,
        span_name="GET /foo",
        transport_handler=transport_handler,
        report_root_timestamp=True,
        get_tracer=lambda: tracer,
        service_name="test_server",
        encoding=Encoding.V1_JSON,
    )

    context.start_timestamp = 24
    context.response_status_code = 200

    context.tags = {"k": "v"}
    time_mock.return_value = 42

    context.emit_spans()
    client_log_call, server_log_call = add_span_mock.call_args_list
    assert (
        server_log_call[0][1].build_v1_span()
        == Span(
            trace_id=trace_id,
            name="GET /foo",
            parent_id=parent_span_id,
            span_id=server_span_id,
            kind=Kind.SERVER,
            timestamp=24.0,
            duration=18.0,
            local_endpoint=fake_endpoint,
            annotations={"sr": 24, "ss": 42},
            tags={"k": "v"},
        ).build_v1_span()
    )
    assert client_log_call[0][1] == client_span
    assert flush_mock.call_count == 1
Exemplo n.º 20
0
def test_zipkin_logging_server_context_emit_spans(add_span_mock, flush_mock,
                                                  time_mock, fake_endpoint):
    # This lengthy function tests that the logging context properly
    # logs both client and server spans.
    trace_id = '000000000000000f'
    parent_span_id = '0000000000000001'
    server_span_id = '0000000000000002'
    client_span_id = '0000000000000003'
    client_span_name = 'breadcrumbs'
    client_svc_name = 'svc'
    attr = ZipkinAttrs(
        trace_id=trace_id,
        span_id=server_span_id,
        parent_span_id=parent_span_id,
        flags=None,
        is_sampled=True,
    )
    span_storage = SpanStorage()

    client_span = SpanBuilder(
        trace_id=trace_id,
        name=client_span_name,
        parent_id=server_span_id,
        span_id=client_span_id,
        timestamp=26.0,
        duration=4.0,
        annotations={
            'ann2': 2,
            'cs': 26,
            'cr': 30
        },
        tags={'bann2': 'yiss'},
        kind=Kind.CLIENT,
        service_name=client_svc_name,
    )
    span_storage.append(client_span)

    transport_handler = mock.Mock()

    context = logging_helper.ZipkinLoggingContext(
        zipkin_attrs=attr,
        endpoint=fake_endpoint,
        span_name='GET /foo',
        transport_handler=transport_handler,
        report_root_timestamp=True,
        span_storage=span_storage,
        service_name='test_server',
        encoding=Encoding.V1_JSON,
    )

    context.start_timestamp = 24
    context.response_status_code = 200

    context.binary_annotations_dict = {'k': 'v'}
    time_mock.return_value = 42

    context.emit_spans()
    client_log_call, server_log_call = add_span_mock.call_args_list
    assert server_log_call[0][1].build_v1_span() == SpanBuilder(
        trace_id=trace_id,
        name='GET /foo',
        parent_id=parent_span_id,
        span_id=server_span_id,
        timestamp=24.0,
        duration=18.0,
        annotations={
            'sr': 24,
            'ss': 42
        },
        tags={
            'k': 'v'
        },
        kind=Kind.SERVER,
        service_name=client_svc_name,
        local_endpoint=fake_endpoint,
    ).build_v1_span()
    assert client_log_call[0][1] == client_span
    assert flush_mock.call_count == 1