@@ -19,6 +19,7 @@ import (
1919 "github.com/stretchr/testify/require"
2020 "go.opentelemetry.io/otel/attribute"
2121 "go.opentelemetry.io/otel/codes"
22+ "go.opentelemetry.io/otel/propagation"
2223 tracesdk "go.opentelemetry.io/otel/sdk/trace"
2324 "go.opentelemetry.io/otel/trace"
2425 "go.opentelemetry.io/otel/trace/embedded"
@@ -42,6 +43,10 @@ func TestNewTracingProvider(t *testing.T) {
4243 emptySpan := client .Tracer ().SpanFromContext (context .Background ())
4344 emptySpan .AddEvent ("noop_event" )
4445
46+ // returns an empty link as there is no span yet
47+ emptyLink := client .Tracer ().LinkFromContext (context .Background ())
48+ require .Empty (t , emptyLink )
49+
4550 ctx , endSpan := azruntime .StartSpan (context .Background (), "test_span" , client .Tracer (), nil )
4651
4752 req , err := azruntime .NewRequest (ctx , http .MethodGet , "https://www.microsoft.com/" )
@@ -50,6 +55,9 @@ func TestNewTracingProvider(t *testing.T) {
5055 startedSpan := client .Tracer ().SpanFromContext (req .Raw ().Context ())
5156 startedSpan .AddEvent ("post_event" )
5257
58+ startedSpanLink := client .Tracer ().LinkFromContext (req .Raw ().Context ())
59+ require .NotEmpty (t , startedSpanLink )
60+
5361 _ , err = client .Pipeline ().Do (req )
5462 require .NoError (t , err )
5563
@@ -61,6 +69,34 @@ func TestNewTracingProvider(t *testing.T) {
6169 require .Len (t , exporter .spans , 2 )
6270}
6371
72+ func TestPropagator (t * testing.T ) {
73+ provider := NewTracingProvider (tracesdk .NewTracerProvider (), nil )
74+ tracer := provider .NewTracer ("test" , "1.0" )
75+ propagator := provider .NewPropagator ()
76+ require .EqualValues (t , 2 , len (propagator .Fields ()))
77+
78+ mapCarrier := propagation.MapCarrier {}
79+ carrier := tracing .NewCarrier (tracing.CarrierImpl {
80+ Get : mapCarrier .Get ,
81+ Set : mapCarrier .Set ,
82+ Keys : mapCarrier .Keys ,
83+ })
84+
85+ ctx , endSpan := azruntime .StartSpan (context .Background (), "test_span" , tracer , nil )
86+ spanContext := tracer .SpanFromContext (ctx ).SpanContext ()
87+ require .NotNil (t , spanContext )
88+ require .False (t , spanContext .IsRemote ())
89+ propagator .Inject (ctx , carrier )
90+ endSpan (nil )
91+
92+ extractedCtx := propagator .Extract (context .Background (), carrier )
93+ extractedSpanContext := tracer .SpanFromContext (extractedCtx ).SpanContext ()
94+ require .NotNil (t , extractedSpanContext )
95+ require .True (t , extractedSpanContext .IsRemote ())
96+ require .EqualValues (t , spanContext .TraceID (), extractedSpanContext .TraceID ())
97+ require .EqualValues (t , spanContext .SpanID (), extractedSpanContext .SpanID ())
98+ }
99+
64100func TestConvertSpan (t * testing.T ) {
65101 ts := testSpan {t : t }
66102 span := convertSpan (& ts )
@@ -84,6 +120,9 @@ func TestConvertSpan(t *testing.T) {
84120 span .SetAttributes (attr )
85121 require .Len (t , ts .attributes , 1 )
86122
123+ span .AddLink (tracing.Link {})
124+ require .Len (t , ts .links , 1 )
125+
87126 const statusDesc = "everything is ok"
88127 span .SetStatus (tracing .SpanStatusOK , statusDesc )
89128 assert .EqualValues (t , tracing .SpanStatusOK , ts .statusCode )
@@ -169,6 +208,65 @@ func TestConvertAttributes(t *testing.T) {
169208 }
170209}
171210
211+ func TestConvertLinks (t * testing.T ) {
212+ attr := tracing.Attribute {
213+ Key : "key" ,
214+ Value : "value" ,
215+ }
216+ spanContext := tracing .NewSpanContext (tracing.SpanContextConfig {
217+ TraceID : tracing.TraceID {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 },
218+ SpanID : tracing.SpanID {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 },
219+ TraceFlags : tracing .TraceFlags (0x1 ),
220+ TraceState : "key1=val1,key2=val2" ,
221+ Remote : true ,
222+ })
223+
224+ links := convertLinks ([]tracing.Link {
225+ {
226+ SpanContext : spanContext ,
227+ },
228+ {
229+ Attributes : []tracing.Attribute {attr },
230+ },
231+ {
232+ SpanContext : spanContext ,
233+ Attributes : []tracing.Attribute {attr },
234+ },
235+ })
236+ require .Len (t , links , 3 )
237+ require .NotNil (t , links [0 ].SpanContext )
238+ require .True (t , links [0 ].SpanContext .IsRemote ())
239+ require .Len (t , links [0 ].Attributes , 0 )
240+
241+ require .NotNil (t , links [1 ].SpanContext )
242+ require .False (t , links [1 ].SpanContext .IsRemote ())
243+ require .Len (t , links [1 ].Attributes , 1 )
244+
245+ require .NotNil (t , links [2 ].SpanContext )
246+ require .True (t , links [2 ].SpanContext .IsRemote ())
247+ require .Len (t , links [2 ].Attributes , 1 )
248+ }
249+
250+ func TestConvertSpanContext (t * testing.T ) {
251+ traceID := tracing.TraceID {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 }
252+ spanID := tracing.SpanID {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 }
253+ traceFlags := tracing .TraceFlags (0x1 )
254+ spanContext := tracing .NewSpanContext (tracing.SpanContextConfig {
255+ TraceID : traceID ,
256+ SpanID : spanID ,
257+ TraceFlags : traceFlags ,
258+ TraceState : "key1=val1,key2=val2" ,
259+ Remote : true ,
260+ })
261+
262+ otelSpanContext := convertSpanContext (spanContext )
263+ assert .EqualValues (t , traceID , otelSpanContext .TraceID ())
264+ assert .EqualValues (t , spanID , otelSpanContext .SpanID ())
265+ assert .EqualValues (t , traceFlags , otelSpanContext .TraceFlags ())
266+ assert .EqualValues (t , "key1=val1,key2=val2" , otelSpanContext .TraceState ().String ())
267+ assert .True (t , otelSpanContext .IsRemote ())
268+ }
269+
172270func TestConvertSpanKind (t * testing.T ) {
173271 assert .EqualValues (t , trace .SpanKindClient , convertSpanKind (tracing .SpanKindClient ))
174272 assert .EqualValues (t , trace .SpanKindConsumer , convertSpanKind (tracing .SpanKindConsumer ))
@@ -185,6 +283,22 @@ func TestConvertStatus(t *testing.T) {
185283 assert .EqualValues (t , codes .Unset , convertStatus (tracing .SpanStatus (12345 )))
186284}
187285
286+ func TestConvertPropagator (t * testing.T ) {
287+ carrier := tracing .NewCarrier (tracing.CarrierImpl {
288+ Get : func (key string ) string { return "" },
289+ Set : func (key , value string ) {},
290+ Keys : func () []string { return nil },
291+ })
292+ propagator := & testPropagator {}
293+ otelPropagator := convertPropagator (propagator )
294+ require .NotNil (t , otelPropagator )
295+ otelPropagator .Inject (context .Background (), carrier )
296+ otelPropagator .Extract (context .Background (), carrier )
297+ require .True (t , propagator .injectCalled )
298+ require .True (t , propagator .extractCalled )
299+ require .Len (t , propagator .Fields (), 1 )
300+ }
301+
188302type testExporter struct {
189303 spans []string
190304}
@@ -207,12 +321,12 @@ type testSpan struct {
207321
208322 t * testing.T
209323 attributes []attribute.KeyValue
324+ links []trace.Link
210325 eventName string
211326 eventOptions []trace.EventOption
212327 endCalled bool
213328 statusCode codes.Code
214329 statusDesc string
215- link trace.Link
216330}
217331
218332func (ts * testSpan ) End (options ... trace.SpanEndOption ) {
@@ -224,10 +338,6 @@ func (ts *testSpan) AddEvent(name string, options ...trace.EventOption) {
224338 ts .eventOptions = options
225339}
226340
227- func (ts * testSpan ) AddLink (link trace.Link ) {
228- ts .link = link
229- }
230-
231341func (ts * testSpan ) IsRecording () bool {
232342 ts .t .Fatal ("IsRecording not required" )
233343 return false
@@ -255,7 +365,29 @@ func (ts *testSpan) SetAttributes(kv ...attribute.KeyValue) {
255365 ts .attributes = kv
256366}
257367
368+ func (ts * testSpan ) AddLink (link trace.Link ) {
369+ ts .links = append (ts .links , link )
370+ }
371+
258372func (ts * testSpan ) TracerProvider () trace.TracerProvider {
259373 ts .t .Fatal ("TracerProvider not required" )
260374 return nil
261375}
376+
377+ type testPropagator struct {
378+ injectCalled bool
379+ extractCalled bool
380+ }
381+
382+ func (tp * testPropagator ) Inject (ctx context.Context , carrier propagation.TextMapCarrier ) {
383+ tp .injectCalled = true
384+ }
385+
386+ func (tp * testPropagator ) Extract (ctx context.Context , carrier propagation.TextMapCarrier ) context.Context {
387+ tp .extractCalled = true
388+ return ctx
389+ }
390+
391+ func (tp * testPropagator ) Fields () []string {
392+ return []string {"testfield" }
393+ }
0 commit comments