Merge branch 'v2/main' into v2/chore/2130-inspectorview-prop-bundles
This commit is contained in:
commit
4e0f4e5460
1 changed files with 58 additions and 7 deletions
|
|
@ -86,20 +86,71 @@ test("passes when the child paints the marker and keeps running", async () => {
|
|||
// visibly contains the marker. A slow-but-fine TUI would fail, intermittently,
|
||||
// with a diagnostic pointing at the wrong thing entirely.
|
||||
test("a paint landing just under the deadline is not failed by the render timer", async () => {
|
||||
const paintAt = 250;
|
||||
// The two clocks start at different moments: the child's `setTimeout` runs
|
||||
// from its own first JS tick, while `renderTimer` is armed in the parent at
|
||||
// spawn. A delay written as a plain `setTimeout(paint, N)` therefore lands at
|
||||
// `N + startup`, so the deadline has to carry a startup allowance — and the
|
||||
// case fails, as "did not render", whenever the machine is loaded enough to
|
||||
// exceed it. It failed three `local:gate` runs in a row that way while
|
||||
// passing every time standalone (#2177), and widening the allowance only
|
||||
// moved the threshold (#2180).
|
||||
//
|
||||
// So the paint is anchored to the PARENT's clock instead: the child is told
|
||||
// the wall-clock instant to paint at, and sleeps for whatever is left of it
|
||||
// when it gets there. Startup is then *absorbed* by the sleep rather than
|
||||
// added to it, and the paint lands at ~`PAINT_AT` measured from spawn no
|
||||
// matter how slow the boot was.
|
||||
const spawnedAt = Date.now();
|
||||
const PAINT_AT = 300;
|
||||
const timeoutMs = 600;
|
||||
const surviveMs = 900;
|
||||
|
||||
const r = await runRenderSmoke({
|
||||
...opts,
|
||||
...stub(
|
||||
`setTimeout(() => { console.log(${JSON.stringify(MARKER)}); ` +
|
||||
`setInterval(() => {}, 1000); }, ${paintAt});`,
|
||||
`const at = ${spawnedAt + PAINT_AT};` +
|
||||
`setTimeout(() => { console.log(${JSON.stringify(MARKER)}); ` +
|
||||
`setInterval(() => {}, 1000); }, Math.max(0, at - Date.now()));`,
|
||||
),
|
||||
// Deliberately tight: the render deadline expires while the survival window
|
||||
// is still open, which is the whole shape of the bug.
|
||||
timeoutMs: paintAt + 150,
|
||||
surviveMs: 400,
|
||||
// The shape being reproduced is an overlap, and only an overlap:
|
||||
//
|
||||
// actual paint < timeoutMs < actual paint + surviveMs
|
||||
//
|
||||
// i.e. the render deadline expires while the survival window is still
|
||||
// open. `done` is first-caller-wins, so an armed render timer firing in
|
||||
// that gap settles the run as "did not render <marker>" while quoting an
|
||||
// output tail that visibly contains the marker.
|
||||
//
|
||||
// `timeoutMs < surviveMs` is what makes the right-hand side hold for ANY
|
||||
// paint time, including 0 — so a boot slow enough to swallow the anchor
|
||||
// still reproduces the overlap rather than degrading into a different
|
||||
// case. The only startup assumption left is that boot finishes before the
|
||||
// deadline at all, and 600ms is an order of magnitude over the 46-59ms
|
||||
// measured here idle.
|
||||
//
|
||||
// Do not tighten these to make the test faster, and do not reorder them so
|
||||
// that `surviveMs <= timeoutMs`: the overlap is the point.
|
||||
timeoutMs,
|
||||
surviveMs,
|
||||
});
|
||||
assert.equal(r.code, 0, `expected pass, got: ${r.message}`);
|
||||
assert.doesNotMatch(r.message, /did not render/);
|
||||
|
||||
// Passing is not on its own evidence that the overlap was reproduced — a
|
||||
// paint late enough to land past `timeoutMs` fails, but one landing so early
|
||||
// that the deadline falls outside the survival window would pass while
|
||||
// testing nothing. Read the paint time back out of the verdict and assert
|
||||
// the shape actually held, so the case cannot go vacuous.
|
||||
const paintedAt = Number(/ at (\d+)ms/.exec(r.message)?.[1]);
|
||||
assert.ok(
|
||||
Number.isFinite(paintedAt),
|
||||
`no first-paint time in verdict: ${r.message}`,
|
||||
);
|
||||
assert.ok(
|
||||
paintedAt < timeoutMs && timeoutMs < paintedAt + surviveMs,
|
||||
`deadline did not fall inside the survival window: painted at ${paintedAt}ms, ` +
|
||||
`timeoutMs ${timeoutMs}, surviveMs ${surviveMs}`,
|
||||
);
|
||||
});
|
||||
|
||||
test("fails when the child exits before painting", async () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue