From 7bbdc47ec072e4044fd65cd65e99c1a8f497e800 Mon Sep 17 00:00:00 2001 From: OrcaWin Date: Sun, 25 Oct 2026 09:26:07 -0700 Subject: [PATCH] test: tighten relay assertions and repair benchmark checks (#33573) Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com> --- config/scripts/ssh-watch-fanout-benchmark.mjs | 49 +++++++------------ ...rminal-reattach-payload-scan-benchmark.mjs | 32 ++++++++---- .../mobile-relay-phone-protocol.test.ts | 7 +++ .../network/server-share-address.test.ts | 10 +++- src/shared/tab-has-live-pty.test.ts | 4 -- 5 files changed, 56 insertions(+), 46 deletions(-) diff --git a/config/scripts/ssh-watch-fanout-benchmark.mjs b/config/scripts/ssh-watch-fanout-benchmark.mjs index c343c3cdc65..37730efd104 100644 --- a/config/scripts/ssh-watch-fanout-benchmark.mjs +++ b/config/scripts/ssh-watch-fanout-benchmark.mjs @@ -1,10 +1,11 @@ #!/usr/bin/env node -// Compare repeated per-registration/event NFC normalization with pre-normalized root matchers/event paths for SSH watcher batches. +// Model repeated per-root/event normalization versus hoisted root matchers/event paths for SSH watcher batches. // Assert identical routed results before timing and import production normalizer so folding drift cannot invalidate measurement. +import assert from 'node:assert/strict' import { execFileSync } from 'node:child_process' -import { readFileSync } from 'node:fs' import { performance } from 'node:perf_hooks' import { fileURLToPath } from 'node:url' +import { createJiti } from 'jiti' const REPO_ROOT = fileURLToPath(new URL('../..', import.meta.url)) const ITERATIONS = Number(process.env.ORCA_SSH_WATCH_BENCH_ITERATIONS ?? '200') @@ -19,25 +20,15 @@ for (const [name, value] of [ } } -// Recheck production normalization source: if NFC fold/cost changes, benchmark’s assumption no longer holds. -const PATH_SOURCE = readFileSync( - new URL('../../src/shared/cross-platform-path.ts', import.meta.url), - 'utf8' -) -for (const marker of ['normalize(', 'createNormalizedPathInsideOrEqualMatcher']) { - if (!PATH_SOURCE.includes(marker)) { - throw new Error(`cross-platform-path.ts no longer contains ${marker}; this benchmark is stale`) - } -} - -// Import the real normalizer so both arms fold paths exactly as production does. +// Jiti resolves the production graph’s extensionless TypeScript imports. +const jiti = createJiti(import.meta.url) const { normalizeRuntimePathForComparison, isPathInsideOrEqual, createNormalizedPathInsideOrEqualMatcher -} = await import(new URL('../../src/shared/cross-platform-path.ts', import.meta.url).href) +} = await jiti.import('../../src/shared/cross-platform-path.ts') -// Pre-fix: mirrors the original routeSshFilesystemWatchNotification inner loop. +// Historical per-pair normalization model. function routeBefore(roots, events, sink) { for (const rootPath of roots) { const matching = events.filter((event) => isPathInsideOrEqual(rootPath, event.absolutePath)) @@ -47,7 +38,7 @@ function routeBefore(roots, events, sink) { } } -// Post-fix: mirrors the current implementation. +// Synthetic hoisted-normalization model; this does not invoke the application router. function routeAfter(roots, events, sink) { const normalizedEvents = events.map((event) => ({ event, @@ -65,13 +56,14 @@ function routeAfter(roots, events, sink) { } // Use real paths: length/segments determine normalization cost, which short synthetic paths understate. -const REPO_PATHS = execFileSync('git', ['ls-files'], { +const REPO_PATHS = execFileSync('git', ['ls-files', '-z'], { cwd: REPO_ROOT, maxBuffer: 256 * 1024 * 1024 }) .toString() - .split('\n') + .split('\0') .filter(Boolean) +assert.ok(REPO_PATHS.length > 0, 'Benchmark needs tracked paths') // Model multi-worktree host with explorer and base-directory watchers per root. function makeRoots(count) { @@ -93,10 +85,8 @@ function makeEvents(roots, count) { function collect(roots, events, route) { const seen = [] - route(roots, events, (rootPath, matching) => - seen.push(`${rootPath} ${matching.map((event) => event.absolutePath).join(',')}`) - ) - return seen.join('\n') + route(roots, events, (rootPath, matching) => seen.push([rootPath, matching])) + return seen } // Interleave rounds and compare medians to share CPU/load drift; batch ordering alone varied observed win from 6.7x to 23.3x. @@ -145,12 +135,11 @@ for (const [rootCount, eventCount] of [ const events = makeEvents(roots, eventCount) const before = collect(roots, events, routeBefore) const after = collect(roots, events, routeAfter) - if (before !== after) { - throw new Error(`routing differs at ${rootCount} roots x ${eventCount} events`) - } - if (!before.includes(' ')) { - throw new Error(`fixture routed nothing at ${rootCount} roots x ${eventCount} events`) - } + assert.deepEqual(after, before, `routing differs at ${rootCount} roots x ${eventCount} events`) + assert.ok( + before.length > 0, + `fixture routed nothing at ${rootCount} roots x ${eventCount} events` + ) const { beforeMs, afterMs } = measureInterleaved(roots, events) console.log( `${pad(rootCount, 6)} ${pad(eventCount, 7)} ${pad(`${beforeMs.toFixed(3)} ms`, 11)} ${pad(`${afterMs.toFixed(3)} ms`, 11)} ${pad(`${(beforeMs / afterMs).toFixed(1)}x`, 9)}` @@ -158,5 +147,5 @@ for (const [rootCount, eventCount] of [ } console.log( - '\nThis times routing only. The saving scales with roots x events, so it is small\nfor a single-worktree session and largest during a remote checkout storm, which\nis exactly when the main process is already busy.' + '\nThis times synthetic routing models with production path normalization.\nIt excludes application dispatch, relay transport, and filesystem work.' ) diff --git a/config/scripts/terminal-reattach-payload-scan-benchmark.mjs b/config/scripts/terminal-reattach-payload-scan-benchmark.mjs index 4a74ddea0a4..d7f75097e64 100644 --- a/config/scripts/terminal-reattach-payload-scan-benchmark.mjs +++ b/config/scripts/terminal-reattach-payload-scan-benchmark.mjs @@ -1,9 +1,21 @@ #!/usr/bin/env node // Compare replay signal’s old CSI scan with shipped 256KB-tail/shared-regex path; assert equivalence before timing deterministic seeded payloads. // Also measure Kitty-mode scan unchanged and with slower includes prefilter; run node config/scripts/terminal-reattach-payload-scan-benchmark.mjs. +import assert from 'node:assert/strict' import { performance } from 'node:perf_hooks' -import { CSI_SEQUENCE_PATTERN } from '../../src/shared/ansi-escape-sequences.ts' -import { TerminalKittyKeyboardModeTracker } from '../../src/shared/terminal-kitty-keyboard-mode-tracker.ts' +import { fileURLToPath } from 'node:url' +import { createJiti } from 'jiti' + +const jiti = createJiti(import.meta.url, { + alias: { '@': fileURLToPath(new URL('../../src/renderer/src', import.meta.url)) } +}) +const { CSI_SEQUENCE_PATTERN } = await jiti.import('../../src/shared/ansi-escape-sequences.ts') +const { TerminalKittyKeyboardModeTracker } = await jiti.import( + '../../src/shared/terminal-kitty-keyboard-mode-tracker.ts' +) +const { hasCursorAgentReattachPayloadScreenSignal: signalSuffixRegex } = await jiti.import( + '../../src/renderer/src/components/terminal-pane/pty-connection/cursor-agent-reattach-screen.ts' +) const ROUNDS = Number(process.env.ORCA_REATTACH_SCAN_BENCH_ROUNDS ?? '7') const MIN_ITERATION_MS = 120 @@ -86,7 +98,7 @@ function buildPayloads() { ] } -// Baseline: verbatim copy of pty-connection.ts:448 (not exported). +// Historical full-payload CSI character scan for comparison. function stripBaseline(data) { let normalized = '' let index = 0 @@ -112,13 +124,9 @@ const stripRegex = (data) => data.replace(CSI_SEQUENCE_PATTERN, '') const HEADER = 'Cursor Agent' const TAIL_CHARS = 5000 -// Mirrors CURSOR_AGENT_REATTACH_SCAN_TAIL_LIMIT_CHARS in pty-connection.ts. -const SUFFIX_RAW_CHARS = 256 * 1024 const signalBaseline = (data) => hasSignal(stripBaseline(data)) const signalRegex = (data) => hasSignal(stripRegex(data)) -const signalSuffixRegex = (data) => - hasSignal(stripRegex(data.length > SUFFIX_RAW_CHARS ? data.slice(-SUFFIX_RAW_CHARS) : data)) function hasSignal(normalized) { const headerIndex = normalized.lastIndexOf(HEADER) @@ -197,12 +205,13 @@ const kittyScan = (data) => { } // The includes() introducer pre-filter a daemon-side mode scan would use. const kittyGated = (data) => { - if (!data.includes('\x1b[?') && !data.includes('\x1bc') && !data.includes('\x9b')) { + if (!data.includes('\x1b[') && !data.includes('\x1bc') && !data.includes('\x9b')) { return 0 } return kittyScan(data) } for (const { name, data } of payloads) { + assert.equal(kittyGated(data), kittyScan(data), `Kitty gate disagrees on ${name}`) console.log( `${pad(name, 36)} ${pad(kb(data), 8)} ${pad(measure(kittyScan, data).toFixed(3), 11)} ${pad(measure(kittyGated, data).toFixed(3), 15)}` ) @@ -212,19 +221,22 @@ for (const { name, data } of payloads) { const liveChunk = buildColoredScrollback(4 * 1024, 5).replaceAll('\x1b', '') const introducerRows = [ ['4KB live chunk, no escapes', liveChunk], - ['4KB live chunk, \\x1b[?25l present', `${liveChunk}\x1b[?25l`] + ['4KB live chunk, \\x1b[?25l present', `${liveChunk}\x1b[?25l`], + ['4KB live chunk, Kitty flags 3', `${liveChunk}\x1b[>3u`], + ['4KB live chunk, Kitty flags 7', `${liveChunk}\x1b[=7u`] ] console.log( `\n${pad('payload', 36)} ${pad('size', 8)} ${pad('scanReplay', 11)} ${pad('+includes gate', 15)}` ) for (const [name, data] of introducerRows) { + assert.equal(kittyGated(data), kittyScan(data), `Kitty gate disagrees on ${name}`) console.log( `${pad(name, 36)} ${pad(kb(data), 8)} ${pad(measure(kittyScan, data).toFixed(3), 11)} ${pad(measure(kittyGated, data).toFixed(3), 15)}` ) } console.log( - '\nSnapshot/replay payloads always contain \\x1b[?, so the includes() gate never fires on\nthe reattach path — it only helps the live per-chunk path.' + '\nThese replay fixtures contain CSI escapes, so the includes() gate never skips\ntheir scan. The live plain-output row measures the no-escape fast path.' ) // Time xterm on identical bytes as reference cost for deciding whether scan optimization matters. diff --git a/src/shared/mobile-relay-phone-protocol.test.ts b/src/shared/mobile-relay-phone-protocol.test.ts index 0935c510853..b55509b5302 100644 --- a/src/shared/mobile-relay-phone-protocol.test.ts +++ b/src/shared/mobile-relay-phone-protocol.test.ts @@ -11,6 +11,13 @@ describe('relay phone outer protocol', () => { leaseExpiresAt: 1 }).success ).toBe(true) + expect( + RelayPhoneHelloSchema.safeParse({ + type: 'relay-hello', + ok: false, + code: 4404 + }).success + ).toBe(true) expect( RelayPhoneHelloSchema.safeParse({ type: 'relay-hello', diff --git a/src/shared/network/server-share-address.test.ts b/src/shared/network/server-share-address.test.ts index 4f09f1f21d6..77ca3a719af 100644 --- a/src/shared/network/server-share-address.test.ts +++ b/src/shared/network/server-share-address.test.ts @@ -5,8 +5,14 @@ import { parseServerShareAddress } from './server-share-address' describe('parseServerShareAddress', () => { it('accepts a bare hostname or IP', () => { expect(parseServerShareAddress('my-host')).toEqual({ ok: true, value: 'my-host' }) - expect(parseServerShareAddress('my-mac.tail-abcd.ts.net').ok).toBe(true) - expect(parseServerShareAddress('192.168.1.50').ok).toBe(true) + expect(parseServerShareAddress('my-mac.tail-abcd.ts.net')).toEqual({ + ok: true, + value: 'my-mac.tail-abcd.ts.net' + }) + expect(parseServerShareAddress('192.168.1.50')).toEqual({ + ok: true, + value: '192.168.1.50' + }) }) it('rejects empty, whitespace-containing, and malformed input', () => { diff --git a/src/shared/tab-has-live-pty.test.ts b/src/shared/tab-has-live-pty.test.ts index 917c6bda7bf..37a057f002b 100644 --- a/src/shared/tab-has-live-pty.test.ts +++ b/src/shared/tab-has-live-pty.test.ts @@ -2,10 +2,6 @@ import { describe, expect, it } from 'vitest' import { tabHasLivePty } from './tab-has-live-pty' describe('tabHasLivePty', () => { - it('returns false for an empty map', () => { - expect(tabHasLivePty({}, 'tab-1')).toBe(false) - }) - it('returns false for a missing tab id', () => { expect(tabHasLivePty({ 'other-tab': ['pty-1'] }, 'tab-1')).toBe(false) })