cc-haha/src/server/__tests__/server-shutdown.test.ts
程序员阿江(Relakkes) d3b2f868a9 fix: guard prewarm resume shutdown paths (#611)
Prevent desktop prewarm launches from inheriting interrupted-turn resume state, while leaving explicit user-message startup unchanged. Also stop server-side background schedulers during shutdown so app quit cannot leave scheduled task runners alive.

Tested:

- bun test src/server/__tests__/conversation-service.test.ts

- bun test src/server/__tests__/conversations.test.ts -t "prewarm"

- bun test src/server/__tests__/conversations.test.ts -t "permission"

- bun test src/server/__tests__/diagnostics-service.test.ts -t "keeps fatal startup errors visible on stderr while recording diagnostics"

- bun test desktop/electron/services/windows.test.ts desktop/electron/services/tray.test.ts desktop/electron/services/sidecarManager.test.ts src/server/__tests__/server-shutdown.test.ts

- bun run check:server
2026-06-09 21:44:46 +08:00

40 lines
1.7 KiB
TypeScript

import { expect, test } from 'bun:test'
import { stopServerRuntimeForShutdown } from '../index.js'
import { conversationService } from '../services/conversationService.js'
import { cronScheduler } from '../services/cronScheduler.js'
import { teamWatcher } from '../services/teamWatcher.js'
test('server shutdown stops background schedulers before waiting for CLI sessions', async () => {
const calls: string[] = []
const originalTeamStop = teamWatcher.stop.bind(teamWatcher)
const originalCronStop = cronScheduler.stop.bind(cronScheduler)
const originalGetActiveSessions = conversationService.getActiveSessions.bind(conversationService)
const originalStopAllSessionsAndWait = conversationService.stopAllSessionsAndWait.bind(conversationService)
try {
teamWatcher.stop = (() => {
calls.push('teamWatcher.stop')
}) as typeof teamWatcher.stop
cronScheduler.stop = (() => {
calls.push('cronScheduler.stop')
}) as typeof cronScheduler.stop
conversationService.getActiveSessions = (() => ['active-session']) as typeof conversationService.getActiveSessions
conversationService.stopAllSessionsAndWait = (async () => {
calls.push('conversationService.stopAllSessionsAndWait')
}) as typeof conversationService.stopAllSessionsAndWait
await stopServerRuntimeForShutdown({ waitForCli: true })
expect(calls).toEqual([
'teamWatcher.stop',
'cronScheduler.stop',
'conversationService.stopAllSessionsAndWait',
])
} finally {
teamWatcher.stop = originalTeamStop
cronScheduler.stop = originalCronStop
conversationService.getActiveSessions = originalGetActiveSessions
conversationService.stopAllSessionsAndWait = originalStopAllSessionsAndWait
}
})