1 package runmetrics_test
2
3 import (
4 "context"
5 "testing"
6
7 "github.com/stretchr/testify/assert"
8
9 "go.opencensus.io/metric/metricdata"
10 "go.opencensus.io/metric/metricexport"
11 "go.opencensus.io/metric/metricproducer"
12 "go.opencensus.io/plugin/runmetrics"
13 )
14
15 type testExporter struct {
16 data []*metricdata.Metric
17 }
18
19 func (t *testExporter) ExportMetrics(ctx context.Context, data []*metricdata.Metric) error {
20 t.data = append(t.data, data...)
21 return nil
22 }
23
24 func TestEnable(t *testing.T) {
25 tests := []struct {
26 name string
27 options runmetrics.RunMetricOptions
28 wantMetricNames [][]string
29 dontWantMetricNames [][]string
30 }{
31 {
32 "no stats",
33 runmetrics.RunMetricOptions{
34 EnableCPU: false,
35 EnableMemory: false,
36 },
37 [][]string{},
38 [][]string{},
39 },
40 {
41 "cpu and memory stats",
42 runmetrics.RunMetricOptions{
43 EnableCPU: true,
44 EnableMemory: true,
45 },
46 [][]string{
47 {"process/memory_alloc", "process/total_memory_alloc", "process/sys_memory_alloc", "process/memory_lookups", "process/memory_malloc", "process/memory_frees"},
48 {"process/heap_alloc", "process/sys_heap", "process/heap_idle", "process/heap_inuse", "process/heap_objects", "process/heap_release"},
49 {"process/stack_inuse", "process/sys_stack", "process/stack_mspan_inuse", "process/sys_stack_mspan", "process/stack_mcache_inuse", "process/sys_stack_mcache"},
50 {"process/gc_sys", "process/other_sys", "process/num_gc", "process/num_forced_gc", "process/next_gc_heap_size", "process/last_gc_finished_timestamp", "process/pause_total", "process/gc_cpu_fraction"},
51 {"process/cpu_goroutines", "process/cpu_cgo_calls"},
52 },
53 [][]string{},
54 },
55 {
56 "cpu and deprecated memory stats",
57 runmetrics.RunMetricOptions{
58 EnableCPU: true,
59 EnableMemory: true,
60 },
61 [][]string{
62 {"process/memory_alloc", "process/total_memory_alloc", "process/sys_memory_alloc", "process/memory_lookups", "process/memory_malloc", "process/memory_frees"},
63 {"process/heap_alloc", "process/sys_heap", "process/heap_idle", "process/heap_inuse", "process/heap_objects", "process/heap_release"},
64 {"process/stack_inuse", "process/sys_stack", "process/stack_mspan_inuse", "process/sys_stack_mspan", "process/stack_mcache_inuse", "process/sys_stack_mcache"},
65 {"process/gc_sys", "process/other_sys", "process/num_gc", "process/num_forced_gc", "process/next_gc_heap_size", "process/last_gc_finished_timestamp", "process/pause_total", "process/gc_cpu_fraction"},
66 {"process/cpu_goroutines", "process/cpu_cgo_calls"},
67 },
68 [][]string{},
69 },
70 {
71 "only cpu stats",
72 runmetrics.RunMetricOptions{
73 EnableCPU: true,
74 EnableMemory: false,
75 },
76 [][]string{
77 {"process/cpu_goroutines", "process/cpu_cgo_calls"},
78 },
79 [][]string{
80 {"process/memory_alloc", "process/total_memory_alloc", "process/sys_memory_alloc", "process/memory_lookups", "process/memory_malloc", "process/memory_frees"},
81 {"process/heap_alloc", "process/sys_heap", "process/heap_idle", "process/heap_inuse", "process/heap_objects", "process/heap_release"},
82 {"process/stack_inuse", "process/sys_stack", "process/stack_mspan_inuse", "process/sys_stack_mspan", "process/stack_mcache_inuse", "process/sys_stack_mcache"},
83 {"process/gc_sys", "process/other_sys", "process/num_gc", "process/num_forced_gc", "process/next_gc_heap_size", "process/last_gc_finished_timestamp", "process/pause_total", "process/gc_cpu_fraction"},
84 },
85 },
86 {
87 "only memory stats",
88 runmetrics.RunMetricOptions{
89 EnableCPU: false,
90 EnableMemory: true,
91 },
92 [][]string{
93 {"process/memory_alloc", "process/total_memory_alloc", "process/sys_memory_alloc", "process/memory_lookups", "process/memory_malloc", "process/memory_frees"},
94 {"process/heap_alloc", "process/sys_heap", "process/heap_idle", "process/heap_inuse", "process/heap_objects", "process/heap_release"},
95 {"process/stack_inuse", "process/sys_stack", "process/stack_mspan_inuse", "process/sys_stack_mspan", "process/stack_mcache_inuse", "process/sys_stack_mcache"},
96 {"process/gc_sys", "process/other_sys", "process/num_gc", "process/num_forced_gc", "process/next_gc_heap_size", "process/last_gc_finished_timestamp", "process/pause_total", "process/gc_cpu_fraction"},
97 },
98 [][]string{
99 {"process/cpu_goroutines", "process/cpu_cgo_calls"},
100 },
101 },
102 {
103 "only deprecated memory stats",
104 runmetrics.RunMetricOptions{
105 EnableCPU: false,
106 EnableMemory: true,
107 UseDerivedCumulative: true,
108 },
109 [][]string{
110 {"process/memory_alloc", "process/total_memory_alloc", "process/sys_memory_alloc", "process/memory_lookups", "process/memory_malloc", "process/memory_frees"},
111 {"process/heap_alloc", "process/sys_heap", "process/heap_idle", "process/heap_inuse", "process/heap_objects", "process/heap_release"},
112 {"process/stack_inuse", "process/sys_stack", "process/stack_mspan_inuse", "process/sys_stack_mspan", "process/stack_mcache_inuse", "process/sys_stack_mcache"},
113 {"process/gc_sys", "process/other_sys", "process/num_gc", "process/num_forced_gc", "process/next_gc_heap_size", "process/last_gc_finished_timestamp", "process/pause_total", "process/gc_cpu_fraction"},
114 },
115 [][]string{
116 {"process/cpu_goroutines", "process/cpu_cgo_calls"},
117 },
118 },
119 {
120 "cpu and deprecated memory stats with custom prefix",
121 runmetrics.RunMetricOptions{
122 EnableCPU: true,
123 EnableMemory: true,
124 UseDerivedCumulative: true,
125 Prefix: "test_",
126 },
127 [][]string{
128 {"test_process/memory_alloc", "test_process/total_memory_alloc", "test_process/sys_memory_alloc", "test_process/memory_lookups", "test_process/memory_malloc", "test_process/memory_frees"},
129 {"test_process/heap_alloc", "test_process/sys_heap", "test_process/heap_idle", "test_process/heap_inuse", "test_process/heap_objects", "test_process/heap_release"},
130 {"test_process/stack_inuse", "test_process/sys_stack", "test_process/stack_mspan_inuse", "test_process/sys_stack_mspan", "test_process/stack_mcache_inuse", "test_process/sys_stack_mcache"},
131 {"test_process/gc_sys", "test_process/other_sys", "test_process/num_gc", "test_process/num_forced_gc", "test_process/next_gc_heap_size", "test_process/last_gc_finished_timestamp", "test_process/pause_total", "test_process/gc_cpu_fraction"},
132 {"test_process/cpu_goroutines", "test_process/cpu_cgo_calls"},
133 },
134 [][]string{},
135 },
136 {
137 "cpu and memory stats with custom prefix",
138 runmetrics.RunMetricOptions{
139 EnableCPU: true,
140 EnableMemory: true,
141 Prefix: "test_",
142 },
143 [][]string{
144 {"test_process/memory_alloc", "test_process/total_memory_alloc", "test_process/sys_memory_alloc", "test_process/memory_lookups", "test_process/memory_malloc", "test_process/memory_frees"},
145 {"test_process/heap_alloc", "test_process/sys_heap", "test_process/heap_idle", "test_process/heap_inuse", "test_process/heap_objects", "test_process/heap_release"},
146 {"test_process/stack_inuse", "test_process/sys_stack", "test_process/stack_mspan_inuse", "test_process/sys_stack_mspan", "test_process/stack_mcache_inuse", "test_process/sys_stack_mcache"},
147 {"test_process/gc_sys", "test_process/other_sys", "test_process/num_gc", "test_process/num_forced_gc", "test_process/next_gc_heap_size", "test_process/last_gc_finished_timestamp", "test_process/pause_total", "test_process/gc_cpu_fraction"},
148 {"test_process/cpu_goroutines", "test_process/cpu_cgo_calls"},
149 },
150 [][]string{},
151 },
152 }
153
154 for _, test := range tests {
155 t.Run(test.name, func(t *testing.T) {
156
157 err := runmetrics.Enable(test.options)
158
159 if err != nil {
160 t.Errorf("want: nil, got: %v", err)
161 }
162
163 defer runmetrics.Disable()
164
165 exporter := &testExporter{}
166 reader := metricexport.NewReader()
167 reader.ReadAndExport(exporter)
168
169 for _, want := range test.wantMetricNames {
170 assertNames(t, true, exporter, want)
171 }
172
173 for _, dontWant := range test.dontWantMetricNames {
174 assertNames(t, false, exporter, dontWant)
175 }
176 })
177 }
178 }
179
180 func assertNames(t *testing.T, wantIncluded bool, exporter *testExporter, expectedNames []string) {
181 t.Helper()
182
183 metricNames := make([]string, 0)
184 for _, v := range exporter.data {
185 metricNames = append(metricNames, v.Descriptor.Name)
186 }
187
188 for _, want := range expectedNames {
189 if wantIncluded {
190 assert.Contains(t, metricNames, want)
191 } else {
192 assert.NotContains(t, metricNames, want)
193 }
194 }
195 }
196
197 func TestEnable_RegistersWithGlobalManager(t *testing.T) {
198 err := runmetrics.Enable(runmetrics.RunMetricOptions{})
199 if err != nil {
200 t.Errorf("want: nil, got: %v", err)
201 }
202
203 registeredCount := len(metricproducer.GlobalManager().GetAll())
204 assert.Equal(t, 1, registeredCount, "expected a producer to be registered")
205 }
206
207 func TestEnable_RegistersNoDuplicates(t *testing.T) {
208 err := runmetrics.Enable(runmetrics.RunMetricOptions{})
209 if err != nil {
210 t.Errorf("want: nil, got: %v", err)
211 }
212
213 err = runmetrics.Enable(runmetrics.RunMetricOptions{})
214 if err != nil {
215 t.Errorf("want: nil, got: %v", err)
216 }
217
218 producerCount := len(metricproducer.GlobalManager().GetAll())
219 assert.Equal(t, 1, producerCount, "expected one registered producer")
220 }
221
222 func TestDisable(t *testing.T) {
223 err := runmetrics.Enable(runmetrics.RunMetricOptions{})
224 if err != nil {
225 t.Errorf("want: nil, got: %v", err)
226 }
227
228 runmetrics.Disable()
229
230 producerCount := len(metricproducer.GlobalManager().GetAll())
231 assert.Equal(t, 0, producerCount, "expected one registered producer")
232 }
233
View as plain text