33import static datadog .trace .api .DDTags .SPAN_LINKS ;
44import static datadog .trace .bootstrap .instrumentation .api .AgentSpanLink .DEFAULT_FLAGS ;
55import static datadog .trace .bootstrap .instrumentation .api .AgentSpanLink .SAMPLED_FLAG ;
6+ import static datadog .trace .bootstrap .instrumentation .api .ContextVisitors .stringValuesMap ;
67import static datadog .trace .bootstrap .instrumentation .api .SpanAttributes .EMPTY ;
78import static datadog .trace .core .propagation .HttpCodecTestHelper .TRACE_PARENT_KEY ;
89import static datadog .trace .core .propagation .HttpCodecTestHelper .TRACE_STATE_KEY ;
10+ import static datadog .trace .core .propagation .HttpCodecTestHelper .newW3cHttpCodecExtractor ;
11+ import static java .util .Collections .emptyList ;
12+ import static java .util .stream .Collectors .toList ;
913import static org .junit .jupiter .api .Assertions .assertEquals ;
1014import static org .junit .jupiter .api .Assertions .assertNull ;
1115import static org .junit .jupiter .api .Assertions .assertTrue ;
1216
1317import com .fasterxml .jackson .databind .ObjectMapper ;
18+ import com .fasterxml .jackson .databind .type .CollectionType ;
1419import datadog .trace .api .Config ;
1520import datadog .trace .api .DDSpanId ;
1621import datadog .trace .api .DDTraceId ;
1722import datadog .trace .api .DynamicConfig ;
1823import datadog .trace .bootstrap .instrumentation .api .AgentSpan ;
19- import datadog .trace .bootstrap .instrumentation .api .AgentTracer ;
20- import datadog .trace .bootstrap .instrumentation .api .ContextVisitors ;
24+ import datadog .trace .bootstrap .instrumentation .api .AgentTracer .SpanBuilder ;
2125import datadog .trace .bootstrap .instrumentation .api .SpanAttributes ;
2226import datadog .trace .bootstrap .instrumentation .api .SpanLink ;
2327import datadog .trace .common .writer .ListWriter ;
2428import datadog .trace .core .propagation .ExtractedContext ;
2529import datadog .trace .core .propagation .HttpCodec ;
26- import datadog .trace .core .propagation .HttpCodecTestHelper ;
2730import java .io .IOException ;
2831import java .util .ArrayList ;
2932import java .util .HashMap ;
3033import java .util .List ;
3134import java .util .Map ;
32- import java .util .stream .Collectors ;
3335import java .util .stream .IntStream ;
3436import org .junit .jupiter .api .AfterEach ;
3537import org .junit .jupiter .api .BeforeEach ;
@@ -41,19 +43,21 @@ class DDSpanLinkTest extends DDCoreJavaSpecification {
4143
4244 private static final int SPAN_LINK_TAG_MAX_LENGTH = 25_000 ;
4345 private static final ObjectMapper JSON_MAPPER = new ObjectMapper ();
46+ private static final CollectionType SPAN_LINK_LIST_TYPE =
47+ JSON_MAPPER .getTypeFactory ().constructCollectionType (List .class , SpanLinkAsTag .class );
4448
4549 private ListWriter writer ;
4650 private CoreTracer tracer ;
4751
4852 @ BeforeEach
4953 void setup () {
50- writer = new ListWriter ();
51- tracer = tracerBuilder ().writer (writer ).build ();
54+ this . writer = new ListWriter ();
55+ this . tracer = tracerBuilder ().writer (this . writer ).build ();
5256 }
5357
5458 @ AfterEach
5559 void cleanupTest () {
56- writer .clear ();
60+ this . writer .clear ();
5761 }
5862
5963 @ TableTest ({
@@ -65,15 +69,15 @@ void createSpanLinkFromExtractedContext(boolean sampled, String traceFlags, Stri
6569 String traceId = "11223344556677889900aabbccddeeff" ;
6670 String spanId = "123456789abcdef0" ;
6771 String traceState = "dd=s:" + sample + ";o:some;t.dm:-4" ;
72+
6873 Map <String , String > headers = new HashMap <>();
6974 headers .put (TRACE_PARENT_KEY .toUpperCase (), "00-" + traceId + "-" + spanId + "-" + traceFlags );
7075 headers .put (TRACE_STATE_KEY .toUpperCase (), traceState );
7176 HttpCodec .Extractor extractor =
72- HttpCodecTestHelper . W3CHttpCodecNewExtractor (
77+ newW3cHttpCodecExtractor (
7378 Config .get (), () -> DynamicConfig .create ().apply ().captureTraceConfig ());
7479
75- ExtractedContext context =
76- (ExtractedContext ) extractor .extract (headers , ContextVisitors .stringValuesMap ());
80+ ExtractedContext context = (ExtractedContext ) extractor .extract (headers , stringValuesMap ());
7781 SpanLink link = DDSpanLink .from (context );
7882
7983 assertEquals (DDTraceId .fromHex (traceId ), link .traceId ());
@@ -85,19 +89,18 @@ void createSpanLinkFromExtractedContext(boolean sampled, String traceFlags, Stri
8589 @ Test
8690 void testSpanLinkEncodingTagMaxSize () throws Exception {
8791 int tooManyLinkCount = 300 ;
88- AgentTracer . SpanBuilder builder = tracer .buildSpan ("test" , "operation" );
92+ SpanBuilder builder = tracer .buildSpan ("test" , "operation" );
8993 List <SpanLink > links =
9094 IntStream .range (0 , tooManyLinkCount )
9195 .mapToObj (this ::createLink )
92- .collect (Collectors .toList ());
93-
94- for (SpanLink link : links ) {
95- builder .withLink (link );
96- }
96+ .peek (builder ::withLink )
97+ .collect (toList ());
9798 AgentSpan span = builder .start ();
9899 span .finish ();
99- writer .waitForTraces (1 );
100- String spanLinksTag = (String ) writer .get (0 ).get (0 ).getTag (SPAN_LINKS );
100+ this .writer .waitForTraces (1 );
101+
102+ assertEquals (1 , this .writer .get (0 ).size ());
103+ String spanLinksTag = (String ) this .writer .get (0 ).get (0 ).getTag (SPAN_LINKS );
101104 List <SpanLinkAsTag > decodedSpanLinks = deserializeSpanLinks (spanLinksTag );
102105
103106 assertTrue (spanLinksTag .length () < SPAN_LINK_TAG_MAX_LENGTH );
@@ -112,20 +115,18 @@ void testSpanLinkEncodingTagMaxSize() throws Exception {
112115
113116 @ Test
114117 void testSpanLinksEncodingOmittedEmptyKeys () throws Exception {
115- AgentTracer .SpanBuilder builder = tracer .buildSpan ("test" , "operation" );
116118 SpanLink link =
117119 new DDSpanLink (
118120 DDTraceId .fromHex ("11223344556677889900aabbccddeeff" ),
119121 DDSpanId .fromHex ("123456789abcdef0" ),
120122 DEFAULT_FLAGS ,
121123 "" ,
122124 EMPTY );
125+ this .tracer .buildSpan ("test" , "operation" ).withLink (link ).start ().finish ();
126+ this .writer .waitForTraces (1 );
123127
124- AgentSpan span = builder .withLink (link ).start ();
125- span .finish ();
126- writer .waitForTraces (1 );
128+ assertEquals (1 , this .writer .get (0 ).size ());
127129 String spanLinksTag = (String ) writer .get (0 ).get (0 ).getTag (SPAN_LINKS );
128-
129130 assertEquals (
130131 "[{\" span_id\" :\" 123456789abcdef0\" ,\" trace_id\" :\" 11223344556677889900aabbccddeeff\" }]" ,
131132 spanLinksTag );
@@ -140,7 +141,7 @@ void testSpanLinksEncodingOmittedEmptyKeys() throws Exception {
140141 })
141142 @ ParameterizedTest (name = "add span link at any time [{index}]" )
142143 void addSpanLinkAtAnyTime (boolean beforeStart , boolean afterStart ) throws Exception {
143- AgentTracer . SpanBuilder builder = tracer .buildSpan ("test" , "operation" );
144+ SpanBuilder builder = this . tracer .buildSpan ("test" , "operation" );
144145 List <SpanLink > links = new ArrayList <>();
145146
146147 if (beforeStart ) {
@@ -155,12 +156,11 @@ void addSpanLinkAtAnyTime(boolean beforeStart, boolean afterStart) throws Except
155156 links .add (link );
156157 }
157158 span .finish ();
158- writer .waitForTraces (1 );
159- String spanLinksTag = (String ) writer .get (0 ).get (0 ).getTag (SPAN_LINKS );
160- List <SpanLinkAsTag > decodedSpanLinks =
161- spanLinksTag == null
162- ? java .util .Collections .emptyList ()
163- : deserializeSpanLinks (spanLinksTag );
159+ this .writer .waitForTraces (1 );
160+
161+ assertEquals (1 , this .writer .get (0 ).size ());
162+ String spanLinksTag = (String ) this .writer .get (0 ).get (0 ).getTag (SPAN_LINKS );
163+ List <SpanLinkAsTag > decodedSpanLinks = deserializeSpanLinks (spanLinksTag );
164164
165165 int expectedLinkCount = (beforeStart ? 1 : 0 ) + (afterStart ? 1 : 0 );
166166 assertEquals (expectedLinkCount , decodedSpanLinks .size ());
@@ -171,14 +171,15 @@ void addSpanLinkAtAnyTime(boolean beforeStart, boolean afterStart) throws Except
171171
172172 @ Test
173173 void filterNullLinks () throws Exception {
174- AgentTracer . SpanBuilder builder = tracer .buildSpan ("test" , "operation" );
174+ SpanBuilder builder = this . tracer .buildSpan ("test" , "operation" );
175175
176176 AgentSpan span = builder .withLink (null ).start ();
177177 span .addLink (null );
178178 span .finish ();
179- writer .waitForTraces (1 );
180- String spanLinksTag = (String ) writer .get (0 ).get (0 ).getTag (SPAN_LINKS );
179+ this .writer .waitForTraces (1 );
181180
181+ assertEquals (1 , this .writer .get (0 ).size ());
182+ String spanLinksTag = (String ) this .writer .get (0 ).get (0 ).getTag (SPAN_LINKS );
182183 assertNull (spanLinksTag );
183184 }
184185
@@ -215,9 +216,10 @@ private void assertLink(SpanLink expected, SpanLinkAsTag actual) {
215216 }
216217
217218 static List <SpanLinkAsTag > deserializeSpanLinks (String json ) throws IOException {
218- return JSON_MAPPER .readValue (
219- json ,
220- JSON_MAPPER .getTypeFactory ().constructCollectionType (List .class , SpanLinkAsTag .class ));
219+ if (json == null ) {
220+ return emptyList ();
221+ }
222+ return JSON_MAPPER .readValue (json , SPAN_LINK_LIST_TYPE );
221223 }
222224
223225 static class SpanLinkAsTag {
0 commit comments