mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-22 05:59:31 +08:00
- Enforce oxlint and oxfmt for owned JavaScript and TypeScript with independent CI checks. - Preserve compiler import boundaries and protected fixtures while cleaning up lint findings. - Standardize source formatting and validate import, fixture, and embedded-source protections.
179 lines
6.2 KiB
TypeScript
179 lines
6.2 KiB
TypeScript
import { spawnSync } from "node:child_process";
|
|
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { expect, test } from "vitest";
|
|
import { analyzeInChild, compileInChild } from "./self-hosting-compiler-process.js";
|
|
import {
|
|
NATIVE_TARGETS,
|
|
nativeCodegenTarget,
|
|
} from "../../packages/compiler/src/backend/targets.js";
|
|
import type { NativeLinkFeatures } from "../../packages/compiler/src/backend/native-link-info.js";
|
|
import type { RuntimePackManifest } from "../../packages/compiler/src/backend/runtime-pack-core.js";
|
|
|
|
const root = join(import.meta.dirname, "../..");
|
|
const entry = join(root, "tests/fixtures/self-hosting/runtime-pack.ts");
|
|
const base: NativeLinkFeatures = {
|
|
dynamic: false,
|
|
regex: false,
|
|
copying: false,
|
|
textDecoderLegacy: false,
|
|
fileHandle: false,
|
|
fetch: false,
|
|
netIsland: false,
|
|
zlib: false,
|
|
assert: false,
|
|
inspect: false,
|
|
dynInvoke: false,
|
|
dc: false,
|
|
dynAsync: false,
|
|
events: false,
|
|
emitter: false,
|
|
symbol: false,
|
|
bigint: false,
|
|
searchParams: false,
|
|
qs: false,
|
|
parseArgs: false,
|
|
stream: false,
|
|
net: false,
|
|
http: false,
|
|
http2: false,
|
|
dgram: false,
|
|
watch: false,
|
|
foreignFfi: false,
|
|
nodeTest: false,
|
|
tls: false,
|
|
tlsCa: false,
|
|
};
|
|
|
|
test("runtime manifest validation and selection are entirely static", async () => {
|
|
const coverage = await analyzeInChild(entry, { dynamic: false });
|
|
expect(coverage.preflightFailed).toBe(false);
|
|
expect(coverage.stats.statementsTotal).toBeGreaterThan(50);
|
|
expect(coverage.stats.statementsFailed).toBe(0);
|
|
expect(coverage.stats.statementsIsland).toBe(0);
|
|
expect(coverage.stats.functionsSkipped).toBe(0);
|
|
});
|
|
|
|
for (const backend of ["llvm"] as const) {
|
|
test(`native runtime manifest selection matches Node (${backend})`, async () => {
|
|
const directory = mkdtempSync(
|
|
join(process.platform === "win32" ? tmpdir() : "/tmp", "scriptc-pack-selection-"),
|
|
);
|
|
try {
|
|
const built = await compileInChild(entry, {
|
|
outDir: directory,
|
|
outPath: join(directory, "selection" + (process.platform === "win32" ? ".exe" : "")),
|
|
backend,
|
|
dynamic: false,
|
|
optimization: "dev",
|
|
sanitize: process.env["SCRIPTC_SAN"] === "1",
|
|
});
|
|
if (!built.ok) throw new Error(JSON.stringify(built.diagnostics));
|
|
expect(built.backend).toBe(backend);
|
|
const input = join(directory, "request.json");
|
|
const check = (request: object, status: number, name: string) => {
|
|
writeFileSync(input, JSON.stringify(request));
|
|
const options = { cwd: root, timeout: 30_000, maxBuffer: 16 * 1024 * 1024 };
|
|
const oracle = spawnSync(process.execPath, ["--import", "tsx", entry, input], options);
|
|
const native = spawnSync(built.binaryPath, [input], {
|
|
...options,
|
|
env: { ...process.env, PATH: "" },
|
|
});
|
|
for (const result of [oracle, native]) {
|
|
expect(result.error, name).toBeUndefined();
|
|
expect(result.signal, name).toBeNull();
|
|
expect(result.status, `${name}: ${result.stderr}`).toBe(status);
|
|
}
|
|
if (status === 0)
|
|
expect(JSON.parse(native.stdout.toString()), name).toEqual(
|
|
JSON.parse(oracle.stdout.toString()),
|
|
);
|
|
else expect(native.stdout.toString(), name).toBe(oracle.stdout.toString());
|
|
expect(native.stderr, name).toEqual(oracle.stderr);
|
|
return native.stdout.toString();
|
|
};
|
|
// The installed manifest exercises the actual predicates and variants.
|
|
// Substitute each target identity to exercise validation on every host.
|
|
const hostTarget = nativeCodegenTarget()!;
|
|
const packageDir = join(
|
|
root,
|
|
"packages",
|
|
hostTarget.runtimePackPackage.replace("@scriptc/", ""),
|
|
);
|
|
const installed = JSON.parse(
|
|
readFileSync(join(packageDir, "runtime-pack.json"), "utf8"),
|
|
) as RuntimePackManifest;
|
|
for (const target of NATIVE_TARGETS) {
|
|
const manifest: RuntimePackManifest = {
|
|
...installed,
|
|
package: target.runtimePackPackage,
|
|
target: {
|
|
name: target.name,
|
|
llvm_triple: target.llvmTriple,
|
|
architecture: target.architecture,
|
|
object_format: target.objectFormat,
|
|
minimum_os: target.minimumOs,
|
|
},
|
|
compiler: { ...installed.compiler, target: target.llvmTriple },
|
|
};
|
|
const request = {
|
|
manifest,
|
|
target,
|
|
packageName: manifest.package,
|
|
packageVersion: manifest.version,
|
|
compilerVersion: manifest.version,
|
|
features: base,
|
|
flavor: "release",
|
|
};
|
|
check(request, 0, target.name + " base");
|
|
if (target.name === hostTarget.name) {
|
|
for (const name of Object.keys(base)) {
|
|
check({ ...request, features: { ...base, [name]: true } }, 0, target.name + " " + name);
|
|
}
|
|
const all = Object.fromEntries(Object.keys(base).map((name) => [name, true]));
|
|
check({ ...request, features: all, flavor: "dev" }, 0, target.name + " all");
|
|
}
|
|
check({ ...request, packageVersion: "mismatch" }, 1, "package version");
|
|
check(
|
|
{
|
|
...request,
|
|
manifest: { ...manifest, target: { ...manifest.target, minimum_os: "other" } },
|
|
},
|
|
1,
|
|
"target identity",
|
|
);
|
|
check(
|
|
{ ...request, manifest: { ...manifest, runtime_abi: { version: 0, marker: "wrong" } } },
|
|
1,
|
|
"runtime ABI",
|
|
);
|
|
check({ ...request, manifest: { ...manifest, flavors: {} } }, 1, "missing flavor");
|
|
check(
|
|
{
|
|
...request,
|
|
manifest: {
|
|
...manifest,
|
|
archives: [
|
|
{ path: "../escape", sha256: "0".repeat(64), size: 1, id: "zlib", predicate: true },
|
|
],
|
|
},
|
|
},
|
|
1,
|
|
"artifact traversal",
|
|
);
|
|
check(
|
|
{
|
|
...request,
|
|
manifest: { ...manifest, system_libraries: [{ name: "m", predicate: { any: [1] } }] },
|
|
},
|
|
1,
|
|
"invalid predicate",
|
|
);
|
|
}
|
|
} finally {
|
|
rmSync(directory, { recursive: true, force: true });
|
|
}
|
|
});
|
|
}
|