...
1 package context
2
3 import (
4 "context"
5 "runtime"
6 "testing"
7 "time"
8 )
9
10
11 func TestWithTrace(t *testing.T) {
12 pc, file, _, _ := runtime.Caller(0)
13 f := runtime.FuncForPC(pc)
14
15 base := []valueTestCase{
16 {
17 key: "trace.id",
18 notnilorempty: true,
19 },
20
21 {
22 key: "trace.file",
23 expected: file,
24 notnilorempty: true,
25 },
26 {
27 key: "trace.line",
28 notnilorempty: true,
29 },
30 {
31 key: "trace.start",
32 notnilorempty: true,
33 },
34 }
35
36 ctx, done := WithTrace(Background())
37 defer done("this will be emitted at end of test")
38
39 checkContextForValues(ctx, t, append(base, valueTestCase{
40 key: "trace.func",
41 expected: f.Name(),
42 }))
43
44 traced := func() {
45 parentID := ctx.Value("trace.id")
46
47 pc, _, _, _ := runtime.Caller(0)
48 f := runtime.FuncForPC(pc)
49 ctx, done := WithTrace(ctx)
50 defer done("this should be subordinate to the other trace")
51 time.Sleep(time.Second)
52 checkContextForValues(ctx, t, append(base, valueTestCase{
53 key: "trace.func",
54 expected: f.Name(),
55 }, valueTestCase{
56 key: "trace.parent.id",
57 expected: parentID,
58 }))
59 }
60 traced()
61
62 time.Sleep(time.Second)
63 }
64
65 type valueTestCase struct {
66 key string
67 expected interface{}
68 notnilorempty bool
69 }
70
71 func checkContextForValues(ctx context.Context, t *testing.T, values []valueTestCase) {
72 for _, testcase := range values {
73 v := ctx.Value(testcase.key)
74 if testcase.notnilorempty {
75 if v == nil || v == "" {
76 t.Fatalf("value was nil or empty for %q: %#v", testcase.key, v)
77 }
78 continue
79 }
80
81 if v != testcase.expected {
82 t.Fatalf("unexpected value for key %q: %v != %v", testcase.key, v, testcase.expected)
83 }
84 }
85 }
86
View as plain text