-
Notifications
You must be signed in to change notification settings - Fork 48
/
beeline_test.go
145 lines (128 loc) · 4.22 KB
/
beeline_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
139
140
141
142
143
144
145
package beeline
import (
"context"
"fmt"
"testing"
"github.com/honeycombio/libhoney-go/transmission"
libhoney "github.com/honeycombio/libhoney-go"
"github.com/stretchr/testify/assert"
)
// TestNestedSpans tests that if you open and close several spans in the same
// function that fields added after the inner spans have closed are correctly
// added to the outer spans. If you don't keep the context from sending the
// spans or somehow break re-inserting the parent span into the context after
// sending a child span, this test will fail.
func TestNestedSpans(t *testing.T) {
mo := setupLibhoney(t)
ctxroot, spanroot := StartSpan(context.Background(), "start")
AddField(ctxroot, "start_col", 1)
ctxmid, spanmid := StartSpan(ctxroot, "middle")
AddField(ctxmid, "mid_col", 1)
ctxleaf, spanleaf := StartSpan(ctxmid, "leaf")
AddField(ctxleaf, "leaf_col", 1)
spanleaf.Send() // sending leaf span
AddField(ctxmid, "after_mid_col", 1) // adding to middle span
spanmid.Send() // sending middle span
AddField(ctxroot, "end_start_col", 1) // adding to start span
spanroot.Send() // sending start span
events := mo.Events()
assert.Equal(t, 3, len(events), "should have sent 3 events")
var foundStart, foundMiddle bool
for _, ev := range events {
fields := ev.Data
if fields["app.start_col"] == 1 {
foundStart = true
assert.Equal(t, fields["app.end_start_col"], 1, "ending start field should be in start span")
}
if fields["app.mid_col"] == 1 {
foundMiddle = true
assert.Equal(t, fields["app.after_mid_col"], 1, "after middle field should be in middle span")
}
}
assert.True(t, foundStart, "didn't find the start span")
assert.True(t, foundMiddle, "didn't find the middle span")
}
// TestBasicSpanAttributes verifies that creating and sending a span gives it
// all the basic required attributes: duration, trace, span, and parentIDs, and
// name.
func TestBasicSpanAttributes(t *testing.T) {
mo := setupLibhoney(t)
ctx, span := StartSpan(context.Background(), "start")
AddField(ctx, "start_col", 1)
ctxLeaf, spanLeaf := StartSpan(ctx, "leaf")
AddField(ctxLeaf, "leaf_col", 1)
spanLeaf.Send()
span.Send()
events := mo.Events()
assert.Equal(t, 2, len(events), "should have sent 2 events")
var foundRoot bool
for _, ev := range events {
fields := ev.Data
name, ok := fields["name"]
assert.True(t, ok, "failed to find name")
_, ok = fields["duration_ms"]
assert.True(t, ok, "failed to find duration_ms")
_, ok = fields["trace.trace_id"]
assert.True(t, ok, fmt.Sprintf("failed to find trace ID for span %s", name))
_, ok = fields["trace.span_id"]
assert.True(t, ok, fmt.Sprintf("failed to find span ID for span %s", name))
spanType, ok := fields["meta.span_type"]
if ok {
spanTypeStr, ok := spanType.(string)
assert.True(t, ok, "span field meta.span_type should be string")
if spanTypeStr == "root" {
foundRoot = true
}
} else {
// non-root spans should have a parent ID
_, ok = fields["trace.parent_id"]
assert.True(t, ok, fmt.Sprintf("failed to find parent ID for span %s", name))
}
// root span will be missing parent ID
}
assert.True(t, foundRoot, "root span missing")
}
func BenchmarkCreateSpan(b *testing.B) {
setupLibhoney(b)
ctx, _ := StartSpan(context.Background(), "parent")
for n := 0; n < b.N; n++ {
StartSpan(ctx, "child")
}
}
func BenchmarkBeelineAddField(b *testing.B) {
setupLibhoney(b)
ctx, _ := StartSpan(context.Background(), "parent")
b.Run("AddField/no-prefix", func(b *testing.B) {
for n := 0; n < b.N; n++ {
AddField(ctx, "foo", 1)
}
})
b.Run("AddField/half-prefixed", func(b *testing.B) {
for n := 0; n < b.N; n++ {
if n%2 == 0 {
AddField(ctx, "app.foo", 1)
} else {
AddField(ctx, "foo", 1)
}
}
})
b.Run("AddField/all-prefixed", func(b *testing.B) {
for n := 0; n < b.N; n++ {
AddField(ctx, "app.foo", 1)
}
})
}
func setupLibhoney(t testing.TB) *transmission.MockSender {
mo := &transmission.MockSender{}
client, err := libhoney.NewClient(
libhoney.ClientConfig{
APIKey: "placeholder",
Dataset: "placeholder",
APIHost: "placeholder",
Transmission: mo,
},
)
assert.Equal(t, nil, err)
Init(Config{Client: client})
return mo
}