Files
orca/config/scripts/ssh-relay-runtime-linux-finalization.test.mjs
T
2026-07-15 09:34:18 -04:00

252 lines
9.2 KiB
JavaScript

import { mkdtemp, mkdir, readFile, realpath, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { parse } from 'yaml'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { createSshRelayArtifactTestManifest } from '../../src/main/ssh/ssh-relay-artifact-test-manifest.ts'
import {
finalizeSshRelayRuntimeLinuxArtifact,
parseSshRelayRuntimeLinuxFinalizationArguments
} from './ssh-relay-runtime-linux-finalization.mjs'
const temporaryDirectories = []
const VERIFIED_AT = '2026-07-15T13:30:00.000Z'
const artifactWorkflowUrl = new URL(
'../../.github/workflows/ssh-relay-runtime-artifacts.yml',
import.meta.url
)
function linuxIdentity() {
const tuple = createSshRelayArtifactTestManifest().tuples[0]
const {
archive,
metadataAssets: _metadataAssets,
nativeVerification: _native,
...identity
} = tuple
return { identity: { ...identity, archive }, finalIdentity: identity }
}
function linuxPlan(identity) {
return {
platform: 'linux',
verificationFiles: identity.entries
.filter(
(entry) =>
entry.type === 'file' &&
['node', 'node-pty-native', 'parcel-watcher-native', 'native-runtime'].includes(
entry.role
)
)
.map((entry) => ({ path: entry.path, role: entry.role, sourceSha256: entry.sha256 }))
}
}
async function fixture() {
const root = await mkdtemp(join(tmpdir(), 'orca-runtime-linux-finalization-'))
temporaryDirectories.push(root)
const source = join(root, 'source')
const runtime = join(source, 'runtime')
const output = join(root, 'final')
await mkdir(runtime, { recursive: true })
const { identity, finalIdentity } = linuxIdentity()
const identityPath = join(source, `orca-ssh-relay-runtime-${identity.tupleId}.identity.json`)
const archivePath = join(source, identity.archive.name)
const sbomPath = join(source, `orca-ssh-relay-runtime-${identity.tupleId}.spdx.json`)
const provenancePath = join(source, `orca-ssh-relay-runtime-${identity.tupleId}.provenance.json`)
await Promise.all([
writeFile(identityPath, `${JSON.stringify(identity)}\n`),
writeFile(archivePath, 'archive'),
writeFile(sbomPath, 'sbom'),
writeFile(provenancePath, 'provenance')
])
return { source, runtime, output, identity, finalIdentity, identityPath }
}
afterEach(async () => {
await Promise.all(
temporaryDirectories
.splice(0)
.map((directory) => rm(directory, { recursive: true, force: true }))
)
})
describe('SSH relay runtime Linux hash-only finalization', () => {
it('verifies before emitting an exact aggregate-ready descriptor and receipt', async () => {
const input = await fixture()
const order = []
const plan = linuxPlan(input.finalIdentity)
const physicalIdentityPath = await realpath(input.identityPath)
const physicalRuntime = await realpath(input.runtime)
const physicalSource = await realpath(input.source)
const verifyRuntimeImpl = vi.fn(async ({ runtimeDirectory, identityPath, archivePath }) => {
order.push('verify')
expect(runtimeDirectory).toBe(physicalRuntime)
expect(identityPath).toBe(physicalIdentityPath)
expect(archivePath).toBe(join(physicalSource, input.identity.archive.name))
return { smoke: { nodeVersion: 'v24.18.0' } }
})
const writeDescriptorImpl = vi.fn(async (options) => {
order.push('descriptor')
expect(options.finalIdentity).toEqual(input.finalIdentity)
expect(options.verificationReport).toEqual({
tupleId: input.identity.tupleId,
sourceContentId: input.identity.contentId,
finalContentId: input.identity.contentId,
verifiedFiles: plan.verificationFiles.map((file) => ({
path: file.path,
role: file.role,
sha256: file.sourceSha256
}))
})
expect(options.nativeVerificationTool).toEqual({ name: 'node', version: '24.18.0' })
expect(options.verifiedAt).toBe(VERIFIED_AT)
return {
tupleId: input.identity.tupleId,
input: {
tupleId: input.identity.tupleId,
descriptor: { name: 'descriptor.json', size: 1, sha256: `sha256:${'a'.repeat(64)}` },
archive: {
name: input.identity.archive.name,
size: 7,
sha256: `sha256:${'b'.repeat(64)}`
},
sbom: { name: 'sbom.json', size: 4, sha256: `sha256:${'c'.repeat(64)}` },
provenance: { name: 'provenance.json', size: 10, sha256: `sha256:${'d'.repeat(64)}` }
}
}
})
const result = await finalizeSshRelayRuntimeLinuxArtifact({
sourceOutputDirectory: input.source,
identityPath: input.identityPath,
outputDirectory: input.output,
verifiedAt: VERIFIED_AT,
nativeVerificationTool: { name: 'node', version: '24.18.0' },
readIdentityImpl: async () => input.identity,
buildPlanImpl: () => plan,
verifyRuntimeImpl,
writeDescriptorImpl
})
expect(order).toEqual(['verify', 'descriptor'])
expect(result).toMatchObject({
tupleId: input.identity.tupleId,
contentId: input.identity.contentId,
aggregateInput: { tupleId: input.identity.tupleId }
})
expect(JSON.parse(await readFile(result.receiptPath, 'utf8'))).toEqual({
tupleId: input.identity.tupleId,
contentId: input.identity.contentId,
verification: { smoke: { nodeVersion: 'v24.18.0' } },
aggregateInput: result.aggregateInput
})
await expect(
readFile(join(result.assetsRoot, input.identity.archive.name), 'utf8')
).resolves.toBe('archive')
})
it('rejects non-Linux input and removes partial output on failure', async () => {
const input = await fixture()
const nonLinux = { ...input.identity, os: 'darwin', tupleId: 'darwin-x64' }
await expect(
finalizeSshRelayRuntimeLinuxArtifact({
sourceOutputDirectory: input.source,
identityPath: input.identityPath,
outputDirectory: input.output,
verifiedAt: VERIFIED_AT,
nativeVerificationTool: { name: 'node', version: '24.18.0' },
readIdentityImpl: async () => nonLinux,
verifyRuntimeImpl: vi.fn(),
writeDescriptorImpl: vi.fn()
})
).rejects.toThrow(/linux/i)
await expect(
finalizeSshRelayRuntimeLinuxArtifact({
sourceOutputDirectory: input.source,
identityPath: input.identityPath,
outputDirectory: input.output,
verifiedAt: VERIFIED_AT,
nativeVerificationTool: { name: 'node', version: '24.18.0' },
readIdentityImpl: async () => input.identity,
buildPlanImpl: () => linuxPlan(input.finalIdentity),
verifyRuntimeImpl: async () => ({ smoke: true }),
writeDescriptorImpl: async () => {
throw new Error('descriptor failed')
}
})
).rejects.toThrow(/descriptor failed/i)
await expect(
readFile(join(input.output, 'assets', input.identity.archive.name))
).rejects.toMatchObject({ code: 'ENOENT' })
})
it('parses only the exact bounded CLI arguments', () => {
expect(
parseSshRelayRuntimeLinuxFinalizationArguments([
'--source-output-directory',
'source',
'--identity',
'identity.json',
'--output-directory',
'output',
'--verified-at',
VERIFIED_AT,
'--native-verification-tool-version',
'24.18.0'
])
).toMatchObject({
verifiedAt: VERIFIED_AT,
nativeVerificationToolVersion: '24.18.0'
})
expect(() =>
parseSshRelayRuntimeLinuxFinalizationArguments(['--output-directory', 'output'])
).toThrow(/missing/i)
expect(() =>
parseSshRelayRuntimeLinuxFinalizationArguments([
'--source-output-directory',
'source',
'--identity',
'identity.json',
'--output-directory',
'output',
'--verified-at',
VERIFIED_AT,
'--native-verification-tool-version',
'24.18.0',
'--extra',
'value'
])
).toThrow(/invalid/i)
})
it('emits Linux descriptors before upload and runs the contract on both native families', async () => {
const source = await readFile(artifactWorkflowUrl, 'utf8')
const workflow = parse(source)
const posix = workflow.jobs['build-posix-runtime']
const windows = workflow.jobs['build-windows-runtime']
const build = posix.steps.find(
(step) => step.name === 'Build twice, inspect, smoke, and compare exact runtime'
).run
const finalization = build.indexOf('ssh-relay-runtime-linux-finalization.mjs')
const descriptorCopy = build.indexOf('.manifest-tuple.json', finalization)
const linuxExit = build.indexOf('exit 0', descriptorCopy)
expect(finalization).toBeGreaterThan(-1)
expect(descriptorCopy).toBeGreaterThan(finalization)
expect(linuxExit).toBeGreaterThan(descriptorCopy)
for (const job of [posix, windows]) {
const contract = job.steps.find(
(step) => step.name === 'Run runtime artifact contract tests'
).run
expect(contract).toContain(
'node --check config/scripts/ssh-relay-runtime-linux-finalization.mjs'
)
expect(contract).toContain('config/scripts/ssh-relay-runtime-linux-finalization.test.mjs')
}
expect(posix.steps.at(-1).with.path).toBe('runtime-evidence/${{ matrix.tuple }}/')
})
})