Cover Ceph pool override path with regression test
Some checks are pending
Build and Test / Secret Scan (push) Waiting to run
Build and Test / Frontend & Backend (push) Waiting to run
Core E2E Tests / Playwright Core E2E (push) Waiting to run

Refs #1341

The 5.1.32 fix in 6f3bea32f only tested the storage default path for
synthetic Ceph pool entries. Reporter on #1341 sets a 50% per-pool
override on a pool at ~61% usage and still doesn't get an alert; lock
the override path against future regressions so this remains a config
question rather than a code regression.
This commit is contained in:
rcourtman 2026-05-28 10:24:35 +01:00
parent 6b5fb6f82a
commit a70f1d9676

View file

@ -638,6 +638,98 @@ func TestPollStorageWithNodesOptimizedChecksCephPoolAlerts(t *testing.T) {
}
}
// Regression for #1341: a per-pool Ceph threshold override (lower than the
// storage default) must fire when the pool's usage exceeds the override
// trigger. The reporter set a 50% threshold on a Ceph pool sitting at ~61%
// and never received an alert.
func TestPollStorageWithNodesOptimizedAppliesCephPoolOverride(t *testing.T) {
t.Setenv("PULSE_DATA_DIR", t.TempDir())
monitor := &Monitor{
state: &models.State{},
metricsHistory: NewMetricsHistory(16, time.Hour),
alertManager: alerts.NewManager(),
}
t.Cleanup(func() {
monitor.alertManager.Stop()
})
overrideTrigger := alerts.HysteresisThreshold{Trigger: 50, Clear: 45}
cfg := monitor.alertManager.GetConfig()
cfg.MinimumDelta = 0
if cfg.TimeThresholds == nil {
cfg.TimeThresholds = make(map[string]int)
}
cfg.TimeThresholds["storage"] = 0
// Default high enough that only the override could fire.
cfg.StorageDefault = alerts.HysteresisThreshold{Trigger: 95, Clear: 90}
cfg.Overrides = map[string]alerts.ThresholdConfig{
"inst1-ceph-pool-data_replication": {Usage: &overrideTrigger},
}
monitor.alertManager.UpdateConfig(cfg)
cephStorage := proxmox.Storage{
Storage: "ceph-shared",
Type: "rbd",
Content: "images,rootdir",
Nodes: "pve1,pve2",
Pool: "ceph-pool",
}
client := &fakeStorageClient{
allStorage: []proxmox.Storage{cephStorage},
storageByNode: map[string][]proxmox.Storage{
"pve1": {},
"pve2": {},
},
cephStatus: &proxmox.CephStatus{
FSID: "ceph-fsid",
PGMap: proxmox.CephPGMap{
BytesTotal: 5000,
BytesUsed: 3050,
BytesAvail: 1950,
},
},
cephDF: &proxmox.CephDF{
Data: proxmox.CephDFData{
Pools: []proxmox.CephDFPool{
{
ID: 2,
Name: "data_replication",
Stats: proxmox.CephDFPoolStat{
BytesUsed: 611,
MaxAvail: 389,
PercentUsed: 61.1,
},
},
},
},
},
}
nodes := []proxmox.Node{
{Node: "pve1", Status: "online"},
{Node: "pve2", Status: "online"},
}
monitor.pollStorageWithNodes(context.Background(), "inst1", client, nodes)
active := monitor.alertManager.GetActiveAlerts()
found := false
for _, alert := range active {
if alert.ID == "inst1-ceph-pool-data_replication-usage" {
found = true
if alert.Threshold != 50 {
t.Fatalf("Ceph pool alert fired but threshold = %.1f, want 50 (override)", alert.Threshold)
}
break
}
}
if !found {
t.Fatalf("expected Ceph pool usage alert to fire from per-pool 50%% override at 61.1%% usage; got %d active alerts", len(active))
}
}
func TestPollStorageWithNodesOptimizedClearsStaleStorageAlertsWhenIdentityChanges(t *testing.T) {
t.Setenv("PULSE_DATA_DIR", t.TempDir())