/
mocktracer.go
105 lines (90 loc) · 3.12 KB
/
mocktracer.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
package mocktracer
import (
"sync"
"github.com/opentracing/opentracing-go"
)
// New returns a MockTracer opentracing.Tracer implementation that's intended
// to facilitate tests of OpenTracing instrumentation.
func New() *MockTracer {
t := &MockTracer{
finishedSpans: []*MockSpan{},
injectors: make(map[interface{}]Injector),
extractors: make(map[interface{}]Extractor),
}
// register default injectors/extractors
textPropagator := new(TextMapPropagator)
t.RegisterInjector(opentracing.TextMap, textPropagator)
t.RegisterExtractor(opentracing.TextMap, textPropagator)
httpPropagator := &TextMapPropagator{HTTPHeaders: true}
t.RegisterInjector(opentracing.HTTPHeaders, httpPropagator)
t.RegisterExtractor(opentracing.HTTPHeaders, httpPropagator)
return t
}
// MockTracer is only intended for testing OpenTracing instrumentation.
//
// It is entirely unsuitable for production use, but appropriate for tests
// that want to verify tracing behavior in other frameworks/applications.
type MockTracer struct {
sync.RWMutex
finishedSpans []*MockSpan
injectors map[interface{}]Injector
extractors map[interface{}]Extractor
}
// FinishedSpans returns all spans that have been Finish()'ed since the
// MockTracer was constructed or since the last call to its Reset() method.
func (t *MockTracer) FinishedSpans() []*MockSpan {
t.RLock()
defer t.RUnlock()
spans := make([]*MockSpan, len(t.finishedSpans))
copy(spans, t.finishedSpans)
return spans
}
// Reset clears the internally accumulated finished spans. Note that any
// extant MockSpans will still append to finishedSpans when they Finish(),
// even after a call to Reset().
func (t *MockTracer) Reset() {
t.Lock()
defer t.Unlock()
t.finishedSpans = []*MockSpan{}
}
// StartSpan belongs to the Tracer interface.
func (t *MockTracer) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span {
sso := opentracing.StartSpanOptions{}
for _, o := range opts {
o.Apply(&sso)
}
return newMockSpan(t, operationName, sso)
}
// RegisterInjector registers injector for given format
func (t *MockTracer) RegisterInjector(format interface{}, injector Injector) {
t.injectors[format] = injector
}
// RegisterExtractor registers extractor for given format
func (t *MockTracer) RegisterExtractor(format interface{}, extractor Extractor) {
t.extractors[format] = extractor
}
// Inject belongs to the Tracer interface.
func (t *MockTracer) Inject(sm opentracing.SpanContext, format interface{}, carrier interface{}) error {
spanContext, ok := sm.(MockSpanContext)
if !ok {
return opentracing.ErrInvalidCarrier
}
injector, ok := t.injectors[format]
if !ok {
return opentracing.ErrUnsupportedFormat
}
return injector.Inject(spanContext, carrier)
}
// Extract belongs to the Tracer interface.
func (t *MockTracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) {
extractor, ok := t.extractors[format]
if !ok {
return nil, opentracing.ErrUnsupportedFormat
}
return extractor.Extract(carrier)
}
func (t *MockTracer) recordSpan(span *MockSpan) {
t.Lock()
defer t.Unlock()
t.finishedSpans = append(t.finishedSpans, span)
}