fix(windows): restore native verification fixture coverage (#7479)
Restore independent PE fixtures and dependency-complete standalone artifact verifier tests. Execute existing real Windows native behavior and inspection recovery proofs before unrelated curated tests. Validation: 101 focused tests; full typecheck; scoped lint, module/discovery/format/docs checks; valid/corrupt real-image verifier controls; real Windows artifact, behavior, and inspection recovery proof steps passed. Greptile found no actionable issues. Codex review quota exhausted. CI remains red from exact-base failures: Source 9, Windows 7 (base 15; loader 8 repaired), and built shard 4's 7 matching failures; 7 other shards cancelled by fail-fast. Later Windows package/Node 22/24 checks skipped. User explicitly authorized bypass of established main failures. No claim of complete CI or unavailable coverage. Fixes #7474.
This commit is contained in:
1 parent
d6f88becd5
commit
740c0f5615
7 files changed
+165
-97
No files matched your search
+18
-16
@@ -855,6 +855,24 @@ jobs:
|
||||
# The matching native artifact establishes real Job Object and private
|
||||
# runtime boundaries for these fixtures. Ghidra and Java are not needed;
|
||||
# real engine claims remain in the separate controlled-provider workflow.
|
||||
# Run native proofs before the broad curated suite so an unrelated
|
||||
# fixture failure cannot hide the real control and recovery checks.
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
name: windows-process-boundary-fixture
|
||||
path: .cache/windows-process-boundary/
|
||||
# Passing the fixture adds the breakaway, caller/child token, environment
|
||||
# semantics and ancestor reparse observations, which the lane skips
|
||||
# entirely when it is absent.
|
||||
- run: >-
|
||||
npm run verify:windows-native -- .
|
||||
"${{ github.workspace }}\.cache\windows-process-boundary\process-boundary.exe"
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
name: windows-native-inspection-fixture
|
||||
path: .cache/windows-native-inspection-fixture/
|
||||
- name: Verify native inspection failure ownership and recovery
|
||||
run: node scripts/verify-windows-native-inspection.mjs
|
||||
- name: Run curated Windows capability tests
|
||||
run: >-
|
||||
npx vitest run --coverage.enabled=false
|
||||
@@ -907,22 +925,6 @@ jobs:
|
||||
tests/process-global/runnerCancellation.test.ts
|
||||
tests/process-global/windowsOwnedCommand.test.ts
|
||||
tests/conformance/providers/ghidra/realGhidraWindowsWorkflow.test.ts
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
name: windows-process-boundary-fixture
|
||||
path: .cache/windows-process-boundary/
|
||||
# Passing the fixture adds the breakaway, caller/child token, environment
|
||||
# semantics and ancestor reparse observations, which the lane skips
|
||||
# entirely when it is absent.
|
||||
- run: >-
|
||||
npm run verify:windows-native -- .
|
||||
"${{ github.workspace }}\.cache\windows-process-boundary\process-boundary.exe"
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
name: windows-native-inspection-fixture
|
||||
path: .cache/windows-native-inspection-fixture/
|
||||
- name: Verify native inspection failure ownership and recovery
|
||||
run: node scripts/verify-windows-native-inspection.mjs
|
||||
- name: Verify real Node Inspector discovery and observation
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
|
||||
@@ -232,6 +232,12 @@ C++ compiler, or the same way they do, and pass its path:
|
||||
node scripts/verify-windows-native.mjs . C:\fixtures\process-boundary.exe
|
||||
```
|
||||
|
||||
The capability lane runs native behavior and inspection-recovery proofs after
|
||||
the verified artifact and runtime build, before the broad curated test group.
|
||||
An unrelated curated failure therefore cannot hide those real native checks.
|
||||
Inert PE identity fixtures are shared under `tests/fixtures/`; they exercise
|
||||
artifact admission and simulated loader outcomes, never native authority.
|
||||
|
||||
`nonAdminRunner.cc` is a test-only launcher for an elevated development shell.
|
||||
It duplicates an existing non-elevated Explorer token belonging to the same
|
||||
user, creates private temporary window-station objects, and launches the test
|
||||
|
||||
@@ -1,33 +1,14 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { expect, it } from "vitest";
|
||||
import { windowsNativeArtifactFixture } from "../../tests/fixtures/windowsNativeArtifact.js";
|
||||
import {
|
||||
createWindowsNativeManifest,
|
||||
parseWindowsNativeManifest,
|
||||
validateWindowsNativeArtifact,
|
||||
} from "./windowsNativeArtifact.js";
|
||||
|
||||
const fixture = () => {
|
||||
const bytes = Buffer.alloc(152);
|
||||
bytes.write("MZ");
|
||||
bytes.writeUInt32LE(64, 0x3c);
|
||||
bytes.write("PE\0\0", 64, "ascii");
|
||||
bytes.writeUInt16LE(0x8664, 68);
|
||||
bytes.writeUInt16LE(64, 84);
|
||||
bytes.writeUInt16LE(0x20b, 88);
|
||||
const manifest = {
|
||||
packageVersion: "1.0.0",
|
||||
platform: "win32",
|
||||
architecture: "x64",
|
||||
abiVersion: 1,
|
||||
nodeApiVersion: 8,
|
||||
artifact: "rea-windows-x64.node",
|
||||
artifactSha256: createHash("sha256").update(bytes).digest("hex"),
|
||||
};
|
||||
return { bytes, manifest };
|
||||
};
|
||||
|
||||
it("produces and admits the exact manifest/byte identity", () => {
|
||||
const { bytes, manifest } = fixture();
|
||||
const { bytes, manifest } = windowsNativeArtifactFixture();
|
||||
const created = createWindowsNativeManifest("1.0.0", bytes);
|
||||
expect(created).toEqual({ ok: true, value: manifest });
|
||||
const parsed = parseWindowsNativeManifest(manifest, "1.0.0");
|
||||
@@ -60,7 +41,7 @@ it.each([null, [], {}, "manifest"])(
|
||||
);
|
||||
|
||||
it("rejects missing and unknown manifest fields", () => {
|
||||
const { manifest } = fixture();
|
||||
const { manifest } = windowsNativeArtifactFixture();
|
||||
expect(
|
||||
parseWindowsNativeManifest({ ...manifest, extra: true }, "1.0.0"),
|
||||
).toMatchObject({ ok: false });
|
||||
@@ -84,7 +65,7 @@ it.each([
|
||||
"artifact",
|
||||
"artifactSha256",
|
||||
])("rejects unsupported %s", (key) => {
|
||||
const { manifest } = fixture();
|
||||
const { manifest } = windowsNativeArtifactFixture();
|
||||
expect(
|
||||
parseWindowsNativeManifest({ ...manifest, [key]: "unsupported" }, "1.0.0"),
|
||||
).toMatchObject({ ok: false });
|
||||
@@ -102,12 +83,12 @@ it.each([0, 63, 64, 89, 128])(
|
||||
it.each(["offset", "signature", "machine", "optional magic"])(
|
||||
"rejects invalid PE %s with a matching digest",
|
||||
(field) => {
|
||||
const { bytes } = fixture();
|
||||
const { bytes } = windowsNativeArtifactFixture();
|
||||
if (field === "offset") bytes.writeUInt32LE(0xffff_ffff, 0x3c);
|
||||
if (field === "signature") bytes.write("BAD!", 64, "ascii");
|
||||
if (field === "machine") bytes.writeUInt16LE(0x14c, 68);
|
||||
if (field === "optional magic") bytes.writeUInt16LE(0x10b, 88);
|
||||
const { manifest } = fixture();
|
||||
const { manifest } = windowsNativeArtifactFixture();
|
||||
manifest.artifactSha256 = createHash("sha256").update(bytes).digest("hex");
|
||||
const parsed = parseWindowsNativeManifest(manifest, "1.0.0");
|
||||
if (!parsed.ok) throw parsed.error;
|
||||
@@ -121,7 +102,7 @@ it.each(["offset", "signature", "machine", "optional magic"])(
|
||||
it.each([0, 1, 65, 0xffff])(
|
||||
"rejects an unavailable declared optional header of %i bytes",
|
||||
(length) => {
|
||||
const { bytes } = fixture();
|
||||
const { bytes } = windowsNativeArtifactFixture();
|
||||
bytes.writeUInt16LE(length, 84);
|
||||
expect(createWindowsNativeManifest("1.0.0", bytes)).toMatchObject({
|
||||
ok: false,
|
||||
@@ -133,7 +114,7 @@ it.each([0, 1, 65, 0xffff])(
|
||||
it.each([2, 32, 63, 64])(
|
||||
"admits PE32+ identity in a present declared header of %i bytes",
|
||||
(length) => {
|
||||
const { bytes } = fixture();
|
||||
const { bytes } = windowsNativeArtifactFixture();
|
||||
bytes.writeUInt16LE(length, 84);
|
||||
expect(createWindowsNativeManifest("1.0.0", bytes)).toMatchObject({
|
||||
ok: true,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { createHash } from "node:crypto";
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { windowsNativeArtifactFixture } from "../../tests/fixtures/windowsNativeArtifact.js";
|
||||
import { inspectWindowsNativeReadiness } from "../process/WindowsAuthority.js";
|
||||
import {
|
||||
loadWindowsNativeAuthority,
|
||||
@@ -15,21 +16,7 @@ const fixture = (
|
||||
privateBridgeDescriptorAccess?: unknown;
|
||||
} = {},
|
||||
) => {
|
||||
const bytes = Buffer.alloc(128);
|
||||
bytes.write("MZ");
|
||||
bytes.writeUInt32LE(64, 0x3c);
|
||||
bytes.write("PE\0\0", 64, "ascii");
|
||||
bytes.writeUInt16LE(0x8664, 68);
|
||||
bytes.writeUInt16LE(0x20b, 88);
|
||||
const manifest = {
|
||||
packageVersion: "1.0.0",
|
||||
platform: "win32",
|
||||
architecture: "x64",
|
||||
abiVersion: 1,
|
||||
nodeApiVersion: 8,
|
||||
artifact: "rea-windows-x64.node",
|
||||
artifactSha256: createHash("sha256").update(bytes).digest("hex"),
|
||||
};
|
||||
const { bytes, manifest } = windowsNativeArtifactFixture();
|
||||
const identity = {
|
||||
requestedPath: "D:\\fixture\\runtime",
|
||||
finalPath: "\\\\?\\D:\\fixture\\runtime",
|
||||
|
||||
@@ -1,13 +1,57 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { copyFile, mkdir, writeFile } from "node:fs/promises";
|
||||
import { dirname, join } from "node:path";
|
||||
import { access, copyFile, mkdir, readFile, writeFile } from "node:fs/promises";
|
||||
import { dirname, join, relative, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { parse } from "@babel/parser";
|
||||
import { expect } from "vitest";
|
||||
import { processTest } from "../../support/process/processFixture.js";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { windowsNativeArtifactFixture } from "../../fixtures/windowsNativeArtifact.js";
|
||||
|
||||
const repository = fileURLToPath(new URL("../../..", import.meta.url));
|
||||
|
||||
/** Copy the selected entry's relative ESM graph; package dependencies stay absent. */
|
||||
const copyModuleGraph = async (root: string, entry: string): Promise<void> => {
|
||||
const pending = [join(repository, entry)];
|
||||
const copied = new Set<string>();
|
||||
while (pending.length > 0) {
|
||||
const source = pending.pop();
|
||||
if (source === undefined || copied.has(source)) continue;
|
||||
copied.add(source);
|
||||
const output = join(root, relative(repository, source));
|
||||
const text = await readFile(source, "utf8");
|
||||
await mkdir(dirname(output), { recursive: true });
|
||||
await copyFile(source, output);
|
||||
for (const node of parse(text, {
|
||||
sourceType: "module",
|
||||
plugins: ["typescript"],
|
||||
}).program.body) {
|
||||
if (
|
||||
node.type !== "ImportDeclaration" &&
|
||||
node.type !== "ExportNamedDeclaration" &&
|
||||
node.type !== "ExportAllDeclaration"
|
||||
)
|
||||
continue;
|
||||
const specifier = node.source?.value;
|
||||
if (!specifier?.startsWith(".")) continue;
|
||||
let dependency = resolve(dirname(source), specifier);
|
||||
try {
|
||||
await access(dependency);
|
||||
} catch (cause) {
|
||||
if (
|
||||
cause instanceof Error &&
|
||||
"code" in cause &&
|
||||
cause.code === "ENOENT" &&
|
||||
dependency.endsWith(".js") &&
|
||||
source.endsWith(".ts")
|
||||
)
|
||||
dependency = dependency.slice(0, -3) + ".ts";
|
||||
else throw cause;
|
||||
}
|
||||
pending.push(dependency);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (const mode of ["preinstall source", "packed source-free"]) {
|
||||
processTest(
|
||||
`verifies native artifact identity from ${mode} without installed dependencies`,
|
||||
@@ -15,27 +59,29 @@ for (const mode of ["preinstall source", "packed source-free"]) {
|
||||
const root = await createTestTempDirectory(
|
||||
"rea-native-artifact-verifier-",
|
||||
);
|
||||
const paths =
|
||||
await mkdir(join(root, "scripts"), { recursive: true });
|
||||
await copyFile(
|
||||
join(repository, "scripts/verify-windows-native-artifact.mjs"),
|
||||
join(root, "scripts/verify-windows-native-artifact.mjs"),
|
||||
);
|
||||
if (mode === "preinstall source")
|
||||
await copyModuleGraph(root, "scripts/lib/verifier-source-loader.mjs");
|
||||
await copyModuleGraph(
|
||||
root,
|
||||
mode === "preinstall source"
|
||||
? [
|
||||
"scripts/lib/verifier-source-loader.mjs",
|
||||
"src/domain/windowsNativeArtifact.ts",
|
||||
"src/domain/peCoffHeader.ts",
|
||||
"src/domain/dosMz.ts",
|
||||
"src/domain/result.ts",
|
||||
]
|
||||
: [
|
||||
"dist/domain/windowsNativeArtifact.js",
|
||||
"dist/domain/peCoffHeader.js",
|
||||
"dist/domain/dosMz.js",
|
||||
"dist/domain/result.js",
|
||||
];
|
||||
for (const path of [
|
||||
"scripts/verify-windows-native-artifact.mjs",
|
||||
...paths,
|
||||
]) {
|
||||
await mkdir(dirname(join(root, path)), { recursive: true });
|
||||
await copyFile(join(repository, path), join(root, path));
|
||||
? "src/domain/windowsNativeArtifact.ts"
|
||||
: "dist/domain/windowsNativeArtifact.js",
|
||||
);
|
||||
await expect(access(join(root, "node_modules"))).rejects.toMatchObject({
|
||||
code: "ENOENT",
|
||||
});
|
||||
if (mode === "packed source-free") {
|
||||
await expect(access(join(root, "src"))).rejects.toMatchObject({
|
||||
code: "ENOENT",
|
||||
});
|
||||
await expect(
|
||||
access(join(root, "scripts/lib/verifier-source-loader.mjs")),
|
||||
).rejects.toMatchObject({ code: "ENOENT" });
|
||||
}
|
||||
await writeFile(
|
||||
join(root, "package.json"),
|
||||
@@ -43,22 +89,7 @@ for (const mode of ["preinstall source", "packed source-free"]) {
|
||||
);
|
||||
const artifactRoot = join(root, "native/windows/build");
|
||||
await mkdir(artifactRoot, { recursive: true });
|
||||
// An inert PE header establishes artifact validation, never addon loading.
|
||||
const bytes = Buffer.alloc(128);
|
||||
bytes.write("MZ");
|
||||
bytes.writeUInt32LE(64, 0x3c);
|
||||
bytes.write("PE\0\0", 64, "ascii");
|
||||
bytes.writeUInt16LE(0x8664, 68);
|
||||
bytes.writeUInt16LE(0x20b, 88);
|
||||
const manifest = {
|
||||
packageVersion: "1.0.0",
|
||||
platform: "win32",
|
||||
architecture: "x64",
|
||||
abiVersion: 1,
|
||||
nodeApiVersion: 8,
|
||||
artifact: "rea-windows-x64.node",
|
||||
artifactSha256: createHash("sha256").update(bytes).digest("hex"),
|
||||
};
|
||||
const { bytes, manifest } = windowsNativeArtifactFixture();
|
||||
await writeFile(join(artifactRoot, manifest.artifact), bytes);
|
||||
const manifestPath = join(artifactRoot, "manifest.json");
|
||||
await writeFile(manifestPath, JSON.stringify(manifest));
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import { createHash } from "node:crypto";
|
||||
|
||||
/** Inert PE32+ identity bytes, never an executable addon or native authority. */
|
||||
export const windowsNativeArtifactFixture = () => {
|
||||
const peOffset = 64;
|
||||
const optionalHeaderOffset = peOffset + 4 + 20;
|
||||
const optionalHeaderSize = 64;
|
||||
const bytes = Buffer.alloc(optionalHeaderOffset + optionalHeaderSize);
|
||||
bytes.write("MZ");
|
||||
bytes.writeUInt32LE(peOffset, 0x3c);
|
||||
bytes.write("PE\0\0", peOffset, "ascii");
|
||||
bytes.writeUInt16LE(0x8664, peOffset + 4);
|
||||
bytes.writeUInt16LE(optionalHeaderSize, peOffset + 4 + 16);
|
||||
bytes.writeUInt16LE(0x20b, optionalHeaderOffset);
|
||||
// Keep the expected wire identity independent of the production producer.
|
||||
const manifest = {
|
||||
packageVersion: "1.0.0",
|
||||
platform: "win32",
|
||||
architecture: "x64",
|
||||
abiVersion: 1,
|
||||
nodeApiVersion: 8,
|
||||
artifact: "rea-windows-x64.node",
|
||||
artifactSha256: createHash("sha256").update(bytes).digest("hex"),
|
||||
};
|
||||
return { bytes, manifest };
|
||||
};
|
||||
@@ -144,6 +144,41 @@ describe("curated Windows test lane", () => {
|
||||
expect(verify).toBeGreaterThan(download);
|
||||
expect(build).toBeGreaterThan(verify);
|
||||
});
|
||||
|
||||
it("executes native behavior and recovery proofs before unrelated curated tests", async () => {
|
||||
const workflow = workflowSchema.parse(
|
||||
parse(await readFile(WORKFLOW, "utf8")),
|
||||
);
|
||||
const steps = workflow.jobs["windows-curated"]?.steps ?? [];
|
||||
const build = steps.findIndex(
|
||||
(step) => step.run === "npm run build:cached",
|
||||
);
|
||||
const boundary = steps.findIndex(
|
||||
(step) => step.with?.name === "windows-process-boundary-fixture",
|
||||
);
|
||||
const native = steps.findIndex((step) =>
|
||||
step.run?.startsWith("npm run verify:windows-native -- "),
|
||||
);
|
||||
const inspectionFixture = steps.findIndex(
|
||||
(step) => step.with?.name === "windows-native-inspection-fixture",
|
||||
);
|
||||
const inspection = steps.findIndex(
|
||||
(step) =>
|
||||
step.run === "node scripts/verify-windows-native-inspection.mjs",
|
||||
);
|
||||
const curated = steps.findIndex(
|
||||
(step) =>
|
||||
step.run?.includes("src/windows/WindowsNativeLoader.test.ts") &&
|
||||
step.run.includes("npx vitest run"),
|
||||
);
|
||||
expect(build).toBeGreaterThanOrEqual(0);
|
||||
expect(boundary).toBeGreaterThan(build);
|
||||
expect(native).toBeGreaterThan(boundary);
|
||||
expect(steps[native]?.run).toContain("process-boundary.exe");
|
||||
expect(inspectionFixture).toBeGreaterThan(native);
|
||||
expect(inspection).toBeGreaterThan(inspectionFixture);
|
||||
expect(curated).toBeGreaterThan(inspection);
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps every explicit focused CI test path executable after file moves", async () => {
|
||||
|
||||
Reference in new issue
Block a user