carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package metrics
2
3import (
4 "context"
5 "encoding/json"
6 "testing"
7 "time"
8
9 "github.com/carlosframework/platform/internal/release"
10)
11
12func rollupFloat(v float64) *float64 { return &v }
13func rollupInt(v int64) *int64 { return &v }
14
15func TestRollupHourHostCPUNilExcluded(t *testing.T) {
16 samples := []Sample{
17 {Host: HostSample{CPUFrac: rollupFloat(0.2), MemFrac: rollupFloat(0.5), DiskFrac: rollupFloat(0.1), Load1: rollupFloat(1.0)}},
18 {Host: HostSample{CPUFrac: nil, MemFrac: rollupFloat(0.6), DiskFrac: rollupFloat(0.2), Load1: rollupFloat(1.5)}},
19 {Host: HostSample{CPUFrac: rollupFloat(0.8), MemFrac: rollupFloat(0.4), DiskFrac: rollupFloat(0.3), Load1: rollupFloat(0.5)}},
20 }
21
22 agg := RollupHour(samples)
23
24 cpu, ok := agg.Host["cpu"]
25 if !ok {
26 t.Fatalf("Host[\"cpu\"] absent, want present with N=2")
27 }
28 if cpu.N != 2 {
29 t.Fatalf("cpu.N = %d, want 2 (nil sample excluded)", cpu.N)
30 }
31 if cpu.Min != 0.2 || cpu.Max != 0.8 || cpu.Avg != 0.5 {
32 t.Fatalf("cpu = %+v, want min=0.2 max=0.8 avg=0.5", cpu)
33 }
34}
35
36func TestRollupHourUnitPresentInOneSample(t *testing.T) {
37 samples := []Sample{
38 {Units: map[string]UnitSample{
39 "a.service": {CPUFrac: rollupFloat(0.3), MemBytes: rollupInt(1000)},
40 }},
41 {Units: map[string]UnitSample{}},
42 }
43
44 agg := RollupHour(samples)
45
46 unit, ok := agg.Units["a.service"]
47 if !ok {
48 t.Fatalf("Units[\"a.service\"] absent, want present")
49 }
50 cpu, ok := unit["cpu"]
51 if !ok || cpu.N != 1 {
52 t.Fatalf("unit cpu = %+v (ok=%v), want N=1", cpu, ok)
53 }
54 if cpu.Min != 0.3 || cpu.Max != 0.3 || cpu.Avg != 0.3 {
55 t.Fatalf("unit cpu = %+v, want min=avg=max=0.3", cpu)
56 }
57 mem, ok := unit["mem_bytes"]
58 if !ok || mem.N != 1 {
59 t.Fatalf("unit mem_bytes = %+v (ok=%v), want N=1", mem, ok)
60 }
61 if mem.Min != 1000 || mem.Max != 1000 || mem.Avg != 1000 {
62 t.Fatalf("unit mem_bytes = %+v, want min=avg=max=1000", mem)
63 }
64}
65
66func TestRollupHourAllNilMetricAbsent(t *testing.T) {
67 samples := []Sample{
68 {Host: HostSample{CPUFrac: rollupFloat(0.1)}},
69 {Host: HostSample{CPUFrac: rollupFloat(0.2)}},
70 }
71
72 agg := RollupHour(samples)
73
74 if _, ok := agg.Host["load1"]; ok {
75 t.Fatalf("Host[\"load1\"] present, want absent (never carried in any sample)")
76 }
77 if _, ok := agg.Host["mem"]; ok {
78 t.Fatalf("Host[\"mem\"] present, want absent")
79 }
80 if _, ok := agg.Host["disk"]; ok {
81 t.Fatalf("Host[\"disk\"] present, want absent")
82 }
83 if len(agg.Units) != 0 {
84 t.Fatalf("Units = %+v, want empty (no unit samples at all)", agg.Units)
85 }
86}
87
88func TestUpsertRollupTwoHoursSameDay(t *testing.T) {
89 store := release.NewDirStore(t.TempDir())
90 ctx := context.Background()
91
92 hour10 := time.Date(2026, 8, 2, 10, 30, 0, 0, time.UTC)
93 hour11 := time.Date(2026, 8, 2, 11, 15, 0, 0, time.UTC)
94
95 agg10 := HourAgg{Host: map[string]Agg{"cpu": {Min: 0.1, Avg: 0.1, Max: 0.1, N: 1}}}
96 agg11 := HourAgg{Host: map[string]Agg{"cpu": {Min: 0.2, Avg: 0.2, Max: 0.2, N: 1}}}
97
98 if err := UpsertRollup(ctx, store, "b", hour10, agg10); err != nil {
99 t.Fatalf("UpsertRollup hour10: %v", err)
100 }
101 if err := UpsertRollup(ctx, store, "b", hour11, agg11); err != nil {
102 t.Fatalf("UpsertRollup hour11: %v", err)
103 }
104
105 keys, err := store.List(ctx, "metrics/boxes/b/days/")
106 if err != nil {
107 t.Fatalf("List: %v", err)
108 }
109 if len(keys) != 1 {
110 t.Fatalf("got %d day keys, want exactly one: %v", len(keys), keys)
111 }
112
113 body, _, err := store.Get(ctx, DayKey("b", "2026-08-02"))
114 if err != nil {
115 t.Fatalf("Get: %v", err)
116 }
117 var got DayRollup
118 if err := json.Unmarshal(body, &got); err != nil {
119 t.Fatalf("Unmarshal: %v", err)
120 }
121 if got.V != 1 || got.Box != "b" || got.Date != "2026-08-02" {
122 t.Fatalf("got %+v, want V=1 Box=b Date=2026-08-02", got)
123 }
124 if len(got.Hours) != 2 {
125 t.Fatalf("got %d hours, want 2 (10 and 11): %+v", len(got.Hours), got.Hours)
126 }
127 if got.Hours["10"].Host["cpu"].N != 1 || got.Hours["10"].Host["cpu"].Avg != 0.1 {
128 t.Fatalf("Hours[10] = %+v, want cpu avg 0.1", got.Hours["10"])
129 }
130 if got.Hours["11"].Host["cpu"].N != 1 || got.Hours["11"].Host["cpu"].Avg != 0.2 {
131 t.Fatalf("Hours[11] = %+v, want cpu avg 0.2", got.Hours["11"])
132 }
133}
134