mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
101 lines
3.3 KiB
JavaScript
101 lines
3.3 KiB
JavaScript
import { readFileSync } from 'node:fs'
|
|
import { describe, expect, it } from 'vitest'
|
|
import { parse } from 'yaml'
|
|
|
|
const { jobs } = parse(readFileSync('.github/workflows/node-server-tests.yml', 'utf8'))
|
|
const step = jobs.desktop_template.steps.find(
|
|
(item) => item.name === 'Wait for every template qualification lane'
|
|
)
|
|
const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor
|
|
function lanes(prefix = 'orcad-template / qualify / ') {
|
|
return [
|
|
{ name: `${prefix}desktop_template`, status: 'in_progress' },
|
|
...Object.entries({
|
|
persistence: 6,
|
|
mobile_web_bundle: 1,
|
|
linux_glibc_floor: 2,
|
|
linux_glibc217_compat: 1,
|
|
linux_musl: 2
|
|
}).flatMap(([name, count]) =>
|
|
Array.from({ length: count }, (_, i) => ({
|
|
name: `${prefix}${name}${count > 1 ? ` (platform-${i})` : ''}`,
|
|
status: 'completed',
|
|
conclusion: 'success'
|
|
}))
|
|
)
|
|
]
|
|
}
|
|
function execute(snapshots) {
|
|
let now = 0
|
|
let index = 0
|
|
const calls = []
|
|
const delays = []
|
|
const github = {
|
|
rest: { actions: { listJobsForWorkflowRun: 'jobs' } },
|
|
async paginate(endpoint, input) {
|
|
calls.push({ endpoint, input })
|
|
return snapshots[Math.min(index, snapshots.length - 1)]
|
|
}
|
|
}
|
|
return {
|
|
calls,
|
|
delays,
|
|
result: new AsyncFunction('github', 'context', 'Date', 'setTimeout', step.with.script)(
|
|
github,
|
|
{ repo: { owner: 'owner', repo: 'repo' }, runId: 42 },
|
|
{ now: () => now },
|
|
(resolve, delay) => {
|
|
delays.push(delay)
|
|
now += delay
|
|
index++
|
|
resolve()
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
describe('early template assembly qualification gate', () => {
|
|
it.each(['', 'orcad-template / qualify / '])(
|
|
'waits for all current-attempt jobs with prefix %s',
|
|
async (prefix) => {
|
|
const incomplete = lanes(prefix)
|
|
incomplete[1] = { ...incomplete[1], status: 'in_progress', conclusion: null }
|
|
const { calls, delays, result } = execute([incomplete, lanes(prefix)])
|
|
await result
|
|
expect(calls).toHaveLength(2)
|
|
expect(delays).toEqual([15_000])
|
|
for (const { endpoint, input } of calls) {
|
|
expect(endpoint).toBe('jobs')
|
|
expect(input).toMatchObject({
|
|
owner: 'owner',
|
|
repo: 'repo',
|
|
filter: 'latest',
|
|
run_id: 42
|
|
})
|
|
}
|
|
}
|
|
)
|
|
it.each(['failure', 'cancelled', 'skipped', 'timed_out', 'action_required', 'startup_failure'])(
|
|
'rejects %s from any lane',
|
|
async (conclusion) => {
|
|
for (let i = 1; i < lanes().length; i++) {
|
|
const input = lanes()
|
|
input[i].conclusion = conclusion
|
|
await expect(execute([input]).result).rejects.toThrow('qualification did not succeed')
|
|
}
|
|
}
|
|
)
|
|
it('fails closed for missing, extra, ambiguous and unrelated jobs', async () => {
|
|
await expect(execute([lanes().slice(0, -1)]).result).rejects.toThrow('Timed out')
|
|
await expect(
|
|
execute([[...lanes(), { ...lanes()[1], name: `${lanes()[1].name}-extra` }]]).result
|
|
).rejects.toThrow('Unexpected')
|
|
await expect(execute([[...lanes(), ...lanes('other / ')]]).result).rejects.toThrow('Ambiguous')
|
|
await expect(
|
|
execute([
|
|
[{ name: 'desktop_template', status: 'in_progress' }, ...lanes('unrelated / ').slice(1)]
|
|
]).result
|
|
).rejects.toThrow('Timed out')
|
|
})
|
|
})
|