test: stabilize timing-sensitive tests (#2316)

This commit is contained in:
JATMN
2026-10-21 14:16:47 -07:00
committed by GitHub
parent 1f6f747309
commit cb9f9ee0ca
4 changed files with 17 additions and 23 deletions
+6 -3
View File
@@ -72,6 +72,7 @@ describe('openclaude launcher heap guard', () => {
expect(source).not.toMatch(/import\s*\{[^}]*enableCompileCache[^}]*\}\s*from\s*['"]node:module['"]/s)
})
// Real CLI startup has an 8s child deadline; allow time to assert its result.
test('strips launcher-only percentage before Commander when native heap and expose-gc are present', () => {
const env = {
...process.env,
@@ -98,8 +99,9 @@ describe('openclaude launcher heap guard', () => {
expect(output).not.toContain(
"unknown option '--max-old-space-size-percentage=50'",
)
})
}, 10_000)
// Real CLI startup has an 8s child deadline; allow time to assert its result.
test('strips launcher-only percentage before Commander when heap relaunch is disabled', () => {
const env = {
...process.env,
@@ -120,8 +122,9 @@ describe('openclaude launcher heap guard', () => {
expect(output).not.toContain(
"unknown option '--max-old-space-size-percentage=50'",
)
})
}, 10_000)
// Real CLI startup has an 8s child deadline; allow time to assert its result.
test('strips launcher-only percentage when OPENCLAUDE_HEAP_RELAUNCHED is already set', () => {
const env = {
...process.env,
@@ -142,7 +145,7 @@ describe('openclaude launcher heap guard', () => {
expect(output).not.toContain(
"unknown option '--max-old-space-size-percentage=50'",
)
})
}, 10_000)
})
describe('heap-limit percentage resolution', () => {
+9 -5
View File
@@ -633,8 +633,8 @@ describe('background session finalizer', () => {
return { id, child, readyPath }
}
async function waitForFile(path: string): Promise<void> {
for (let attempt = 0; attempt < 500; attempt += 1) {
async function waitForFile(path: string, attempts: number = 500): Promise<void> {
for (let attempt = 0; attempt < attempts; attempt += 1) {
if (await Bun.file(path).exists()) return
await new Promise(resolve => setTimeout(resolve, 10))
}
@@ -967,6 +967,7 @@ describe('background session finalizer', () => {
async function runWaitingDetachedLaunch(
name: string,
fixtureEnv: NodeJS.ProcessEnv = {},
readinessAttempts?: number,
): Promise<{ id: string; childPid: number; readyPath: string }> {
const readyPath = join(configDir, `${name}.ready`)
const launcher = spawn(
@@ -1017,7 +1018,7 @@ describe('background session finalizer', () => {
if (!id || childPid === undefined) {
throw new Error('detached wait launch omitted its session identity')
}
await waitForFile(readyPath)
await waitForFile(readyPath, readinessAttempts)
ownershipTransferred = true
return { id, childPid, readyPath }
} finally {
@@ -1044,6 +1045,9 @@ describe('background session finalizer', () => {
env: {
OPENCLAUDE_BG_FINALIZER_FIXTURE_SKIP_READY: '1',
},
// Readiness is deliberately suppressed; only exercise the failure path.
readinessAttempts: 25,
expectedError: 'fixture readiness file was not created',
},
]) {
it(
@@ -1051,8 +1055,8 @@ describe('background session finalizer', () => {
async () => {
const name = `failed-handoff-${scenario.label.replaceAll(' ', '-')}`
await expect(
runWaitingDetachedLaunch(name, scenario.env),
).rejects.toThrow()
runWaitingDetachedLaunch(name, scenario.env, scenario.readinessAttempts),
).rejects.toThrow(scenario.expectedError)
const session = (await listBackgroundSessions()).find(
candidate => candidate.name === name,
)
+1 -14
View File
@@ -135,18 +135,6 @@ function createHeadlessRunOptions(maxTurns: number | undefined) {
}
}
async function waitForAskCall(
askSpy: ReturnType<typeof spyOn<typeof queryEngineModule, 'ask'>>,
): Promise<void> {
const deadline = Date.now() + 15_000
while (askSpy.mock.calls.length === 0) {
if (Date.now() >= deadline) {
throw new Error('Timed out waiting for runHeadless to call ask()')
}
await new Promise(resolve => setTimeout(resolve, 25))
}
}
describe('headless --print max-turns', () => {
const savedSimple = process.env.CLAUDE_CODE_SIMPLE
@@ -213,9 +201,8 @@ describe('headless --print max-turns', () => {
createHeadlessRunOptions(0),
)
await waitForAskCall(askSpy)
expect(askSpy.mock.calls[0]?.[0]?.maxTurns).toBe(0)
await runPromise
expect(askSpy.mock.calls[0]?.[0]?.maxTurns).toBe(0)
expect(shutdownSpy).toHaveBeenCalledWith(0)
} finally {
await runPromise?.catch(() => {})
+1 -1
View File
@@ -119,7 +119,7 @@ test.each([
/** Observes the real hook after mounting its AppState provider. */
function HookProbe() {
observedBanner = useSwarmBanner()
React.useEffect(() => { notifyRendered() }, [])
React.useLayoutEffect(() => { notifyRendered() }, [])
return null
}