Capture M16 gap execution artifacts
This commit is contained in:
@@ -67,6 +67,77 @@ test("stream consumer classifies a transport/body decoding disconnect as incompl
|
||||
);
|
||||
});
|
||||
|
||||
test("stream consumer reconnects from the confirmed byte cursor after a transport disconnect", async () => {
|
||||
let reconnects = 0;
|
||||
const result = await stream.consumeUtf8Stream(
|
||||
streamOf([bytes(0x61)], new Error("Transport error: network error: error decoding response body")),
|
||||
{
|
||||
maxRetries: 1,
|
||||
reconnect: (progress, error) => {
|
||||
reconnects += 1;
|
||||
assert.equal(progress.byteCount, 1);
|
||||
assert.equal(progress.chunkCount, 1);
|
||||
assert.equal(progress.sha256, digest(Buffer.from("a")));
|
||||
assert.match(error.message, /error decoding response body/u);
|
||||
return streamOf([bytes(0x62)]);
|
||||
},
|
||||
},
|
||||
);
|
||||
assert.equal(reconnects, 1);
|
||||
assert.equal(result.text, "ab");
|
||||
assert.equal(result.byteCount, 2);
|
||||
assert.equal(result.chunkCount, 2);
|
||||
});
|
||||
|
||||
test("stream consumer gives a reconnect callback one bounded retry by default", async () => {
|
||||
const result = await stream.consumeUtf8Stream(
|
||||
streamOf([], new Error("error decoding response body")),
|
||||
{ reconnect: () => streamOf([bytes(0x6f, 0x6b)]) },
|
||||
);
|
||||
assert.equal(result.text, "ok");
|
||||
});
|
||||
|
||||
test("stream consumer reports the final transport error when reconnect attempts are exhausted", async () => {
|
||||
let reconnects = 0;
|
||||
await assert.rejects(
|
||||
stream.consumeUtf8Stream(streamOf([], new Error("error decoding response body")), {
|
||||
maxRetries: 1,
|
||||
reconnect: () => {
|
||||
reconnects += 1;
|
||||
return streamOf([], new Error("connection reset"));
|
||||
},
|
||||
}),
|
||||
(error) => error.code === "STREAM_DISCONNECTED" && /connection reset/u.test(error.message),
|
||||
);
|
||||
assert.equal(reconnects, 1);
|
||||
});
|
||||
|
||||
test("stream consumer keeps the disconnect diagnostic when reconnect creation fails", async () => {
|
||||
await assert.rejects(
|
||||
stream.consumeUtf8Stream(streamOf([], new Error("error decoding response body")), {
|
||||
maxRetries: 1,
|
||||
reconnect: () => { throw new Error("retry unavailable"); },
|
||||
}),
|
||||
(error) => error.code === "STREAM_DISCONNECTED" && /error decoding response body/u.test(error.message),
|
||||
);
|
||||
});
|
||||
|
||||
test("stream consumer turns an abort during retry backoff into cancellation", async () => {
|
||||
const controller = new AbortController();
|
||||
let reconnects = 0;
|
||||
const promise = stream.consumeUtf8Stream(streamOf([], new Error("error decoding response body")), {
|
||||
signal: controller.signal,
|
||||
retryDelayMs: 50,
|
||||
reconnect: () => {
|
||||
reconnects += 1;
|
||||
return streamOf([bytes(0x6f, 0x6b)]);
|
||||
},
|
||||
});
|
||||
setTimeout(() => controller.abort(), 1);
|
||||
await assert.rejects(promise, (error) => error.code === "STREAM_CANCELLED");
|
||||
assert.equal(reconnects, 0);
|
||||
});
|
||||
|
||||
test("stream consumer bounds a provider error body before surfacing it", async () => {
|
||||
const detail = "x".repeat(10_000);
|
||||
await assert.rejects(
|
||||
|
||||
Reference in New Issue
Block a user