1
2
3
4
5 package pprof
6
7 import (
8 "context"
9 "fmt"
10 "reflect"
11 "slices"
12 "strings"
13 "testing"
14 )
15
16 func labelsSorted(ctx context.Context) []label {
17 ls := []label{}
18 ForLabels(ctx, func(key, value string) bool {
19 ls = append(ls, label{key, value})
20 return true
21 })
22 slices.SortFunc(ls, func(a, b label) int { return strings.Compare(a.key, b.key) })
23 return ls
24 }
25
26 func TestContextLabels(t *testing.T) {
27
28 ctx := context.Background()
29 labels := labelsSorted(ctx)
30 if len(labels) != 0 {
31 t.Errorf("labels on background context: want [], got %v ", labels)
32 }
33
34
35 ctx = WithLabels(ctx, Labels("key", "value"))
36
37 v, ok := Label(ctx, "key")
38 if !ok || v != "value" {
39 t.Errorf(`Label(ctx, "key"): got %v, %v; want "value", ok`, v, ok)
40 }
41 gotLabels := labelsSorted(ctx)
42 wantLabels := []label{{"key", "value"}}
43 if !reflect.DeepEqual(gotLabels, wantLabels) {
44 t.Errorf("(sorted) labels on context: got %v, want %v", gotLabels, wantLabels)
45 }
46
47
48 ctx = WithLabels(ctx, Labels("key2", "value2"))
49 v, ok = Label(ctx, "key2")
50 if !ok || v != "value2" {
51 t.Errorf(`Label(ctx, "key2"): got %v, %v; want "value2", ok`, v, ok)
52 }
53 gotLabels = labelsSorted(ctx)
54 wantLabels = []label{{"key", "value"}, {"key2", "value2"}}
55 if !reflect.DeepEqual(gotLabels, wantLabels) {
56 t.Errorf("(sorted) labels on context: got %v, want %v", gotLabels, wantLabels)
57 }
58
59
60 ctx = WithLabels(ctx, Labels("key", "value3"))
61 v, ok = Label(ctx, "key")
62 if !ok || v != "value3" {
63 t.Errorf(`Label(ctx, "key3"): got %v, %v; want "value3", ok`, v, ok)
64 }
65 gotLabels = labelsSorted(ctx)
66 wantLabels = []label{{"key", "value3"}, {"key2", "value2"}}
67 if !reflect.DeepEqual(gotLabels, wantLabels) {
68 t.Errorf("(sorted) labels on context: got %v, want %v", gotLabels, wantLabels)
69 }
70
71
72 ctx = WithLabels(ctx, Labels("key4", "value4a", "key4", "value4b"))
73 v, ok = Label(ctx, "key4")
74 if !ok || v != "value4b" {
75 t.Errorf(`Label(ctx, "key4"): got %v, %v; want "value4b", ok`, v, ok)
76 }
77 gotLabels = labelsSorted(ctx)
78 wantLabels = []label{{"key", "value3"}, {"key2", "value2"}, {"key4", "value4b"}}
79 if !reflect.DeepEqual(gotLabels, wantLabels) {
80 t.Errorf("(sorted) labels on context: got %v, want %v", gotLabels, wantLabels)
81 }
82 }
83
84 func TestLabelMapStringer(t *testing.T) {
85 for _, tbl := range []struct {
86 m labelMap
87 expected string
88 }{
89 {
90 m: labelMap{
91
92 },
93 expected: "{}",
94 }, {
95 m: labelMap{
96 Labels("foo", "bar"),
97 },
98 expected: `{"foo":"bar"}`,
99 }, {
100 m: labelMap{
101 Labels(
102 "foo", "bar",
103 "key1", "value1",
104 "key2", "value2",
105 "key3", "value3",
106 "key4WithNewline", "\nvalue4",
107 ),
108 },
109 expected: `{"foo":"bar", "key1":"value1", "key2":"value2", "key3":"value3", "key4WithNewline":"\nvalue4"}`,
110 },
111 } {
112 if got := tbl.m.String(); tbl.expected != got {
113 t.Errorf("%#v.String() = %q; want %q", tbl.m, got, tbl.expected)
114 }
115 }
116 }
117
118 func BenchmarkLabels(b *testing.B) {
119 b.Run("set-one", func(b *testing.B) {
120 b.ReportAllocs()
121 b.ResetTimer()
122 for i := 0; i < b.N; i++ {
123 Do(context.Background(), Labels("key", "value"), func(context.Context) {})
124 }
125 })
126
127 b.Run("merge-one", func(b *testing.B) {
128 ctx := WithLabels(context.Background(), Labels("key1", "val1"))
129
130 b.ReportAllocs()
131 b.ResetTimer()
132 for i := 0; i < b.N; i++ {
133 Do(ctx, Labels("key2", "value2"), func(context.Context) {})
134 }
135 })
136
137 b.Run("overwrite-one", func(b *testing.B) {
138 ctx := WithLabels(context.Background(), Labels("key", "val"))
139
140 b.ReportAllocs()
141 b.ResetTimer()
142 for i := 0; i < b.N; i++ {
143 Do(ctx, Labels("key", "value"), func(context.Context) {})
144 }
145 })
146
147 for _, scenario := range []string{"ordered", "unordered"} {
148 var labels []string
149 for i := 0; i < 10; i++ {
150 labels = append(labels, fmt.Sprintf("key%03d", i), fmt.Sprintf("value%03d", i))
151 }
152 if scenario == "unordered" {
153 labels[0], labels[len(labels)-1] = labels[len(labels)-1], labels[0]
154 }
155
156 b.Run(scenario, func(b *testing.B) {
157 b.Run("set-many", func(b *testing.B) {
158 b.ReportAllocs()
159 b.ResetTimer()
160 for i := 0; i < b.N; i++ {
161 Do(context.Background(), Labels(labels...), func(context.Context) {})
162 }
163 })
164
165 b.Run("merge-many", func(b *testing.B) {
166 ctx := WithLabels(context.Background(), Labels(labels[:len(labels)/2]...))
167
168 b.ResetTimer()
169 b.ReportAllocs()
170 for i := 0; i < b.N; i++ {
171 Do(ctx, Labels(labels[len(labels)/2:]...), func(context.Context) {})
172 }
173 })
174
175 b.Run("overwrite-many", func(b *testing.B) {
176 ctx := WithLabels(context.Background(), Labels(labels...))
177
178 b.ReportAllocs()
179 b.ResetTimer()
180 for i := 0; i < b.N; i++ {
181 Do(ctx, Labels(labels...), func(context.Context) {})
182 }
183 })
184 })
185 }
186
187
188 }
189
View as plain text