diff --git a/src/incus/client.ts b/src/incus/client.ts index 31d9e66..276b63f 100644 --- a/src/incus/client.ts +++ b/src/incus/client.ts @@ -20,7 +20,24 @@ import { around, log, shorten } from "../log.ts"; * predates the group grant cannot reach it — which is a real thing that happens on the * machine that just installed it. */ -const INCUS = (process.env["MESH_LAB_INCUS"] ?? "incus").split(" ").filter(Boolean); +let INCUS = (process.env["MESH_LAB_INCUS"] ?? "incus").split(" ").filter(Boolean); + +/** + * Point every call at another program, and say what it was pointed at before. + * + * **For a test about how the lab reads a failure, never about the hypervisor.** The command was + * read from `MESH_LAB_INCUS` once, when this module loaded — and a test file setting that variable + * in its body set it too late, because an ES module's imports are evaluated before its body. So the + * enumeration tests asked the real incus wherever one was installed and reachable: they passed on a + * machine without incus (the spawn fails) and failed on the workstation that runs the lab, where + * listing succeeds. Injected here, a test names the failing program and gets it, on every machine. + */ +export function useIncusCommand(argv: string[]): string[] { + if (argv.length === 0 || !argv[0]) throw new Error("an incus command needs a program to run"); + const was = INCUS; + INCUS = [...argv]; + return was; +} export interface IncusResult { stdout: string; diff --git a/test/enumerate.test.ts b/test/enumerate.test.ts index 93a8b4d..ee78b51 100644 --- a/test/enumerate.test.ts +++ b/test/enumerate.test.ts @@ -1,11 +1,14 @@ -// Set before importing: the client reads MESH_LAB_INCUS once, at module load. -// `false` is a real program that exits non-zero and prints nothing — which is also the worst -// case, because an empty stderr is how a failure arrives with no explanation. -process.env["MESH_LAB_INCUS"] = "false"; - import { test } from "node:test"; import assert from "node:assert/strict"; -import { instanceExists, taggedInstances, taggedNetworks } from "../src/incus/client.ts"; +import { instanceExists, taggedInstances, taggedNetworks, useIncusCommand } from "../src/incus/client.ts"; + +// `false` is a real program that exits non-zero and prints nothing — which is also the worst +// case, because an empty stderr is how a failure arrives with no explanation. +// +// **Injected, never set in the environment here.** This file used to set MESH_LAB_INCUS in its body, +// which runs after the imports above — so the client had already read the variable, and these tests +// asked the real incus: green on a machine without one, red on the workstation that runs the lab. +useIncusCommand(["false"]); /** * "I cannot see" must never be answered as "there is nothing there."