Skip to content

Commit 1b8c486

Browse files
committed
unit test
1 parent 1f5273b commit 1b8c486

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

coderd/prometheusmetrics/aggregator.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ func (ma *MetricsAggregator) Run(ctx context.Context) func() {
185185

186186
timer.ObserveDuration()
187187
cleanupTicker.Reset(ma.metricsCleanupInterval)
188+
188189
case <-ctx.Done():
189190
ma.log.Debug(ctx, "metrics aggregator: is stopped")
190191
return
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package prometheusmetrics_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
8+
"github.com/prometheus/client_golang/prometheus"
9+
dto "github.com/prometheus/client_model/go"
10+
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
12+
13+
"cdr.dev/slog/sloggers/slogtest"
14+
"github.com/coder/coder/coderd/prometheusmetrics"
15+
"github.com/coder/coder/codersdk/agentsdk"
16+
"github.com/coder/coder/testutil"
17+
)
18+
19+
const (
20+
testWorkspaceName = "yogi-workspace"
21+
testUsername = "yogi-bear"
22+
testAgentName = "main-agent"
23+
)
24+
25+
func TestUpdateMetrics_MetricsDoNotExpire(t *testing.T) {
26+
t.Parallel()
27+
28+
// given
29+
registry := prometheus.NewRegistry()
30+
metricsAggregator, err := prometheusmetrics.NewMetricsAggregator(slogtest.Make(t, &slogtest.Options{
31+
IgnoreErrors: true,
32+
}), registry, time.Hour) // time.Hour, so metrics won't expire
33+
require.NoError(t, err)
34+
35+
ctx, cancelFunc := context.WithCancel(context.Background())
36+
t.Cleanup(cancelFunc)
37+
38+
closeFunc := metricsAggregator.Run(ctx)
39+
t.Cleanup(closeFunc)
40+
41+
given := []agentsdk.AgentMetric{
42+
{
43+
Name: "a_counter_one",
44+
Type: agentsdk.AgentMetricTypeCounter,
45+
Value: 1,
46+
},
47+
{
48+
Name: "b_counter_two",
49+
Type: agentsdk.AgentMetricTypeCounter,
50+
Value: 2,
51+
},
52+
{
53+
Name: "c_gauge_three",
54+
Type: agentsdk.AgentMetricTypeCounter,
55+
Value: 3,
56+
},
57+
{
58+
Name: "d_gauge_four",
59+
Type: agentsdk.AgentMetricTypeCounter,
60+
Value: 4,
61+
},
62+
}
63+
64+
// when
65+
metricsAggregator.Update(ctx, testUsername, testWorkspaceName, testAgentName, given)
66+
67+
// then
68+
require.Eventually(t, func() bool {
69+
var actual []prometheus.Metric
70+
metricsCh := make(chan prometheus.Metric)
71+
go func() {
72+
for m := range metricsCh {
73+
actual = append(actual, m)
74+
}
75+
}()
76+
metricsAggregator.Collect(metricsCh)
77+
return verifyCollectedMetrics(t, given, actual)
78+
}, testutil.WaitMedium, testutil.IntervalFast)
79+
}
80+
81+
func verifyCollectedMetrics(t *testing.T, expected []agentsdk.AgentMetric, actual []prometheus.Metric) bool {
82+
if len(expected) != len(actual) {
83+
return false
84+
}
85+
86+
// Metrics are expected to arrive in order
87+
for i, e := range expected {
88+
desc := actual[i].Desc()
89+
assert.Contains(t, desc.String(), e.Name)
90+
91+
var d dto.Metric
92+
err := actual[i].Write(&d)
93+
require.NoError(t, err)
94+
95+
require.Equal(t, "agent_name", *d.Label[0].Name)
96+
require.Equal(t, testAgentName, *d.Label[0].Value)
97+
require.Equal(t, "username", *d.Label[1].Name)
98+
require.Equal(t, testUsername, *d.Label[1].Value)
99+
require.Equal(t, "workspace_name", *d.Label[2].Name)
100+
require.Equal(t, testWorkspaceName, *d.Label[2].Value)
101+
102+
if e.Type == agentsdk.AgentMetricTypeCounter {
103+
require.Equal(t, e.Value, *d.Counter.Value)
104+
} else if e.Type == agentsdk.AgentMetricTypeGauge {
105+
require.Equal(t, e.Value, *d.Gauge.Value)
106+
} else {
107+
require.Failf(t, "unsupported type: %s", string(e.Type))
108+
}
109+
}
110+
return true
111+
}

0 commit comments

Comments
 (0)