private TracingState generateTracingStateOnCurrentThread() { Tracer.getInstance().startRequestWithRootSpan(UUID.randomUUID().toString()); Tracer.getInstance().startSubSpan(UUID.randomUUID().toString(), SpanPurpose.LOCAL_ONLY); return TracingState.getCurrentThreadTracingState(); }
private TracingState generateTracingStateOnCurrentThread() { Tracer.getInstance().startRequestWithRootSpan(UUID.randomUUID().toString()); Tracer.getInstance().startSubSpan(UUID.randomUUID().toString(), Span.SpanPurpose.LOCAL_ONLY); return TracingState.getCurrentThreadTracingState(); }
@Test public void getCurrentTracerManagedSpanStatus_works_as_expected_for_managed_noncurrent() { // given Span nonCurrentRootSpan = Tracer.getInstance().startRequestWithRootSpan("root"); Span nonCurrentSubspan = Tracer.getInstance().startSubSpan("subspan1", SpanPurpose.LOCAL_ONLY); Span currentSubspan = Tracer.getInstance().startSubSpan("subspan2", SpanPurpose.LOCAL_ONLY); // expect assertThat(nonCurrentRootSpan.getCurrentTracerManagedSpanStatus()) .isEqualTo(TracerManagedSpanStatus.MANAGED_NON_CURRENT_ROOT_SPAN); assertThat(nonCurrentSubspan.getCurrentTracerManagedSpanStatus()) .isEqualTo(TracerManagedSpanStatus.MANAGED_NON_CURRENT_SUB_SPAN); }
@Test public void getCurrentManagedStatusForSpan_works_as_expected_for_managed_noncurrent() { // given Span nonCurrentRootSpan = Tracer.getInstance().startRequestWithRootSpan("root"); Span nonCurrentSubspan = Tracer.getInstance().startSubSpan("subspan1", SpanPurpose.LOCAL_ONLY); Span currentSubspan = Tracer.getInstance().startSubSpan("subspan2", SpanPurpose.LOCAL_ONLY); // expect assertThat(Tracer.getInstance().getCurrentManagedStatusForSpan(nonCurrentRootSpan)) .isEqualTo(TracerManagedSpanStatus.MANAGED_NON_CURRENT_ROOT_SPAN); assertThat(Tracer.getInstance().getCurrentManagedStatusForSpan(nonCurrentSubspan)) .isEqualTo(TracerManagedSpanStatus.MANAGED_NON_CURRENT_SUB_SPAN); }
@Test public void spanLifecycleListener_spanStarted_is_called_when_subspan_is_started() { // given SpanLifecycleListener listener1 = mock(SpanLifecycleListener.class); SpanLifecycleListener listener2 = mock(SpanLifecycleListener.class); Tracer tracer = Tracer.getInstance(); tracer.addSpanLifecycleListener(listener1); tracer.addSpanLifecycleListener(listener2); tracer.startRequestWithRootSpan("newspan"); // when Span subspan = tracer.startSubSpan("subspan", SpanPurpose.LOCAL_ONLY); // then verify(listener1).spanStarted(subspan); verify(listener1, times(0)).spanCompleted(subspan); verify(listener2).spanStarted(subspan); verify(listener2, times(0)).spanCompleted(subspan); }
@Test public void spanLifecycleListener_spanSampled_is_not_called_when_subspan_is_started_if_subspan_is_not_sampleable() { // given SpanLifecycleListener listener1 = mock(SpanLifecycleListener.class); SpanLifecycleListener listener2 = mock(SpanLifecycleListener.class); Tracer tracer = Tracer.getInstance(); tracer.addSpanLifecycleListener(listener1); tracer.addSpanLifecycleListener(listener2); tracer.startRequestWithSpanInfo("t", "p", "n", false, "u", SpanPurpose.LOCAL_ONLY); // when Span subspan = tracer.startSubSpan("subspan", SpanPurpose.LOCAL_ONLY); // then verify(listener1).spanStarted(subspan); verify(listener1, times(0)).spanSampled(subspan); verify(listener1, times(0)).spanCompleted(subspan); verify(listener2).spanStarted(subspan); verify(listener2, times(0)).spanSampled(subspan); verify(listener2, times(0)).spanCompleted(subspan); }
@Test public void unregisterFromThread_should_work_as_advertised() { // given Tracer tracer = Tracer.getInstance(); Span parentSpan = tracer.startRequestWithRootSpan("foo"); Span subspan = tracer.startSubSpan("bar", SpanPurpose.LOCAL_ONLY); assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isEqualTo(subspan.getTraceId()); assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isEqualTo(subspan.toJSON()); assertThat(getSpanStackSize()).isEqualTo(2); // when Deque<Span> unregisteredStack = tracer.unregisterFromThread(); // then assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isNull(); assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isNull(); assertThat(getSpanStackSize()).isEqualTo(0); assertThat(unregisteredStack).hasSize(2); assertThat(unregisteredStack.pop()).isEqualTo(subspan); assertThat(unregisteredStack.pop()).isEqualTo(parentSpan); }
@Test public void startRequestWithRootSpan_wipes_out_any_existing_spans_on_the_stack() { // given: Tracer already has some Spans on the stack Tracer.getInstance().startRequestWithRootSpan("span1"); Tracer.getInstance().startSubSpan("span2", SpanPurpose.LOCAL_ONLY); assertThat(getSpanStackSize()).isEqualTo(2); // when: Tracer.startRequestWithRootSpan(String) is called to start a span without a parent Tracer.getInstance().startRequestWithRootSpan("noparent"); // then: a new span is started for it, and the other spans on the stack are removed assertThat(getSpanStackSize()).isEqualTo(1); Span span = Tracer.getInstance().getCurrentSpan(); assertThat(span).isNotNull(); assertThat(span.getSpanName()).isEqualTo("noparent"); }
@Test public void spanLifecycleListener_spanSampled_is_called_when_subspan_is_started_if_subspan_is_sampleable() { // given SpanLifecycleListener listener1 = mock(SpanLifecycleListener.class); SpanLifecycleListener listener2 = mock(SpanLifecycleListener.class); Tracer tracer = Tracer.getInstance(); tracer.addSpanLifecycleListener(listener1); tracer.addSpanLifecycleListener(listener2); tracer.startRequestWithSpanInfo("t", "p", "n", true, "u", SpanPurpose.LOCAL_ONLY); // when Span subspan = tracer.startSubSpan("subspan", SpanPurpose.LOCAL_ONLY); // then verify(listener1).spanStarted(subspan); verify(listener1).spanSampled(subspan); verify(listener1, times(0)).spanCompleted(subspan); verify(listener2).spanStarted(subspan); verify(listener2).spanSampled(subspan); verify(listener2, times(0)).spanCompleted(subspan); }
@Test public void registerWithThread_should_do_nothing_if_copy_of_same_stack_is_passed_in() { // given Tracer tracer = Tracer.getInstance(); tracer.startRequestWithRootSpan("foo"); Span subspan = tracer.startSubSpan("bar", SpanPurpose.LOCAL_ONLY); assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isEqualTo(subspan.getTraceId()); assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isEqualTo(subspan.toJSON()); // when Deque<Span> spanStack = getSpanStackThreadLocal().get(); tracer.registerWithThread(new LinkedList<>(spanStack)); // then assertThat(getSpanStackThreadLocal().get()).isEqualTo(spanStack); assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isEqualTo(subspan.getTraceId()); assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isEqualTo(subspan.toJSON()); }
@Test public void registerWithThread_should_do_nothing_if_same_stack_is_passed_in() { // given Tracer tracer = Tracer.getInstance(); tracer.startRequestWithRootSpan("foo"); Span subspan = tracer.startSubSpan("bar", SpanPurpose.LOCAL_ONLY); assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isEqualTo(subspan.getTraceId()); assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isEqualTo(subspan.toJSON()); // when Deque<Span> spanStack = getSpanStackThreadLocal().get(); tracer.registerWithThread(spanStack); // then assertThat(getSpanStackThreadLocal().get()).isEqualTo(spanStack); assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isEqualTo(subspan.getTraceId()); assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isEqualTo(subspan.toJSON()); }
@Test public void registerWithThread_should_reset_everything_if_passed_empty_instance() { // given Tracer tracer = Tracer.getInstance(); tracer.startRequestWithRootSpan("foo"); Span subspan = tracer.startSubSpan("bar", SpanPurpose.LOCAL_ONLY); assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isEqualTo(subspan.getTraceId()); assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isEqualTo(subspan.toJSON()); // when Deque<Span> emptyStack = new LinkedList<>(); tracer.registerWithThread(emptyStack); // then assertThat(getSpanStackThreadLocal().get()).isEqualTo(emptyStack); assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isNull(); assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isNull(); }
@Test public void startRequestWithChildSpan_wipes_out_any_existing_spans_on_the_stack() { // given: Tracer already has some Spans on the stack, and we have a parent span we're going to use Tracer.getInstance().startRequestWithRootSpan("span1"); Tracer.getInstance().startSubSpan("span2", SpanPurpose.LOCAL_ONLY); assertThat(getSpanStackSize()).isEqualTo(2); Span newSpanParent = Span.generateRootSpanForNewTrace("parentspan", SpanPurpose.CLIENT).build(); // when: Tracer.startRequestWithChildSpan(Span, String) is called to start a span with a parent Tracer.getInstance().startRequestWithChildSpan(newSpanParent, "childspan"); // then: a new span is started that has the given parent, and the other spans on the stack are removed assertThat(getSpanStackSize()).isEqualTo(1); Span span = Tracer.getInstance().getCurrentSpan(); assertThat(span).isNotNull(); assertThat(span.getSpanName()).isEqualTo("childspan"); }
@Test public void registerWithThread_should_reset_everything_if_passed_null() { // given Tracer tracer = Tracer.getInstance(); tracer.startRequestWithRootSpan("foo"); Span subspan = tracer.startSubSpan("bar", SpanPurpose.LOCAL_ONLY); assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isEqualTo(subspan.getTraceId()); assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isEqualTo(subspan.toJSON()); // when tracer.registerWithThread(null); // then assertThat(getSpanStackThreadLocal().get()).isNull(); assertThat(MDC.get(Tracer.TRACE_ID_MDC_KEY)).isNull(); assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isNull(); }
@Test public void getCurrentManagedStatusForSpan_works_as_expected_for_managed_current() { { // given Span currentRootSpan = Tracer.getInstance().startRequestWithRootSpan("root"); // when TracerManagedSpanStatus tmss = Tracer.getInstance().getCurrentManagedStatusForSpan(currentRootSpan); // then assertThat(tmss).isEqualTo(TracerManagedSpanStatus.MANAGED_CURRENT_ROOT_SPAN); } { // and given Span currentSubspan = Tracer.getInstance().startSubSpan("subspan", SpanPurpose.LOCAL_ONLY); // when TracerManagedSpanStatus tmss = Tracer.getInstance().getCurrentManagedStatusForSpan(currentSubspan); // then assertThat(tmss).isEqualTo(TracerManagedSpanStatus.MANAGED_CURRENT_SUB_SPAN); } }
@Test public void close_completes_the_span_as_expected_subspan() { // given Span parentSpan = Tracer.getInstance().startRequestWithRootSpan("root"); Span subspan = Tracer.getInstance().startSubSpan("subspan", SpanPurpose.LOCAL_ONLY); assertThat(Tracer.getInstance().getCurrentSpan()).isSameAs(subspan); assertThat(subspan.isCompleted()).isFalse(); // when subspan.close(); // then assertThat(subspan.isCompleted()).isTrue(); assertThat(Tracer.getInstance().getCurrentSpan()).isSameAs(parentSpan); }
@Test public void handleSpanCloseMethod_completes_the_span_as_expected_subspan() { // given Span parentSpan = Tracer.getInstance().startRequestWithRootSpan("root"); Span subspan = Tracer.getInstance().startSubSpan("subspan", SpanPurpose.LOCAL_ONLY); assertThat(Tracer.getInstance().getCurrentSpan()).isSameAs(subspan); assertThat(subspan.isCompleted()).isFalse(); // when Tracer.getInstance().handleSpanCloseMethod(subspan); // then assertThat(subspan.isCompleted()).isTrue(); assertThat(Tracer.getInstance().getCurrentSpan()).isSameAs(parentSpan); }
@Test public void close_does_nothing_if_span_is_already_completed() { // given Span rootSpan = Tracer.getInstance().startRequestWithRootSpan("root"); Span subspan = Tracer.getInstance().startSubSpan("subspan", SpanPurpose.LOCAL_ONLY); Tracer.getInstance().completeSubSpan(); assertThat(subspan.isCompleted()).isTrue(); assertThat(rootSpan.isCompleted()).isFalse(); assertThat(Tracer.getInstance().getCurrentSpan()).isSameAs(rootSpan); assertThat(Tracer.getInstance().getCurrentSpanStackCopy()).isEqualTo(singletonList(rootSpan)); // when subspan.close(); // then assertThat(rootSpan.isCompleted()).isFalse(); assertThat(Tracer.getInstance().getCurrentSpan()).isSameAs(rootSpan); assertThat(Tracer.getInstance().getCurrentSpanStackCopy()).isEqualTo(singletonList(rootSpan)); }
@Test public void handleSpanCloseMethod_does_nothing_if_span_is_already_completed() { // given Span rootSpan = Tracer.getInstance().startRequestWithRootSpan("root"); Span subspan = Tracer.getInstance().startSubSpan("subspan", SpanPurpose.LOCAL_ONLY); Tracer.getInstance().completeSubSpan(); assertThat(subspan.isCompleted()).isTrue(); assertThat(rootSpan.isCompleted()).isFalse(); assertThat(Tracer.getInstance().getCurrentSpan()).isSameAs(rootSpan); assertThat(Tracer.getInstance().getCurrentSpanStackCopy()).isEqualTo(singletonList(rootSpan)); // when Tracer.getInstance().handleSpanCloseMethod(subspan); // then assertThat(rootSpan.isCompleted()).isFalse(); assertThat(Tracer.getInstance().getCurrentSpan()).isSameAs(rootSpan); assertThat(Tracer.getInstance().getCurrentSpanStackCopy()).isEqualTo(singletonList(rootSpan)); }
private Pair<Deque<Span>, Map<String, String>> generateTraceInfo(Boolean setupForSubspan) { if (setupForSubspan == null) return Pair.of(null, null); try { resetTracingAndMdc(); Tracer.getInstance().startRequestWithRootSpan("overallReqSpan"); if (setupForSubspan) Tracer.getInstance().startSubSpan("subSpan", Span.SpanPurpose.LOCAL_ONLY); return Pair.of(Tracer.getInstance().getCurrentSpanStackCopy(), MDC.getCopyOfContextMap()); } finally { resetTracingAndMdc(); } }