test: fake-clock the agent-session start backoff; drop the CLI owner-choice work-count suite (#39685)

* test(agent-session): jump the start retry backoff on a fake clock

The five-attempt cases waited 1.5s of real 100·2^n ms backoff each. Route the
backoff's promise delay through fake timers and jump it while real time still
passes for file and database work.

* test(cli): delete the owner-choice work-count suite

It asserted property visits, serialized bytes and call counts under spied
globals at 10,000 workspaces; owner election behavior stays covered by
index-workspace-owner-choice.test.ts.

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
OrcaWin
2026-11-07 19:10:56 -08:00
committed by GitHub
co-authored by OrcaWin
parent 88f452a665
commit 35547956dd
2 changed files with 23 additions and 515 deletions
@@ -1,512 +0,0 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
const {
callMock,
runtimeClientConstructorMock,
serveOrcaAppMock,
getDefaultUserDataPathMock,
addEnvironmentFromPairingCodeMock,
listEnvironmentsMock,
spawnMock
} = vi.hoisted(() => ({
callMock: vi.fn(),
runtimeClientConstructorMock: vi.fn(),
serveOrcaAppMock: vi.fn(),
getDefaultUserDataPathMock: vi.fn(() => '/tmp/orca-user-data'),
addEnvironmentFromPairingCodeMock: vi.fn(),
listEnvironmentsMock: vi.fn(),
spawnMock: vi.fn()
}))
vi.mock('./runtime-client', async () => {
const { createRuntimeClientModuleMock } = await import('./index-test-harness.js')
return createRuntimeClientModuleMock({
callMock,
runtimeClientConstructorMock,
serveOrcaAppMock,
getDefaultUserDataPathMock
})
})
vi.mock('./runtime/environments', () => ({
addEnvironmentFromPairingCode: addEnvironmentFromPairingCodeMock,
removeEnvironment: vi.fn(),
resolveEnvironment: vi.fn()
}))
vi.mock('../shared/remote-runtime/host-store/runtime-environment-store', () => ({
listEnvironments: listEnvironmentsMock
}))
vi.mock('child_process', async () => {
const { createChildProcessModuleMock } = await import('./index-test-harness.js')
return createChildProcessModuleMock(spawnMock)
})
import { createHash } from 'node:crypto'
import { readFileSync } from 'node:fs'
import * as compatibilityEvidence from '../shared/orchestration-compatibility-evidence'
import * as nativeHosts from '../shared/folder-workspaces/folder-workspace-execution-host'
import * as workspaceSelection from './caller-host-worktree-selection'
import { reportCliError } from './cli-error'
import { main } from './index'
import { buildWorktree, okFixture, worktreeListFixture } from './test-fixtures'
import { useWorktreeAwarenessEnvironment } from './index-test-harness'
// Count only choice structures; spies call the actual reporter, recursive redactor and serializer.
function traceChoiceReporting() {
const stringify = JSON.stringify
const entries = Object.entries
const metrics = {
propertyVisits: 0,
redactions: 0,
serializations: 0,
serializedBytes: 0,
inputCodeUnits: 0,
choices: 0,
forms: 0
}
const objectEntries = vi.spyOn(Object, 'entries').mockImplementation((value) => {
const result = entries(value)
if (value && typeof value === 'object' && 'selector' in value && 'path' in value) {
metrics.propertyVisits += result.length
}
return result
})
const originalRedact = compatibilityEvidence.redactOrchestrationCompatibilitySecrets
const redactor = vi
.spyOn(compatibilityEvidence, 'redactOrchestrationCompatibilitySecrets')
.mockImplementation((value) => {
if (
value &&
typeof value === 'object' &&
'workspaces' in value &&
'validSelectorForms' in value
) {
metrics.redactions++
if (Array.isArray(value.workspaces)) {
metrics.choices += value.workspaces.length
}
if (Array.isArray(value.validSelectorForms)) {
metrics.forms += value.validSelectorForms.length
}
}
return originalRedact(value)
})
const serialization = vi.spyOn(JSON, 'stringify').mockImplementation((value, replacer, space) => {
const result = stringify(value, replacer, space)
if (
value &&
typeof value === 'object' &&
(('error' in value && value.error?.code === 'selector_ambiguous') ||
(Array.isArray(value) &&
value[0] &&
typeof value[0] === 'object' &&
'selector' in value[0]))
) {
const stringUnits = (input: unknown): number =>
typeof input === 'string'
? input.length
: Array.isArray(input)
? input.reduce((n, entry) => n + stringUnits(entry), 0)
: input && typeof input === 'object'
? entries(input).reduce((n, [key, entry]) => n + key.length + stringUnits(entry), 0)
: 0
metrics.inputCodeUnits += stringUnits(value)
metrics.serializations++
metrics.serializedBytes += Buffer.byteLength(result ?? '')
}
return result
})
return {
metrics,
stop: () => {
serialization.mockRestore()
redactor.mockRestore()
objectEntries.mockRestore()
}
}
}
describe('cwd workspace owner election and reporting at N and 10N', () => {
useWorktreeAwarenessEnvironment({
callMock,
serveOrcaAppMock,
getDefaultUserDataPathMock,
addEnvironmentFromPairingCodeMock,
listEnvironmentsMock,
spawnMock
})
beforeEach(() => {
vi.stubEnv('ORCA_AGENT_SESSION_ID', undefined)
vi.stubEnv('ORCA_STRUCTURED_SESSION', undefined)
})
afterEach(() => vi.unstubAllEnvs())
const root = buildWorktree('/tmp/owner-choice', 'main', 'abc', 'repo-a')
it.each([
{ caller: false, json: false },
{ caller: false, json: true },
{ caller: true, json: true }
])(
'bounds real-main owner/identity/diagnostic work at N and 10N (%j)',
async ({ caller, json }) => {
const log = vi.spyOn(console, 'log').mockImplementation(() => {})
const prior = process.exitCode
const samples: number[] = []
const serialized: number[] = []
const timings: {
count: number
elapsedMs: number
operations: number
outputBytes: number
reporting: ReturnType<typeof traceChoiceReporting>['metrics']
}[] = []
const errors = vi.spyOn(console, 'error').mockImplementation(() => {})
try {
for (const count of [1_000, 10_000]) {
let operations = 0
const rows = Array.from({ length: count }, (_, index) => {
const owner = index % (count / 2)
const host = index < count / 2 ? 'local' : 'ssh:other'
return {
...root,
get id() {
operations++
return `${root.id}::workspace:${owner}`
},
get repoId() {
operations++
return root.repoId
},
get path() {
operations++
return root.path
},
get hostId() {
operations++
return host
},
get identity() {
operations++
return {
get key() {
operations++
return `${host}:owner-${owner}`
}
}
}
}
})
if (caller) {
process.env.ORCA_WORKTREE_ID = `${root.id}::workspace:0`
} else {
delete process.env.ORCA_WORKTREE_ID
}
callMock.mockReset()
log.mockClear()
process.exitCode = prior
callMock.mockImplementation(async (method) =>
method === 'worktree.list'
? worktreeListFixture(rows)
: okFixture('show', { worktree: root })
)
errors.mockClear()
const trace = traceChoiceReporting()
let elapsedMs = 0
try {
const started = performance.now()
await main(['worktree', 'current', ...(json ? ['--json'] : [])], root.path)
elapsedMs = performance.now() - started
} finally {
trace.stop()
}
const measured = operations
expect(measured).toBeGreaterThanOrEqual(count)
expect(measured).toBeLessThanOrEqual(50 * count)
expect(callMock.mock.calls.filter(([method]) => method === 'worktree.list')).toEqual([
['worktree.list', { limit: 10_000 }]
])
const printed = (json ? log : errors).mock.calls.flat().join('\n')
const output = json
? JSON.parse(printed)
: {
error: {
data: {
workspaces: JSON.parse(
printed
.split('Workspace choices (JSON data):\n')[1]!
.split('\nNext step:')[0]!
),
validSelectorForms: [],
nextSteps: printed.split('Next step:').slice(1)
}
}
}
if (!json) {
output.error.data.validSelectorForms = output.error.data.workspaces.map(
(choice: { selector: string }) => choice.selector
)
}
if (caller) {
expect(process.exitCode).toBe(prior)
expect(callMock).toHaveBeenCalledWith('worktree.show', {
worktree: 'identity:local:owner-0'
})
expect(output.result.worktree.id).toBe(root.id)
} else {
expect(process.exitCode).toBe(1)
expect(output.error.data.workspaces).toHaveLength(count / 2)
expect(output.error.data.validSelectorForms).toHaveLength(count / 2)
expect(output.error.data.validSelectorForms[0]).toBe('identity:local:owner-0')
expect(output.error.data.nextSteps).toHaveLength(3)
expect(callMock).toHaveBeenCalledTimes(1)
expect(printed.split('More than one Orca workspace')).toHaveLength(2)
if (!json) {
expect(printed.split('Workspace choices (JSON data):')).toHaveLength(2)
}
expect(trace.metrics).toMatchObject({
redactions: 1,
choices: count / 2,
forms: count / 2,
serializations: 1
})
expect(trace.metrics.propertyVisits).toBeGreaterThanOrEqual((4 * count) / 2)
expect(trace.metrics.propertyVisits).toBeLessThanOrEqual((8 * count) / 2)
const rawBytes = Buffer.byteLength(JSON.stringify(output.error.data.workspaces))
expect(trace.metrics.serializedBytes).toBeGreaterThanOrEqual(rawBytes)
expect(trace.metrics.serializedBytes).toBeLessThanOrEqual(6 * rawBytes + 4096)
expect(trace.metrics.inputCodeUnits).toBeGreaterThan(0)
expect(trace.metrics.serializedBytes).toBeLessThanOrEqual(
6 * trace.metrics.inputCodeUnits + 32 * count + 4096
)
serialized.push(trace.metrics.serializedBytes)
}
timings.push({
count,
elapsedMs,
operations: measured,
outputBytes: Buffer.byteLength(printed),
reporting: { ...trace.metrics }
})
samples.push(measured)
}
expect(samples[1]!).toBeLessThanOrEqual(11 * samples[0]!)
if (!caller) {
expect(serialized[1]!).toBeLessThanOrEqual(11 * serialized[0]!)
}
console.info(
'immediate-cwd-benchmark',
JSON.stringify({
platform: process.platform,
node: process.version,
base: '3bfcda1bf043af8d83371b2f131a65f2056f7970',
sourceInputSha256: createHash('sha256').update(readFileSync(__filename)).digest('hex'),
format: json ? 'json' : 'text',
caller,
samplesPerPopulation: 1,
boundary:
'real CLI main(current), election and reporter with call-through counters; fresh corpus and reset client/output per N before timing; modules already loaded, N first trigger then 10N warm modules; no cold-process sample; corpus setup and assertions excluded',
samples: timings
})
)
} finally {
process.exitCode = prior
}
}
)
it.each([false, true])(
'measures native presence, eligible caller/full election and added reporting (caller=%s)',
async (caller) => {
const log = vi.spyOn(console, 'log').mockImplementation(() => {})
const error = vi.spyOn(console, 'error').mockImplementation(() => {})
const resolveHost = vi.spyOn(nativeHosts, 'resolveFolderWorkspaceHost')
const elect = workspaceSelection.selectEnclosingWorktreeOnHost
const presence = workspaceSelection.hasEnclosingWorktreeOnHost
const samples: {
count: number
nativeMs: number
addedMs: number
baselineFolderReads: number
hostCalls: number
addedReads: number
presenceReads: number
serializations: number
bytes: number
}[] = []
const prior = process.exitCode
try {
for (const count of [1000, 10000]) {
let baselineFolderReads = 0
let addedReads = 0
let presenceReads = 0
const folders = Array.from({ length: count }, (_, index) => ({
get id() {
baselineFolderReads++
return `native-${index}`
},
get folderPath() {
baselineFolderReads++
return root.path
},
projectGroupId: index % 2 === 0 ? 'local' : 'remote'
}))
const observe = <Row extends object>(rows: readonly Row[], visit: () => void) =>
rows.map(
(row) =>
new Proxy(row, {
get(target, key, receiver) {
visit()
// oxlint-disable-next-line anti-slop/no-reflect-get -- Proxy `get` trap: only Reflect.get forwards a raw string|symbol key with the proxy receiver.
return Reflect.get(target, key, receiver)
}
})
)
let eligible: Parameters<typeof elect>[0] = []
const selection = vi
.spyOn(workspaceSelection, 'selectEnclosingWorktreeOnHost')
.mockImplementation((rows, ...args) => {
if (rows.length > eligible.length) {
eligible = rows
}
return elect(
observe(rows, () => {
addedReads++
}),
...args
)
})
const present = vi
.spyOn(workspaceSelection, 'hasEnclosingWorktreeOnHost')
.mockImplementation((rows, ...args) =>
presence(
observe(rows, () => {
presenceReads++
}),
...args
)
)
if (caller) {
process.env.ORCA_WORKSPACE_ID = 'folder:native-0'
} else {
delete process.env.ORCA_WORKSPACE_ID
}
callMock.mockReset()
log.mockClear()
error.mockClear()
resolveHost.mockClear()
process.exitCode = prior
callMock.mockImplementation(async (method) => {
if (method === 'folderWorkspace.list') {
return okFixture('folders', { folderWorkspaces: folders })
}
if (method === 'projectGroup.list') {
return okFixture('groups', {
groups: [{ id: 'local' }, { id: 'remote', connectionId: 'other' }]
})
}
if (method === 'repo.list') {
return okFixture('repos', { repos: [] })
}
if (method === 'workspacePorts.scanHost') {
return okFixture('ports', { ports: [] })
}
throw new Error(`unexpected native scale RPC ${method}`)
})
const started = performance.now()
await main(['ports', '--all', '--json'], root.path)
const nativeMs = performance.now() - started
expect(resolveHost).toHaveBeenCalledTimes(count)
expect(present).toHaveBeenCalledTimes(1)
expect(selection).toHaveBeenCalledTimes(caller ? 1 : 2)
expect(presenceReads).toBeLessThanOrEqual(10 * count)
expect(addedReads).toBeLessThanOrEqual(50 * count)
expect(callMock.mock.calls.map(([method]) => method)).toEqual([
'folderWorkspace.list',
'projectGroup.list',
'repo.list',
...(caller ? ['workspacePorts.scanHost'] : [])
])
if (caller) {
expect(process.exitCode).toBe(prior)
expect(callMock).toHaveBeenLastCalledWith('workspacePorts.scanHost', {
worktree: 'id:folder:native-0'
})
expect(JSON.parse(log.mock.calls.flat().join('\n')).result.ports).toEqual([])
} else {
expect(process.exitCode).toBe(1)
expect(eligible).toHaveLength(count / 2)
expect(JSON.parse(log.mock.calls.flat().join('\n')).error.data.workspaces).toHaveLength(
count / 2
)
}
selection.mockRestore()
present.mockRestore()
// Isolate added election/reporting on the actual native entry's supplied population.
addedReads = 0
log.mockClear()
error.mockClear()
const trace = traceChoiceReporting()
const addedStarted = performance.now()
try {
try {
elect(
observe(eligible, () => {
addedReads++
}),
root.path,
'local',
'ports'
)
} catch (failure) {
reportCliError(failure, false)
}
} finally {
trace.stop()
}
const addedMs = performance.now() - addedStarted
expect(addedReads).toBeLessThanOrEqual(50 * count)
if (!caller) {
expect(trace.metrics).toMatchObject({
choices: count / 2,
forms: count / 2,
redactions: 1,
serializations: 1
})
expect(trace.metrics.propertyVisits).toBeLessThanOrEqual((8 * count) / 2)
expect(
error.mock.calls.flat().join('\n').split('Workspace choices (JSON data):')
).toHaveLength(2)
}
samples.push({
count,
nativeMs,
addedMs,
baselineFolderReads,
hostCalls: resolveHost.mock.calls.length,
addedReads,
presenceReads,
serializations: trace.metrics.serializations,
bytes: trace.metrics.serializedBytes
})
}
expect(samples[1]!.addedReads).toBeLessThanOrEqual(11 * samples[0]!.addedReads)
expect(samples[1]!.presenceReads).toBeLessThanOrEqual(11 * samples[0]!.presenceReads)
console.info(
'native-cwd-benchmark',
JSON.stringify({
platform: process.platform,
node: process.version,
caller,
base: '3bfcda1bf043af8d83371b2f131a65f2056f7970',
boundary:
'real native entry includes existing per-folder F/G/R scans, possibly quadratic; added election/reporter timed separately; each N uses fresh corpus, modules already loaded',
samples
})
)
} finally {
process.exitCode = prior
}
}
)
})
@@ -2,7 +2,8 @@ import { claudeScriptedChild } from '../../claude/claude-scripted-child.test-fix
import { mkdtemp, rm } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, expect, it, vi } from 'vitest'
import type * as TimersPromises from 'node:timers/promises'
import { afterEach, beforeEach, expect, it, vi } from 'vitest'
import { readWholeAgentSessionFailureFact } from '../../../shared/agent-session/failures/agent-session-failure'
import { computeAgentSessionPayloadFingerprint } from '../../../shared/agent-session/lifecycle/agent-session-mutation-envelope'
import {
@@ -19,12 +20,25 @@ import {
stopStructuredAgentSessionRuntime
} from './structured-agent-session-runtime'
// The start retry backoff's promise delay must use the fake clock this suite jumps.
vi.mock('node:timers/promises', async (importOriginal) => ({
...(await importOriginal<typeof TimersPromises>()),
// ast-grep-ignore: test-no-real-time-wait -- Backed by the fake setTimeout installed per test.
setTimeout: (ms?: number) => new Promise<void>((resolve) => setTimeout(resolve, ms))
}))
let directory: string | undefined
let operations = 0
const operationId = () => `${Date.now()}-${(++operations).toString(16).padStart(32, '0')}`
const caller = { callerKey: 'adapter-start-failure-test' }
beforeEach(() => {
// Real time still passes, so file and database work settles; waits jump the clock.
vi.useFakeTimers({ shouldAdvanceTime: true, toFake: ['setTimeout', 'clearTimeout'] })
})
afterEach(async () => {
vi.useRealTimers()
await stopStructuredAgentSessionRuntime()
if (directory) {
await rm(directory, { recursive: true, force: true })
@@ -96,8 +110,14 @@ async function failedStart(
}
const expectedAttempts = unanswered || agent === 'grok' || agent === 'claude' ? 5 : 1
for (let attempt = 1; attempt <= expectedAttempts; attempt++) {
// Retries back off 100·2^n ms (800 ms before the fifth spawn); the 1 s default leaves no room under load.
await vi.waitFor(() => expect(script.spawns()).toBe(attempt), { timeout: 5_000 })
// Retries back off 100·2^n ms (800 ms before the fifth spawn); each poll jumps 100 ms.
await vi.waitFor(
() => {
vi.advanceTimersByTime(100)
expect(script.spawns()).toBe(attempt)
},
{ timeout: 5_000, interval: 10 }
)
const fail = unanswered ? script.exitHandshake : script.failHandshake
if (!fail) {
throw new Error('fixture has no unanswered exit')