1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package noop
16
17 import (
18 "context"
19 "reflect"
20 "testing"
21
22 "github.com/stretchr/testify/assert"
23
24 "go.opentelemetry.io/otel/trace"
25 )
26
27 func TestImplementationNoPanics(t *testing.T) {
28
29
30 t.Run("TracerProvider", assertAllExportedMethodNoPanic(
31 reflect.ValueOf(TracerProvider{}),
32 reflect.TypeOf((*trace.TracerProvider)(nil)).Elem(),
33 ))
34 t.Run("Meter", assertAllExportedMethodNoPanic(
35 reflect.ValueOf(Tracer{}),
36 reflect.TypeOf((*trace.Tracer)(nil)).Elem(),
37 ))
38 t.Run("Span", assertAllExportedMethodNoPanic(
39 reflect.ValueOf(Span{}),
40 reflect.TypeOf((*trace.Span)(nil)).Elem(),
41 ))
42 }
43
44 func assertAllExportedMethodNoPanic(rVal reflect.Value, rType reflect.Type) func(*testing.T) {
45 return func(t *testing.T) {
46 for n := 0; n < rType.NumMethod(); n++ {
47 mType := rType.Method(n)
48 if !mType.IsExported() {
49 t.Logf("ignoring unexported %s", mType.Name)
50 continue
51 }
52 m := rVal.MethodByName(mType.Name)
53 if !m.IsValid() {
54 t.Errorf("unknown method for %s: %s", rVal.Type().Name(), mType.Name)
55 }
56
57 numIn := mType.Type.NumIn()
58 if mType.Type.IsVariadic() {
59 numIn--
60 }
61 args := make([]reflect.Value, numIn)
62 ctx := context.Background()
63 for i := range args {
64 aType := mType.Type.In(i)
65 if aType.Name() == "Context" {
66
67 args[i] = reflect.ValueOf(ctx)
68 } else {
69 args[i] = reflect.New(aType).Elem()
70 }
71 }
72
73 assert.NotPanicsf(t, func() {
74 _ = m.Call(args)
75 }, "%s.%s", rVal.Type().Name(), mType.Name)
76 }
77 }
78 }
79
80 func TestNewTracerProvider(t *testing.T) {
81 tp := NewTracerProvider()
82 assert.Equal(t, tp, TracerProvider{})
83 tracer := tp.Tracer("")
84 assert.Equal(t, tracer, Tracer{})
85 }
86
87 func TestTracerStartPropagatesSpanContext(t *testing.T) {
88 tracer := NewTracerProvider().Tracer("")
89 spanCtx := trace.SpanContext{}
90
91 ctx := trace.ContextWithSpanContext(context.Background(), spanCtx)
92 ctx, span := tracer.Start(ctx, "test_span")
93 assert.Equal(t, spanCtx, trace.SpanContextFromContext(ctx), "empty span context not set in context")
94 assert.IsType(t, Span{}, span, "non-noop span returned")
95 assert.Equal(t, spanCtx, span.SpanContext(), "empty span context not returned from span")
96 assert.False(t, span.IsRecording(), "empty span context returned recording span")
97
98 spanCtx = spanCtx.WithTraceID(trace.TraceID([16]byte{1}))
99 spanCtx = spanCtx.WithSpanID(trace.SpanID([8]byte{1}))
100 ctx = trace.ContextWithSpanContext(context.Background(), spanCtx)
101 ctx, span = tracer.Start(ctx, "test_span")
102 assert.Equal(t, spanCtx, trace.SpanContextFromContext(ctx), "non-empty span context not set in context")
103 assert.Equal(t, spanCtx, span.SpanContext(), "non-empty span context not returned from span")
104 assert.False(t, span.IsRecording(), "non-empty span context returned recording span")
105
106 rSpan := recordingSpan{Span: Span{sc: spanCtx}}
107 ctx = trace.ContextWithSpan(context.Background(), rSpan)
108 ctx, span = tracer.Start(ctx, "test_span")
109 assert.Equal(t, spanCtx, trace.SpanContextFromContext(ctx), "recording span's span context not set in context")
110 assert.IsType(t, Span{}, span, "non-noop span returned")
111 assert.Equal(t, spanCtx, span.SpanContext(), "recording span's span context not returned from span")
112 assert.False(t, span.IsRecording(), "recording span returned")
113 }
114
115 type recordingSpan struct{ Span }
116
117 func (recordingSpan) IsRecording() bool { return true }
118
View as plain text