feat: add multi-engine regex flavour support
This commit is contained in:
128
scripts/php-engine-pack.test.ts
Normal file
128
scripts/php-engine-pack.test.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
// @vitest-environment node
|
||||
|
||||
import { createHash } from "node:crypto";
|
||||
import {
|
||||
appendFile,
|
||||
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 {
|
||||
buildPhpPack,
|
||||
PHP_ENGINE_LOCK,
|
||||
verifyPhpPack,
|
||||
} from "./php-engine-pack.mjs";
|
||||
|
||||
const temporaryDirectories: string[] = [];
|
||||
|
||||
afterEach(async () => {
|
||||
await Promise.all(
|
||||
temporaryDirectories
|
||||
.splice(0)
|
||||
.map((directory) => rm(directory, { recursive: true, force: true })),
|
||||
);
|
||||
});
|
||||
|
||||
async function digest(file: string): Promise<string> {
|
||||
return createHash("sha256")
|
||||
.update(await readFile(file))
|
||||
.digest("hex");
|
||||
}
|
||||
|
||||
describe("PHP engine-pack gate", () => {
|
||||
it("verifies the installed Asyncify PHP runtime and native smoke cases", async () => {
|
||||
await expect(
|
||||
verifyPhpPack(path.resolve("public", "engines", "php")),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
engineVersion: "PHP 8.5.8 preg / PCRE2 10.44",
|
||||
platform: "wasm32-emscripten",
|
||||
source: expect.objectContaining({
|
||||
runtimeVariant: "PHP 8.5 Asyncify web build (without intl extension)",
|
||||
nativeComponents: expect.objectContaining({
|
||||
linkedComponentCount: 32,
|
||||
excludedDetectionCount: 7,
|
||||
}),
|
||||
}),
|
||||
licensing: expect.objectContaining({
|
||||
nativeInventory: expect.objectContaining({
|
||||
independentlyPinnedLegalAssets: 42,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("pins exact package, loader, and WebAssembly identities", () => {
|
||||
expect(PHP_ENGINE_LOCK.packageVersion).toBe("3.1.46");
|
||||
expect(PHP_ENGINE_LOCK.phpVersion).toBe("8.5.8");
|
||||
expect(PHP_ENGINE_LOCK.pcreVersion).toBe("10.44");
|
||||
expect(PHP_ENGINE_LOCK.asyncMode).toBe("asyncify");
|
||||
expect(PHP_ENGINE_LOCK.npm.web.integrity).toMatch(/^sha512-/u);
|
||||
expect(PHP_ENGINE_LOCK.npm.universal.integrity).toMatch(/^sha512-/u);
|
||||
expect(PHP_ENGINE_LOCK.sourceAssets.wasm).toHaveLength(64);
|
||||
expect(PHP_ENGINE_LOCK.sourceAssets.nativeInventory).toHaveLength(64);
|
||||
expect(Object.keys(PHP_ENGINE_LOCK.legalAssets)).toHaveLength(42);
|
||||
});
|
||||
|
||||
it("builds byte-identical closed packs from pinned npm inputs", async () => {
|
||||
const directory = await mkdtemp(path.join(tmpdir(), "regex-php-pack-"));
|
||||
temporaryDirectories.push(directory);
|
||||
const first = path.join(directory, "first");
|
||||
const second = path.join(directory, "second");
|
||||
|
||||
await buildPhpPack({ output: first });
|
||||
await buildPhpPack({ output: second });
|
||||
|
||||
for (const file of [
|
||||
"php.wasm",
|
||||
"php-loader.mjs",
|
||||
"engine-metadata.json",
|
||||
"native-components.json",
|
||||
"SHA256SUMS",
|
||||
"LICENSE.Emscripten-4.0.19.txt",
|
||||
"LICENSE.llvm-compiler-rt.txt",
|
||||
"LICENSE.PHP-4.0.txt",
|
||||
"LICENSE.PHP-Zend-2.0.txt",
|
||||
"LICENSE.PCRE2-10.44.txt",
|
||||
"LICENSE.php-wasm-GPL-2.0-or-later.txt",
|
||||
"NOTICE.PHP-REDIST-BINS.txt",
|
||||
"PATENTS.libaom-3.12.1.txt",
|
||||
]) {
|
||||
expect(await digest(path.join(first, file))).toBe(
|
||||
await digest(path.join(second, file)),
|
||||
);
|
||||
}
|
||||
}, 30_000);
|
||||
|
||||
it("anchors legal assets independently from the pack checksum manifest", async () => {
|
||||
const directory = await mkdtemp(path.join(tmpdir(), "regex-php-legal-"));
|
||||
temporaryDirectories.push(directory);
|
||||
const pack = path.join(directory, "pack");
|
||||
await cp(path.resolve("public", "engines", "php"), pack, {
|
||||
recursive: true,
|
||||
force: false,
|
||||
errorOnExist: true,
|
||||
});
|
||||
const legalName = "LICENSE.OpenSSL-1.1.1t.txt";
|
||||
const legalFile = path.join(pack, legalName);
|
||||
await appendFile(legalFile, "\n");
|
||||
const checksumsFile = path.join(pack, "SHA256SUMS");
|
||||
const checksums = await readFile(checksumsFile, "utf8");
|
||||
const updated = checksums.replace(
|
||||
new RegExp(`^[a-f0-9]{64} ${legalName}$`, "mu"),
|
||||
`${await digest(legalFile)} ${legalName}`,
|
||||
);
|
||||
expect(updated).not.toBe(checksums);
|
||||
await writeFile(checksumsFile, updated);
|
||||
|
||||
await expect(verifyPhpPack(pack)).rejects.toThrow(
|
||||
`Packed PHP legal asset ${legalName} SHA-256 mismatch`,
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user