77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { RUN_STATUS } from '@/lib/run-runtime/types'
|
|
import { isRecoverableRunRecord, selectRecoverableRun } from '@/lib/run-runtime/recovery'
|
|
|
|
describe('run recovery', () => {
|
|
it('treats queued runs as recoverable', () => {
|
|
expect(isRecoverableRunRecord({
|
|
id: 'run-1',
|
|
status: RUN_STATUS.QUEUED,
|
|
})).toBe(true)
|
|
})
|
|
|
|
it('rejects running runs with expired lease and no heartbeat extension', () => {
|
|
const now = Date.parse('2026-03-30T10:00:00.000Z')
|
|
expect(isRecoverableRunRecord({
|
|
id: 'run-1',
|
|
status: RUN_STATUS.RUNNING,
|
|
leaseExpiresAt: '2026-03-30T09:59:00.000Z',
|
|
heartbeatAt: '2026-03-30T09:58:30.000Z',
|
|
}, now)).toBe(false)
|
|
})
|
|
|
|
it('prefers the latest recoverable run and skips stale leased runs', () => {
|
|
const now = Date.parse('2026-03-30T10:00:00.000Z')
|
|
const decision = selectRecoverableRun([
|
|
{
|
|
id: 'run-stale',
|
|
status: RUN_STATUS.RUNNING,
|
|
createdAt: '2026-03-30T09:00:00.000Z',
|
|
updatedAt: '2026-03-30T09:30:00.000Z',
|
|
leaseExpiresAt: '2026-03-30T09:59:00.000Z',
|
|
heartbeatAt: '2026-03-30T09:58:30.000Z',
|
|
},
|
|
{
|
|
id: 'run-fresh',
|
|
status: RUN_STATUS.RUNNING,
|
|
createdAt: '2026-03-30T09:50:00.000Z',
|
|
updatedAt: '2026-03-30T09:59:30.000Z',
|
|
leaseExpiresAt: '2026-03-30T10:02:00.000Z',
|
|
heartbeatAt: '2026-03-30T09:59:30.000Z',
|
|
},
|
|
], now)
|
|
|
|
expect(decision).toEqual({
|
|
runId: 'run-fresh',
|
|
reason: 'latest_active',
|
|
})
|
|
})
|
|
|
|
it('skips a newer stale active run when an older recoverable run still exists', () => {
|
|
const now = Date.parse('2026-03-30T10:00:00.000Z')
|
|
const decision = selectRecoverableRun([
|
|
{
|
|
id: 'run-new-stale',
|
|
status: RUN_STATUS.RUNNING,
|
|
createdAt: '2026-03-30T09:58:00.000Z',
|
|
updatedAt: '2026-03-30T09:59:50.000Z',
|
|
leaseExpiresAt: '2026-03-30T09:59:00.000Z',
|
|
heartbeatAt: '2026-03-30T09:58:30.000Z',
|
|
},
|
|
{
|
|
id: 'run-older-fresh',
|
|
status: RUN_STATUS.RUNNING,
|
|
createdAt: '2026-03-30T09:50:00.000Z',
|
|
updatedAt: '2026-03-30T09:59:30.000Z',
|
|
leaseExpiresAt: '2026-03-30T10:02:00.000Z',
|
|
heartbeatAt: '2026-03-30T09:59:30.000Z',
|
|
},
|
|
], now)
|
|
|
|
expect(decision).toEqual({
|
|
runId: 'run-older-fresh',
|
|
reason: 'latest_active',
|
|
})
|
|
})
|
|
})
|