first commit
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
package report
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestHeartbeatPayloadIncludesHostMetrics(t *testing.T) {
|
||||
payload := HeartbeatPayload("test-version", 30)
|
||||
|
||||
capabilities, ok := payload["capabilities"].([]any)
|
||||
if !ok {
|
||||
t.Fatalf("capabilities missing or invalid: %#v", payload["capabilities"])
|
||||
}
|
||||
if !containsCapability(capabilities, "host-metrics") {
|
||||
t.Fatalf("host-metrics capability missing: %#v", capabilities)
|
||||
}
|
||||
if !containsCapability(capabilities, "instance-status") {
|
||||
t.Fatalf("instance-status capability missing: %#v", capabilities)
|
||||
}
|
||||
if !containsCapability(capabilities, "traffic-counters") {
|
||||
t.Fatalf("traffic-counters capability missing: %#v", capabilities)
|
||||
}
|
||||
|
||||
instances, ok := payload["instances"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("instances report missing or invalid: %#v", payload["instances"])
|
||||
}
|
||||
for _, key := range []string{"available", "reportedAt", "total", "items"} {
|
||||
if _, ok := instances[key]; !ok {
|
||||
t.Fatalf("instances key %s missing: %#v", key, instances)
|
||||
}
|
||||
}
|
||||
|
||||
runtimeInfo, ok := payload["runtime"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("runtime missing or invalid: %#v", payload["runtime"])
|
||||
}
|
||||
for _, key := range []string{"goos", "goarch"} {
|
||||
if _, ok := runtimeInfo[key]; !ok {
|
||||
t.Fatalf("runtime key %s missing: %#v", key, runtimeInfo)
|
||||
}
|
||||
}
|
||||
|
||||
resources, ok := payload["resources"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("resources missing or invalid: %#v", payload["resources"])
|
||||
}
|
||||
for _, key := range []string{
|
||||
"cpuTotal",
|
||||
"cpuUsagePercent",
|
||||
"memoryTotalMb",
|
||||
"memoryUsedMb",
|
||||
"memoryUsagePercent",
|
||||
"swapTotalMb",
|
||||
"swapUsedMb",
|
||||
"swapUsagePercent",
|
||||
"diskTotalBytes",
|
||||
"diskUsedBytes",
|
||||
"diskUsagePercent",
|
||||
"processCount",
|
||||
} {
|
||||
if _, ok := resources[key]; !ok {
|
||||
t.Fatalf("resource key %s missing: %#v", key, resources)
|
||||
}
|
||||
}
|
||||
|
||||
metrics, ok := payload["metrics"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("metrics missing or invalid: %#v", payload["metrics"])
|
||||
}
|
||||
for _, key := range []string{"reportedAt", "heartbeatIntervalSeconds", "uptimeSeconds", "load1", "load5", "load15"} {
|
||||
if _, ok := metrics[key]; !ok {
|
||||
t.Fatalf("metric key %s missing: %#v", key, metrics)
|
||||
}
|
||||
}
|
||||
if metrics["heartbeatIntervalSeconds"] != 30 {
|
||||
t.Fatalf("heartbeat interval mismatch: %#v", metrics["heartbeatIntervalSeconds"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeartbeatPayloadClampsHeartbeatInterval(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input int
|
||||
expected int
|
||||
}{
|
||||
{name: "zero falls back", input: 0, expected: 30},
|
||||
{name: "too low clamps to min", input: 1, expected: 5},
|
||||
{name: "too high clamps to max", input: 7200, expected: 3600},
|
||||
{name: "valid stays unchanged", input: 60, expected: 60},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
payload := HeartbeatPayload("test-version", tt.input)
|
||||
metrics, ok := payload["metrics"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("metrics missing or invalid: %#v", payload["metrics"])
|
||||
}
|
||||
if metrics["heartbeatIntervalSeconds"] != tt.expected {
|
||||
t.Fatalf("heartbeat interval mismatch: got=%#v want=%d", metrics["heartbeatIntervalSeconds"], tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrafficCountersFromIncusStateUsesBillableInterfaces(t *testing.T) {
|
||||
state := incusInstanceState{
|
||||
Network: map[string]incusNetworkDevice{
|
||||
"lo": {
|
||||
Counters: incusNetworkCounters{
|
||||
BytesReceived: "999",
|
||||
BytesSent: "999",
|
||||
},
|
||||
},
|
||||
"eth0": {
|
||||
Counters: incusNetworkCounters{
|
||||
BytesReceived: "100",
|
||||
BytesSent: "200",
|
||||
},
|
||||
},
|
||||
"docker0": {
|
||||
Counters: incusNetworkCounters{
|
||||
BytesReceived: "300",
|
||||
BytesSent: "400",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
counters := getTrafficCountersFromIncusState("vm-test", state)
|
||||
if counters.rx != 100 || counters.tx != 200 {
|
||||
t.Fatalf("traffic counters mismatch: got=%+v", counters)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrafficCountersFromIncusStateFallsBackToExternalInterfaces(t *testing.T) {
|
||||
state := incusInstanceState{
|
||||
Network: map[string]incusNetworkDevice{
|
||||
"lo": {
|
||||
Counters: incusNetworkCounters{
|
||||
BytesReceived: "999",
|
||||
BytesSent: "999",
|
||||
},
|
||||
},
|
||||
"enp5s0": {
|
||||
Counters: incusNetworkCounters{
|
||||
BytesReceived: "123",
|
||||
BytesSent: "456",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
counters := getTrafficCountersFromIncusState("vm-test", state)
|
||||
if counters.rx != 123 || counters.tx != 456 {
|
||||
t.Fatalf("traffic counters mismatch: got=%+v", counters)
|
||||
}
|
||||
}
|
||||
|
||||
func containsCapability(capabilities []any, expected string) bool {
|
||||
for _, capability := range capabilities {
|
||||
if capability == expected {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user