mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-30 15:15:24 +00:00
81 lines
2.8 KiB
TypeScript
81 lines
2.8 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
|
|
const execCommand = vi.fn();
|
|
vi.mock("../../../src/backend/proxmox/common-utils.js", () => ({
|
|
execCommand: (...args: unknown[]) => execCommand(...args),
|
|
toFixedNum: (n: number | null | undefined, digits = 2) => {
|
|
if (typeof n !== "number" || !Number.isFinite(n)) return null;
|
|
return Number(n.toFixed(digits));
|
|
},
|
|
}));
|
|
|
|
import { collectProxmoxNodeStatus } from "../../../src/backend/proxmox/node-status-collector.js";
|
|
import type { Client } from "ssh2";
|
|
|
|
const fakeClient = {} as Client;
|
|
|
|
function result(stdout: string, code: number | null = 0) {
|
|
return { stdout, stderr: "", code };
|
|
}
|
|
|
|
beforeEach(() => {
|
|
execCommand.mockReset();
|
|
});
|
|
|
|
describe("collectProxmoxNodeStatus", () => {
|
|
it("parses a healthy pvesh /nodes/{node}/status response", async () => {
|
|
execCommand.mockResolvedValueOnce(
|
|
result(
|
|
JSON.stringify({
|
|
cpu: 0.15,
|
|
cpuinfo: { cores: 8 },
|
|
loadavg: ["0.5", "0.6", "0.7"],
|
|
memory: { used: 4 * 1024 ** 3, total: 16 * 1024 ** 3 },
|
|
rootfs: { used: 20 * 1024 ** 3, total: 100 * 1024 ** 3 },
|
|
uptime: 90061,
|
|
hostname: "pve1",
|
|
kversion: "Linux 6.8.0",
|
|
pveversion: "pve-manager/8.2.0",
|
|
}),
|
|
),
|
|
);
|
|
|
|
const res = await collectProxmoxNodeStatus(fakeClient, "pve1");
|
|
|
|
expect(res.cpu.percent).toBe(15);
|
|
expect(res.cpu.cores).toBe(8);
|
|
expect(res.cpu.load).toEqual([0.5, 0.6, 0.7]);
|
|
expect(res.memory.percent).toBe(25);
|
|
expect(res.memory.usedGiB).toBeCloseTo(4, 1);
|
|
expect(res.memory.totalGiB).toBeCloseTo(16, 1);
|
|
expect(res.disk.percent).toBe(20);
|
|
expect(res.uptime.seconds).toBe(90061);
|
|
expect(res.uptime.formatted).toBe("1d 1h 1m");
|
|
expect(res.system.hostname).toBe("pve1");
|
|
expect(res.system.kernel).toBe("Linux 6.8.0");
|
|
expect(res.system.pveVersion).toBe("pve-manager/8.2.0");
|
|
});
|
|
|
|
it("returns a fully null-filled shape when pvesh exits non-zero", async () => {
|
|
execCommand.mockResolvedValueOnce(result("", 1));
|
|
const res = await collectProxmoxNodeStatus(fakeClient, "pve1");
|
|
expect(res.cpu.percent).toBeNull();
|
|
expect(res.memory.percent).toBeNull();
|
|
expect(res.disk.percent).toBeNull();
|
|
expect(res.uptime.seconds).toBeNull();
|
|
expect(res.system.hostname).toBeNull();
|
|
});
|
|
|
|
it("returns null-filled shape on malformed JSON", async () => {
|
|
execCommand.mockResolvedValueOnce(result("not json", 0));
|
|
const res = await collectProxmoxNodeStatus(fakeClient, "pve1");
|
|
expect(res.cpu.percent).toBeNull();
|
|
});
|
|
|
|
it("rejects an unsafe node name before running any command", async () => {
|
|
const res = await collectProxmoxNodeStatus(fakeClient, "pve1; rm -rf /");
|
|
expect(res.cpu.percent).toBeNull();
|
|
expect(execCommand).not.toHaveBeenCalled();
|
|
});
|
|
});
|