Files
orca/src/main/runtime/rpc/terminal-multiplex-source-range-request.test.ts
T
OrcaWinandm4air 8731ca9672 refactor(rpc): delete host-side terminal source-range acks (#27546)
The host side of the terminal source-range ACK protocol had one producer: the
relay-fed SSH output intake, deleted in #27515. Since then nothing installs the
runtime's source-range hooks and nothing passes source ranges into PTY output,
so every terminal.multiplex subscribe that offers ackOutputSourceRanges is
already answered without it and uses the byte-window ACK.

Delete the ledger, the per-connection registry, the consumer hook surface on
the runtime, the stream-level reservation/commit/rollback plumbing in flow
control, initial snapshot and cleanup, the source-range ACK frame schema, and
the range slicing in output chunks, batching and replay. The subscribe schema
still accepts the ackOutputSourceRanges capability, and the client keeps its
range-ACK support for older hosts. A new golden test pins that an offering
subscribe gets the same reply and frames as a byte-ACK one.

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-11 13:04:34 -07:00

81 lines
3.1 KiB
TypeScript

import './unused-default-rpc-methods.test-fixture'
import { describe, expect, it, vi } from 'vitest'
import type { RuntimeTerminalDataMeta } from '../orca-runtime'
import {
TerminalStreamOpcode,
decodeTerminalStreamFrame,
encodeTerminalStreamFrame,
encodeTerminalStreamJson
} from '../../../shared/terminal-stream-protocol'
import {
sendDesktopMultiplexSubscribe,
startDesktopMultiplexSubscribe
} from './terminal-multiplex-test-harness'
type Harness = ReturnType<typeof startDesktopMultiplexSubscribe>
const GOLDEN_SUBSCRIBED =
'{"type":"subscribed","streamId":7,"terminal":"terminal-1","cols":120,"rows":40,"displayMode":"auto","seq":1,"capabilities":{"outputPause":1},"truncated":false}'
function sendAck(harness: Harness, payload: unknown): void {
harness.handlers.get(7)?.(
decodeTerminalStreamFrame(
encodeTerminalStreamFrame({
opcode: TerminalStreamOpcode.Ack,
streamId: 7,
seq: 2,
payload: encodeTerminalStreamJson(payload)
})
)!
)
}
function hexFrames(harness: Harness): string[] {
return harness.binaryFrames.map((bytes) => Buffer.from(bytes).toString('hex'))
}
// Older clients still offer ackOutputSourceRanges; this host never accepts it, so they fall back to byte ACKs.
async function runSession(capabilities: Record<string, 1>) {
let dataListener: ((data: string, meta?: RuntimeTerminalDataMeta) => void) | undefined
const harness = startDesktopMultiplexSubscribe({
subscribeToTerminalData: vi.fn((_ptyId, listener) => {
dataListener = listener
return vi.fn()
})
})
sendDesktopMultiplexSubscribe(harness.handlers, capabilities)
await vi.waitFor(() =>
expect(harness.messages.some((m) => JSON.parse(m).result?.type === 'subscribed')).toBe(true)
)
await vi.waitFor(() => expect(dataListener).toBeDefined())
const flood = 'x'.repeat(700 * 1024)
dataListener!(flood, { seq: flood.length, rawLength: flood.length })
await new Promise((resolve) => setTimeout(resolve, 20))
const beforeAck = hexFrames(harness).length
// A source-range ACK shape is not a byte ACK, so it must release no credit.
sendAck(harness, { streamGeneration: 'generation', ackedEndByte: flood.length })
const afterRangeAck = hexFrames(harness).length
sendAck(harness, { bytes: flood.length })
await new Promise((resolve) => setTimeout(resolve, 20))
harness.registry.cleanupSubscription('terminal-multiplex:conn-desktop-first-paint')
await harness.dispatchPromise
return {
messages: harness.messages.map((message) => JSON.stringify(JSON.parse(message).result)),
frames: hexFrames(harness),
beforeAck,
afterRangeAck
}
}
describe('terminal.multiplex subscribe offering ackOutputSourceRanges', () => {
it('gets the byte-identical reply and frames of a byte-ACK subscribe', async () => {
const offered = await runSession({ ackOutput: 1, ackOutputSourceRanges: 1, outputPause: 1 })
const plain = await runSession({ ackOutput: 1, outputPause: 1 })
expect(offered.messages).toContain(GOLDEN_SUBSCRIBED)
expect(offered).toEqual(plain)
expect(offered.afterRangeAck).toBe(offered.beforeAck)
expect(offered.frames.length).toBeGreaterThan(offered.beforeAck)
})
})