Files
go2rtc/internal/api/system_darwin_test.go
T
Sergey Krashevich 0b80fa53cf feat(api): add system resource monitoring functionality
- implement getSystemInfo to gather CPU and memory usage
- add platform-specific implementations for memory and CPU usage
- enhance OpenAPI documentation to include system resource metrics
2026-02-13 14:49:20 +03:00

117 lines
2.7 KiB
Go

//go:build darwin
package api
import (
"os/exec"
"runtime"
"strconv"
"strings"
"syscall"
"testing"
)
func TestGetMemoryInfo(t *testing.T) {
total, used := getMemoryInfo()
if total == 0 {
t.Fatal("mem_total is 0")
}
if total < 512*1024*1024 {
t.Fatalf("mem_total too small: %d", total)
}
// total should match sysctl64("hw.memsize")
expectedTotal := sysctl64("hw.memsize")
if total != expectedTotal {
t.Errorf("mem_total %d != hw.memsize %d", total, expectedTotal)
}
if used == 0 {
t.Fatal("mem_used is 0")
}
if used > total {
t.Fatalf("mem_used (%d) > mem_total (%d)", used, total)
}
// cross-check: used should be >= wired+active pages (minimum real usage)
pageSize, _ := syscall.SysctlUint32("hw.pagesize")
wired := vmStatPages("Pages wired down")
active := vmStatPages("Pages active")
minUsed := (wired + active) * uint64(pageSize)
if used < minUsed/2 {
t.Errorf("mem_used (%d) is less than half of wired+active (%d)", used, minUsed)
}
avail := total - used
t.Logf("RAM total: %.1f GB, used: %.1f GB, avail: %.1f GB",
float64(total)/1024/1024/1024,
float64(used)/1024/1024/1024,
float64(avail)/1024/1024/1024)
}
func TestGetCPUUsage(t *testing.T) {
usage := getCPUUsage()
// cross-check with sysctl vm.loadavg
out, err := exec.Command("sysctl", "-n", "vm.loadavg").Output()
if err != nil {
t.Fatal("sysctl vm.loadavg:", err)
}
// format: { 4.24 4.57 5.76 } or { 4,24 4,57 5,76 }
s := strings.Trim(string(out), "{ }\n")
fields := strings.Fields(s)
if len(fields) < 1 {
t.Fatal("cannot parse vm.loadavg:", string(out))
}
load1Str := strings.ReplaceAll(fields[0], ",", ".")
load1, err := strconv.ParseFloat(load1Str, 64)
if err != nil {
t.Fatal("parse load1:", err)
}
numCPU := float64(runtime.NumCPU())
expected := load1 / numCPU * 100
if expected > 100 {
expected = 100
}
if usage < 0 || usage > 100 {
t.Fatalf("cpu_usage out of range: %.1f%%", usage)
}
// allow 15% absolute deviation (load average fluctuates between reads)
diff := usage - expected
if diff < 0 {
diff = -diff
}
if diff > 15 {
t.Errorf("cpu_usage %.1f%% deviates from expected %.1f%% (load1=%.2f, cpus=%d) by %.1f%%",
usage, expected, load1, int(numCPU), diff)
}
t.Logf("CPU usage: %.1f%%, expected: %.1f%% (load1=%.2f, cpus=%d)",
usage, expected, load1, int(numCPU))
}
func TestVmStatPages(t *testing.T) {
inactive := vmStatPages("Pages inactive")
if inactive == 0 {
t.Error("Pages inactive returned 0")
}
free := vmStatPages("Pages free")
if free == 0 {
t.Error("Pages free returned 0")
}
bogus := vmStatPages("Pages nonexistent")
if bogus != 0 {
t.Errorf("nonexistent key returned %d", bogus)
}
t.Logf("inactive=%d, free=%d pages", inactive, free)
}