Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2e2ed9aa2 | ||
|
|
1ae4bec45b | ||
|
|
058bc0af35 |
@@ -47,6 +47,7 @@ it.each(["Page.disable", "Target.detachFromTarget"])(
|
||||
expect(methods).toContain("Target.detachFromTarget");
|
||||
expect(methods).not.toContain("Target.closeTarget");
|
||||
expect(methods).not.toContain("Browser.close");
|
||||
await vi.waitFor(() => expect(browser.activeConnectionCount()).toBe(0));
|
||||
},
|
||||
);
|
||||
|
||||
@@ -73,9 +74,11 @@ it("releases cleanup when cancellation arrives after capture completes", async (
|
||||
controller.abort();
|
||||
const result = await pending;
|
||||
expect(result.ok).toBe(true);
|
||||
expect(browser.commands.map(({ method }) => method)).toContain(
|
||||
"Target.detachFromTarget",
|
||||
);
|
||||
await vi.waitFor(() => expect(browser.activeConnectionCount()).toBe(0));
|
||||
const methods = browser.commands.map(({ method }) => method);
|
||||
expect(methods).not.toContain("Target.closeTarget");
|
||||
expect(methods).not.toContain("Browser.close");
|
||||
expect((await fetch(`${browser.endpoint}/json/version`)).ok).toBe(true);
|
||||
});
|
||||
|
||||
it("closes an Electron inspection session when cleanup is cancelled", async () => {
|
||||
@@ -122,11 +125,10 @@ it("closes an Electron inspection session when cleanup is cancelled", async () =
|
||||
operation: "inspect_electron_page",
|
||||
},
|
||||
});
|
||||
expect(browser.commands.map(({ method }) => method)).toContain(
|
||||
"Page.disable",
|
||||
);
|
||||
const methods = browser.commands.map(({ method }) => method);
|
||||
expect(methods).toContain("Target.detachFromTarget");
|
||||
expect(methods).not.toContain("Target.closeTarget");
|
||||
expect(methods).not.toContain("Browser.close");
|
||||
await vi.waitFor(() => expect(browser.activeConnectionCount()).toBe(0));
|
||||
expect((await fetch(`${browser.endpoint}/json/version`)).ok).toBe(true);
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ import { projectAnalysisError } from "../../../src/domain/analysisErrorProjectio
|
||||
import { evmInterfaceSchema } from "../../../src/domain/evm/evmInterface.js";
|
||||
import { EvmoleInterfaceProvider } from "../../../src/evm/EvmoleInterfaceProvider.js";
|
||||
import { spawnOwnedProviderProcess } from "../../../src/process/ProviderProcess.js";
|
||||
import { cleanupOwnedProcessGroup } from "../../../src/process/ProcessOwnership.js";
|
||||
import { waitForProviderProcessReady } from "../../fixtures/providerProcess.js";
|
||||
import { PrivateRuntimeRoot } from "../../../src/process/PrivateRuntimeRoot.js";
|
||||
import {
|
||||
@@ -128,6 +129,7 @@ it.runIf(!unsupportedHost)(
|
||||
async () => {
|
||||
const { path } = await fixture();
|
||||
let ownedPath = "";
|
||||
let failCleanupReport = true;
|
||||
const provider = new EvmoleInterfaceProvider({}, async (spawn) => {
|
||||
ownedPath = spawn.cwd ?? "";
|
||||
const launched = await spawnOwnedProviderProcess({
|
||||
@@ -135,24 +137,48 @@ it.runIf(!unsupportedHost)(
|
||||
command: process.execPath,
|
||||
arguments: ["-e", 'process.stdout.write("x".repeat(1048577))'],
|
||||
});
|
||||
const ownership = launched.ownership;
|
||||
if (ownership === undefined)
|
||||
throw new Error("Owned launcher must expose process identity");
|
||||
const cleanup =
|
||||
launched.cleanup ?? (() => cleanupOwnedProcessGroup(ownership));
|
||||
return {
|
||||
...launched,
|
||||
cleanup: async () => {
|
||||
await launched.cleanup?.();
|
||||
throw new Error("injected post-cleanup reporting failure");
|
||||
const result = await cleanup();
|
||||
if (failCleanupReport)
|
||||
throw new Error("injected post-cleanup reporting failure");
|
||||
return result;
|
||||
},
|
||||
};
|
||||
});
|
||||
onTestFinished(async () => {
|
||||
failCleanupReport = false;
|
||||
await provider.close();
|
||||
});
|
||||
const result = await provider.inspect({ path, encoding: "hex" });
|
||||
if (result.ok) throw new Error("Expected compounded lifecycle failure");
|
||||
expect(result.error).toMatchObject({
|
||||
cleanupIncomplete: true,
|
||||
diagnostics: {
|
||||
reason: "injected post-cleanup reporting failure",
|
||||
previous_error: { failure_kind: "output-limit" },
|
||||
captured_output: { truncated: true, stderr: "" },
|
||||
expect(projectAnalysisError(result.error)).toMatchObject({
|
||||
code: "cleanup_incomplete",
|
||||
details: {
|
||||
diagnostics: {
|
||||
reason: "Owned EVM worker cleanup could not be confirmed",
|
||||
previous_error: {
|
||||
code: "cleanup_incomplete",
|
||||
details: {
|
||||
diagnostics: {
|
||||
reason: "injected post-cleanup reporting failure",
|
||||
previous_error: { failure_kind: "output-limit" },
|
||||
captured_output: { truncated: true, stderr: "" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
await access(ownedPath);
|
||||
failCleanupReport = false;
|
||||
await provider.close();
|
||||
await expect(access(ownedPath)).rejects.toMatchObject({ code: "ENOENT" });
|
||||
},
|
||||
);
|
||||
|
||||
@@ -157,6 +157,8 @@ describe("Qwen Code profile setup", () => {
|
||||
expect(await setup.clientNeedsConfigure(client, {}, command)).toBe(false);
|
||||
expect(await setup.skillNeedsInstall([client.name])).toBe(false);
|
||||
expect(await setup.installSkill([client.name])).toBe("unchanged");
|
||||
const userFile = join(skill, "user-note.txt");
|
||||
await writeFile(userFile, "caller-owned skill notes\n");
|
||||
expect(
|
||||
(
|
||||
await readClientRegistrationStatuses(
|
||||
@@ -173,7 +175,12 @@ describe("Qwen Code profile setup", () => {
|
||||
expect(registered).toEqual(client);
|
||||
expect((await uninstall.removeClient(client)).status).toBe("removed");
|
||||
expect((await uninstall.removeSkill()).status).toBe("removed");
|
||||
await expect(access(skill)).rejects.toMatchObject({ code: "ENOENT" });
|
||||
await expect(access(join(skill, "SKILL.md"))).rejects.toMatchObject({
|
||||
code: "ENOENT",
|
||||
});
|
||||
expect(await readFile(userFile, "utf8")).toBe(
|
||||
"caller-owned skill notes\n",
|
||||
);
|
||||
if (customHome)
|
||||
await expect(access(join(home, ".qwen"))).rejects.toMatchObject({
|
||||
code: "ENOENT",
|
||||
|
||||
@@ -324,7 +324,7 @@ it("cancels a waiting request promptly while keeping later launches behind the a
|
||||
await assertFirmwareCleanup(fixture.launches);
|
||||
});
|
||||
|
||||
it("retains an uncertain workspace and lets the next operation create a new root", async () => {
|
||||
it("retains an uncertain worker's workspace and blocks later launches", async () => {
|
||||
const fixture = await firmwareFixture("cleanup-failure");
|
||||
const first = await fixture.service.execute("inspect_firmware_regions", {
|
||||
path: fixture.path,
|
||||
@@ -335,18 +335,15 @@ it("retains an uncertain workspace and lets the next operation create a new root
|
||||
});
|
||||
const workspace = fixture.launches[0]?.cwd;
|
||||
expect(workspace).toBeDefined();
|
||||
if (workspace === undefined) return;
|
||||
if (workspace === undefined) throw new Error("Expected retained workspace");
|
||||
await access(workspace);
|
||||
const acquiredLaunches = [...fixture.launches];
|
||||
const next = await fixture.service.execute("inspect_firmware_regions", {
|
||||
path: fixture.path,
|
||||
});
|
||||
expect(next).toMatchObject({ ok: false, error: { cleanupIncomplete: true } });
|
||||
expect(fixture.launches).toHaveLength(2);
|
||||
const nextWorkspace = fixture.launches[1]?.cwd;
|
||||
expect(nextWorkspace).toBeDefined();
|
||||
expect(nextWorkspace).not.toBe(workspace);
|
||||
expect(fixture.launches).toEqual(acquiredLaunches);
|
||||
await access(workspace);
|
||||
if (nextWorkspace !== undefined) await access(nextWorkspace);
|
||||
});
|
||||
|
||||
it("accepts another build on the verified release line and reports it", async () => {
|
||||
|
||||
Vendored
+1
@@ -143,6 +143,7 @@ export const startFakeCdpBrowser = async (
|
||||
browserWebSocketUrl: `ws://127.0.0.1:${String(port)}/devtools/browser/fake`,
|
||||
allowedOrigin: endpoint,
|
||||
commands,
|
||||
activeConnectionCount: () => sockets.size,
|
||||
emitRawMessage(message) {
|
||||
for (const socket of sockets) socket.send(message);
|
||||
},
|
||||
|
||||
+2
@@ -11,6 +11,8 @@ export interface FakeCdpBrowser {
|
||||
readonly browserWebSocketUrl: string;
|
||||
readonly allowedOrigin: string;
|
||||
readonly commands: readonly FakeCdpCommand[];
|
||||
/** Actual WebSocket connections still held by the wire fixture. */
|
||||
activeConnectionCount(): number;
|
||||
/** Deliver actual malformed wire data without bypassing the production transport parser. */
|
||||
emitRawMessage(message: string): void;
|
||||
emitEvent(event: {
|
||||
|
||||
Reference in New Issue
Block a user