Ver código fonte

test: raise the contended Windows spawn budgets to 90s

The per-case 15-30s budgets on the Windows native and coverage lanes fire
before oxlint, workflow-worker-thread, and other subprocess-spawning cases
finish under the loaded self-hosted pool; the failures rotate across cases
as load shifts, so per-case widening only moved the flake. Raise the lane
defaults (DSH_COVERAGE_TEST_TIMEOUT_MS and the native --testTimeout) to 90s,
align the oxlint and workflow-worker-thread case budgets, and keep the
built-bin SPAWN_TIMEOUT_MS at 60s under a 90s outer budget.
Chinesezjc 1 semana atrás
pai
commit
84692044af

+ 2 - 2
.github/workflows/ci.yml

@@ -446,7 +446,7 @@ jobs:
     env:
       DSH_COVERAGE_MAX_WORKERS: '6'
       DSH_COVERAGE_PARTITIONS: '4'
-      DSH_COVERAGE_TEST_TIMEOUT_MS: '30000'
+      DSH_COVERAGE_TEST_TIMEOUT_MS: '90000'
       DSH_GATE_CONCURRENCY: '3'
     steps:
       - uses: actions/checkout@v6
@@ -505,7 +505,7 @@ jobs:
         run: >-
           pnpm exec vitest run
           --no-file-parallelism
-          --testTimeout 30000
+          --testTimeout 90000
           packages/shell/tool-pwsh/tests/loader.spec.ts
           packages/workflow/workflow-worker-thread/tests/workflow-worker-thread.spec.ts
           packages/workflow/tool-ralph/tests/integration.spec.ts

+ 9 - 9
packages/workflow/workflow-worker-thread/tests/workflow-worker-thread.spec.ts

