1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package trace_test
16
17 import (
18 "context"
19 "testing"
20
21 "go.opentelemetry.io/otel/attribute"
22 sdktrace "go.opentelemetry.io/otel/sdk/trace"
23 "go.opentelemetry.io/otel/trace"
24 )
25
26 type testSpanProcessor struct {
27 name string
28 spansStarted []sdktrace.ReadWriteSpan
29 spansEnded []sdktrace.ReadOnlySpan
30 shutdownCount int
31 }
32
33 func (t *testSpanProcessor) OnStart(parent context.Context, s sdktrace.ReadWriteSpan) {
34 if t == nil {
35 return
36 }
37 psc := trace.SpanContextFromContext(parent)
38 kv := []attribute.KeyValue{
39 {
40 Key: "SpanProcessorName",
41 Value: attribute.StringValue(t.name),
42 },
43
44
45
46
47 {
48 Key: "ParentTraceID",
49 Value: attribute.StringValue(psc.TraceID().String()),
50 },
51 {
52 Key: "ParentSpanID",
53 Value: attribute.StringValue(psc.SpanID().String()),
54 },
55 }
56 s.AddEvent("OnStart", trace.WithAttributes(kv...))
57 t.spansStarted = append(t.spansStarted, s)
58 }
59
60 func (t *testSpanProcessor) OnEnd(s sdktrace.ReadOnlySpan) {
61 if t == nil {
62 return
63 }
64 t.spansEnded = append(t.spansEnded, s)
65 }
66
67 func (t *testSpanProcessor) Shutdown(_ context.Context) error {
68 if t == nil {
69 return nil
70 }
71 t.shutdownCount++
72 return nil
73 }
74
75 func (t *testSpanProcessor) ForceFlush(context.Context) error {
76 if t == nil {
77 return nil
78 }
79 return nil
80 }
81
82 func TestRegisterSpanProcessor(t *testing.T) {
83 name := "Register span processor before span starts"
84 tp := basicTracerProvider(t)
85 spNames := []string{"sp1", "sp2", "sp3"}
86 sps := NewNamedTestSpanProcessors(spNames)
87
88 for _, sp := range sps {
89 tp.RegisterSpanProcessor(sp)
90 }
91
92 tid, _ := trace.TraceIDFromHex("01020304050607080102040810203040")
93 sid, _ := trace.SpanIDFromHex("0102040810203040")
94 parent := trace.NewSpanContext(trace.SpanContextConfig{
95 TraceID: tid,
96 SpanID: sid,
97 })
98 ctx := trace.ContextWithRemoteSpanContext(context.Background(), parent)
99
100 tr := tp.Tracer("SpanProcessor")
101 _, span := tr.Start(ctx, "OnStart")
102 span.End()
103 wantCount := 1
104
105 for _, sp := range sps {
106 gotCount := len(sp.spansStarted)
107 if gotCount != wantCount {
108 t.Errorf("%s: started count: got %d, want %d\n", name, gotCount, wantCount)
109 }
110 gotCount = len(sp.spansEnded)
111 if gotCount != wantCount {
112 t.Errorf("%s: ended count: got %d, want %d\n", name, gotCount, wantCount)
113 }
114
115 c := 0
116 tidOK := false
117 sidOK := false
118 for _, e := range sp.spansStarted[0].Events() {
119 for _, kv := range e.Attributes {
120 switch kv.Key {
121 case "SpanProcessorName":
122 gotValue := kv.Value.AsString()
123 if gotValue != spNames[c] {
124 t.Errorf("%s: attributes: got %s, want %s\n", name, gotValue, spNames[c])
125 }
126 c++
127 case "ParentTraceID":
128 gotValue := kv.Value.AsString()
129 if gotValue != parent.TraceID().String() {
130 t.Errorf("%s: attributes: got %s, want %s\n", name, gotValue, parent.TraceID())
131 }
132 tidOK = true
133 case "ParentSpanID":
134 gotValue := kv.Value.AsString()
135 if gotValue != parent.SpanID().String() {
136 t.Errorf("%s: attributes: got %s, want %s\n", name, gotValue, parent.SpanID())
137 }
138 sidOK = true
139 default:
140 continue
141 }
142 }
143 }
144 if c != len(spNames) {
145 t.Errorf("%s: expected attributes(SpanProcessorName): got %d, want %d\n", name, c, len(spNames))
146 }
147 if !tidOK {
148 t.Errorf("%s: expected attributes(ParentTraceID)\n", name)
149 }
150 if !sidOK {
151 t.Errorf("%s: expected attributes(ParentSpanID)\n", name)
152 }
153 }
154 }
155
156 func TestUnregisterSpanProcessor(t *testing.T) {
157 name := "Start span after unregistering span processor"
158 tp := basicTracerProvider(t)
159 spNames := []string{"sp1", "sp2", "sp3"}
160 sps := NewNamedTestSpanProcessors(spNames)
161
162 for _, sp := range sps {
163 tp.RegisterSpanProcessor(sp)
164 }
165
166 tr := tp.Tracer("SpanProcessor")
167 _, span := tr.Start(context.Background(), "OnStart")
168 span.End()
169 for _, sp := range sps {
170 tp.UnregisterSpanProcessor(sp)
171 }
172
173
174 _, span = tr.Start(context.Background(), "Start span after unregister")
175 span.End()
176
177 for _, sp := range sps {
178 wantCount := 1
179 gotCount := len(sp.spansStarted)
180 if gotCount != wantCount {
181 t.Errorf("%s: started count: got %d, want %d\n", name, gotCount, wantCount)
182 }
183
184 gotCount = len(sp.spansEnded)
185 if gotCount != wantCount {
186 t.Errorf("%s: ended count: got %d, want %d\n", name, gotCount, wantCount)
187 }
188 }
189 }
190
191 func TestUnregisterSpanProcessorWhileSpanIsActive(t *testing.T) {
192 name := "Unregister span processor while span is active"
193 tp := basicTracerProvider(t)
194 sp := NewTestSpanProcessor("sp")
195 tp.RegisterSpanProcessor(sp)
196
197 tr := tp.Tracer("SpanProcessor")
198 _, span := tr.Start(context.Background(), "OnStart")
199 tp.UnregisterSpanProcessor(sp)
200
201 span.End()
202
203 wantCount := 1
204 gotCount := len(sp.spansStarted)
205 if gotCount != wantCount {
206 t.Errorf("%s: started count: got %d, want %d\n", name, gotCount, wantCount)
207 }
208
209 wantCount = 0
210 gotCount = len(sp.spansEnded)
211 if gotCount != wantCount {
212 t.Errorf("%s: ended count: got %d, want %d\n", name, gotCount, wantCount)
213 }
214 }
215
216 func TestSpanProcessorShutdown(t *testing.T) {
217 name := "Increment shutdown counter of a span processor"
218 tp := basicTracerProvider(t)
219 sp := NewTestSpanProcessor("sp")
220 tp.RegisterSpanProcessor(sp)
221
222 wantCount := 1
223 err := sp.Shutdown(context.Background())
224 if err != nil {
225 t.Error("Error shutting the testSpanProcessor down\n")
226 }
227
228 gotCount := sp.shutdownCount
229 if wantCount != gotCount {
230 t.Errorf("%s: wrong counter: got %d, want %d\n", name, gotCount, wantCount)
231 }
232 }
233
234 func TestMultipleUnregisterSpanProcessorCalls(t *testing.T) {
235 name := "Increment shutdown counter after first UnregisterSpanProcessor call"
236 tp := basicTracerProvider(t)
237 sp := NewTestSpanProcessor("sp")
238
239 wantCount := 1
240
241 tp.RegisterSpanProcessor(sp)
242 tp.UnregisterSpanProcessor(sp)
243
244 gotCount := sp.shutdownCount
245 if wantCount != gotCount {
246 t.Errorf("%s: wrong counter: got %d, want %d\n", name, gotCount, wantCount)
247 }
248
249
250 tp.UnregisterSpanProcessor(sp)
251
252 gotCount = sp.shutdownCount
253 if wantCount != gotCount {
254 t.Errorf("%s: wrong counter: got %d, want %d\n", name, gotCount, wantCount)
255 }
256 }
257
258 func NewTestSpanProcessor(name string) *testSpanProcessor {
259 return &testSpanProcessor{name: name}
260 }
261
262 func NewNamedTestSpanProcessors(names []string) []*testSpanProcessor {
263 tsp := []*testSpanProcessor{}
264 for _, n := range names {
265 tsp = append(tsp, NewTestSpanProcessor(n))
266 }
267 return tsp
268 }
269
View as plain text