ed4c78bc0f
- Enhance CI workflows to build and reuse native addon artifacts instead of recompiling. - Update bazel cache actions with selective backend detection and separate remote and disk modes. - Add `--source` CLI option to install prebuilt native targets without requiring Bazel. - Increase Kata runner memory configuration from 12Gi to 24Gi.
157 lines
6.3 KiB
TypeScript
157 lines
6.3 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import * as fs from "node:fs/promises";
|
|
import * as os from "node:os";
|
|
import * as path from "node:path";
|
|
import { $ } from "bun";
|
|
import {
|
|
conventionOutputPaths,
|
|
type HostInfo,
|
|
hostTargetName,
|
|
parseBazelFilesOutput,
|
|
parseCliArgs,
|
|
resolveTargetLabels,
|
|
} from "./bazel-natives";
|
|
|
|
const linuxModern: HostInfo = { platform: "linux", arch: "x64", avx2: true };
|
|
const linuxBaseline: HostInfo = { platform: "linux", arch: "x64", avx2: false };
|
|
const macArm: HostInfo = { platform: "darwin", arch: "arm64", avx2: false };
|
|
|
|
describe("hostTargetName", () => {
|
|
test("picks the x64 variant from AVX2 support", () => {
|
|
expect(hostTargetName(linuxModern)).toBe("linux-x64-modern");
|
|
expect(hostTargetName(linuxBaseline)).toBe("linux-x64-baseline");
|
|
// darwin x64 ships baseline only; AVX2 must not invent a modern target.
|
|
expect(hostTargetName({ platform: "darwin", arch: "x64", avx2: true })).toBe("darwin-x64-baseline");
|
|
});
|
|
|
|
test("maps non-x64 and windows hosts", () => {
|
|
expect(hostTargetName(macArm)).toBe("darwin-arm64");
|
|
expect(hostTargetName({ platform: "linux", arch: "arm64", avx2: false })).toBe("linux-arm64");
|
|
expect(hostTargetName({ platform: "win32", arch: "x64", avx2: true })).toBe("win32-x64-baseline");
|
|
});
|
|
|
|
test("rejects hosts without an addon target", () => {
|
|
expect(() => hostTargetName({ platform: "freebsd", arch: "x64", avx2: false })).toThrow(
|
|
/No pi_natives addon target/,
|
|
);
|
|
expect(() => hostTargetName({ platform: "win32", arch: "arm64", avx2: false })).toThrow(
|
|
/No pi_natives addon target/,
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("resolveTargetLabels", () => {
|
|
test("maps explicit names, pseudo-targets, and aggregates to labels", () => {
|
|
expect(resolveTargetLabels(["linux-x64-baseline", "linux-x64-modern"], macArm)).toEqual([
|
|
"//:natives-linux-x64-baseline",
|
|
"//:natives-linux-x64-modern",
|
|
]);
|
|
expect(resolveTargetLabels(["host"], linuxModern)).toEqual(["//:natives-linux-x64-modern"]);
|
|
expect(resolveTargetLabels(["linux-all", "darwin-all"], macArm)).toEqual([
|
|
"//:natives-linux-all",
|
|
"//:natives-darwin-all",
|
|
]);
|
|
});
|
|
|
|
test("deduplicates and rejects unknown targets", () => {
|
|
expect(resolveTargetLabels(["host", "darwin-arm64"], macArm)).toEqual(["//:natives-darwin-arm64"]);
|
|
expect(() => resolveTargetLabels(["linux-x64"], macArm)).toThrow(/Unknown native target "linux-x64"/);
|
|
});
|
|
});
|
|
|
|
describe("conventionOutputPaths", () => {
|
|
test("builds bazel-bin paths with canonical filenames (musl reuses linux names)", () => {
|
|
expect(conventionOutputPaths(["linux-musl-x64-baseline", "win32-x64-baseline"], macArm)).toEqual([
|
|
"bazel-bin/natives-linux-musl-x64-baseline/pi_natives.linux-x64-baseline.node",
|
|
"bazel-bin/natives-win32-x64-baseline/pi_natives.win32-x64-baseline.node",
|
|
]);
|
|
});
|
|
|
|
test("expands aggregates and the host pseudo-target", () => {
|
|
expect(conventionOutputPaths(["darwin-all"], macArm)).toEqual([
|
|
"bazel-bin/natives-darwin-arm64/pi_natives.darwin-arm64.node",
|
|
"bazel-bin/natives-darwin-x64-baseline/pi_natives.darwin-x64-baseline.node",
|
|
]);
|
|
expect(conventionOutputPaths(["host"], linuxBaseline)).toEqual([
|
|
"bazel-bin/natives-linux-x64-baseline/pi_natives.linux-x64-baseline.node",
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe("parseBazelFilesOutput", () => {
|
|
test("keeps only .node paths, trimmed and deduplicated", () => {
|
|
const output = [
|
|
"bazel-bin/natives-linux-x64-baseline/pi_natives.linux-x64-baseline.node",
|
|
" bazel-bin/natives-linux-x64-modern/pi_natives.linux-x64-modern.node ",
|
|
"bazel-bin/natives-linux-x64-baseline/pi_natives.linux-x64-baseline.node",
|
|
"INFO: Analyzed 2 targets (0 packages loaded, 0 targets configured).",
|
|
"",
|
|
].join("\n");
|
|
expect(parseBazelFilesOutput(output)).toEqual([
|
|
"bazel-bin/natives-linux-x64-baseline/pi_natives.linux-x64-baseline.node",
|
|
"bazel-bin/natives-linux-x64-modern/pi_natives.linux-x64-modern.node",
|
|
]);
|
|
});
|
|
|
|
test("returns empty for output without addon files", () => {
|
|
expect(parseBazelFilesOutput("INFO: Build completed successfully\n")).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe("parseCliArgs", () => {
|
|
test("splits targets, paths, and passthrough bazel args", () => {
|
|
expect(
|
|
parseCliArgs(["linux-x64-baseline", "linux-x64-modern", "--dest", "out", "--", "--config=ci", "--dest"]),
|
|
).toEqual({
|
|
targets: ["linux-x64-baseline", "linux-x64-modern"],
|
|
dest: "out",
|
|
source: null,
|
|
bazelArgs: ["--config=ci", "--dest"],
|
|
});
|
|
expect(parseCliArgs(["host", "--source", "artifact"])).toEqual({
|
|
targets: ["host"],
|
|
dest: null,
|
|
source: "artifact",
|
|
bazelArgs: [],
|
|
});
|
|
});
|
|
|
|
test("rejects invalid build and artifact source combinations", () => {
|
|
expect(() => parseCliArgs([])).toThrow(/Usage:/);
|
|
expect(() => parseCliArgs(["--", "--config=ci"])).toThrow(/Usage:/);
|
|
expect(() => parseCliArgs(["host", "--config=ci"])).toThrow(/Unknown flag --config=ci/);
|
|
expect(() => parseCliArgs(["host", "--dest"])).toThrow(/--dest requires/);
|
|
expect(() => parseCliArgs(["host", "--source"])).toThrow(/--source requires/);
|
|
expect(() => parseCliArgs(["host", "--source", "artifact", "--", "--config=ci"])).toThrow(
|
|
/--source cannot be combined/,
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("artifact source install", () => {
|
|
test("installs exact target outputs without invoking Bazel", async () => {
|
|
const root = await fs.mkdtemp(path.join(os.tmpdir(), "omp-native-artifacts-"));
|
|
const source = path.join(root, "source");
|
|
const dest = path.join(root, "dest");
|
|
const baseline = "pi_natives.linux-x64-baseline.node";
|
|
const modern = "pi_natives.linux-x64-modern.node";
|
|
try {
|
|
await fs.mkdir(path.join(source, "natives-linux-x64-baseline"), { recursive: true });
|
|
await fs.mkdir(path.join(source, "natives-linux-x64-modern"), { recursive: true });
|
|
await Bun.write(path.join(source, "natives-linux-x64-baseline", baseline), "baseline");
|
|
await Bun.write(path.join(source, "natives-linux-x64-modern", modern), "modern");
|
|
|
|
const result =
|
|
await $`${process.execPath} ${path.join(import.meta.dir, "bazel-natives.ts")} linux-x64-baseline linux-x64-modern --source ${source} --dest ${dest}`
|
|
.quiet()
|
|
.nothrow();
|
|
|
|
expect(result.exitCode).toBe(0);
|
|
expect(await Bun.file(path.join(dest, baseline)).text()).toBe("baseline");
|
|
expect(await Bun.file(path.join(dest, modern)).text()).toBe("modern");
|
|
} finally {
|
|
await fs.rm(root, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|