fix: make bench arm bin provisioning idempotent across trials
All checks were successful
CI / test (pull_request) Successful in 1m5s

provisionArmBin symlinks the shell arm's one allow-listed binary into a
per-sitting bin directory, but a sitting's trials share that directory and
re-provision it each trial, so the second trial's symlinkSync threw EEXIST.
This crashed every shell arm (gitea-axi, tea, raw-api) at more than one
trial per sitting; the gitea-mcp arm was unaffected because its shell is
disabled and it symlinks nothing.

Remove any existing link before re-creating it so provisioning is
idempotent. Add a regression test that provisions the same bin directory
twice and asserts it neither throws nor duplicates the link.
This commit is contained in:
2026-07-16 22:13:38 -04:00
parent 1c92a389dd
commit 9ceadb3482
2 changed files with 21 additions and 2 deletions

View File

@@ -219,4 +219,18 @@ describe("provisionArmBin", () => {
it("throws when the arm's binary cannot be located", () => {
expect(() => provisionArmBin("tea", binDir, () => null)).toThrow(/tea/);
});
it("is idempotent across the trials of one sitting sharing a bin directory", () => {
// A benchmark sitting runs several trials against one per-sitting bin
// directory, so provisionArmBin is called once per trial on the same dir.
// A repeat call must not throw and must leave a single symlink, not a
// duplicate or a partially-clobbered link.
expect(() => {
provisionArmBin("gitea-axi", binDir, locate);
provisionArmBin("gitea-axi", binDir, locate);
}).not.toThrow();
expect(readdirSync(binDir)).toEqual(["gitea-axi"]);
expect(readlinkSync(join(binDir, "gitea-axi"))).toBe("/fake/prefix/gitea-axi");
});
});

View File

@@ -1,4 +1,4 @@
import { accessSync, constants, mkdirSync, symlinkSync } from "node:fs";
import { accessSync, constants, mkdirSync, rmSync, symlinkSync } from "node:fs";
import { join } from "node:path";
import type { Arm } from "./result.js";
@@ -303,7 +303,12 @@ export function provisionArmBin(
`cannot provision the ${arm} arm: its binary "${binary}" was not found on PATH`,
);
}
symlinkSync(target, join(binDir, binary));
// Idempotent: the trials in one sitting share a single bin directory, so a prior
// trial may have already created this link. Remove any existing entry before
// re-linking rather than letting symlinkSync fail with EEXIST on the second trial.
const linkPath = join(binDir, binary);
rmSync(linkPath, { force: true });
symlinkSync(target, linkPath);
}
/** Resolve `binary` to the absolute path of the first executable of that name on PATH. */