You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
4.0 KiB
79 lines
4.0 KiB
package systemmetrics
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"tera-clone/services/tera-api/internal/domain"
|
|
)
|
|
|
|
func TestLinuxReaderCollectsBoundedDashboardMetrics(t *testing.T) {
|
|
root := t.TempDir()
|
|
procRoot := filepath.Join(root, "proc")
|
|
sysRoot := filepath.Join(root, "sys")
|
|
etcRoot := filepath.Join(root, "etc")
|
|
writeMetricFile(t, filepath.Join(procRoot, "uptime"), "93784.9 0\n")
|
|
writeMetricFile(t, filepath.Join(procRoot, "loadavg"), "0.46 0.45 0.41 1/100 10\n")
|
|
writeMetricFile(t, filepath.Join(procRoot, "stat"), "cpu 100 0 50 850 0 0 0 0\n")
|
|
writeMetricFile(t, filepath.Join(procRoot, "meminfo"), "MemTotal: 2048000 kB\nMemFree: 256000 kB\nMemAvailable: 512000 kB\nBuffers: 64000 kB\nCached: 128000 kB\n")
|
|
writeMetricFile(t, filepath.Join(sysRoot, "class", "thermal", "thermal_zone0", "temp"), "53800\n")
|
|
writeMetricFile(t, filepath.Join(etcRoot, "tera", "build-number"), "N010-0020-2609-0062\n")
|
|
writeMetricFile(t, filepath.Join(etcRoot, "machine-id"), "device-4027\n")
|
|
interfaceRoot := filepath.Join(sysRoot, "class", "net", "eth0")
|
|
writeMetricFile(t, filepath.Join(interfaceRoot, "address"), "6c:b3:50:0d:36:12\n")
|
|
writeMetricFile(t, filepath.Join(interfaceRoot, "operstate"), "up\n")
|
|
writeMetricFile(t, filepath.Join(interfaceRoot, "speed"), "1000\n")
|
|
writeMetricFile(t, filepath.Join(interfaceRoot, "statistics", "rx_bytes"), "12345\n")
|
|
writeMetricFile(t, filepath.Join(interfaceRoot, "statistics", "tx_bytes"), "67890\n")
|
|
now := time.Date(2026, 8, 14, 12, 0, 0, 0, time.UTC)
|
|
reader := NewLinuxReader(LinuxReaderOptions{ProcRoot: procRoot, SysRoot: sysRoot, EtcRoot: etcRoot, Clock: func() time.Time { return now }})
|
|
interfaces := []domain.NetworkInterface{{Name: "Interface-1", Device: "eth0", Address: "192.168.0.223/24", IPv6Address: "fe80::1/64"}}
|
|
|
|
first := reader.Read(context.Background(), interfaces)
|
|
if first.CPUUsagePercent != nil {
|
|
t.Fatalf("first CPU sample = %v, want nil baseline", *first.CPUUsagePercent)
|
|
}
|
|
writeMetricFile(t, filepath.Join(procRoot, "stat"), "cpu 150 0 50 900 0 0 0 0\n")
|
|
metrics := reader.Read(context.Background(), interfaces)
|
|
if metrics.BuildNumber != "N010-0020-2609-0062" || metrics.DeviceID != "device-4027" || metrics.UptimeSeconds != 93784 || !metrics.SystemTime.Equal(now) {
|
|
t.Fatalf("identity/runtime metrics = %+v", metrics)
|
|
}
|
|
if metrics.TemperatureCelsius == nil || *metrics.TemperatureCelsius != 53.8 || metrics.CPUUsagePercent == nil || *metrics.CPUUsagePercent != 50 {
|
|
t.Fatalf("temperature/CPU metrics = %+v", metrics)
|
|
}
|
|
if len(metrics.LoadAverages) != 3 || metrics.LoadAverages[2] != 0.41 {
|
|
t.Fatalf("load averages = %v", metrics.LoadAverages)
|
|
}
|
|
if metrics.MemoryTotalBytes != 2097152000 || metrics.MemoryAvailableBytes != 524288000 || metrics.MemoryUsedBytes != 1572864000 || metrics.MemoryUsagePercent == nil || *metrics.MemoryUsagePercent != 75 {
|
|
t.Fatalf("memory metrics = %+v", metrics)
|
|
}
|
|
if len(metrics.NetworkInterfaces) != 1 {
|
|
t.Fatalf("interfaces = %+v", metrics.NetworkInterfaces)
|
|
}
|
|
item := metrics.NetworkInterfaces[0]
|
|
if item.MACAddress != "6c:b3:50:0d:36:12" || item.Link != "up" || item.SpeedMbps != 1000 || item.RXBytes != 12345 || item.TXBytes != 67890 || len(item.Addresses) != 2 {
|
|
t.Fatalf("network metrics = %+v", item)
|
|
}
|
|
}
|
|
|
|
func TestLinuxReaderRejectsUnsafeInterfaceDevicePath(t *testing.T) {
|
|
root := t.TempDir()
|
|
reader := NewLinuxReader(LinuxReaderOptions{ProcRoot: root, SysRoot: root, EtcRoot: root})
|
|
metrics := reader.Read(context.Background(), []domain.NetworkInterface{{Name: "Interface-1", Device: "../secret", Link: "down"}})
|
|
if len(metrics.NetworkInterfaces) != 1 || metrics.NetworkInterfaces[0].MACAddress != "" || metrics.NetworkInterfaces[0].Link != "down" {
|
|
t.Fatalf("unsafe device result = %+v", metrics.NetworkInterfaces)
|
|
}
|
|
}
|
|
|
|
func writeMetricFile(t *testing.T, path, content string) {
|
|
t.Helper()
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|