MCPcopy
hub / github.com/grafana/tempo / TestAvgOverTime

Function TestAvgOverTime

pkg/traceql/engine_metrics_average_test.go:42–122  ·  view source on GitHub ↗
(t *testing.T)

Source from the content-addressed store, hash-verified

40}
41
42func TestAvgOverTime(t *testing.T) {
43 req := &tempopb.QueryRangeRequest{
44 Start: 1,
45 End: uint64(3 * time.Second),
46 Step: uint64(1 * time.Second),
47 Query: "{ } | avg_over_time(duration) by (span.service)",
48 }
49
50 // Test data designed to verify multiplication accuracy in weighted mean calculation
51 // The addWeigthedMean function uses: meanDelta := ((mean - currentMean.mean) * weight) / sumWeights
52 in := []Span{
53 // Time interval 1: service=a has 2 spans with durations 100, 200 (mean=150, count=2)
54 newMockSpan(nil).WithStartTime(uint64(1*time.Second)).WithSpanString("service", "a").WithDuration(uint64(100 * time.Second)),
55 newMockSpan(nil).WithStartTime(uint64(1*time.Second)).WithSpanString("service", "a").WithDuration(uint64(200 * time.Second)),
56
57 // Time interval 1: service=b has 3 spans with durations 300, 600, 900 (mean=600, count=3)
58 newMockSpan(nil).WithStartTime(uint64(1*time.Second)).WithSpanString("service", "b").WithDuration(uint64(300 * time.Second)),
59 newMockSpan(nil).WithStartTime(uint64(1*time.Second)).WithSpanString("service", "b").WithDuration(uint64(600 * time.Second)),
60 newMockSpan(nil).WithStartTime(uint64(1*time.Second)).WithSpanString("service", "b").WithDuration(uint64(900 * time.Second)),
61
62 // Time interval 2: service=a has 4 spans with durations 400, 800, 1200, 1600 (mean=1000, count=4)
63 newMockSpan(nil).WithStartTime(uint64(2*time.Second)).WithSpanString("service", "a").WithDuration(uint64(400 * time.Second)),
64 newMockSpan(nil).WithStartTime(uint64(2*time.Second)).WithSpanString("service", "a").WithDuration(uint64(800 * time.Second)),
65 newMockSpan(nil).WithStartTime(uint64(2*time.Second)).WithSpanString("service", "a").WithDuration(uint64(1200 * time.Second)),
66 newMockSpan(nil).WithStartTime(uint64(2*time.Second)).WithSpanString("service", "a").WithDuration(uint64(1600 * time.Second)),
67
68 // Time interval 2: service=b has 1 span with duration 2000 (mean=2000, count=1)
69 newMockSpan(nil).WithStartTime(uint64(2*time.Second)).WithSpanString("service", "b").WithDuration(uint64(2000 * time.Second)),
70
71 // Time interval 3: service=a has varying precision values to test floating point accuracy
72 newMockSpan(nil).WithStartTime(uint64(3*time.Second)).WithSpanString("service", "a").WithDuration(uint64(123 * time.Second)),
73 newMockSpan(nil).WithStartTime(uint64(3*time.Second)).WithSpanString("service", "a").WithDuration(uint64(456 * time.Second)),
74 newMockSpan(nil).WithStartTime(uint64(3*time.Second)).WithSpanString("service", "a").WithDuration(uint64(789 * time.Second)),
75 }
76
77 result, _, err := runTraceQLMetric(req, in)
78 require.NoError(t, err)
79 require.Equal(t, 2, len(result))
80
81 actualServiceA := result[LabelsFromArgs("span.service", "a").MapKey()]
82 actualServiceB := result[LabelsFromArgs("span.service", "b").MapKey()]
83
84 expectedServiceA := []struct {
85 interval int
86 expected float64
87 }{
88 {0, 150.0}, // (100 + 200) / 2 = 150 s
89 {1, 1000.0}, // (400 + 800 + 1200 + 1600) / 4 = 1000 s
90 {2, 456.0}, // (123 + 456 + 789) / 3 = 456 s
91 }
92 expectedServiceB := []struct {
93 interval int
94 expected float64
95 isNaN bool
96 }{
97 {0, 600.0, false}, // (300 + 600 + 900) / 3 = 600 s
98 {1, 2000.0, false}, // 2000 / 1 = 2000 s
99 {2, 0.0, true}, // no spans, should be NaN

Callers

nothing calls this directly

Calls 8

newMockSpanFunction · 0.85
runTraceQLMetricFunction · 0.85
LabelsFromArgsFunction · 0.85
WithDurationMethod · 0.80
WithSpanStringMethod · 0.80
WithStartTimeMethod · 0.80
EqualMethod · 0.45
MapKeyMethod · 0.45

Tested by

no test coverage detected