CI green on a loaded shared machine: browser suites (now also glyph-ligatures and feature-fit, through the shared launch helper) in one dedicated shard started first at concurrency 2; timeouts scaled by load ÷ cores (tests/helpers/load.ts, max(1-, 5-min average), capped at 5x, logged) for browser tests, waits, launch/close, the other shards' default and the desktop boot check; one retry for a browser test that timed out while the factor was above 2, listed as 'retried under load' in the CI summary, never for an assertion failure; the six-type App Privacy walk no longer dumps every step (the --debug-dump check walks two types), wait timeouts print per-line times; play-edit-lock checks reads in flight instead of wall time; tests/load-retry.test.ts
This commit is contained in:
parent
21fa91afd1
commit
918146d4a6
13 changed files with 261 additions and 96 deletions
59
tests/load-retry.test.ts
Normal file
59
tests/load-retry.test.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// Load-aware timeouts and the one retry under load (tests/helpers/load.ts, testScope().concurrent in
|
||||
// tests/helpers/browser.ts): a timeout on a loaded machine runs once more; an assertion failure never does.
|
||||
import { describe, expect, test } from 'bun:test';
|
||||
import { retryUnderLoad, WaitTimeout, withBudget } from './helpers/browser';
|
||||
import { loadFactor, RETRY_MARK, scaled } from './helpers/load';
|
||||
|
||||
describe('load factor', () => {
|
||||
test('load ÷ cores from the larger of the 1- and 5-minute averages, between 1 and the cap', () => {
|
||||
expect(loadFactor({}, [5, 2, 1], 10)).toBe(1);
|
||||
expect(loadFactor({}, [30, 45, 50], 10)).toBe(4.5);
|
||||
expect(loadFactor({}, [577, 300, 100], 10)).toBe(5);
|
||||
expect(loadFactor({ STOREBOUND_LOAD_FACTOR: '3' }, [0, 0, 0], 10)).toBe(3);
|
||||
expect(loadFactor({ STOREBOUND_LOAD_FACTOR: '50' }, [0, 0, 0], 10)).toBe(5);
|
||||
expect(scaled(1000, 2.5)).toBe(2500);
|
||||
});
|
||||
});
|
||||
|
||||
describe('one retry, only for a timeout under load', () => {
|
||||
const run = async (err: () => unknown, factor: number) => {
|
||||
const said: string[] = [];
|
||||
let n = 0;
|
||||
let failed: unknown = null;
|
||||
await retryUnderLoad('t', async () => { if (++n === 1) throw err(); }, () => factor, m => said.push(m)).catch(e => { failed = e; });
|
||||
return { n, said, failed };
|
||||
};
|
||||
test('a wait timeout or a Playwright TimeoutError under load: retried once and reported', async () => {
|
||||
for (const err of [() => new WaitTimeout('timed out after 1 ms'), () => Object.assign(new Error('locator.click: Timeout 50ms exceeded'), { name: 'TimeoutError' })]) {
|
||||
const r = await run(err, 3);
|
||||
expect(r.n).toBe(2);
|
||||
expect(r.failed).toBeNull();
|
||||
expect(r.said).toHaveLength(1);
|
||||
expect(r.said[0]!.startsWith(`${RETRY_MARK} t (load x3)`)).toBe(true);
|
||||
}
|
||||
});
|
||||
test('an assertion failure is never retried, under any load', async () => {
|
||||
const r = await run(() => { try { expect(1).toBe(2); } catch (e) { return e; } }, 5);
|
||||
expect(r.n).toBe(1);
|
||||
expect(r.failed).not.toBeNull();
|
||||
expect(r.said).toEqual([]);
|
||||
});
|
||||
test('a timeout on a quiet machine (factor <= 2) is final', async () => {
|
||||
const r = await run(() => new WaitTimeout('timed out'), 2);
|
||||
expect(r.n).toBe(1);
|
||||
expect(r.failed).toBeInstanceOf(WaitTimeout);
|
||||
});
|
||||
test('a second timeout fails the test (one retry only)', async () => {
|
||||
let n = 0;
|
||||
const e = await retryUnderLoad('t', async () => { n++; throw new WaitTimeout('again'); }, () => 4, () => {}).catch(x => x);
|
||||
expect(n).toBe(2);
|
||||
expect(e).toBeInstanceOf(WaitTimeout);
|
||||
});
|
||||
test('the test budget: a run past it fails as a timeout, and the settle runs either way', async () => {
|
||||
let settled = 0;
|
||||
const e = await withBudget(() => Bun.sleep(200), 20, async () => { settled++; }).catch(x => x);
|
||||
expect(e).toBeInstanceOf(WaitTimeout);
|
||||
await withBudget(async () => {}, 1000, async () => { settled++; });
|
||||
expect(settled).toBe(2);
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue