fix(test): stabilize tooling guard probes (#95114)

* fix(test): release kitchen sink probe readers

* test(github): follow shared guard membership helper
This commit is contained in:
Vincent Koc
2026-06-20 06:55:40 +08:00
committed by GitHub
parent 7ee1dafd4f
commit be7807f65e
3 changed files with 51 additions and 19 deletions
+24 -18
View File
@@ -996,25 +996,31 @@ export async function readBoundedResponseText(response, byteLimit, timeoutPromis
}
const chunks = [];
let totalBytes = 0;
for (;;) {
const read = reader.read();
const { done, value } = await withOptionalTimeout(
read,
timeoutPromise?.catch((error) => {
cancelReaderSoon(reader);
throw error;
}),
);
if (done) {
break;
try {
for (;;) {
const read = reader.read();
const { done, value } = await withOptionalTimeout(
read,
timeoutPromise?.catch((error) => {
cancelReaderSoon(reader);
throw error;
}),
);
if (done) {
break;
}
const chunk = Buffer.from(value);
totalBytes += chunk.byteLength;
if (totalBytes > resolvedByteLimit) {
await reader.cancel().catch(() => undefined);
throw createFetchBodyTooLargeError(resolvedByteLimit);
}
chunks.push(chunk);
}
const chunk = Buffer.from(value);
totalBytes += chunk.byteLength;
if (totalBytes > resolvedByteLimit) {
await reader.cancel().catch(() => undefined);
throw createFetchBodyTooLargeError(resolvedByteLimit);
}
chunks.push(chunk);
} finally {
try {
reader.releaseLock?.();
} catch {}
}
return Buffer.concat(chunks, totalBytes).toString("utf8");
}
@@ -1976,6 +1976,30 @@ describe("kitchen-sink RPC process sampling", () => {
);
});
it("releases HTTP probe response stream readers after bounded reads", async () => {
const releaseLock = vi.fn();
const response = {
headers: new Headers(),
body: {
getReader() {
return {
read: vi
.fn()
.mockResolvedValueOnce({ done: false, value: new TextEncoder().encode("ok") })
.mockResolvedValueOnce({ done: true }),
releaseLock,
};
},
},
text: vi.fn(async () => "not read"),
};
await expect(readBoundedResponseText(response, 1024)).resolves.toBe("ok");
expect(releaseLock).toHaveBeenCalledOnce();
expect(response.text).not.toHaveBeenCalled();
});
it("cancels stalled HTTP probe response streams when the timeout wins", async () => {
let canceled = false;
const timeoutError = Object.assign(new Error("fetch probe timed out"), {
@@ -136,6 +136,8 @@ describe("security-sensitive guard workflow", () => {
it("uses a dedicated checked-in script and detects the intended file surfaces", () => {
const workflow = readFileSync(WORKFLOW, "utf8");
const script = readFileSync("scripts/github/security-sensitive-guard.mjs", "utf8");
const sharedScript = readFileSync("scripts/github/guard-shared.mjs", "utf8");
const guardSources = `${script}\n${sharedScript}`;
expect(workflow).toContain("scripts/github/security-sensitive-guard.mjs");
expect(script).toContain('"security-sensitive-changed"');
@@ -143,7 +145,7 @@ describe("security-sensitive guard workflow", () => {
expect(script).toContain(".env");
expect(script).toContain("/allow-security-sensitive-change");
expect(script).toContain("openclaw-secops");
expect(script).toContain("/memberships/");
expect(guardSources).toContain("/memberships/");
expect(script).toContain("A later push requires a fresh approval.");
expect(script).toContain("process.exitCode = 1");
});