Files
reverse-engineering-anything/tests/boundary/browser/runtimeFixtureReadiness.test.ts
T
22e5aa97af feat(artifacts): inspect classic iNES container regions (#2816)
* feat(artifacts): inspect classic iNES container regions

* fix(artifacts): preserve iNES source disappearance as integrity failure

* fix(artifacts): revalidate iNES source before parsing header

* fix(artifacts): validate admitted roots before classification

* fix(artifacts): normalize source loss during root hashing

* fix(artifacts): bind iNES extraction admission to inventory

* test(artifacts): clarify non-executing inspection wording

* fix: preserve binary plist detection with extended magic probe

* test(browser): wait for popup document loads before capture

* fix(artifacts): honor cancellation across source validation

* fix(artifacts): prefer artifact magic over implicit database suffix

* fix(artifacts): select extraction readers from scanned format

* fix(artifacts): complete prefix reads and share ZIP format admission

* fix(browser): budget scenario cleanup for content drain and shutdown

* test(artifacts): admit valid universal inputs before routing

* test(artifacts): verify iNES workflows on macOS

* test(ci): own iNES macOS coverage and portable fixture paths

* fix: preserve cleanup retries and avoid duplicate inventory parsing

* fix(contracts): share ZIP target formats across MCP lifecycle schemas

* fix(target): preserve typed cancellation during descriptor admission

* refactor(artifacts): use JSON-safe inventory producer output directly

* test(artifacts): share file read setup and satisfy CI checks

* fix(artifacts): classify changed admission as integrity failure

* ci: run Mach-O summary delivery coverage on macOS

* test(javascript): align parameter provenance with main contract

* test(browser): await discoverable fixture pages before runtime verification

* fix(artifacts): pass target metadata to format detection

* fix(artifacts): bind extraction to opened target

* fix: repair the static-check failures on the default branch (#2895)

* fix: repair the static-check failures on the default branch

The default branch fails its own required `Static checks` job three ways, so
every pull request reports that job as failed regardless of its own change.

- `npm run format:check` reports `src/domain/functionComparison.test.ts` and
  `src/ida/IdaOperationRunner.ts`.
- `npm run lint` reports a duplicate `import { join } from "node:path"` in
  `tests/boundary/mcp/ghidraInventoryMcp.test.ts` (lines 4 and 17).
- `npm run typecheck` reports `format: "devin"` missing from the client format
  union in `src/application/SupportedClients.ts`, and an unchecked index in
  `tests/boundary/cli/clientProfileLifecycle.test.ts`, whose pair array is
  inferred as `string[][]`.

Apply the pinned formatter, drop the duplicate import, list the `"devin"` format
that its own definition already uses, and mark the pair array `as const`.

Validation: `npm run check:fast` and `npm run format:check` pass.

* fix(setup): keep Devin on the JSON configuration dialect

---------

Co-authored-by: 吴佳浩 <wujiahao@supremind.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
(cherry picked from commit df3d96da80)

* fix(artifacts): bind session inventories to target identity

* test(browser): bound fixture readiness acknowledgements

---------

Co-authored-by: 64579525 <17373302683@163.com>
Co-authored-by: 吴佳浩Alben <35291372+XiaoBinGan@users.noreply.github.com>
Co-authored-by: 吴佳浩 <wujiahao@supremind.com>
2026-10-31 15:49:16 +08:00

232 lines
6.4 KiB
TypeScript

import { ChildProcess } from "node:child_process";
import { createServer } from "node:http";
import { setImmediate } from "node:timers/promises";
import { afterEach, expect, it, vi } from "vitest";
import { z } from "zod";
import { awaitAcknowledgement } from "../../fixtures/lifecycleAcknowledgement.js";
const mock = vi.hoisted(() => ({ spawn: vi.fn(), port: vi.fn() }));
vi.mock("../../../dist/process/ProviderProcess.js", () => ({
spawnOwnedProviderProcess: mock.spawn,
ProviderProcessSupervisor: class {
constructor(
readonly launch: {
process: ChildProcess;
cleanup: () => Promise<unknown>;
},
) {}
snapshot() {
return { stderr: { text: "" } };
}
async stop() {
await this.launch.cleanup();
return { status: "complete" };
}
},
}));
vi.mock("../../../dist/process/ProcessOwnershipObservation.js", () => ({
createSystemProcessOwnershipHost: () => ({ listProcesses: async () => [] }),
}));
vi.mock("../../../scripts/lib/verifier-source-loader.mjs", () => ({
importVerifierSource: async () => ({
BROWSER_DEVTOOLS_STARTUP_TIMEOUT_MS: 60_000,
waitForBrowserDevtoolsPort: mock.port,
}),
}));
afterEach(() => vi.restoreAllMocks());
interface FixtureLease {
readonly port: number;
close(): Promise<void>;
}
type StartFixture = (
executable: string,
origin: string,
) => Promise<FixtureLease>;
const startFixture = async (): Promise<StartFixture> =>
z
.object({
startRuntimeFixtureBrowser: z.custom<StartFixture>(
(value) => typeof value === "function",
),
})
.parse(
await import(
new URL(
"../../../scripts/lib/browser-runtime-fixture-lifecycle.mjs",
import.meta.url,
).href
),
).startRuntimeFixtureBrowser;
const deferred = () => {
let resolve!: () => void;
const promise = new Promise<void>((complete) => {
resolve = complete;
});
return { promise, resolve };
};
const fixture = async (
mode: "empty targets" | "discovery timeout" | "malformed" | "exited",
) => {
let ready = false;
let requests = 0;
const listed = deferred();
const published = deferred();
const server = createServer((request, response) => {
requests += 1;
if (mode === "exited") {
listed.resolve();
return;
}
if (mode === "malformed") {
response.end("{broken");
return;
}
if (mode === "discovery timeout" && requests === 1) {
response.once("close", () => {
ready = true;
});
return;
}
response.end(
JSON.stringify(
request.url === "/json/version"
? {
Browser: "FixtureChrome/1",
"Protocol-Version": "1.3",
"User-Agent": "FixtureChrome",
"V8-Version": "1",
"WebKit-Version": "1",
webSocketDebuggerUrl: `ws://127.0.0.1:${port}/devtools/browser/fixture`,
}
: ready
? [{ id: "fixture", type: "page", title: "fixture", url: origin }]
: [],
),
);
if (request.url === "/json/list") listed.resolve();
});
await new Promise<void>((resolve) => server.listen(0, "127.0.0.1", resolve));
const address = server.address();
if (address === null || typeof address === "string")
throw new Error("Missing fixture address");
const port = address.port;
const origin = `http://127.0.0.1:${port}`;
const child = new ChildProcess();
let signalCode: NodeJS.Signals | null = null;
Object.defineProperty(child, "signalCode", { get: () => signalCode });
vi.spyOn(child, "kill").mockImplementation(() => {
signalCode = "SIGTERM";
child.emit("exit", null, "SIGTERM");
return true;
});
const cleanup = vi.fn(async () => ({ cleaned: true }));
mock.spawn.mockResolvedValue({
process: child,
ownership: { processGroupId: 7 },
cleanup,
});
mock.port.mockImplementation(async () => {
published.resolve();
return port;
});
return {
origin,
listed: listed.promise,
published: published.promise,
cleanup,
exit: () => child.kill("SIGTERM"),
makeReady: () => {
ready = true;
},
requests: () => requests,
close: async () => {
server.closeAllConnections();
await new Promise<void>((resolve) => server.close(() => resolve()));
},
};
};
it.each(["empty targets", "discovery timeout"] as const)(
"does not hand out the owned fixture while CDP has %s",
async (mode) => {
const start = await startFixture();
const server = await fixture(mode);
const pending = start(process.execPath, server.origin);
let settled = false;
void pending.then(
() => {
settled = true;
},
() => {
settled = true;
},
);
try {
await awaitAcknowledgement(
server.published,
pending,
"fixture port publication",
);
await setImmediate();
expect(settled).toBe(false);
if (mode === "empty targets") {
await awaitAcknowledgement(
server.listed,
pending,
"fixture target listing",
);
expect(settled).toBe(false);
server.makeReady();
}
await pending;
expect(server.requests()).toBeGreaterThanOrEqual(3);
} finally {
server.makeReady();
await (await pending.catch(() => undefined))?.close();
await server.close();
}
},
);
it("preserves malformed discovery and closes the owned fixture", async () => {
const start = await startFixture();
const server = await fixture("malformed");
const pending = start(process.execPath, server.origin);
try {
await expect(pending).rejects.toMatchObject({
reason: "invalid_endpoint_response",
});
expect(server.requests()).toBe(1);
expect(server.cleanup).toHaveBeenCalledTimes(1);
} finally {
await (await pending.catch(() => undefined))?.close();
await server.close();
}
});
it("interrupts pending discovery when the owned fixture exits", async () => {
const start = await startFixture();
const server = await fixture("exited");
const pending = start(process.execPath, server.origin);
const rejected = expect(pending).rejects.toThrow(
"exited before CDP discovery",
);
try {
await awaitAcknowledgement(
server.listed,
pending,
"fixture target listing",
);
server.exit();
await rejected;
expect(server.cleanup).toHaveBeenCalledTimes(1);
} finally {
await (await pending.catch(() => undefined))?.close();
await server.close();
}
});