fix(pcap): retain independent probe cleanup owners

This commit is contained in:
morluto
2026-10-24 07:43:56 +08:00
parent 4643844ea5
commit c2455152c9
4 changed files with 22 additions and 9 deletions
+10 -8
View File
@@ -181,14 +181,16 @@ export const runPcapCommand = async (options: {
},
}
: {}),
...(cause instanceof OwnedCommandFailure && cause.cleanupFailure !== null
? {
cleanup: {
reason: cause.cleanupFailure,
resources: cause.resources,
},
}
: {}),
...(cleanup !== undefined
? { cleanup }
: cause instanceof OwnedCommandFailure && cause.cleanupFailure !== null
? {
cleanup: {
reason: cause.cleanupFailure,
resources: cause.resources,
},
}
: {}),
};
if (cause instanceof OwnedCommandFailure && cause.reason === "cancelled")
throw new AnalysisCancelledError(operation, {
+1
View File
@@ -347,6 +347,7 @@ export class PcapProvider {
assertValidPcapCommandText(operation, stage, output);
} catch (cause) {
if (
!commandReturned &&
retainedCommand !== undefined &&
cause instanceof AnalysisError &&
cause.cleanupIncomplete
@@ -144,9 +144,11 @@ const probeCleanupFixture = async (rereadCloseFailure = false) => {
if (tsharkReads !== 3) return snapshot;
if (!rereadCloseFailure) return { ...snapshot, sha256: "0".repeat(64) };
const resource = `executable-read:${tshark}`;
const lease = new AnalysisCleanupLease(async () => {}, [resource]);
args[4]?.retain({ kind: "lease", resource, lease });
throw new ArtifactReaderFailure("io", "injected executable read failure", {
cleanup: { reason: "injected file close failure", resources: [resource] },
cleanupLeases: [new AnalysisCleanupLease(async () => {}, [resource])],
cleanupLeases: [lease],
});
};
const provider = new PcapProvider({
@@ -196,6 +198,8 @@ it("keeps an executable re-read's own cleanup live beside the probe's pending cl
expect.stringMatching(/^process-group:/u),
]),
);
await provider.close();
expect(result.error.cleanupIncomplete).toBe(false);
});
it("availability surfaces a probe's pending cleanup instead of reporting the tool unavailable", async () => {
@@ -230,6 +230,12 @@ it.each([0, 7])(
expect(result.error.diagnostics).toMatchObject({
reason: "injected tool-probe cleanup failure",
});
else {
expect(result.error).toMatchObject({
_tag: "AnalysisCapabilityUnavailableError",
capturedOutput: { exit_code: 7 },
});
}
expect(projectAnalysisError(result.error).code).toBe("cleanup_incomplete");
const retry = await provider.execute({
operation: "inspect_pcap_client",