From e579fa986d89c0caa1e01bd432fdb9d23b35c587 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 20 Aug 2026 02:09:43 -0700 Subject: [PATCH] test(ssh): scope the relay liveness double's invalidation to one PTY The double invalidated every pending live evidence on any exit, while the real SshPtyLivenessState invalidates only the exiting PTY's. Nothing is vacuous today because each test uses one PTY, but a two-PTY test would pass here and fail in production. --- .../ssh/ssh-relay-session-incarnation.test.ts | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/ssh/ssh-relay-session-incarnation.test.ts b/src/main/ssh/ssh-relay-session-incarnation.test.ts index 925fa6c6507..eacf3e101a7 100644 --- a/src/main/ssh/ssh-relay-session-incarnation.test.ts +++ b/src/main/ssh/ssh-relay-session-incarnation.test.ts @@ -51,7 +51,7 @@ vi.mock('../agent-hooks/remote-managed-hook-installers', () => ({ })) vi.mock('../providers/ssh-pty-provider', () => ({ SshPtyProvider: class MockSshPtyProvider { - private readonly pendingLiveEvidence = new Set<{ valid: boolean }>() + private readonly pendingLiveEvidence = new Map>() readonly providerGeneration: number onData = vi.fn().mockReturnValue(() => {}) onReplay = vi.fn().mockReturnValue(() => {}) @@ -59,32 +59,34 @@ vi.mock('../providers/ssh-pty-provider', () => ({ attach = vi.fn().mockResolvedValue(undefined) attachForReconnect = vi.fn().mockResolvedValue({}) acceptLivePty = vi.fn() - beginLivePtyEvidence = vi.fn(() => { + beginLivePtyEvidence = vi.fn((id: string) => { const evidence = { valid: true } - this.pendingLiveEvidence.add(evidence) + const pending = this.pendingLiveEvidence.get(id) ?? new Set<{ valid: boolean }>() + pending.add(evidence) + this.pendingLiveEvidence.set(id, pending) return evidence }) settleLivePtyEvidence = vi.fn( (id: string, evidence: { valid: boolean }, acceptLive: boolean) => { - this.pendingLiveEvidence.delete(evidence) + this.pendingLiveEvidence.get(id)?.delete(evidence) if (evidence.valid && acceptLive) { this.acceptLivePty(id) } } ) - acceptUnverifiablePty = vi.fn((_id: string) => { - for (const evidence of this.pendingLiveEvidence) { + // Mirrors SshPtyLivenessState: only the named PTY's pending live evidence is invalidated. + acceptUnverifiablePty = vi.fn((id: string) => { + for (const evidence of this.pendingLiveEvidence.get(id) ?? []) { evidence.valid = false } - this.pendingLiveEvidence.clear() + this.pendingLiveEvidence.delete(id) }) acceptAmbiguousExitPty = vi.fn((id: string) => this.acceptUnverifiablePty(id)) - // Mirrors SshPtyLivenessState.acceptExited, which invalidates pending live evidence. - acceptExitedPtyLiveness = vi.fn((_id: string) => { - for (const evidence of this.pendingLiveEvidence) { + acceptExitedPtyLiveness = vi.fn((id: string) => { + for (const evidence of this.pendingLiveEvidence.get(id) ?? []) { evidence.valid = false } - this.pendingLiveEvidence.clear() + this.pendingLiveEvidence.delete(id) }) acceptExitedPty = vi.fn() dispose = vi.fn()