fix(windows): preserve unresolved readiness and cleanup ownership
Do not report a retryable failed capture admission as available. A fresh capability declaration must observe actual admission success. Report combined window resources when closing a session, preserving helper and executable cleanup observations without assigning the wrong owner. Both regressions fail before the change. Focused provider, loader, helper and lazy-client checks pass after the fixes.
This commit is contained in:
1 parent
dcccb4fca7
commit
283292edda
4 files changed
+61
-7
No files matched your search
@@ -9,6 +9,7 @@ import type { BinaryTarget } from "../domain/binaryTargetTypes.js";
|
||||
import { MAX_WINDOWS_WINDOW_PNG_BYTES } from "../domain/native/windowsWindowScreenshot.js";
|
||||
import { OwnedFileHandle } from "../filesystem/OwnedFileHandle.js";
|
||||
import { RegularFileAdmissionFailure } from "../filesystem/RegularFile.js";
|
||||
import * as execution from "./WindowsWindowCaptureExecution.js";
|
||||
import {
|
||||
captureWindowsWindowScreenshot,
|
||||
hashWindowsCaptureExecutable,
|
||||
@@ -56,6 +57,33 @@ const host = (
|
||||
...overrides,
|
||||
});
|
||||
|
||||
it("attributes a helper-only close failure to selected-window resources", async () => {
|
||||
const observation = {
|
||||
reason: "Owned capture Job cleanup remains pending",
|
||||
resources: ["capture-run:42"],
|
||||
};
|
||||
const cleanup = vi
|
||||
.spyOn(execution, "retryWindowsCaptureCleanup")
|
||||
.mockResolvedValue(observation);
|
||||
try {
|
||||
const client = new NativeWindowsUiProvider(
|
||||
{},
|
||||
host(),
|
||||
"linux",
|
||||
).createClient(TARGET);
|
||||
expect(await client.close()).toMatchObject({
|
||||
ok: false,
|
||||
error: {
|
||||
_tag: "AnalysisOutputError",
|
||||
reason: "Selected-window capture resource cleanup remains incomplete.",
|
||||
cleanup: observation,
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
cleanup.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it("captures only an HWND whose live executable identity matches the active PE target", async () => {
|
||||
const captured = await captureWindowsWindowScreenshot(
|
||||
TARGET,
|
||||
|
||||
@@ -238,10 +238,20 @@ export class NativeWindowsUiProvider implements AnalysisProvider {
|
||||
return incomplete.length === 0
|
||||
? ok(null)
|
||||
: err(
|
||||
incompleteExecutableIdentityCleanupError({
|
||||
reason: incomplete.map((cleanup) => cleanup.reason).join("; "),
|
||||
resources: incomplete.flatMap((cleanup) => cleanup.resources),
|
||||
}),
|
||||
new AnalysisOutputError(
|
||||
OPERATION,
|
||||
"Selected-window capture resource cleanup remains incomplete.",
|
||||
{
|
||||
cleanup: {
|
||||
reason: incomplete
|
||||
.map((cleanup) => cleanup.reason)
|
||||
.join("; "),
|
||||
resources: incomplete.flatMap(
|
||||
(cleanup) => cleanup.resources,
|
||||
),
|
||||
},
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -24,3 +24,21 @@ it("requires affirmative inspected capture support on the shipped Windows archit
|
||||
}))[0],
|
||||
).toMatchObject({ available: false, reason: "artifact unavailable" });
|
||||
});
|
||||
|
||||
it("keeps retryable admission unavailable until a fresh successful snapshot", () => {
|
||||
let readiness: WindowsWindowCaptureLoadResult = {
|
||||
available: false,
|
||||
reason: "Private runtime admission is still unresolved",
|
||||
retryable: true,
|
||||
};
|
||||
const first = nativeWindowsUiCapabilities("win32", "x64", () => readiness);
|
||||
expect(first[0]).toMatchObject({
|
||||
available: false,
|
||||
reason: readiness.reason,
|
||||
});
|
||||
readiness = loaded();
|
||||
expect(
|
||||
nativeWindowsUiCapabilities("win32", "x64", () => readiness)[0],
|
||||
).toMatchObject({ available: true });
|
||||
expect(first[0]).toMatchObject({ available: false });
|
||||
});
|
||||
@@ -23,9 +23,7 @@ export const nativeWindowsUiCapabilities = (
|
||||
): readonly CapabilityDescriptor[] => {
|
||||
const loaded =
|
||||
platform === "win32" && architecture === "x64" ? load() : undefined;
|
||||
const captureReady =
|
||||
loaded?.available === true ||
|
||||
(loaded?.available === false && loaded.retryable === true);
|
||||
const captureReady = loaded?.available === true;
|
||||
const availability =
|
||||
platform === "win32" && architecture === "x64"
|
||||
? captureReady
|
||||
|
||||
Reference in new issue
Block a user