mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 10:35:51 +00:00
111 lines
3.6 KiB
Go
111 lines
3.6 KiB
Go
package monitoring
|
|
|
|
import (
|
|
"math"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/models"
|
|
agentshost "github.com/rcourtman/pulse-go-rewrite/pkg/agents/host"
|
|
)
|
|
|
|
func TestNormalizeAgentLibvirtInventoryDerivesCPUAndIORates(t *testing.T) {
|
|
monitor := &Monitor{rateTracker: NewRateTracker()}
|
|
t0 := time.Date(2026, 7, 30, 12, 0, 0, 0, time.UTC)
|
|
firstReport := &agentshost.LibvirtInventory{Domains: []agentshost.LibvirtDomain{{
|
|
Name: "app",
|
|
State: "running",
|
|
VCPUs: 2,
|
|
CPUTimeNanoseconds: 2_000_000_000,
|
|
MemoryCurrentBytes: 2 << 30,
|
|
MemoryMaximumBytes: 4 << 30,
|
|
NetworkRXBytes: 1000,
|
|
NetworkTXBytes: 2000,
|
|
DiskReadBytes: 3000,
|
|
DiskWriteBytes: 4000,
|
|
}}}
|
|
first := monitor.normalizeAgentLibvirtInventory(firstReport, "host-1", nil, t0)
|
|
if first == nil || len(first.Domains) != 1 {
|
|
t.Fatalf("first inventory = %+v", first)
|
|
}
|
|
if first.Domains[0].CPUUsageValid || first.Domains[0].IORatesValid {
|
|
t.Fatalf("first sample invented rates: %+v", first.Domains[0])
|
|
}
|
|
|
|
previous := &models.Host{
|
|
ID: "host-1",
|
|
LastSeen: t0,
|
|
Libvirt: first,
|
|
}
|
|
secondReport := &agentshost.LibvirtInventory{Domains: []agentshost.LibvirtDomain{{
|
|
Name: "app",
|
|
State: "running",
|
|
VCPUs: 2,
|
|
CPUTimeNanoseconds: 3_000_000_000,
|
|
MemoryCurrentBytes: 5 << 30,
|
|
MemoryMaximumBytes: 4 << 30,
|
|
NetworkRXBytes: 2000,
|
|
NetworkTXBytes: 4000,
|
|
DiskReadBytes: 6000,
|
|
DiskWriteBytes: 8000,
|
|
}}}
|
|
second := monitor.normalizeAgentLibvirtInventory(secondReport, "host-1", previous, t0.Add(10*time.Second))
|
|
if second == nil || len(second.Domains) != 1 {
|
|
t.Fatalf("second inventory = %+v", second)
|
|
}
|
|
got := second.Domains[0]
|
|
if !got.CPUUsageValid || math.Abs(got.CPUUsagePercent-5) > 0.001 {
|
|
t.Fatalf("CPU usage = (%v, %v), want valid 5%%", got.CPUUsagePercent, got.CPUUsageValid)
|
|
}
|
|
if !got.IORatesValid ||
|
|
got.NetworkInRate != 100 ||
|
|
got.NetworkOutRate != 200 ||
|
|
got.DiskReadRate != 300 ||
|
|
got.DiskWriteRate != 400 {
|
|
t.Fatalf("I/O rates = %+v", got)
|
|
}
|
|
if got.MemoryCurrentBytes != 4<<30 {
|
|
t.Fatalf("memory current = %d, want clamped to maximum", got.MemoryCurrentBytes)
|
|
}
|
|
}
|
|
|
|
func TestNormalizeAgentLibvirtInventoryBoundsAndDeduplicates(t *testing.T) {
|
|
monitor := &Monitor{rateTracker: NewRateTracker()}
|
|
report := &agentshost.LibvirtInventory{Domains: []agentshost.LibvirtDomain{
|
|
{Name: " VM ", State: "CRASHED", VCPUs: 5000},
|
|
{Name: "vm", State: "running"},
|
|
{Name: "bad\x00name", State: "running"},
|
|
}}
|
|
got := monitor.normalizeAgentLibvirtInventory(report, "host-1", nil, time.Now())
|
|
if got == nil || len(got.Domains) != 1 {
|
|
t.Fatalf("inventory = %+v, want one domain", got)
|
|
}
|
|
if got.Domains[0].Name != "VM" || got.Domains[0].State != "crashed" || got.Domains[0].VCPUs != 4096 {
|
|
t.Fatalf("normalized domain = %+v", got.Domains[0])
|
|
}
|
|
}
|
|
|
|
func TestNormalizeAgentLibvirtInventoryPreservesLastSuccessfulSampleOnFailure(t *testing.T) {
|
|
collectedAt := time.Now().Add(-time.Minute).UTC()
|
|
previous := &models.Host{Libvirt: &models.HostLibvirtInventory{
|
|
CollectedAt: collectedAt,
|
|
Domains: []models.HostLibvirtDomain{{
|
|
ID: "domain-a",
|
|
Name: "app",
|
|
}},
|
|
}}
|
|
got := (&Monitor{rateTracker: NewRateTracker()}).normalizeAgentLibvirtInventory(
|
|
nil,
|
|
"host-1",
|
|
previous,
|
|
time.Now(),
|
|
)
|
|
if got == nil || len(got.Domains) != 1 || !got.CollectedAt.Equal(collectedAt) {
|
|
t.Fatalf("preserved inventory = %+v", got)
|
|
}
|
|
got.Domains[0].Name = "mutated"
|
|
if previous.Libvirt.Domains[0].Name != "app" {
|
|
t.Fatal("preserved inventory aliases previous host state")
|
|
}
|
|
}
|