@@ -787,7 +787,7 @@ describe('dsh-workflow-worker-thread', { timeout: 120_000 }, () => {
       expect(result.error).toContain('raced the completion')
       expect(narration).toEqual(['started'])
       await handle.dispose()
-    }, 15_000)
+    }, 90_000)
 
     it('cancel() force-settles a script parked on a promise no hook owns, and TERMINATES its worker', async () => {
       const { ctx, parent } = await setup({ config: { provider: 'stub', disposeGraceMs: 50 } })
@@ -1027,7 +1027,7 @@ describe('dsh-workflow-worker-thread', { timeout: 120_000 }, () => {
       expect(provider.runs[0]!.disposeCalls).toBe(1)
       await handle.dispose()
       await ctx.fiber.dispose()
-    }, 15_000)
+    }, 90_000)
 
     it('dispose() on a wedged worker host-drives child disposal inside the grace: it returns with the children DISPOSED, not with their teardown still in flight', async () => {
       const { ctx, parent, provider } = await setup({
@@ -1062,7 +1062,7 @@ describe('dsh-workflow-worker-thread', { timeout: 120_000 }, () => {
       expect(provider.runs[0]!.disposed).toBe(true)
       const result = await handle.result
       expect(result.stopReason).toBe('cancelled')
-    }, 15_000)
+    }, 90_000)
 
     it('a live child disposed by the dispose() drive is disposed ONCE, and the worker\'s late dispose RPC still gets its ack (the script settles, not the grace)', async () => {
       const { ctx, parent, provider } = await setup({ manual: true })
@@ -1127,7 +1127,7 @@ describe('dsh-workflow-worker-thread', { timeout: 120_000 }, () => {
       // can finalize its state at run-end without dangling agents.
       expect(order.indexOf('run-end')).toBe(order.length - 1)
       await handle.dispose()
-    }, 15_000)
+    }, 90_000)
 
     it('graceful cancellation keeps pairing worker-authored: exactly one agent-end per start, nothing synthesized on top', async () => {
       const { ctx, parent, provider } = await setup({ manual: true })
@@ -1305,7 +1305,7 @@ describe('dsh-workflow-worker-thread', { timeout: 120_000 }, () => {
       await Promise.resolve()
       expect(result.stopReason).toBe('error')
       await handle.dispose()
-    }, 15_000)
+    }, 90_000)
 
     it('an uncaught exception inside the worker surfaces as an error result and reaps the in-flight child', async () => {
       const { ctx, parent, provider } = await setup({ manual: true })
@@ -1331,7 +1331,7 @@ describe('dsh-workflow-worker-thread', { timeout: 120_000 }, () => {
         expect(provider.runs[0]!.disposed).toBe(true)
       }, 1000)
       await handle.dispose()
-    }, 15_000)
+    }, 90_000)
 
     it('a worker death pairs every stranded start: the synthesized cancelled agent-end precedes the error workflow/end', async () => {
       const { ctx, parent, provider } = await setup({ manual: true })
@@ -1366,7 +1366,7 @@ describe('dsh-workflow-worker-thread', { timeout: 120_000 }, () => {
       ])
       expect(order.indexOf('run-end')).toBe(order.length - 1)
       await handle.dispose()
-    }, 15_000)
+    }, 90_000)
 
     it('a dispose ack racing the worker death is dropped, not crashed (post after exit)', async () => {
       // Slow child disposal: the ack resolves only AFTER the worker died, so
@@ -1395,7 +1395,7 @@ describe('dsh-workflow-worker-thread', { timeout: 120_000 }, () => {
       // tight explicit bound (see the helper's doc comment).
       await waitFor(() => { expect(provider.runs[0]!.disposed).toBe(true) }, 1000)
       await handle.dispose()
-    }, 15_000)
+    }, 90_000)
 
     it('a worker death AFTER a cancel reports cancelled, not error', async () => {
       const { ctx, parent } = await setup({ config: { provider: 'stub', disposeGraceMs: 60_000 } })
@@ -1421,7 +1421,7 @@ describe('dsh-workflow-worker-thread', { timeout: 120_000 }, () => {
       expect(result.stopReason).toBe('cancelled')
       expect(result.error).toContain('stop it')
       await handle.dispose()
-    }, process.platform === 'win32' ? 30_000 : 15_000)
+    }, process.platform === 'win32' ? 90_000 : 15_000)
   })
 
   describe('service API', () => {

+ 1 - 1
scripts/ci-workflow.spec.ts

@@ -134,7 +134,7 @@ describe('CI workflow', () => {
     ))
     const nativeTestCommand = nativeTestCommands.map(step => step.run).join('\n')
     expect(nativeTestCommand).toContain('--no-file-parallelism')
-    expect(nativeTestCommand).toContain('--testTimeout 30000')
+    expect(nativeTestCommand).toContain('--testTimeout 90000')
     expect(nativeTestCommand).toContain('tool-pwsh/tests/loader.spec.ts')
     expect(nativeTestCommand).toContain('workflow-worker-thread.spec.ts')
 

+ 4 - 4
scripts/oxlint-contract.spec.ts

@@ -105,7 +105,7 @@ probePromise()
         rm(configPath, { force: true }),
       ])
     }
-  }, 60_000)
+  }, 90_000)
 
   it('runs JavaScript compatibility and nursery rules', async () => {
     const suffix = randomUUID()
@@ -152,7 +152,7 @@ export const longProbe = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 +
         rm(configPath, { force: true }),
       ])
     }
-  }, 60_000)
+  }, 90_000)
 
   it('keeps the complete stylistic contract in Oxlint', async () => {
     const oxlintPath = join(repositoryRoot, '.oxlintrc.json')
@@ -252,7 +252,7 @@ export const longProbe = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 +
         rm(configPath, { force: true }),
       ])
     }
-  }, 60_000)
+  }, 90_000)
 
   it('accepts an ignored-only staged selection', () => {
     const result = runOxlint([
@@ -371,6 +371,6 @@ export const longProbe = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 +
         await rm(directory, { recursive: true, force: true })
       }
     },
-    60_000,
+    90_000,
   )
 })