test(ssh): keep relay liveness coverage within limits

This commit is contained in:
Brennan Benson
2026-08-16 22:43:22 -07:00
parent 25d8388698
commit 74e2e2d926
3 changed files with 50 additions and 66 deletions
+1 -2
View File
@@ -24,8 +24,7 @@ export function isSshPtyExitedEvidenceError(error: unknown): boolean {
const message = error instanceof Error ? error.message : String(error)
return (
!isSshPtyIdentityMismatchError(error) &&
(message.includes(SSH_SESSION_EXPIRED_ERROR) ||
message === 'agent_session_exited_during_start')
(message.includes(SSH_SESSION_EXPIRED_ERROR) || message === 'agent_session_exited_during_start')
)
}
@@ -84,12 +84,25 @@ vi.mock('../providers/ssh-pty-provider', () => ({
isSshPtyNotFoundError: (error: unknown) => String(error).includes('not found'),
isSshPtyIdentityMismatchError: (error: unknown) => String(error).includes('identity mismatch'),
SshPtyProvider: class MockSshPtyProvider {
readonly initialUnverifiablePtyIds: Set<string>
onData = vi.fn().mockReturnValue(() => {})
onReplay = vi.fn().mockReturnValue(() => {})
onExit = vi.fn().mockReturnValue(() => {})
attach = vi.fn().mockResolvedValue(undefined)
attachForReconnect = vi.fn().mockResolvedValue({})
acceptUnverifiablePty = vi.fn()
acceptExitedPty = vi.fn()
dispose = vi.fn()
constructor(
_connectionId: string,
_mux: unknown,
_remoteCliBridgeEnv: unknown,
_providerGeneration: number,
initialUnverifiablePtyIds: Iterable<string> = []
) {
this.initialUnverifiablePtyIds = new Set(initialUnverifiablePtyIds)
}
}
}))
vi.mock('../providers/ssh-filesystem-provider', () => ({
@@ -181,6 +194,42 @@ describe('SshRelaySession reconnect incarnation ordering', () => {
vi.mocked(getPtyIdsForConnection).mockReturnValue([])
})
it('keeps a transiently unreattached PTY unverifiable after the relay becomes ready', async () => {
const { mockConn, mockStore, mockPortForward, getMainWindow } = createMockDeps()
vi.mocked(getPtyIdsForConnection).mockReturnValue(['pty-unverifiable'])
vi.mocked(getSshPtyProvider).mockImplementationOnce(() => {
const provider = vi.mocked(registerSshPtyProvider).mock.calls.at(-1)?.[1] as unknown as {
attachForReconnect: ReturnType<typeof vi.fn>
}
provider.attachForReconnect.mockRejectedValue(new Error('transport interrupted'))
return provider as never
})
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
const session = new SshRelaySession('target-1', getMainWindow, mockStore, mockPortForward)
try {
await session.establish(mockConn)
const provider = vi.mocked(registerSshPtyProvider).mock.calls.at(-1)?.[1] as unknown as {
initialUnverifiablePtyIds: Set<string>
acceptUnverifiablePty: ReturnType<typeof vi.fn>
acceptExitedPty: ReturnType<typeof vi.fn>
}
const appPtyId = 'ssh:target-1@@pty-unverifiable'
expect(session.getState()).toBe('ready')
expect(provider.initialUnverifiablePtyIds).toContain(appPtyId)
expect(provider.acceptUnverifiablePty).toHaveBeenCalledWith(appPtyId)
expect(provider.acceptExitedPty).not.toHaveBeenCalled()
expect(mockStore.markSshRemotePtyLease).not.toHaveBeenCalledWith(
'target-1',
'pty-unverifiable',
'expired'
)
} finally {
warn.mockRestore()
}
})
it('bounds fifty reattaches to eight workers without slow or failed sibling head-of-line delay', async () => {
const { mockConn, mockStore, mockPortForward, getMainWindow } = createMockDeps()
const session = new SshRelaySession('target-1', getMainWindow, mockStore, mockPortForward)
-64
View File
@@ -66,9 +66,6 @@ vi.mock('../providers/ssh-pty-provider', () => ({
isSshPtyIdentityMismatchError: (err: unknown) =>
(err instanceof Error ? err.message : String(err)).includes('identity mismatch'),
SshPtyProvider: class MockSshPtyProvider {
private livePtyIds = new Set<string>()
private unverifiablePtyIds = new Set<string>()
private exitedPtyIds = new Set<string>()
onData = vi.fn().mockReturnValue(() => {})
onReplay = vi.fn().mockReturnValue(() => {})
onExit = vi.fn().mockReturnValue(() => {})
@@ -76,32 +73,6 @@ vi.mock('../providers/ssh-pty-provider', () => ({
attachForReconnect = vi.fn().mockResolvedValue({})
setPtyDeliveryPauseAdapter = pauseAdapterMock
dispose = vi.fn()
constructor(
_connectionId: string,
_mux: unknown,
_remoteCliBridgeEnv: unknown,
_providerGeneration: number,
initialUnverifiablePtyIds: Iterable<string> = []
) {
this.unverifiablePtyIds = new Set(initialUnverifiablePtyIds)
}
hasPty = (id: string): boolean => this.livePtyIds.has(id) || this.unverifiablePtyIds.has(id)
probePtyLiveness = vi.fn(
async (id: string): Promise<boolean | null> =>
this.livePtyIds.has(id) ? true : this.exitedPtyIds.has(id) ? false : null
)
acceptUnverifiablePty = vi.fn((id: string) => {
this.livePtyIds.delete(id)
this.exitedPtyIds.delete(id)
this.unverifiablePtyIds.add(id)
})
acceptExitedPty = vi.fn((id: string) => {
this.livePtyIds.delete(id)
this.unverifiablePtyIds.delete(id)
this.exitedPtyIds.add(id)
})
}
}))
@@ -235,41 +206,6 @@ describe('SshRelaySession', () => {
expect(registerSshGitProvider).toHaveBeenCalledWith('target-1', expect.anything())
})
it('keeps a transiently unreattached PTY unverifiable after the relay becomes ready', async () => {
const { mockConn, mockStore, mockPortForward, getMainWindow } = createMockDeps()
const { getSshPtyProvider } = await import('../ipc/pty')
vi.mocked(getPtyIdsForConnection).mockReturnValue(['pty-unverifiable'])
vi.mocked(getSshPtyProvider).mockImplementationOnce(() => {
const provider = vi.mocked(registerSshPtyProvider).mock.calls.at(-1)?.[1] as {
attachForReconnect: ReturnType<typeof vi.fn>
}
provider.attachForReconnect.mockRejectedValue(new Error('transport interrupted'))
return provider as never
})
const warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
const session = new SshRelaySession('target-1', getMainWindow, mockStore, mockPortForward)
try {
await session.establish(mockConn)
const provider = vi.mocked(registerSshPtyProvider).mock.calls.at(-1)?.[1] as {
hasPty: (id: string) => boolean
probePtyLiveness: (id: string) => Promise<boolean | null>
}
const appPtyId = 'ssh:target-1@@pty-unverifiable'
expect(session.getState()).toBe('ready')
expect(provider.hasPty(appPtyId)).toBe(true)
await expect(provider.probePtyLiveness(appPtyId)).resolves.toBeNull()
expect(mockStore.markSshRemotePtyLease).not.toHaveBeenCalledWith(
'target-1',
'pty-unverifiable',
'expired'
)
} finally {
warn.mockRestore()
}
})
it('continues provider registration when the relay managed-hook request fails', async () => {
process.env.ORCA_FEATURE_REMOTE_AGENT_HOOKS = '1'
muxRequestMock.mockImplementation(async (method: string) => {