Skip to content

Commit c697247

Browse files
test(aws-serverless): Score the poll loop by its own clock, not the driver's
`runToOutcome` advances the fake timers by the whole drive window whether the loop is still running or not, so an elapsed-time assertion taken around the call reports that window back and holds however early the loop gave up. One test read the driver that way; it now reads the timestamps its own polls were issued at, and fails at 1,500ms against a give-up window of 960,000 when the condition is broken. Also derives the two poll counts in the neighbouring test from the constants whose relationship the comment claims, rather than leaving them as figures that only hold for today's values.
1 parent 56d2a3f commit c697247

1 file changed

Lines changed: 16 additions & 9 deletions

File tree

  • packages/aws-serverless/test/lambda-extension

‎packages/aws-serverless/test/lambda-extension/run.test.ts‎

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -188,19 +188,24 @@ describe('AwsLambdaExtension.run', () => {
188188
// to is still the API working, so it has to reprieve the clock the same way SHUTDOWN would.
189189
const extension = new AwsLambdaExtension();
190190
const failure = new Error('ECONNREFUSED');
191-
// Capped backoff makes this about 14 minutes of failing before the API answers once.
191+
// Capped backoff puts these `POLL_RETRY_MAX_MS` apart, so this is most of the give-up window
192+
// spent failing before the API answers once — close enough that a clock which did not restart
193+
// expires within the drive window, far enough that one which did cannot.
194+
const failuresBeforeDelivery = Math.floor((POLL_GIVE_UP_MS * 0.9) / POLL_RETRY_MAX_MS);
192195
const { next } = scriptPolls(extension, [
193-
...Array<Error>(170).fill(failure),
196+
...Array<Error>(failuresBeforeDelivery).fill(failure),
194197
{ eventType: 'INVOKE' },
195-
...Array<Error>(400).fill(failure),
198+
// Enough to outlast the drive window, so the loop never runs off the end of the script into
199+
// the SHUTDOWN `scriptPolls` answers with.
200+
...Array<Error>(Math.ceil((POLL_GIVE_UP_MS + 30_000) / POLL_RETRY_MAX_MS)).fill(failure),
196201
]);
197202

198203
// Past the give-up measured from the first failure, well short of it measured from the event —
199204
// so a loop still running here is one whose clock the delivery restarted.
200205
const outcome = await runToOutcome(extension, POLL_GIVE_UP_MS + 30_000);
201206

202207
expect(outcome).toBe('still polling');
203-
expect(next.mock.calls.length).toBeGreaterThan(170);
208+
expect(next.mock.calls.length).toBeGreaterThan(failuresBeforeDelivery);
204209
});
205210

206211
test('keeps polling through events it never subscribed to, however long they go on', async () => {
@@ -262,18 +267,20 @@ describe('AwsLambdaExtension.run', () => {
262267
// cannot trip it — and a 20-poll cap would, since capped backoff reaches 20 polls in ~80s.
263268
const extension = new AwsLambdaExtension();
264269
const failure = new Error('ECONNREFUSED');
265-
let polls = 0;
270+
const polledAt: number[] = [];
266271
vi.spyOn(extension, 'next').mockImplementation(async () => {
267-
polls++;
272+
polledAt.push(Date.now());
268273
throw failure;
269274
});
270-
const startedAt = Date.now();
271275

272276
const outcome = await runToOutcome(extension, POLL_GIVE_UP_MS + 60_000);
273277

274278
expect(outcome).toEqual({ reason: 'unrecoverable', pollAccepted: false, error: failure });
275-
expect(Date.now() - startedAt).toBeGreaterThanOrEqual(POLL_GIVE_UP_MS);
276-
expect(polls).toBeGreaterThan(MAX_REPORTED_FAILURES);
279+
// Measured across the loop's own polls: `runToOutcome` advances the fake clock by the whole
280+
// drive window whether the loop is still running or not, so reading it around the call would
281+
// report that window back and hold however early the loop had given up.
282+
expect(polledAt.at(-1)! - polledAt[0]!).toBeGreaterThanOrEqual(POLL_GIVE_UP_MS);
283+
expect(polledAt.length).toBeGreaterThan(MAX_REPORTED_FAILURES);
277284
// The loop outlives the console reporting, which is capped so it does not bill the customer
278285
// for one line every 5s until the environment is recycled.
279286
expect(errorSpy).toHaveBeenCalledTimes(MAX_REPORTED_FAILURES);

0 commit comments

Comments
 (0)