Files
system_update/server/services/machineMetrics.test.ts
T
gilles c390addadb feat(metrics): machine_metrics_simple — CPU/RAM/disque live par machine (tâche 4)
- template machine-metrics (loadavg/nproc, /proc/meminfo, df -B1) non destructif
- parseMetrics (TDD) → cpu load/cores, mémoire kB→B + %, filesystems, warnings >=90%
- collectMetrics (SSH léger) persiste machine_metrics_latest ; getLatestMetrics (sans SSH)
- routes GET /machines/:id/metrics + POST /metrics/collect ; api latestMetrics/collectMetrics
- section Hardware : bloc métriques live (CPU/RAM/disques + alertes) + bouton Collecter
  → comble le gap « Health » de la tâche 3

tsc 0 · 108 tests · build OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 17:01:45 +02:00

50 lines
1.4 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { parseMetrics } from "./machineMetrics.js";
const RAW = [
"===SU:METRICS_CPU===",
"0.08 0.12 0.09 1/234 5678",
"4",
"===SU:METRICS_MEM===",
"MemTotal: 4194304 kB",
"MemAvailable: 2097152 kB",
"===SU:METRICS_FS===",
"FS\t/\text4\t32000000000\t9280000000\t29%",
"FS\t/boot\text2\t500000000\t475000000\t95%",
"===SU:EXIT=0===",
].join("\n");
describe("parseMetrics", () => {
it("lit load average et cores", () => {
const m = parseMetrics(RAW);
expect(m.cpu.load1).toBe(0.08);
expect(m.cpu.load5).toBe(0.12);
expect(m.cpu.cores).toBe(4);
});
it("calcule la mémoire en octets (kB→B) et le pourcentage utilisé", () => {
const m = parseMetrics(RAW);
expect(m.memory.totalBytes).toBe(4194304 * 1024);
expect(m.memory.availableBytes).toBe(2097152 * 1024);
expect(m.memory.usedBytes).toBe((4194304 - 2097152) * 1024);
expect(m.memory.usedPercent).toBe(50);
});
it("liste les systèmes de fichiers", () => {
const m = parseMetrics(RAW);
expect(m.filesystems).toHaveLength(2);
expect(m.filesystems[0]).toEqual({
mount: "/",
fstype: "ext4",
sizeBytes: 32000000000,
usedBytes: 9280000000,
usedPercent: 29,
});
});
it("émet un warning pour un FS quasi plein (>=90%)", () => {
const m = parseMetrics(RAW);
expect(m.warnings.some((w) => w.includes("/boot"))).toBe(true);
});
});