mirror of
https://github.com/stablyai/orca.git
synced 2026-09-29 08:03:20 +00:00
83 lines
2.8 KiB
TypeScript
83 lines
2.8 KiB
TypeScript
import { mkdtempSync, rmSync, truncateSync, writeFileSync } from 'node:fs'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import { NodeFileReadTooLargeError } from '../shared/node-bounded-file-reader'
|
|
import {
|
|
MAX_AGENT_STATE_FILE_BYTES,
|
|
MAX_AGENT_STATE_JSON_NESTING_DEPTH,
|
|
MAX_AGENT_STATE_JSON_STRUCTURAL_TOKENS,
|
|
readAgentStateFileSync,
|
|
readAgentStateJsonFileSync
|
|
} from './agent-state-file-reader'
|
|
|
|
const tempDirs: string[] = []
|
|
|
|
function tempFile(name: string): string {
|
|
const directory = mkdtempSync(join(tmpdir(), 'orca-agent-state-'))
|
|
tempDirs.push(directory)
|
|
return join(directory, name)
|
|
}
|
|
|
|
afterEach(() => {
|
|
for (const directory of tempDirs.splice(0)) {
|
|
rmSync(directory, { recursive: true, force: true })
|
|
}
|
|
})
|
|
|
|
describe('readAgentStateFileSync', () => {
|
|
it('preserves normal UTF-8 auth and config contents', () => {
|
|
const filePath = tempFile('auth.json')
|
|
const contents = '{"token":"你好","refresh":"abc"}\n'
|
|
writeFileSync(filePath, contents)
|
|
|
|
expect(readAgentStateFileSync(filePath)).toBe(contents)
|
|
})
|
|
|
|
it('reads a sparse file at the exact 4 MiB boundary', () => {
|
|
const filePath = tempFile('snapshot.json')
|
|
writeFileSync(filePath, '')
|
|
truncateSync(filePath, MAX_AGENT_STATE_FILE_BYTES)
|
|
|
|
const contents = readAgentStateFileSync(filePath)
|
|
|
|
expect(contents).toHaveLength(MAX_AGENT_STATE_FILE_BYTES)
|
|
expect(contents.charCodeAt(MAX_AGENT_STATE_FILE_BYTES - 1)).toBe(0)
|
|
})
|
|
|
|
it('rejects a sparse file one byte over the boundary before reading its payload', () => {
|
|
const filePath = tempFile('oversized.json')
|
|
writeFileSync(filePath, '')
|
|
truncateSync(filePath, MAX_AGENT_STATE_FILE_BYTES + 1)
|
|
|
|
expect(() => readAgentStateFileSync(filePath)).toThrow(NodeFileReadTooLargeError)
|
|
})
|
|
})
|
|
|
|
describe('readAgentStateJsonFileSync', () => {
|
|
it('preserves ordinary JSON values', () => {
|
|
const filePath = tempFile('auth.json')
|
|
writeFileSync(filePath, '{"token":"你好","nested":{"enabled":true}}')
|
|
|
|
expect(readAgentStateJsonFileSync(filePath)).toEqual({
|
|
token: '你好',
|
|
nested: { enabled: true }
|
|
})
|
|
})
|
|
|
|
it('rejects structural-token and nesting amplification before JSON.parse', () => {
|
|
const structuralPath = tempFile('structural.json')
|
|
writeFileSync(structuralPath, `[${'0,'.repeat(MAX_AGENT_STATE_JSON_STRUCTURAL_TOKENS)}0]`)
|
|
const nestedPath = tempFile('nested.json')
|
|
writeFileSync(
|
|
nestedPath,
|
|
`${'['.repeat(MAX_AGENT_STATE_JSON_NESTING_DEPTH + 1)}0${']'.repeat(
|
|
MAX_AGENT_STATE_JSON_NESTING_DEPTH + 1
|
|
)}`
|
|
)
|
|
|
|
expect(() => readAgentStateJsonFileSync(structuralPath)).toThrow('JSON structure exceeds')
|
|
expect(() => readAgentStateJsonFileSync(nestedPath)).toThrow('JSON nesting exceeds')
|
|
})
|
|
})
|