In /proc/stat, guest is already inside user (and guest_nice inside nice). Peardata was adding guest into the total again, which shrinks every other slice — including idle.
CI / test (push) Successful in 1m0s
Release rolling / release (push) Failing after 1m50s

readFileCached capped at 64KB. On 56-core hosts /proc/interrupts (and similar) often exceeds that — reads were silently truncated. Buffer now grows (up to 1MB). That didn’t break system.cpu idle (aggregate line is first), but it was a real high-core regression.
This commit is contained in:
Raven Scott
2026-07-22 12:36:30 -04:00
parent 6570276179
commit da9541528e
5 changed files with 114 additions and 44 deletions
+44
View File
@@ -0,0 +1,44 @@
import test from 'brittle'
import { cpuDeltaPct } from '../server/services/collector.js'
test('cpuDeltaPct: idle is 100 with no prev', (t) => {
const v = cpuDeltaPct(null, { user: 1, idle: 9 })
t.is(v.idle, 100)
})
test('cpuDeltaPct: bare metal percentages sum to ~100', (t) => {
const prev = { user: 0, nice: 0, system: 0, idle: 0, iowait: 0, irq: 0, softirq: 0, steal: 0, guest: 0, guest_nice: 0 }
const cur = { user: 20, nice: 0, system: 10, idle: 60, iowait: 10, irq: 0, softirq: 0, steal: 0, guest: 0, guest_nice: 0 }
const v = cpuDeltaPct(prev, cur)
t.is(v.user, 20)
t.is(v.system, 10)
t.is(v.idle, 60)
t.is(v.iowait, 10)
const sum = Object.values(v).reduce((a, b) => a + b, 0)
t.ok(Math.abs(sum - 100) < 0.01, `sum=${sum}`)
})
test('cpuDeltaPct: guest already in user is not double-counted (idle stays correct)', (t) => {
// Kernel: user includes guest. True idle should be 55%, not ~45%.
const prev = { user: 0, nice: 0, system: 0, idle: 0, iowait: 0, irq: 0, softirq: 0, steal: 0, guest: 0, guest_nice: 0 }
const cur = {
user: 30, // includes 20 guest
nice: 0,
system: 10,
idle: 55,
iowait: 5,
irq: 0,
softirq: 0,
steal: 0,
guest: 20,
guest_nice: 0,
}
const v = cpuDeltaPct(prev, cur)
t.ok(Math.abs(v.idle - 55) < 1e-9, `idle=${v.idle}`)
t.is(v.guest, 20)
t.is(v.user, 10) // 30 - 20
t.is(v.system, 10)
t.is(v.iowait, 5)
const sum = Object.values(v).reduce((a, b) => a + b, 0)
t.ok(Math.abs(sum - 100) < 0.01, `sum=${sum}`)
})