mirror of
https://github.com/stablyai/orca.git
synced 2026-10-21 00:03:46 +00:00
test(terminal): bound perf marker scans
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
type HiddenPressureOutputMode,
|
||||
writePressureOutputScript
|
||||
} from './artificial-opencode-hidden-pressure-script'
|
||||
import { waitForMarkerLatency } from './artificial-opencode-pane-interactions'
|
||||
import {
|
||||
ensureTerminalVisible,
|
||||
getActiveWorktreeId,
|
||||
@@ -16,7 +17,6 @@ import {
|
||||
waitForSessionReady
|
||||
} from './helpers/store'
|
||||
import {
|
||||
getTerminalContent,
|
||||
sendToTerminal,
|
||||
waitForActivePanePtyId,
|
||||
waitForActiveTerminalManager
|
||||
@@ -83,11 +83,8 @@ type HiddenPressureAckGate = {
|
||||
heldAckChars: number
|
||||
}
|
||||
|
||||
// Why: restore still has to finish promptly, but parallel Electron workers on
|
||||
// Linux CI can overshoot the 1s product target without a responsiveness regression.
|
||||
// Main relaxed this to 4s for drain-plus-poll overhead on loaded OSS runners; this
|
||||
// branch keeps a far stricter budget with only a small margin for the whole-buffer
|
||||
// serialize-poll overhead (seen at ~1.5s), so a genuinely slow restore is still caught.
|
||||
// Why: keep a runtime backstop so loaded CI still emits the measurement;
|
||||
// saved perf reports enforce the stricter 1s product budget.
|
||||
const MAX_HIDDEN_RESTORE_LATENCY_MS = 2_000
|
||||
// Why: Phase-4 hidden-delivery gate contract — hidden PTY bytes are dropped in
|
||||
// main after model ingestion, so renderer-delivery pressure must stay FAR
|
||||
@@ -269,12 +266,7 @@ async function measureHiddenOutputRestoreLatency(
|
||||
): Promise<number> {
|
||||
const restoreStart = performance.now()
|
||||
await switchToWorktree(orcaPage, worktreeId)
|
||||
await expect
|
||||
.poll(() => getTerminalContent(orcaPage, 20_000), {
|
||||
timeout: 20_000,
|
||||
message: 'Hidden PTY output was not restored from main buffer on return'
|
||||
})
|
||||
.toContain(`OPENCODE_PRESSURE_DONE_${runId}_`)
|
||||
await waitForMarkerLatency(orcaPage, `OPENCODE_PRESSURE_DONE_${runId}_`, 20_000)
|
||||
return performance.now() - restoreStart
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { Page } from '@stablyai/playwright-test'
|
||||
import { expect } from './helpers/orca-app'
|
||||
import { ensureTerminalVisible } from './helpers/store'
|
||||
import {
|
||||
getTerminalContent,
|
||||
splitActiveTerminalPane,
|
||||
waitForActiveTerminalManager,
|
||||
waitForPaneIdentitySnapshot
|
||||
@@ -76,7 +75,7 @@ export async function waitForMarkerLatency(
|
||||
): Promise<number> {
|
||||
const start = performance.now()
|
||||
while (performance.now() - start < timeoutMs) {
|
||||
if ((await getTerminalContent(page, 12_000)).includes(marker)) {
|
||||
if (await activeTerminalTailContains(page, marker)) {
|
||||
return performance.now() - start
|
||||
}
|
||||
await page.waitForTimeout(5)
|
||||
@@ -84,6 +83,53 @@ export async function waitForMarkerLatency(
|
||||
throw new Error(`Timed out waiting for terminal marker ${marker}`)
|
||||
}
|
||||
|
||||
// Marker probes only need recent text; serializing full scrollback can dominate the latency under test.
|
||||
export async function activeTerminalTailContains(
|
||||
page: Page,
|
||||
expected: string,
|
||||
maxRows = 200
|
||||
): Promise<boolean> {
|
||||
return page.evaluate(
|
||||
({ expected, maxRows }) => {
|
||||
const state = window.__store?.getState()
|
||||
const worktreeId = state?.activeWorktreeId
|
||||
const tabs = worktreeId ? (state?.tabsByWorktree[worktreeId] ?? []) : []
|
||||
const preferredTabId =
|
||||
state?.activeTabType === 'terminal'
|
||||
? state.activeTabId
|
||||
: worktreeId
|
||||
? (state?.activeTabIdByWorktree?.[worktreeId] ?? null)
|
||||
: null
|
||||
const tabId =
|
||||
preferredTabId && tabs.some((tab) => tab.id === preferredTabId)
|
||||
? preferredTabId
|
||||
: (tabs[0]?.id ?? null)
|
||||
const manager = tabId ? window.__paneManagers?.get(tabId) : null
|
||||
const pane = manager?.getActivePane?.() ?? manager?.getPanes?.()[0] ?? null
|
||||
const buffer = pane?.terminal?.buffer?.active
|
||||
if (!buffer) {
|
||||
return false
|
||||
}
|
||||
const firstRow = Math.max(0, buffer.length - maxRows)
|
||||
let logicalHead = ''
|
||||
for (let row = buffer.length - 1; row >= firstRow; row -= 1) {
|
||||
const line = buffer.getLine(row)
|
||||
if (!line) {
|
||||
logicalHead = ''
|
||||
continue
|
||||
}
|
||||
logicalHead = line.translateToString(true) + logicalHead
|
||||
if (logicalHead.includes(expected)) {
|
||||
return true
|
||||
}
|
||||
logicalHead = line.isWrapped ? logicalHead.slice(0, expected.length) : ''
|
||||
}
|
||||
return false
|
||||
},
|
||||
{ expected, maxRows }
|
||||
)
|
||||
}
|
||||
|
||||
export async function getTerminalContentForPtyId(
|
||||
page: Page,
|
||||
ptyId: string,
|
||||
|
||||
@@ -4,6 +4,7 @@ import { randomUUID } from 'node:crypto'
|
||||
import { rmSync } from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { writePressureOutputScript } from './artificial-opencode-hidden-pressure-script'
|
||||
import { waitForMarkerLatency } from './artificial-opencode-pane-interactions'
|
||||
import {
|
||||
ensureTerminalVisible,
|
||||
getAllWorktreeIds,
|
||||
@@ -12,7 +13,6 @@ import {
|
||||
waitForSessionReady
|
||||
} from './helpers/store'
|
||||
import {
|
||||
getTerminalContent,
|
||||
sendToTerminal,
|
||||
waitForActivePanePtyId,
|
||||
waitForActiveTerminalManager
|
||||
@@ -262,21 +262,6 @@ async function startRealPtyPressureCommands({
|
||||
)
|
||||
}
|
||||
|
||||
async function waitForMarkerLatency(
|
||||
page: Page,
|
||||
marker: string,
|
||||
timeoutMs: number
|
||||
): Promise<number> {
|
||||
const start = performance.now()
|
||||
while (performance.now() - start < timeoutMs) {
|
||||
if ((await getTerminalContent(page, 12_000)).includes(marker)) {
|
||||
return performance.now() - start
|
||||
}
|
||||
await page.waitForTimeout(5)
|
||||
}
|
||||
throw new Error(`Timed out waiting for terminal marker ${marker}`)
|
||||
}
|
||||
|
||||
function expectPressureStayedBounded<TMeasurement extends RevisitPressureMeasurement>({
|
||||
ackGate,
|
||||
mainRendererPressureTargetChars,
|
||||
|
||||
Reference in New Issue
Block a user