Go · 3415 bytes Raw Blame History
1 // SPDX-License-Identifier: AGPL-3.0-or-later
2
3 package telemetry
4
5 import (
6 "testing"
7 "time"
8
9 "github.com/jackc/pgx/v5/pgtype"
10 "github.com/prometheus/client_golang/prometheus"
11 dto "github.com/prometheus/client_model/go"
12
13 actionsdb "github.com/tenseleyFlow/shithub/internal/actions/sqlc"
14 "github.com/tenseleyFlow/shithub/internal/infra/metrics"
15 )
16
17 func TestRecordRunTerminalBoundsLabelsAndDuration(t *testing.T) {
18 metrics.ActionsRunsCompletedTotal.Reset()
19 metrics.ActionsRunDurationSeconds.Reset()
20
21 started := time.Date(2026, 5, 12, 10, 0, 0, 0, time.UTC)
22 completed := started.Add(75 * time.Second)
23 RecordRunTerminal(actionsdb.WorkflowRun{
24 Event: actionsdb.WorkflowRunEvent("pull_request"),
25 Status: actionsdb.WorkflowRunStatusCompleted,
26 Conclusion: actionsdb.NullCheckConclusion{CheckConclusion: actionsdb.CheckConclusionSuccess, Valid: true},
27 StartedAt: pgtype.Timestamptz{Time: started, Valid: true},
28 CompletedAt: pgtype.Timestamptz{Time: completed, Valid: true},
29 })
30
31 var completedMetric dto.Metric
32 if err := metrics.ActionsRunsCompletedTotal.WithLabelValues("pull_request", "success").Write(&completedMetric); err != nil {
33 t.Fatalf("read completed counter: %v", err)
34 }
35 if got := completedMetric.GetCounter().GetValue(); got != 1 {
36 t.Fatalf("completed counter = %v, want 1", got)
37 }
38
39 histogram, ok := metrics.ActionsRunDurationSeconds.WithLabelValues("pull_request", "success").(prometheus.Histogram)
40 if !ok {
41 t.Fatalf("duration metric is not a prometheus.Histogram")
42 }
43 var durationMetric dto.Metric
44 if err := histogram.Write(&durationMetric); err != nil {
45 t.Fatalf("read duration histogram: %v", err)
46 }
47 if got := durationMetric.GetHistogram().GetSampleCount(); got != 1 {
48 t.Fatalf("duration sample count = %v, want 1", got)
49 }
50 if got := durationMetric.GetHistogram().GetSampleSum(); got != 75 {
51 t.Fatalf("duration sample sum = %v, want 75", got)
52 }
53 }
54
55 func TestRecordStepTerminalUsesBoundedStepTypes(t *testing.T) {
56 metrics.ActionsStepsCompletedTotal.Reset()
57
58 RecordStepTerminal(actionsdb.WorkflowStep{
59 UsesAlias: "actions/checkout@v4",
60 Status: actionsdb.WorkflowStepStatusCompleted,
61 Conclusion: actionsdb.NullCheckConclusion{CheckConclusion: actionsdb.CheckConclusionSuccess, Valid: true},
62 })
63 RecordStepTerminal(actionsdb.WorkflowStep{
64 StepName: "user controlled label with high cardinality potential",
65 UsesAlias: "owner/custom-action@v1",
66 Status: actionsdb.WorkflowStepStatusCompleted,
67 Conclusion: actionsdb.NullCheckConclusion{CheckConclusion: actionsdb.CheckConclusionFailure, Valid: true},
68 })
69 RecordStepTerminal(actionsdb.WorkflowStep{
70 RunCommand: "go test ./...",
71 Status: actionsdb.WorkflowStepStatusCompleted,
72 Conclusion: actionsdb.NullCheckConclusion{CheckConclusion: actionsdb.CheckConclusionSuccess, Valid: true},
73 })
74
75 assertStepCounter(t, "checkout", "success", 1)
76 assertStepCounter(t, "uses", "failure", 1)
77 assertStepCounter(t, "run", "success", 1)
78 }
79
80 func assertStepCounter(t *testing.T, stepType, conclusion string, want float64) {
81 t.Helper()
82 var metric dto.Metric
83 if err := metrics.ActionsStepsCompletedTotal.WithLabelValues(stepType, conclusion).Write(&metric); err != nil {
84 t.Fatalf("read step counter %s/%s: %v", stepType, conclusion, err)
85 }
86 if got := metric.GetCounter().GetValue(); got != want {
87 t.Fatalf("step counter %s/%s = %v, want %v", stepType, conclusion, got, want)
88 }
89 }
90