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