From 397fb929def1c5fb7af019a84b7f82ad96d267cf Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Thu, 27 Aug 2026 14:50:21 +0800 Subject: [PATCH] test(host): drain Include write queue in picker composition spec Replace the debounce-timer polling with Include.stop(), which flushes the file-backed write queue deterministically. This avoids Windows coverage flakes where the self-dispose write could land after the expect.poll timeout. --- .../tests/loader-composition.spec.ts | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/host/directory-picker-auto/tests/loader-composition.spec.ts b/packages/host/directory-picker-auto/tests/loader-composition.spec.ts index 783e4e1e6f..29bf3ed30a 100644 --- a/packages/host/directory-picker-auto/tests/loader-composition.spec.ts +++ b/packages/host/directory-picker-auto/tests/loader-composition.spec.ts @@ -138,6 +138,14 @@ function entryNames(ctx: Context): string[] { return [...ctx.loader.entries()].map(entry => entry.options.name) } +/** The Include tree that backs the booted `cordis.yml` file. */ +function includeTree(ctx: Context): Include { + const include = [...ctx.loader.entries()] + .find(entry => entry.options.name === 'cordis:include')?.subtree as Include | undefined + if (include === undefined) throw new Error('expected the root Include tree') + return include +} + /** * Force every signal of an attended host on any platform: no SSH launch, a * display, and a PATH holding one executable chooser binary so the real @@ -188,10 +196,10 @@ describe('real Loader composition', () => { // behavior, not the chooser's); await that debounced write so it cannot // race the temp-dir removal, and pin that the persisted row is the // chooser itself — the resolved backend still never reaches the file. - await expect.poll( - async () => await readFile(configPath, 'utf8'), - { timeout: 15_000 }, - ).toContain('disabled: true') + // stop() drains the Include write queue, so this assertion does not depend + // on the debounce timer racing Windows coverage load. + await includeTree(ctx).stop() + expect(await readFile(configPath, 'utf8')).toContain('disabled: true') expect(await readFile(configPath, 'utf8')).not.toContain(NATIVE) }) @@ -240,8 +248,10 @@ describe('real Loader composition', () => { await expect(autoEntry.fiber!.dispose()).resolves.not.toThrow() expect(entryNames(ctx)).not.toContain(NATIVE) expect(entryNames(ctx)).not.toContain(NATIVE_SURFACE) - // Same self-dispose persistence as above: let the write land before teardown. - await expect.poll(async () => await readFile(configPath, 'utf8')).toContain('disabled: true') + // Same self-dispose persistence as above: drain the Include write queue + // deterministically before asserting the persisted row. + await includeTree(ctx).stop() + expect(await readFile(configPath, 'utf8')).toContain('disabled: true') expect(renameControl.injectedFailures).toBe(1) expect(renameControl.remainingFailures).toBe(0) expect(renameControl.attempts).toBeGreaterThanOrEqual(2) @@ -251,9 +261,7 @@ describe('real Loader composition', () => { stubAttendedHost() const { ctx } = await loadComposition('127.0.0.1') const autoEntry = [...ctx.loader.entries()].find(entry => entry.options.name === AUTO)! - const include = [...ctx.loader.entries()] - .find(entry => entry.options.name === 'cordis:include')?.subtree as Include | undefined - if (include === undefined) throw new Error('expected the root Include tree') + const include = includeTree(ctx) renameControl.failureCode = 'EIO' renameControl.remainingFailures = 1