fix false missing Hermes CLI detection after deployment
This commit is contained in:
@@ -16,6 +16,7 @@ type LoadHealthControllerOptions = {
|
||||
bridgeReadinessError?: Error
|
||||
managerError?: Error
|
||||
runtimeStateError?: Error
|
||||
cliProbe?: ReturnType<typeof vi.fn>
|
||||
}
|
||||
|
||||
const defaultBridgeReadiness = {
|
||||
@@ -65,6 +66,12 @@ async function loadHealthController(options: LoadHealthControllerOptions = {}) {
|
||||
isDockerContainer: () => options.isDocker === true,
|
||||
}))
|
||||
|
||||
const cliProbe = options.cliProbe || vi.fn().mockResolvedValue({ available: true, reason: 'ready' })
|
||||
vi.doMock('../../packages/server/src/services/hermes/hermes-process', () => ({
|
||||
probeHermesCli: cliProbe,
|
||||
resolveHermesBin: () => '/opt/hermes/bin/hermes',
|
||||
}))
|
||||
|
||||
const health = await import('../../packages/server/src/controllers/health')
|
||||
|
||||
return {
|
||||
@@ -303,3 +310,43 @@ describe('health controller version metadata', () => {
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('CLI status cache', () => {
|
||||
afterEach(() => { vi.useRealTimers(); vi.resetModules() })
|
||||
|
||||
it('coalesces concurrent requests and allows an explicit recheck after failure', async () => {
|
||||
let finish!: (value: any) => void
|
||||
const probe = vi.fn().mockReturnValueOnce(new Promise(resolve => { finish = resolve }))
|
||||
.mockResolvedValue({ available: true, reason: 'ready' })
|
||||
const { hermesCliStatus } = await loadHealthController({ cliProbe: probe })
|
||||
const first = createMockCtx()
|
||||
const second = createMockCtx()
|
||||
const pending = [hermesCliStatus(first), hermesCliStatus(second)]
|
||||
expect(probe).toHaveBeenCalledOnce()
|
||||
finish({ available: false, reason: 'timeout' })
|
||||
await Promise.all(pending)
|
||||
expect(first.body).toMatchObject({ available: false, reason: 'timeout' })
|
||||
expect(second.body).toEqual(first.body)
|
||||
await hermesCliStatus(createMockCtx())
|
||||
expect(probe).toHaveBeenCalledOnce()
|
||||
const retry = { ...createMockCtx(), query: { refresh: '1' } }
|
||||
await hermesCliStatus(retry)
|
||||
expect(retry.body).toMatchObject({ available: true, reason: 'ready' })
|
||||
expect(probe).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('expires failures quickly and starts successful cache lifetime after the probe completes', async () => {
|
||||
vi.useFakeTimers()
|
||||
const probe = vi.fn().mockResolvedValueOnce({ available: false, reason: 'permission_denied' })
|
||||
.mockImplementationOnce(() => new Promise(resolve => setTimeout(() => resolve({ available: true, reason: 'ready' }), 8000)))
|
||||
const { hermesCliStatus } = await loadHealthController({ cliProbe: probe })
|
||||
await hermesCliStatus(createMockCtx())
|
||||
await vi.advanceTimersByTimeAsync(5001)
|
||||
const pending = hermesCliStatus(createMockCtx())
|
||||
await vi.advanceTimersByTimeAsync(8000)
|
||||
await pending
|
||||
await vi.advanceTimersByTimeAsync(29000)
|
||||
await hermesCliStatus(createMockCtx())
|
||||
expect(probe).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user