CodeNomad/scripts/native-fixture-diagnostics.test.mjs
Pascal André 0983db3c30
fix(ci): stabilize Windows native tests and artifact comments (#828)
Stabilize the Windows pruning/UI CI harness by loading its unchanged UI dependencies before the long native/SQLite preamble. The late-import baseline reproduced locally under CI's Node 24.20.0 with native status 0xC0000374. This is a qualified import-order workaround, not attribution or repair of the underlying heap corruption; no assertions, dependencies, test skips or retries change.

Retain actual child exit status/signal, stdout/stderr, durable stages and synthetic fixture logs through a parent runner. Require explicit completion as well as exit zero, and upload parent/fixture diagnostics on failure. Preserve the original UI scenario exception if diagnostic capture fails.

Trigger artifact announcements from validation completion rather than bounded polling. Failed validation stays red in its own workflow. Run only trusted default-branch helper code, verify the originating workflow and current authorized PR head, use GitHub commit association when needed and update only bot-owned marker comments. Artifact names remain escaped display text, never executed contents.

Fifteen focused tests pass under Node 24.20.0. Two coordinator-run and one independent full Windows native/UI scenarios complete naturally with all original assertions, restart persistence and presence cleanup. YAML and diff checks pass. The published independent gatekeeper review of this exact head has zero findings.

Admin merge is explicitly requested without waiting for CI. GitHub workflow_run delivery needs post-merge confirmation; no universal CI reliability, underlying heap repair, Linux/macOS native rerun, installed app replacement or shared daemon restart is claimed.
2026-10-02 11:24:27 +02:00

51 lines
3.3 KiB
JavaScript

import assert from "node:assert/strict"
import { test } from "node:test"
import { mkdtemp, mkdir, readFile, writeFile, rm } from "node:fs/promises"
import path from "node:path"
import os from "node:os"
import { runNativeFixture } from "./native-fixture-diagnostics.mjs"
for (const mode of ["complete", "early-zero", "early-seven", "throw", "unsettled-import"]) {
test(`native runner retains status, stage and output for ${mode}`, async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "native-diagnostics-test-"))
try {
const fixture = path.join(directory, "fixture with spaces")
await mkdir(fixture)
const script = path.join(directory, "child with spaces.mjs")
await writeFile(script, `
import { createNativeFixtureReporter } from ${JSON.stringify(new URL("./native-fixture-diagnostics.mjs", import.meta.url).href)};
const reporter = createNativeFixtureReporter(process.argv[2], () => 'isolated server output');
console.log(JSON.stringify(process.argv.slice(3)));
console.error('isolated stderr');
reporter.stage('ui-import-vite');
if (${JSON.stringify(mode)} === 'early-zero') process.exit(0);
if (${JSON.stringify(mode)} === 'early-seven') process.exit(7);
if (${JSON.stringify(mode)} === 'throw') throw new Error('original diagnostic failure');
if (${JSON.stringify(mode)} === 'unsettled-import') await new Promise(() => {});
reporter.complete();
`)
const args = ['C:\\Program Files\\native.exe', 'Unicode-é-漢', '"quoted"']
const result = await runNativeFixture(script, [fixture, ...args], { directory })
assert.equal(result.exitCode, { complete: 0, "early-zero": 1, "early-seven": 7, throw: 1, "unsettled-import": 13 }[mode])
assert.equal(result.completed, mode === "complete")
assert.match(await readFile(path.join(result.root, "stdout.log"), "utf8"), new RegExp(JSON.stringify(args).replace(/[.*+?^${}()|[\]\\]/g, "\\$&")))
assert.match(await readFile(path.join(result.root, "stderr.log"), "utf8"), /isolated stderr/)
assert.equal(await readFile(path.join(fixture, "server.log"), "utf8"), "isolated server output")
const records = (await readFile(path.join(result.root, "child.jsonl"), "utf8")).trim().split("\n").map(line => JSON.parse(line))
assert(records.some(record => record.stage === "ui-import-vite"))
if (mode === "throw") assert.match(records.find(record => record.event === "uncaught-error").error, /original diagnostic failure/)
if (mode !== "complete") assert(records.some(record => record.event === "exit"))
assert.equal(JSON.parse(await readFile(path.join(result.root, "result.json"), "utf8")).code, result.code)
} finally { await rm(directory, { recursive: true, force: true }) }
})
}
test("failure before fixture creation is captured instead of reported as success", async () => {
const directory = await mkdtemp(path.join(os.tmpdir(), "native-diagnostics-missing-"))
try {
const result = await runNativeFixture(path.join(directory, "missing.mjs"), [], { directory })
assert.equal(result.completed, false)
assert.notEqual(result.exitCode, 0)
assert.match(await readFile(path.join(result.root, "stderr.log"), "utf8"), /MODULE_NOT_FOUND/)
} finally { await rm(directory, { recursive: true, force: true }) }
})