Files
regex-tools/scripts/python-engine-pack.test.ts

135 lines
3.8 KiB
TypeScript

// @vitest-environment node
import { cp, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { verifyPythonPack } from "./python-engine-pack.mjs";
import {
PYTHON_LEGAL_RESOURCES,
PYTHON_SOURCE_MANIFEST_BASE,
} from "./python-engine-provenance.mjs";
const temporaryDirectories: string[] = [];
afterEach(async () => {
await Promise.all(
temporaryDirectories
.splice(0)
.map((directory) => rm(directory, { recursive: true, force: true })),
);
});
describe("Python engine-pack provenance gate", () => {
it("pins the complete base-runtime source, patch, and legal closure", () => {
expect(PYTHON_LEGAL_RESOURCES.map(({ output }) => output)).toEqual([
"LICENSE.pyodide.txt",
"LICENSE.pyodide-stacktrace-vendors.txt",
"LICENSE.cpython.txt",
"NOTICE.cpython-bundled.rst",
"LICENSE.expat.txt",
"LICENSE.libmpdec.txt",
"LICENSE.hacl-mit.txt",
"LICENSE.libffi.txt",
"LICENSE.hiwire.txt",
"LICENSE.xz.txt",
"LICENSE.zstd.txt",
"LICENSE.sqlite.txt",
"LICENSE.bzip2.txt",
"LICENSE.zlib.txt",
"LICENSE.emscripten.txt",
"NOTICE.emscripten-dlmalloc.txt",
"NOTICE.emscripten-musl.txt",
"LICENSE.llvm-compiler-rt.txt",
"LICENSE.llvm-libcxx.txt",
"LICENSE.llvm-libcxxabi.txt",
"LICENSE.llvm-libunwind.txt",
"LICENSE.emscripten-mini-lz4.txt",
]);
expect(PYTHON_SOURCE_MANIFEST_BASE.patches.cpython).toHaveLength(9);
expect(PYTHON_SOURCE_MANIFEST_BASE.patches.emscripten).toHaveLength(5);
expect(
PYTHON_SOURCE_MANIFEST_BASE.sourceInputs.map(({ id }) => id),
).toEqual([
"pyodide",
"pyodide-build",
"error-stack-parser",
"stackframe",
"cpython",
"libffi",
"hiwire",
"xz-liblzma",
"zstandard",
"sqlite",
"bzip2",
"zlib",
"emscripten",
"hacl-star-preferred-source",
]);
});
it("verifies the installed runtime and independently anchored inventory", async () => {
await expect(
verifyPythonPack(
path.resolve("public", "engines", "python"),
path.resolve(),
),
).resolves.toEqual(
expect.objectContaining({
engineVersion: "CPython 3.14.2 re",
runtime: "Pyodide 314.0.3",
source: expect.objectContaining({
manifest: expect.objectContaining({
path: "SOURCE-MANIFEST.json",
}),
}),
}),
);
}, 30_000);
it("rejects substituted legal material before runtime startup", async () => {
const directory = await mkdtemp(path.join(tmpdir(), "regex-python-pack-"));
temporaryDirectories.push(directory);
const pack = path.join(directory, "python");
await cp(path.resolve("public", "engines", "python"), pack, {
recursive: true,
});
await writeFile(
path.join(pack, "LICENSE.libffi.txt"),
"substituted legal text\n",
);
await expect(verifyPythonPack(pack, path.resolve())).rejects.toThrow(
/libffi legal material SHA-256 mismatch/u,
);
});
it("ships a manifest whose legal records match every pinned output", async () => {
const manifest = JSON.parse(
await readFile(
path.resolve("public", "engines", "python", "SOURCE-MANIFEST.json"),
"utf8",
),
) as {
legalFiles: {
path: string;
sha256: string;
sourceSha256: string;
}[];
};
expect(
manifest.legalFiles.map(({ path: file, sha256, sourceSha256 }) => ({
file,
sha256,
sourceSha256,
})),
).toEqual(
PYTHON_LEGAL_RESOURCES.map(({ output, outputSha256, sourceSha256 }) => ({
file: output,
sha256: outputSha256,
sourceSha256,
})),
);
});
});