mirror of
https://github.com/stablyai/orca.git
synced 2026-10-18 00:03:20 +00:00
180 lines
6.9 KiB
JavaScript
180 lines
6.9 KiB
JavaScript
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import { dirname, join } from 'node:path'
|
|
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
assertSshRelayRuntimeClosureEntries,
|
|
expectedSshRelayRuntimeClosureEntries,
|
|
verifySshRelayRuntimeClosure
|
|
} from './ssh-relay-runtime-closure.mjs'
|
|
|
|
const temporaryDirectories = []
|
|
|
|
afterEach(async () => {
|
|
await Promise.all(temporaryDirectories.splice(0).map((path) => rm(path, { recursive: true })))
|
|
})
|
|
|
|
const watcherPackages = Object.freeze({
|
|
'linux-x64-glibc': '@parcel/watcher-linux-x64-glibc',
|
|
'linux-arm64-glibc': '@parcel/watcher-linux-arm64-glibc',
|
|
'darwin-x64': '@parcel/watcher-darwin-x64',
|
|
'darwin-arm64': '@parcel/watcher-darwin-arm64',
|
|
'win32-x64': '@parcel/watcher-win32-x64',
|
|
'win32-arm64': '@parcel/watcher-win32-arm64'
|
|
})
|
|
|
|
function identity(tuple) {
|
|
return {
|
|
tupleId: tuple,
|
|
nodeVersion: '24.18.0',
|
|
dependencies: { nodePtyVersion: '1.1.0', parcelWatcherVersion: '2.5.6' },
|
|
entries: expectedSshRelayRuntimeClosureEntries(tuple)
|
|
}
|
|
}
|
|
|
|
function packageRecords(tuple) {
|
|
return [
|
|
{ name: 'node-pty', version: '1.1.0', main: './lib/index.js', license: 'MIT' },
|
|
{ name: '@parcel/watcher', version: '2.5.6', main: 'index.js', license: 'MIT' },
|
|
{ name: watcherPackages[tuple], version: '2.5.6', main: 'watcher.node', license: 'MIT' },
|
|
{ name: 'detect-libc', version: '2.1.2', main: 'lib/detect-libc.js', license: 'Apache-2.0' },
|
|
{ name: 'is-glob', version: '4.0.3', main: 'index.js', license: 'MIT' },
|
|
{ name: 'is-extglob', version: '2.1.1', main: 'index.js', license: 'MIT' },
|
|
{ name: 'picomatch', version: '4.0.4', main: 'index.js', license: 'MIT' }
|
|
]
|
|
}
|
|
|
|
async function writeClosureMetadata(tuple = 'linux-x64-glibc') {
|
|
const runtimeRoot = await mkdtemp(join(tmpdir(), 'orca-runtime-closure-'))
|
|
temporaryDirectories.push(runtimeRoot)
|
|
const packages = packageRecords(tuple)
|
|
for (const record of packages) {
|
|
const path = join(runtimeRoot, 'node_modules', ...record.name.split('/'), 'package.json')
|
|
await mkdir(dirname(path), { recursive: true })
|
|
await writeFile(path, `${JSON.stringify(record, null, 2)}\n`)
|
|
}
|
|
await writeFile(join(runtimeRoot, '.version'), '1.4.140+123456789abc\n')
|
|
await writeFile(
|
|
join(runtimeRoot, 'runtime-metadata.json'),
|
|
`${JSON.stringify(
|
|
{
|
|
schemaVersion: 1,
|
|
tuple,
|
|
nodeVersion: '24.18.0',
|
|
relayBuildVersion: '1.4.140+123456789abc',
|
|
dependencies: { nodePtyVersion: '1.1.0', parcelWatcherVersion: '2.5.6' }
|
|
},
|
|
null,
|
|
2
|
|
)}\n`
|
|
)
|
|
const licenseNames = ['Node.js', ...packages.map((entry) => entry.name)]
|
|
await writeFile(
|
|
join(runtimeRoot, 'THIRD_PARTY_LICENSES.txt'),
|
|
`${licenseNames.map((name) => `===== ${name} =====\n${name} license text\n`).join('\n')}\n`
|
|
)
|
|
return { runtimeRoot, packages }
|
|
}
|
|
|
|
describe('SSH relay runtime exact closure', () => {
|
|
it.each([
|
|
['linux-x64-glibc', 34],
|
|
['linux-arm64-glibc', 34],
|
|
['darwin-x64', 35],
|
|
['darwin-arm64', 35],
|
|
['win32-x64', 42],
|
|
['win32-arm64', 42]
|
|
])('pins the reviewed %s runtime to %i files and one native watcher', (tuple, fileCount) => {
|
|
const entries = expectedSshRelayRuntimeClosureEntries(tuple)
|
|
const files = entries.filter((entry) => entry.type === 'file')
|
|
expect(files).toHaveLength(fileCount)
|
|
expect(files.filter((entry) => entry.role === 'parcel-watcher-native')).toEqual([
|
|
expect.objectContaining({ path: `node_modules/${watcherPackages[tuple]}/watcher.node` })
|
|
])
|
|
expect(files.map((entry) => entry.path)).not.toEqual(
|
|
expect.arrayContaining([
|
|
expect.stringMatching(/(?:^|\/)(?:npm|npx|corepack|pnpm|yarn)(?:\.|\/|$)/i),
|
|
expect.stringMatching(/\.(?:map|pdb|ilk|cc|cpp|c|h|hpp|o|obj)$/i)
|
|
])
|
|
)
|
|
expect(() => assertSshRelayRuntimeClosureEntries(identity(tuple))).not.toThrow()
|
|
})
|
|
|
|
it('rejects undeclared package managers, source maps, and native build outputs', () => {
|
|
const fixture = identity('linux-x64-glibc')
|
|
for (const path of [
|
|
'node_modules/npm/bin/npm-cli.js',
|
|
'relay.js.map',
|
|
'node_modules/node-pty/build/Release/pty.pdb'
|
|
]) {
|
|
expect(() =>
|
|
assertSshRelayRuntimeClosureEntries({
|
|
...fixture,
|
|
entries: [
|
|
...fixture.entries,
|
|
{ path, type: 'file', role: 'runtime-javascript', mode: 0o644 }
|
|
]
|
|
})
|
|
).toThrow(/undeclared file/i)
|
|
}
|
|
})
|
|
|
|
it('rejects a missing native dependency, wrong role, or unreviewed dependency refresh', () => {
|
|
const fixture = identity('darwin-arm64')
|
|
expect(() =>
|
|
assertSshRelayRuntimeClosureEntries({
|
|
...fixture,
|
|
entries: fixture.entries.filter((entry) => !entry.path.endsWith('/watcher.node'))
|
|
})
|
|
).toThrow(/missing required file/i)
|
|
expect(() =>
|
|
assertSshRelayRuntimeClosureEntries({
|
|
...fixture,
|
|
entries: fixture.entries.map((entry) =>
|
|
entry.path === 'bin/node' ? { ...entry, role: 'runtime-javascript' } : entry
|
|
)
|
|
})
|
|
).toThrow(/unexpected role/i)
|
|
expect(() =>
|
|
assertSshRelayRuntimeClosureEntries({ ...fixture, nodeVersion: '24.19.0' })
|
|
).toThrow(/dependency versions/i)
|
|
})
|
|
|
|
it('verifies exact package metadata, runtime metadata, and non-empty license sections', async () => {
|
|
const fixture = await writeClosureMetadata()
|
|
await expect(
|
|
verifySshRelayRuntimeClosure(fixture.runtimeRoot, identity('linux-x64-glibc'))
|
|
).resolves.toEqual({ files: 34, packages: 7 })
|
|
|
|
const packagePath = join(fixture.runtimeRoot, 'node_modules', 'node-pty', 'package.json')
|
|
const packageJson = JSON.parse(await readFile(packagePath, 'utf8'))
|
|
await writeFile(packagePath, `${JSON.stringify({ ...packageJson, version: '1.1.1' })}\n`)
|
|
await expect(
|
|
verifySshRelayRuntimeClosure(fixture.runtimeRoot, identity('linux-x64-glibc'))
|
|
).rejects.toThrow(/node-pty/i)
|
|
})
|
|
|
|
it('rejects omitted and empty dependency license sections', async () => {
|
|
const fixture = await writeClosureMetadata()
|
|
const licensePath = join(fixture.runtimeRoot, 'THIRD_PARTY_LICENSES.txt')
|
|
const licenseText = await readFile(licensePath, 'utf8')
|
|
await writeFile(licensePath, licenseText.replace(/===== picomatch =====[\s\S]*$/, ''))
|
|
await expect(
|
|
verifySshRelayRuntimeClosure(fixture.runtimeRoot, identity('linux-x64-glibc'))
|
|
).rejects.toThrow(/license bundle/i)
|
|
|
|
const second = await writeClosureMetadata()
|
|
const secondLicensePath = join(second.runtimeRoot, 'THIRD_PARTY_LICENSES.txt')
|
|
const secondText = await readFile(secondLicensePath, 'utf8')
|
|
await writeFile(
|
|
secondLicensePath,
|
|
secondText.replace('===== picomatch =====\npicomatch license text', '===== picomatch =====')
|
|
)
|
|
await expect(
|
|
verifySshRelayRuntimeClosure(second.runtimeRoot, identity('linux-x64-glibc'))
|
|
).rejects.toThrow(/empty section/i)
|
|
})
|
|
})
|