def test_get_current_context_non_root_existing( self, mock_create_attr, ): # Non root, zipkin_attrs in context stack. # Return existing zipkin_attrs with the current one as parent zipkin_attrs = ZipkinAttrs( trace_id=generate_random_64bit_string(), span_id=generate_random_64bit_string(), parent_span_id=generate_random_64bit_string(), flags=None, is_sampled=True, ) tracer = MockTracer() context = tracer.zipkin_span( service_name='test_service', span_name='test_span', ) tracer._context_stack.push(zipkin_attrs) _, current_attrs = context._get_current_context() assert mock_create_attr.call_count == 0 assert current_attrs == ZipkinAttrs( trace_id=zipkin_attrs.trace_id, span_id=mock.ANY, parent_span_id=zipkin_attrs.span_id, flags=zipkin_attrs.flags, is_sampled=zipkin_attrs.is_sampled, )
def test_stop_non_root_ts_duration_overridden(self): tracer = MockTracer() tracer.set_transport_configured(configured=True) tracer.get_context().push(zipkin.create_attrs_for_span()) ts = time.time() context = tracer.zipkin_span( service_name='test_service', span_name='test_span', timestamp=ts, duration=25, ) context.start() context.stop() assert len(tracer.get_spans()) == 1 endpoint = create_endpoint(service_name='test_service') assert tracer.get_spans()[0] == Span( trace_id=context.zipkin_attrs.trace_id, name='test_span', parent_id=context.zipkin_attrs.parent_span_id, span_id=context.zipkin_attrs.span_id, kind=Kind.LOCAL, timestamp=ts, duration=25, annotations={}, local_endpoint=endpoint, remote_endpoint=None, tags={}, ) assert tracer.is_transport_configured() is True
def test_stop_non_root(self, mock_time): tracer = MockTracer() tracer.set_transport_configured(configured=True) tracer.get_context().push(zipkin.create_attrs_for_span()) context = tracer.zipkin_span( service_name="test_service", span_name="test_span", ) context.start() context.stop() assert len(tracer.get_spans()) == 1 endpoint = create_endpoint(service_name="test_service") assert tracer.get_spans()[0] == Span( trace_id=context.zipkin_attrs.trace_id, name="test_span", parent_id=context.zipkin_attrs.parent_span_id, span_id=context.zipkin_attrs.span_id, kind=Kind.LOCAL, timestamp=123, duration=0, annotations={}, local_endpoint=endpoint, remote_endpoint=None, tags={}, ) assert tracer.is_transport_configured() is True
def test_init(self, mock_generate_kind): # Test that all arguments are correctly saved zipkin_attrs = ZipkinAttrs(None, None, None, None, None) transport = MockTransportHandler() firehose = MockTransportHandler() stack = Stack([]) span_storage = SpanStorage() tracer = MockTracer() context = tracer.zipkin_span( service_name="test_service", span_name="test_span", zipkin_attrs=zipkin_attrs, transport_handler=transport, max_span_batch_size=10, annotations={"test_annotation": 1}, binary_annotations={"status": "200"}, port=80, sample_rate=100.0, include=("cs", "cr"), add_logging_annotation=True, report_root_timestamp=True, use_128bit_trace_id=True, host="127.0.0.255", context_stack=stack, span_storage=span_storage, firehose_handler=firehose, kind=Kind.CLIENT, timestamp=1234, duration=10, encoding=Encoding.V2_JSON, ) assert context.service_name == "test_service" assert context.span_name == "test_span" assert context.zipkin_attrs_override == zipkin_attrs assert context.transport_handler == transport assert context.max_span_batch_size == 10 assert context.annotations == {"test_annotation": 1} assert context.binary_annotations == {"status": "200"} assert context.port == 80 assert context.sample_rate == 100.0 assert context.add_logging_annotation is True assert context.report_root_timestamp_override is True assert context.use_128bit_trace_id is True assert context.host == "127.0.0.255" assert context._context_stack == stack assert context._span_storage == span_storage assert context.firehose_handler == firehose assert mock_generate_kind.call_count == 1 assert mock_generate_kind.call_args == mock.call( context, Kind.CLIENT, ("cs", "cr"), ) assert context.timestamp == 1234 assert context.duration == 10 assert context.encoding == Encoding.V2_JSON assert context._tracer == tracer # Check for backward compatibility assert tracer.get_spans() == span_storage assert tracer.get_context() == stack
def test_service_exits_on_erroneous_span(log_mock): """Tests that for invalid zipkin_attrs exceptions are not thrown Services may not be handling them. Instead log an error """ mock_transport_handler, mock_logs = mock_logger() tracer = MockTracer() try: zipkin_attrs = ZipkinAttrs( trace_id='0', span_id='1, 1', # invalid span id parent_span_id='2', flags='0', is_sampled=True, ) with tracer.zipkin_span( service_name='test_service_name', span_name='service_span', zipkin_attrs=zipkin_attrs, transport_handler=mock_transport_handler, encoding=Encoding.V1_THRIFT, ): pass except Exception: pytest.fail('Exception not expected to be thrown!') finally: assert log_mock.call_count == 1 assert len(mock_logs) == 0 assert len(tracer.get_spans()) == 0
def test_start_root_span_not_sampled(self, mock_log_ctx): transport = MockTransportHandler() tracer = MockTracer() context = tracer.zipkin_span( service_name='test_service', span_name='test_span', transport_handler=transport, sample_rate=0.0, ) context.start() assert context.zipkin_attrs is not None assert mock_log_ctx.call_count == 0 assert tracer.is_transport_configured() is False
def test_stop_root(self): transport = MockTransportHandler() tracer = MockTracer() context = tracer.zipkin_span( service_name='test_service', span_name='test_span', transport_handler=transport, sample_rate=100.0, ) context.start() with mock.patch.object(context, 'logging_context') as mock_log_ctx: context.stop() assert mock_log_ctx.stop.call_count == 1 # Test that we reset everything after calling stop() assert context.logging_context is None assert tracer.is_transport_configured() is False assert len(tracer.get_spans()) == 0
def test_start_root_span_redef_transport(self, mock_log, mock_log_ctx): # Transport is already setup, so we should not override it # and log a message to inform the user. transport = MockTransportHandler() tracer = MockTracer() context = tracer.zipkin_span( service_name='test_service', span_name='test_span', transport_handler=transport, sample_rate=100.0, ) tracer.set_transport_configured(configured=True) context.start() assert context.zipkin_attrs is not None assert mock_log_ctx.call_count == 0 assert tracer.is_transport_configured() is True assert mock_log.call_count == 1
def test_start_root_span_not_sampled_firehose(self, mock_log_ctx): # This request is not sampled, but firehose is setup. So we need to # setup the transport anyway. transport = MockTransportHandler() firehose = MockTransportHandler() tracer = MockTracer() context = tracer.zipkin_span( service_name='test_service', span_name='test_span', transport_handler=transport, firehose_handler=firehose, sample_rate=0.0, ) context.start() assert context.zipkin_attrs is not None assert mock_log_ctx.call_count == 1 assert mock_log_ctx.return_value.start.call_count == 1 assert tracer.is_transport_configured() is True
def test_start_root_span(self, mock_time, mock_log_ctx): transport = MockTransportHandler() firehose = MockTransportHandler() tracer = MockTracer() context = tracer.zipkin_span( service_name="test_service", span_name="test_span", transport_handler=transport, firehose_handler=firehose, sample_rate=100.0, max_span_batch_size=50, encoding=Encoding.V2_JSON, ) context.start() assert context.zipkin_attrs is not None assert context.start_timestamp == 123 assert mock_log_ctx.call_args == mock.call( context.zipkin_attrs, mock.ANY, "test_span", transport, True, context.get_tracer, "test_service", binary_annotations={}, add_logging_annotation=False, client_context=False, max_span_batch_size=50, firehose_handler=firehose, encoding=Encoding.V2_JSON, annotations={}, ) assert mock_log_ctx.return_value.start.call_count == 1 assert tracer.is_transport_configured() is True
def test_error_stopping_log_context(self): '''Tests if exception is raised while emitting traces that 1. tracer is cleared 2. excpetion is not passed up ''' transport = MockTransportHandler() tracer = MockTracer() context = tracer.zipkin_span( service_name='test_service', span_name='test_span', transport_handler=transport, sample_rate=100.0, ) context.start() with mock.patch.object(context, 'logging_context') as mock_log_ctx: mock_log_ctx.stop.side_effect = Exception try: context.stop() except Exception: pytest.fail('Exception not expected to be thrown!') assert mock_log_ctx.stop.call_count == 1 assert len(tracer.get_spans()) == 0