mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
* test: exercise fresh orchestration output and identity fixtures * test: check brief task values at the current output boundary * test: observe worker CLI receipts through actual output * test: reach sender lookup and print real worker wait states * test: verify retry deadlines and headless recovery admission * test: audit ACP lifecycle and recorded response boundaries * test: exercise mobile and CI admission contracts * test: check cache producers and exact capped output * test: reconcile upstream audit coverage and cache admission * docs: align integrated audit record hashes --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
236 lines
9.0 KiB
JavaScript
236 lines
9.0 KiB
JavaScript
import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { runInNewContext } from 'node:vm'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import { parse } from 'yaml'
|
|
import {
|
|
finishModuleCache,
|
|
moduleCacheIdentity,
|
|
prepareModuleCache
|
|
} from './ci-unit-module-cache.mjs'
|
|
|
|
const temporary = []
|
|
afterEach(() => {
|
|
for (const directory of temporary.splice(0)) {
|
|
rmSync(directory, { recursive: true, force: true })
|
|
}
|
|
})
|
|
|
|
function options() {
|
|
const directory = mkdtempSync(join(tmpdir(), 'orca-unit-cache-identity-'))
|
|
temporary.push(directory)
|
|
return {
|
|
root: directory,
|
|
cacheRoot: directory,
|
|
policyHash: 'a'.repeat(64),
|
|
installedLockHash: 'b'.repeat(64),
|
|
versions: { node: '24.21.0', bun: '1.4.3', vitest: '5.0.3' },
|
|
shard: { index: 1, count: 5 },
|
|
platform: 'linux',
|
|
arch: 'arm64',
|
|
nodeEnv: 'test',
|
|
namespace: ''
|
|
}
|
|
}
|
|
|
|
describe('persistent unit module cache boundary', () => {
|
|
it('separates hosts, runtimes, config, lockfiles, roots, shards and experiments', () => {
|
|
const original = options()
|
|
const identity = moduleCacheIdentity(original)
|
|
const anotherRoot = options().root
|
|
for (const update of [
|
|
{ root: anotherRoot },
|
|
{ policyHash: 'c'.repeat(64) },
|
|
{ installedLockHash: 'd'.repeat(64) },
|
|
{ platform: 'win32' },
|
|
{ arch: 'x64' },
|
|
{ nodeEnv: 'production' },
|
|
{ namespace: 'comparison' },
|
|
{ shard: { index: 2, count: 5 } },
|
|
{ shard: { index: 1, count: 10 } },
|
|
{ versions: { ...original.versions, node: '26.6.0' } },
|
|
{ versions: { ...original.versions, bun: '1.4.4' } },
|
|
{ versions: { ...original.versions, vitest: '5.0.4' } }
|
|
]) {
|
|
const next = moduleCacheIdentity({ ...original, ...update })
|
|
expect(next.key).not.toBe(identity.key)
|
|
expect(next.path).toBe(identity.path)
|
|
}
|
|
expect(moduleCacheIdentity(original)).toEqual(identity)
|
|
})
|
|
|
|
it.each([
|
|
{ cacheRoot: '' },
|
|
{ policyHash: '' },
|
|
{ installedLockHash: '' },
|
|
{ versions: { node: '24', bun: '1.4.3', vitest: '5.0.3' } },
|
|
{ shard: { index: 0, count: 5 } },
|
|
{ shard: { index: 6, count: 5 } }
|
|
])('refuses an incomplete identity %j', (update) => {
|
|
expect(() => moduleCacheIdentity({ ...options(), ...update })).toThrow('incomplete')
|
|
})
|
|
|
|
it.each([false, true])(
|
|
'starts cold and discards unusable restored bytes (hit %s)',
|
|
async (hit) => {
|
|
const identity = moduleCacheIdentity(options())
|
|
mkdirSync(identity.path)
|
|
writeFileSync(join(identity.path, 'untrusted'), 'throw Error("must not execute")')
|
|
const prepared = await prepareModuleCache(identity, { restoreHit: hit })
|
|
expect(prepared.available).toBe(false)
|
|
expect(prepared.validationMs).toBeGreaterThanOrEqual(0)
|
|
expect(() => readFileSync(join(identity.path, 'untrusted'))).toThrow()
|
|
}
|
|
)
|
|
it('restores a matching cache produced from an earlier source', async () => {
|
|
const identity = moduleCacheIdentity(options())
|
|
mkdirSync(identity.path)
|
|
writeFileSync(
|
|
join(identity.path, '_metadata.json'),
|
|
JSON.stringify({ lockfileHash: identity.installedLockHash.slice(0, 8) })
|
|
)
|
|
const metadata = [
|
|
{ id: '1', url: '2', file: '1', imports: '3', mappings: false },
|
|
join(identity.root, 'source.ts'),
|
|
'/source.ts',
|
|
{ urls: '4', ids: '5' },
|
|
[],
|
|
{}
|
|
]
|
|
writeFileSync(
|
|
join(identity.path, 'a'.repeat(40)),
|
|
`export const value = 1\n//# vitestCache=${Buffer.from(JSON.stringify(metadata)).toString('base64')}`
|
|
)
|
|
const produced = await finishModuleCache(identity, { sourceSha: 'a'.repeat(40) })
|
|
expect(produced.entries).toBe(2)
|
|
const prepared = await prepareModuleCache(
|
|
{ ...identity, sourceSha: 'b'.repeat(40) },
|
|
{ restoreHit: true }
|
|
)
|
|
expect(prepared).toMatchObject({
|
|
available: true,
|
|
entries: produced.entries,
|
|
bytes: produced.bytes,
|
|
producerSourceSha: 'a'.repeat(40)
|
|
})
|
|
})
|
|
})
|
|
|
|
it('uses an optional exact restore after install and saves successful scoped producers', () => {
|
|
const workflow = parse(readFileSync('.github/workflows/unit-tests.yml', 'utf8'))
|
|
const steps = workflow.jobs.test.steps
|
|
const dependencies = steps.findIndex(
|
|
(step) => step.uses === './.github/actions/install-node-dependencies'
|
|
)
|
|
const identity = steps.findIndex((step) => step.id === 'module-cache')
|
|
const restore = steps.findIndex((step) => step.id === 'module-cache-restore')
|
|
const prepare = steps.findIndex((step) => step.run?.endsWith('ci-unit-module-cache.mjs prepare'))
|
|
const tests = steps.findIndex((step) => step.name === 'Test shard')
|
|
const seal = steps.find((step) => step.id === 'module-cache-seal')
|
|
const save = steps.find((step) => step.uses === 'actions/cache/save@v5')
|
|
expect(identity).toBeGreaterThan(dependencies)
|
|
expect(restore).toBeGreaterThan(identity)
|
|
expect(prepare).toBeGreaterThan(restore)
|
|
expect(tests).toBeGreaterThan(prepare)
|
|
expect(steps[restore].uses).toBe('actions/cache/restore@v5')
|
|
expect(steps[restore].with['restore-keys']).toBeUndefined()
|
|
expect(steps[restore]['continue-on-error']).toBe(true)
|
|
const guard = seal.if
|
|
.replaceAll('steps.module-cache.outputs.key', 'steps["module-cache"].outputs.key')
|
|
.replaceAll(
|
|
'steps.module-cache-restore.outputs.cache-hit',
|
|
'steps["module-cache-restore"].outputs["cache-hit"]'
|
|
)
|
|
const producer = {
|
|
event: 'pull_request',
|
|
ref: 'refs/pull/1/merge',
|
|
success: true,
|
|
key: 'scoped',
|
|
hit: '',
|
|
seed: false
|
|
}
|
|
for (const [name, update, expected] of [
|
|
['successful PR cache miss', {}, true],
|
|
['successful main producer', { event: 'push', ref: 'refs/heads/main' }, true],
|
|
[
|
|
'successful manually seeded branch',
|
|
{ event: 'workflow_dispatch', ref: 'refs/heads/experiment', seed: true },
|
|
true
|
|
],
|
|
['failed PR', { success: false }, false],
|
|
['missing identity', { key: '' }, false],
|
|
['exact restored hit', { hit: 'true' }, false],
|
|
['ordinary branch push', { event: 'push', ref: 'refs/heads/experiment' }, false],
|
|
['unseeded manual branch', { event: 'workflow_dispatch', ref: 'refs/heads/experiment' }, false],
|
|
[
|
|
'seed does not admit a nonmanual event',
|
|
{ event: 'push', ref: 'refs/heads/experiment', seed: true },
|
|
false
|
|
],
|
|
['failed main producer', { event: 'push', ref: 'refs/heads/main', success: false }, false]
|
|
]) {
|
|
const control = { ...producer, ...update }
|
|
const admitted = runInNewContext(guard, {
|
|
github: { event_name: control.event, ref: control.ref },
|
|
steps: {
|
|
'module-cache': { outputs: { key: control.key } },
|
|
'module-cache-restore': { outputs: { 'cache-hit': control.hit } }
|
|
},
|
|
inputs: { module_cache_seed: control.seed },
|
|
success: () => control.success
|
|
})
|
|
expect(admitted, name).toBe(expected)
|
|
}
|
|
expect(save.if).toBe("steps.module-cache-seal.outputs.ready == 'true'")
|
|
expect(save.with.key).toBe(steps[restore].with.key)
|
|
expect(workflow.on.workflow_call.inputs.module_cache.default).toBe('off')
|
|
expect(workflow.on.workflow_call.inputs.run_relay_integration.default).toBe(true)
|
|
})
|
|
|
|
it('retains four workers on ARM and the four-core Blacksmith unit runner', () => {
|
|
const workflow = parse(readFileSync('.github/workflows/unit-tests.yml', 'utf8'))
|
|
const step = workflow.jobs.test.steps.find((step) => step.name === 'Test shard')
|
|
const expression = [...step.run.matchAll(/\$\{\{(.+?)\}\}/g)].find((match) =>
|
|
match[1].includes('--maxWorkers')
|
|
)[1]
|
|
for (const [arch, runner] of [
|
|
['ARM64', 'ubuntu-24.04-arm'],
|
|
['ARM64', 'blacksmith-4vcpu-ubuntu-2404-arm'],
|
|
['X64', 'blacksmith-4vcpu-ubuntu-2404']
|
|
]) {
|
|
expect(runInNewContext(expression, { runner: { arch }, inputs: { runner } })).toBe(
|
|
'--maxWorkers=4'
|
|
)
|
|
}
|
|
expect(
|
|
runInNewContext(expression, {
|
|
runner: { arch: 'X64' },
|
|
inputs: { runner: 'blacksmith-8vcpu-ubuntu-2404' }
|
|
})
|
|
).toBe('--maxWorkers=8')
|
|
expect(
|
|
runInNewContext(expression, { runner: { arch: 'X64' }, inputs: { runner: 'ubuntu-latest' } })
|
|
).toBe('')
|
|
})
|
|
|
|
it('runs baseline, producer and warm controls serially with matching runtimes and shards', () => {
|
|
const workflow = parse(readFileSync('.github/workflows/unit-module-cache-benchmark.yml', 'utf8'))
|
|
const { baseline, producer, warm } = workflow.jobs
|
|
expect(producer.needs).toBe('baseline')
|
|
expect(warm.needs).toBe('producer')
|
|
for (const job of [baseline, producer, warm]) {
|
|
expect(job.uses).toBe('./.github/workflows/unit-tests.yml')
|
|
expect(job.with.node_versions).toBe('["24.22.1"]')
|
|
expect(job.with.runner).toBe('ubuntu-24.04-arm')
|
|
expect(JSON.parse(job.with.shards)).toEqual(
|
|
Array.from({ length: 5 }, (_, index) => ({ index: index + 1, count: 5 }))
|
|
)
|
|
expect(job.with.phase_diagnostics).toBe(true)
|
|
}
|
|
expect(producer.with.module_cache).toBe('cold')
|
|
expect(producer.with.module_cache_seed).toBe(true)
|
|
expect(warm.with.module_cache).toBe('warm')
|
|
expect(warm.with.module_cache_namespace).toBe(producer.with.module_cache_namespace)
|
|
})
|