@DataProvider public static Object[][] spanStackDataProvider() { Span rootSpan = Span.generateRootSpanForNewTrace("rootspan", SpanPurpose.SERVER).build(); Span childSpan = rootSpan.generateChildSpan("childSpan", SpanPurpose.CLIENT); return new Object[][] { { null }, { new LinkedList<>() }, { new LinkedList<>(Collections.singleton(rootSpan)) }, { new LinkedList<>(Arrays.asList(rootSpan, childSpan)) } }; }
@Test public void toJson_should_use_cached_json() { // given Span validSpan = Span.generateRootSpanForNewTrace(spanName, spanPurpose).build(); String uuidString = UUID.randomUUID().toString(); Whitebox.setInternalState(validSpan, "cachedJsonRepresentation", uuidString); // when String toJsonResult = validSpan.toJSON(); // then assertThat(toJsonResult).isEqualTo(uuidString); }
@Test public void toKeyValueString_should_use_cached_key_value_string() { // given Span validSpan = Span.generateRootSpanForNewTrace(spanName, spanPurpose).build(); String uuidString = UUID.randomUUID().toString(); Whitebox.setInternalState(validSpan, "cachedKeyValueRepresentation", uuidString); // when String toKeyValueStringResult = validSpan.toKeyValueString(); // then assertThat(toKeyValueStringResult).isEqualTo(uuidString); }
private Pair<Span, Map<String, String>> generateUpstreamSpanHeaders() { Span span = Span.newBuilder("upstreamSpan", Span.SpanPurpose.CLIENT).build(); Map<String, String> headers = MapBuilder .builder(TraceHeaders.TRACE_ID, span.getTraceId()) .put(TraceHeaders.SPAN_ID, span.getSpanId()) .put(TraceHeaders.SPAN_NAME, span.getSpanName()) .put(TraceHeaders.TRACE_SAMPLED, String.valueOf(span.isSampleable())) .build(); return Pair.of(span, headers); }
@Override public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { capturedSpan = Tracer.getInstance().getCurrentSpan(); captureSpanCopyAtTimeOfDoFilter = Span.newBuilder(capturedSpan).build(); } }
@Test public void fromJSON_delegates_to_span_parser() { // given Span span = Span.newBuilder("foo", SpanPurpose.CLIENT) .withTag("blahtag", UUID.randomUUID().toString()) .build(); String json = span.toJSON(); // when Span result = span.fromJSON(json); // then verifySpanDeepEquals(result, span, true); }
@Test public void getDuration_should_be_null_until_span_is_completed() { // given Span validSpan = Span.generateRootSpanForNewTrace(spanName, spanPurpose).build(); assertThat(validSpan.getDurationNanos()).isNull(); // when validSpan.complete(); // then assertThat(validSpan.getDurationNanos()).isNotNull(); }
@Test public void setSpanName_throws_IllegalArgumentException_if_passed_null() { // given Span span = Span.newBuilder("origSpanName", SpanPurpose.SERVER).build(); // when Throwable ex = catchThrowable(() -> span.setSpanName(null)); // then assertThat(ex).isInstanceOf(IllegalArgumentException.class); }
@Test public void convertSpanToKeyValueFormat_should_function_properly_for_non_completed_spans() { // given: valid span and key/value string from SpanParser.convertSpanToKeyValueFormat() Span validSpan = Span.generateRootSpanForNewTrace(spanName, spanPurpose).build(); assertThat(validSpan.isCompleted()).isFalse(); String keyValueStr = SpanParser.convertSpanToKeyValueFormat(validSpan); // when: the string is deserialized into a map Map<String, Object> deserializedValues = deserializeKeyValueSpanString(keyValueStr); // then: the original span and deserialized map values should be exactly the same verifySpanEqualsDeserializedValues(validSpan, deserializedValues); }
@Test public void convertSpanToKeyValueFormat_should_function_properly_for_completed_spans() { // given: valid span and completed, and key/value string from SpanParser.convertSpanToKeyValueFormat() Span validSpan = Span.generateRootSpanForNewTrace(spanName, spanPurpose).build(); completeSpan(validSpan); assertThat(validSpan.isCompleted()).isTrue(); String keyValueStr = SpanParser.convertSpanToKeyValueFormat(validSpan); // when: the string is deserialized into a map Map<String, Object> deserializedValues = deserializeKeyValueSpanString(keyValueStr); // then: the original span and deserialized map values should be exactly the same verifySpanEqualsDeserializedValues(validSpan, deserializedValues); }
@Test public void fromJson_should_function_properly_for_completed_spans() { // given: valid span that has been completed, and JSON string from SpanParser.convertSpanToJSON() Span validSpan = Span.generateRootSpanForNewTrace(spanName, spanPurpose).build(); completeSpan(validSpan); assertThat(validSpan.isCompleted()).isTrue(); String json = SpanParser.convertSpanToJSON(validSpan); // when: fromJson is called Span spanFromJson = SpanParser.fromJSON(json); // then: the original span and the fromJson() span values should be exactly the same verifySpanDeepEquals(spanFromJson, validSpan, true); }
@Test public void fromJson_should_function_properly_for_non_completed_spans() { // given: valid, non-completed span and JSON string from SpanParser.convertSpanToJSON() Span validSpan = Span.generateRootSpanForNewTrace(spanName, spanPurpose).build(); String json = SpanParser.convertSpanToJSON(validSpan); assertThat(validSpan.isCompleted()).isFalse(); // when: fromJson is called Span spanFromJson = SpanParser.fromJSON(json); // then: the original span and the fromJson() span values should be exactly the same verifySpanDeepEquals(spanFromJson, validSpan, true); }
@Test public void convertSpanToJSON_should_function_properly_for_non_completed_spans() throws IOException { // given: valid span and JSON string from SpanParser.convertSpanToJSON() Span validSpan = Span.generateRootSpanForNewTrace(spanName, spanPurpose).build(); String json = SpanParser.convertSpanToJSON(validSpan); assertThat(validSpan.isCompleted()).isFalse(); assertThat(validSpan.getDurationNanos()).isNull(); // when: jackson is used to deserialize that JSON Map<String, Object> spanValuesFromJackson = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {}); // then: the original span and jackson's span values should be exactly the same verifySpanEqualsDeserializedValues(validSpan, spanValuesFromJackson); }
@Test public void unconfigureMDC_should_unset_span_values_on_MDC() throws Exception { // given Span span = Span.newBuilder("test-span", SpanPurpose.LOCAL_ONLY).withParentSpanId("3").build(); Tracer.configureMDC(span); // when Tracer.unconfigureMDC(); // then assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isNull(); }
@Test public void fromKeyValueString_should_function_properly_for_non_completed_spans() { // given: valid, non-completed span and key/value string from Span.fromKeyValueString() Span validSpan = Span.generateRootSpanForNewTrace(spanName, spanPurpose).build(); String keyValStr = SpanParser.convertSpanToKeyValueFormat(validSpan); assertThat(validSpan.isCompleted()).isFalse(); // when: fromKeyValueString is called Span spanFromKeyValStr = SpanParser.fromKeyValueString(keyValStr); // then: the original span and the fromKeyValueString() span values should be exactly the same verifySpanDeepEquals(spanFromKeyValStr, validSpan, true); }
private Pair<Span, Map<String, String>> generateUpstreamSpanHeaders() { Span span = Span.newBuilder("upstreamSpan", Span.SpanPurpose.CLIENT).build(); Map<String, String> headers = MapBuilder .builder(TraceHeaders.TRACE_ID, span.getTraceId()) .put(TraceHeaders.SPAN_ID, span.getSpanId()) .put(TraceHeaders.SPAN_NAME, span.getSpanName()) .put(TraceHeaders.TRACE_SAMPLED, String.valueOf(span.isSampleable())) .build(); return Pair.of(span, headers); }
@Test public void addTimestampedAnnotation_works_as_expected() { // given Span span = Span.newBuilder("foo", SpanPurpose.CLIENT).build(); TimestampedAnnotation annotationMock = mock(TimestampedAnnotation.class); // when span.addTimestampedAnnotation(annotationMock); // then assertThat(span.getTimestampedAnnotations()) .hasSize(1) .containsExactly(annotationMock); }
private Pair<Span, Map<String, String>> generateUpstreamSpanHeaders() { Span span = Span.newBuilder("upstreamSpan", Span.SpanPurpose.CLIENT).build(); Map<String, String> headers = MapBuilder .builder(TraceHeaders.TRACE_ID, span.getTraceId()) .put(TraceHeaders.SPAN_ID, span.getSpanId()) .put(TraceHeaders.SPAN_NAME, span.getSpanName()) .put(TraceHeaders.TRACE_SAMPLED, String.valueOf(span.isSampleable())) .build(); return Pair.of(span, headers); }
@Test public void configureMDC_should_set_span_values_on_MDC() throws Exception { // given Span span = Span.newBuilder("test-span", SpanPurpose.LOCAL_ONLY).withParentSpanId("3").build(); String expected = span.toJSON(); // when Tracer.configureMDC(span); // then assertThat(MDC.get(Tracer.SPAN_JSON_MDC_KEY)).isEqualTo(expected); }
private Pair<Span, Map<String, String>> generateUpstreamSpanHeaders() { Span span = Span.newBuilder("upstreamSpan", Span.SpanPurpose.CLIENT).build(); Map<String, String> headers = MapBuilder .builder(TraceHeaders.TRACE_ID, span.getTraceId()) .put(TraceHeaders.SPAN_ID, span.getSpanId()) .put(TraceHeaders.SPAN_NAME, span.getSpanName()) .put(TraceHeaders.TRACE_SAMPLED, String.valueOf(span.isSampleable())) .build(); return Pair.of(span, headers); }