forked from opentracing/opentracing-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
testtracer_test.go
138 lines (120 loc) · 3.8 KB
/
testtracer_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package opentracing
import (
"strconv"
"strings"
"time"
"github.com/opentracing/opentracing-go/log"
)
const testHTTPHeaderPrefix = "testprefix-"
// testTracer is a most-noop Tracer implementation that makes it possible for
// unittests to verify whether certain methods were / were not called.
type testTracer struct{}
var fakeIDSource = 1
func nextFakeID() int {
fakeIDSource++
return fakeIDSource
}
type testSpanContext struct {
HasParent bool
FakeID int
}
func (n testSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {}
type testSpan struct {
spanContext testSpanContext
OperationName string
StartTime time.Time
Tags map[string]interface{}
}
func (n testSpan) Equal(os Span) bool {
other, ok := os.(testSpan)
if !ok {
return false
}
if n.spanContext != other.spanContext {
return false
}
if n.OperationName != other.OperationName {
return false
}
if !n.StartTime.Equal(other.StartTime) {
return false
}
if len(n.Tags) != len(other.Tags) {
return false
}
for k, v := range n.Tags {
if ov, ok := other.Tags[k]; !ok || ov != v {
return false
}
}
return true
}
// testSpan:
func (n testSpan) Context() SpanContext { return n.spanContext }
func (n testSpan) SetTag(key string, value interface{}) Span { return n }
func (n testSpan) Finish() {}
func (n testSpan) FinishWithOptions(opts FinishOptions) {}
func (n testSpan) LogFields(fields ...log.Field) {}
func (n testSpan) LogKV(kvs ...interface{}) {}
func (n testSpan) SetOperationName(operationName string) Span { return n }
func (n testSpan) Tracer() Tracer { return testTracer{} }
func (n testSpan) SetBaggageItem(key, val string) Span { return n }
func (n testSpan) BaggageItem(key string) string { return "" }
func (n testSpan) LogEvent(event string) {}
func (n testSpan) LogEventWithPayload(event string, payload interface{}) {}
func (n testSpan) Log(data LogData) {}
// StartSpan belongs to the Tracer interface.
func (n testTracer) StartSpan(operationName string, opts ...StartSpanOption) Span {
sso := StartSpanOptions{}
for _, o := range opts {
o.Apply(&sso)
}
return n.startSpanWithOptions(operationName, sso)
}
func (n testTracer) startSpanWithOptions(name string, opts StartSpanOptions) Span {
fakeID := nextFakeID()
if len(opts.References) > 0 {
fakeID = opts.References[0].ReferencedContext.(testSpanContext).FakeID
}
return testSpan{
OperationName: name,
StartTime: opts.StartTime,
Tags: opts.Tags,
spanContext: testSpanContext{
HasParent: len(opts.References) > 0,
FakeID: fakeID,
},
}
}
// Inject belongs to the Tracer interface.
func (n testTracer) Inject(sp SpanContext, format interface{}, carrier interface{}) error {
spanContext := sp.(testSpanContext)
switch format {
case HTTPHeaders, TextMap:
carrier.(TextMapWriter).Set(testHTTPHeaderPrefix+"fakeid", strconv.Itoa(spanContext.FakeID))
return nil
}
return ErrUnsupportedFormat
}
// Extract belongs to the Tracer interface.
func (n testTracer) Extract(format interface{}, carrier interface{}) (SpanContext, error) {
switch format {
case HTTPHeaders, TextMap:
// Just for testing purposes... generally not a worthwhile thing to
// propagate.
sm := testSpanContext{}
err := carrier.(TextMapReader).ForeachKey(func(key, val string) error {
switch strings.ToLower(key) {
case testHTTPHeaderPrefix + "fakeid":
i, err := strconv.Atoi(val)
if err != nil {
return err
}
sm.FakeID = i
}
return nil
})
return sm, err
}
return nil, ErrSpanContextNotFound
}