@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); }
@Test public void convertSpanToJSON_and_fromJSON_should_escape_and_unescape_expected_non_tag_or_annotation_values() { // The TAGS_AND_ANNOTATIONS_WITH_SPECIAL_CHARS case already verified tags and annotations. Now we need to // verify that non-tag values are escaped. Also note that other tests have verified that escapeJson() // and unescapeJson() work properly. // given String complexSpanName = "span-name-" + ALL_JSON_CHARS_THAT_NEED_ESCAPING; String complexTraceId = "trace-id-" + ALL_JSON_CHARS_THAT_NEED_ESCAPING; String complexParentId = "parent-id-" + ALL_JSON_CHARS_THAT_NEED_ESCAPING; String complexSpanId = "span-id-" + ALL_JSON_CHARS_THAT_NEED_ESCAPING; String complexUserId = "user-id-" + ALL_JSON_CHARS_THAT_NEED_ESCAPING; Span span = Span.newBuilder(complexSpanName, SpanPurpose.CLIENT) .withTraceId(complexTraceId) .withParentSpanId(complexParentId) .withSpanId(complexSpanId) .withUserId(complexUserId) .build(); // when String json = SpanParser.convertSpanToJSON(span); // then assertThat(json).contains("\"traceId\":\"trace-id-" + ESCAPED_JSON_CHARS + "\""); assertThat(json).contains("\"parentSpanId\":\"parent-id-" + ESCAPED_JSON_CHARS + "\""); assertThat(json).contains("\"spanId\":\"span-id-" + ESCAPED_JSON_CHARS + "\""); assertThat(json).contains("\"userId\":\"user-id-" + ESCAPED_JSON_CHARS + "\""); assertThat(json).contains("\"spanName\":\"span-name-" + ESCAPED_JSON_CHARS + "\""); // and when Span deserialized = SpanParser.fromJSON(json); // then verifySpanDeepEquals(deserialized, span, 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 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 fromKeyValueString_delegates_to_span_parser() { // given Span span = Span.newBuilder("foo", SpanPurpose.CLIENT) .withTag("blahtag", UUID.randomUUID().toString()) .build(); String keyValueStr = span.toKeyValueString(); // when Span result = span.fromKeyValueString(keyValueStr); // then verifySpanDeepEquals(result, span, true); }
@Test public void convertSpanToKeyValueFormat_and_fromKeyValueString_escapes_and_unescapes_tag_keys_as_expected() { // given String unescapedTagKey = "fookey=blah withspaceandequals,andcomma"; String tagValue = UUID.randomUUID().toString(); Span span = Span.newBuilder("someSpan", SpanPurpose.CLIENT) .withTag(unescapedTagKey, tagValue) .build(); String expectedEscapedTagKey = "fookey\\u003Dblah\\u0020withspaceandequals\\u002Candcomma"; // when String keyValueStr = SpanParser.convertSpanToKeyValueFormat(span); // then assertThat(keyValueStr).contains("," + SpanParser.KEY_VALUE_TAG_PREFIX + expectedEscapedTagKey + "=\"" + tagValue + "\""); // and when Span deserialized = SpanParser.fromKeyValueString(keyValueStr); // then verifySpanDeepEquals(deserialized, span, true); } }
@Test public void protected_constructor_generates_instance_with_placeholder_values() { // given String placeholderValue = "PLACEHOLDER"; // when Span result = new Span(); // then verifySpanDeepEquals( result, new Span( placeholderValue, null, placeholderValue, placeholderValue, false, null, SpanPurpose.UNKNOWN, -1, -1L, -1L, null, null ), false ); }
@Test public void convertSpanToKeyValueFormat_and_fromKeyValueString_should_escape_and_unescape_expected_non_tag_or_annotation_values() { // The TAGS_AND_ANNOTATIONS_WITH_SPECIAL_CHARS case already verified tags and annotations. Now we need to // verify that non-tag values are escaped. Also note that other tests have verified that escapeJson() // and unescapeJson() work properly. // given String complexSpanName = "span-name-" + ALL_JSON_CHARS_THAT_NEED_ESCAPING; String complexTraceId = "trace-id-" + ALL_JSON_CHARS_THAT_NEED_ESCAPING; String complexParentId = "parent-id-" + ALL_JSON_CHARS_THAT_NEED_ESCAPING; String complexSpanId = "span-id-" + ALL_JSON_CHARS_THAT_NEED_ESCAPING; String complexUserId = "user-id-" + ALL_JSON_CHARS_THAT_NEED_ESCAPING; Span span = Span.newBuilder(complexSpanName, SpanPurpose.CLIENT) .withTraceId(complexTraceId) .withParentSpanId(complexParentId) .withSpanId(complexSpanId) .withUserId(complexUserId) .build(); // when String keyValueStr = SpanParser.convertSpanToKeyValueFormat(span); // then assertThat(keyValueStr).contains("traceId=\"trace-id-" + ESCAPED_JSON_CHARS + "\""); assertThat(keyValueStr).contains("parentSpanId=\"parent-id-" + ESCAPED_JSON_CHARS + "\""); assertThat(keyValueStr).contains("spanId=\"span-id-" + ESCAPED_JSON_CHARS + "\""); assertThat(keyValueStr).contains("userId=\"user-id-" + ESCAPED_JSON_CHARS + "\""); assertThat(keyValueStr).contains("spanName=\"span-name-" + ESCAPED_JSON_CHARS + "\""); // and when Span deserialized = SpanParser.fromKeyValueString(keyValueStr); // then verifySpanDeepEquals(deserialized, span, true); }
@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 fromKeyValueString_should_function_properly_for_completed_spans() { // given: valid span that has been completed, and key/value string from Span.fromKeyValueString() Span validSpan = Span.generateRootSpanForNewTrace(spanName, spanPurpose).build(); completeSpan(validSpan); assertThat(validSpan.isCompleted()).isTrue(); String keyValStr = SpanParser.convertSpanToKeyValueFormat(validSpan); // 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); }
@DataProvider(value = { "SERVER", "CLIENT", "LOCAL_ONLY", "UNKNOWN" }, splitBy = "\\|") @Test public void newBuilder_with_copy_arg_returns_exact_copy(SpanPurpose spanPurpose) { // given Span origSpan = createFilledOutSpan(true); Whitebox.setInternalState(origSpan, "spanPurpose", spanPurpose); assertThat(origSpan.getSpanPurpose()).isEqualTo(spanPurpose); // when Span copySpan = Span.newBuilder(origSpan).build(); // then verifySpanDeepEquals(copySpan, origSpan, false); }
@Test public void fromKeyValueString_should_function_properly_when_there_are_null_values() { // given: valid span with null values and key/value string from Span.fromKeyValueString() Span validSpan = Span.generateRootSpanForNewTrace(spanName, null).build(); assertThat(validSpan.getParentSpanId()).isNull(); assertThat(validSpan.getUserId()).isNull(); assertThat(validSpan.getDurationNanos()).isNull(); String keyValStr = SpanParser.convertSpanToKeyValueFormat(validSpan); // 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); }
@Test public void fromJson_should_function_properly_when_there_are_null_values() { // given: valid span with null values and JSON string from SpanParser.convertSpanToJSON() Span validSpan = Span.generateRootSpanForNewTrace(spanName, null).build(); assertThat(validSpan.getParentSpanId()).isNull(); assertThat(validSpan.getUserId()).isNull(); assertThat(validSpan.getDurationNanos()).isNull(); 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); }
@UseDataProvider("tagAndAnnotationScenarioDataProvider") @Test public void fromJson_should_function_properly_when_there_are_no_null_values(TagAndAnnotationScenario scenario) { // given: valid span without any null values, completed (so that end time is not null) and JSON string // from SpanParser.convertSpanToJSON() Span validSpan = createFilledOutSpan(true, scenario.tags, scenario.annotations); assertThat(validSpan).isNotNull(); assertThat(validSpan.getTraceId()).isNotNull(); assertThat(validSpan.getUserId()).isNotNull(); assertThat(validSpan.getParentSpanId()).isNotNull(); assertThat(validSpan.getSpanName()).isNotNull(); assertThat(validSpan.getSpanId()).isNotNull(); assertThat(validSpan.getDurationNanos()).isNotNull(); assertThat(validSpan.isCompleted()).isTrue(); assertThat(validSpan.getSpanPurpose()).isNotNull(); assertThat(validSpan.getTags()).isEqualTo(scenario.tags); assertThat(validSpan.getTimestampedAnnotations()).isEqualTo(scenario.annotations); 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); }
@UseDataProvider("tagAndAnnotationScenarioDataProvider") @Test public void fromKeyValueString_should_function_properly_when_there_are_no_null_values( TagAndAnnotationScenario scenario) { // given: valid span without any null values, completed (so that end time is not null) and key/value string // from Span.fromKeyValueString() Span validSpan = createFilledOutSpan(true, scenario.tags, scenario.annotations); assertThat(validSpan).isNotNull(); assertThat(validSpan.getTraceId()).isNotNull(); assertThat(validSpan.getUserId()).isNotNull(); assertThat(validSpan.getParentSpanId()).isNotNull(); assertThat(validSpan.getSpanName()).isNotNull(); assertThat(validSpan.getSpanId()).isNotNull(); assertThat(validSpan.getDurationNanos()).isNotNull(); assertThat(validSpan.isCompleted()).isTrue(); assertThat(validSpan.getSpanPurpose()).isNotNull(); assertThat(validSpan.getTags()).isNotNull(); assertThat(validSpan.getTags()).isEqualTo(scenario.tags); assertThat(validSpan.getTimestampedAnnotations()).isEqualTo(scenario.annotations); String keyValStr = SpanParser.convertSpanToKeyValueFormat(validSpan); // 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); }