fix: make bench arm bin provisioning idempotent across trials #34
@@ -219,4 +219,18 @@ describe("provisionArmBin", () => {
|
|||||||
it("throws when the arm's binary cannot be located", () => {
|
it("throws when the arm's binary cannot be located", () => {
|
||||||
expect(() => provisionArmBin("tea", binDir, () => null)).toThrow(/tea/);
|
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");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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 { join } from "node:path";
|
||||||
import type { Arm } from "./result.js";
|
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`,
|
`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. */
|
/** Resolve `binary` to the absolute path of the first executable of that name on PATH. */
|
||||||
|
|||||||
Reference in New Issue
Block a user