Files
worker/internal/webapp/metrics_test.go
Gleb Tv 2c7a0236da feat: publish standalone worker
Separate worker packaging and service lifecycle from the control plane.
2026-07-13 17:55:14 +03:00

141 строка
5.1 KiB
Go

package webapp
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// makeFakeMetricsProc writes a minimal /proc tree with stat, meminfo,
// loadavg, uptime, and net/dev files so CollectSnapshot can parse
// it without a real /proc.
func makeFakeMetricsProc(t *testing.T) string {
t.Helper()
root := t.TempDir()
require.NoError(t, os.WriteFile(filepath.Join(root, "stat"), []byte(statFixture), 0o644))
require.NoError(t, os.WriteFile(filepath.Join(root, "meminfo"), []byte(meminfoFixture), 0o644))
require.NoError(t, os.WriteFile(filepath.Join(root, "loadavg"), []byte(loadavgFixture), 0o644))
require.NoError(t, os.WriteFile(filepath.Join(root, "uptime"), []byte(uptimeFixture), 0o644))
require.NoError(t, os.MkdirAll(filepath.Join(root, "net"), 0o755))
require.NoError(t, os.WriteFile(filepath.Join(root, "net", "dev"), []byte(netdevFixture), 0o644))
require.NoError(t, os.WriteFile(filepath.Join(root, "mounts"), []byte(mountsFixture), 0o644))
return root
}
const statFixture = `cpu 100 0 50 800 20 0 0 0 0 0
cpu0 25 0 12 200 5 0 0 0 0 0
intr 12345 0 0 0
ctxt 78910
btime 1700000000
`
const meminfoFixture = `MemTotal: 16384000 kB
MemFree: 4096000 kB
MemAvailable: 8192000 kB
Buffers: 512000 kB
Cached: 2048000 kB
SwapCached: 0 kB
SwapTotal: 2048000 kB
SwapFree: 2048000 kB
`
const loadavgFixture = "0.42 0.85 1.23 1/123 4567\n"
const uptimeFixture = "12345.67\n"
const netdevFixture = `Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 1000000 1000 0 0 0 0 0 0 1000000 1000 0 0 0 0 0 0
eth0: 9999999 5000 1 2 0 0 0 0 8888888 4500 0 0 0 0 0 0
`
const mountsFixture = `/dev/sda1 / ext4 rw,relatime 0 0
tmpfs /run tmpfs rw,nosuid 0 0
`
func TestReadProcStatPercentages(t *testing.T) {
root := t.TempDir()
require.NoError(t, os.WriteFile(filepath.Join(root, "stat"), []byte(statFixture), 0o644))
cpu, err := readProcStat(filepath.Join(root, "stat"))
require.NoError(t, err)
// Fixture: user=100, nice=0, system=50, idle=800, iowait=20, steal=0
// Total = 970, idle+iowait = 820, busy = 150.
assert.InDelta(t, 10.31, cpu.UserPct, 0.01)
assert.InDelta(t, 5.15, cpu.SystemPct, 0.01)
assert.InDelta(t, 82.47, cpu.IdlePct, 0.01)
assert.InDelta(t, 15.46, cpu.TotalPct, 0.01)
}
func TestReadMemInfoBytes(t *testing.T) {
root := t.TempDir()
require.NoError(t, os.WriteFile(filepath.Join(root, "meminfo"), []byte(meminfoFixture), 0o644))
mem, err := readMemInfo(filepath.Join(root, "meminfo"))
require.NoError(t, err)
assert.Equal(t, uint64(16384000*1024), mem.Total)
assert.Equal(t, uint64(8192000*1024), mem.Available)
assert.Equal(t, uint64(2048000*1024), mem.SwapTotal)
// used = total - available = 8192 MiB
// pct = 8192 / 16384 * 100 = 50.00
assert.InDelta(t, 50.0, mem.UsedPct, 0.01)
}
func TestReadLoadAvg(t *testing.T) {
root := t.TempDir()
require.NoError(t, os.WriteFile(filepath.Join(root, "loadavg"), []byte(loadavgFixture), 0o644))
load, err := readLoadAvg(filepath.Join(root, "loadavg"))
require.NoError(t, err)
assert.InDelta(t, 0.42, load.One, 0.001)
assert.InDelta(t, 0.85, load.Five, 0.001)
assert.InDelta(t, 1.23, load.Fifteen, 0.001)
}
func TestReadUptime(t *testing.T) {
root := t.TempDir()
require.NoError(t, os.WriteFile(filepath.Join(root, "uptime"), []byte(uptimeFixture), 0o644))
d, err := readUptime(filepath.Join(root, "uptime"))
require.NoError(t, err)
assert.InDelta(t, 12345.67, d.Seconds(), 0.01)
}
func TestReadNetDev(t *testing.T) {
root := t.TempDir()
require.NoError(t, os.MkdirAll(filepath.Join(root, "net"), 0o755))
require.NoError(t, os.WriteFile(filepath.Join(root, "net", "dev"), []byte(netdevFixture), 0o644))
ifaces, err := readNetDev(filepath.Join(root, "net", "dev"))
require.NoError(t, err)
require.Len(t, ifaces, 2)
eth := ifaces[1]
assert.Equal(t, "eth0", eth.Name)
assert.Equal(t, uint64(9999999), eth.RxBytes)
assert.Equal(t, uint64(8888888), eth.TxBytes)
assert.Equal(t, uint64(5000), eth.RxPkt)
assert.Equal(t, uint64(1), eth.RxErr)
}
func TestReadMounts(t *testing.T) {
root := t.TempDir()
require.NoError(t, os.WriteFile(filepath.Join(root, "mounts"), []byte(mountsFixture), 0o644))
mounts, err := readMounts(filepath.Join(root, "mounts"))
require.NoError(t, err)
require.Len(t, mounts, 2)
assert.Equal(t, "/", mounts[0].Mount)
assert.Equal(t, "ext4", mounts[0].FSType)
}
func TestCollectSnapshotEndToEnd(t *testing.T) {
root := makeFakeMetricsProc(t)
snap, err := CollectSnapshot(root)
require.NoError(t, err)
assert.InDelta(t, 15.46, snap.CPU.TotalPct, 0.5,
"CPU busy should be in the expected range")
assert.InDelta(t, 50.0, snap.Memory.UsedPct, 0.5,
"memory used should be ~50% from the fixture")
assert.InDelta(t, 12345.67, snap.Uptime.Seconds(), 0.5)
require.Len(t, snap.Networks, 2)
require.Len(t, snap.Disks, 2)
assert.False(t, snap.BootAt.IsZero(), "boot time must be derivable")
}