mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2026-04-22 23:57:20 +08:00
0b80fa53cf
- 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
117 lines
2.7 KiB
Go
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)
|
|
}
|