Files
orca/config/scripts/desktop-distribution/linux/package-linux-formats.test.mjs
OrcaWinandOrcaWin 06178ea9af test: remove low-value build and packaging test inventories (#38593)
* test: remove low-value build and packaging test inventories

* ci: retire removed dependency resolution suite invocation

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-05 08:47:58 -08:00

214 lines
7.5 KiB
JavaScript

import {
chmodSync,
existsSync,
mkdirSync,
mkdtempSync,
readFileSync,
readdirSync,
readlinkSync,
rmSync,
statSync,
symlinkSync,
writeFileSync
} from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
import { packageLinuxFormats } from './package-linux-formats.mjs'
let root
let preparedDirectory
let outputDirectory
const targets = ['AppImage', 'deb', 'rpm']
const valueAfter = (args, flag) => args[args.indexOf(flag) + 1]
beforeEach(() => {
root = mkdtempSync(join(tmpdir(), 'orca formats with spaces-'))
preparedDirectory = join(root, 'prepared app')
outputDirectory = join(root, 'output packages')
mkdirSync(join(preparedDirectory, 'resources'), { recursive: true })
mkdirSync(outputDirectory)
writeFileSync(join(preparedDirectory, 'resources/package-type'), 'AppImage')
writeFileSync(join(preparedDirectory, 'resources/app.asar'), 'verified application')
writeFileSync(join(preparedDirectory, 'orca-ide'), 'executable')
chmodSync(join(preparedDirectory, 'orca-ide'), 0o755)
})
afterEach(() => rmSync(root, { recursive: true, force: true }))
function emitPackage(args) {
const format = valueAfter(args, '--linux')
const app = valueAfter(args, '--prepackaged')
const output = valueAfter(args, '--config.directories.output')
writeFileSync(join(app, 'resources/package-type'), format)
mkdirSync(output, { recursive: true })
writeFileSync(join(output, `orca.${format}`), format)
writeFileSync(join(output, 'latest-linux.yml'), format)
return { format, app, output }
}
describe('independent Linux package formats', () => {
it('starts all formats before awaiting completion and isolates metadata writes', async () => {
if (process.platform !== 'win32') {
symlinkSync('resources/package-type', join(preparedDirectory, 'marker-link'))
}
let release
const gate = new Promise((resolve) => {
release = resolve
})
const copies = []
await packageLinuxFormats({
preparedDirectory,
outputDirectory,
prepareAppImageTools: async () => ({}),
runBuilder: async (args) => {
const app = valueAfter(args, '--prepackaged')
const format = valueAfter(args, '--linux')
expect(readFileSync(join(app, 'resources/package-type'), 'utf8')).toBe('AppImage')
expect(readFileSync(join(app, 'resources/app.asar'), 'utf8')).toBe('verified application')
if (process.platform !== 'win32') {
expect(readlinkSync(join(app, 'marker-link'))).toBe('resources/package-type')
expect(statSync(join(app, 'orca-ide')).mode & 0o777).toBe(0o755)
expect(statSync(join(app, 'resources/package-type')).ino).not.toBe(
statSync(join(preparedDirectory, 'resources/package-type')).ino
)
}
copies.push(app)
if (copies.length === 3) {
release()
}
await gate
expect(readdirSync(outputDirectory)).toHaveLength(1)
emitPackage(args)
await Promise.resolve()
expect(readFileSync(join(app, 'resources/package-type'), 'utf8')).toBe(format)
}
})
expect(new Set(copies).size).toBe(3)
expect(readFileSync(join(preparedDirectory, 'resources/package-type'), 'utf8')).toBe('AppImage')
expect(readFileSync(join(preparedDirectory, 'resources/app.asar'), 'utf8')).toBe(
'verified application'
)
for (const format of targets) {
expect(readFileSync(join(outputDirectory, `orca.${format}`), 'utf8')).toBe(format)
expect(
readFileSync(
join(outputDirectory, 'linux-package-formats', format, 'latest-linux.yml'),
'utf8'
)
).toBe(format)
}
expect(
readdirSync(outputDirectory).some((name) => name.startsWith('.linux-package-formats-'))
).toBe(false)
})
it.each(['builder', 'tool preparation'])(
'settles every worker before cleanup and exposes no partial artifact on %s failure',
async (failurePhase) => {
const finished = []
let overlay
let release
const gate = new Promise((resolve) => {
release = resolve
})
await expect(
packageLinuxFormats({
preparedDirectory,
outputDirectory,
prepareAppImageTools: async ({ directory }) => {
overlay = directory
mkdirSync(directory)
writeFileSync(join(directory, 'mksquashfs'), 'private wrapper')
if (failurePhase === 'tool preparation') {
throw new Error('compression failed')
}
return { APPIMAGE_TOOLS_PATH: directory, ORCA_PR_APPIMAGE_MKSQUASHFS: 'original tool' }
},
runBuilder: async (args, environment) => {
const format = valueAfter(args, '--linux')
if (format === 'AppImage') {
expect(environment).toEqual({
APPIMAGE_TOOLS_PATH: overlay,
ORCA_PR_APPIMAGE_MKSQUASHFS: 'original tool'
})
throw new Error('compression failed')
}
expect(environment).toEqual({})
if (format === 'rpm') {
release()
}
await gate
const { app } = emitPackage(args)
expect(existsSync(app)).toBe(true)
expect(existsSync(overlay)).toBe(true)
finished.push(format)
}
})
).rejects.toMatchObject({
message: 'Linux package formats failed',
errors: [
expect.objectContaining({
message: 'AppImage packaging failed',
cause: expect.objectContaining({ message: 'compression failed' })
})
]
})
expect(finished.sort()).toEqual(['deb', 'rpm'])
expect(existsSync(overlay)).toBe(false)
expect(readdirSync(outputDirectory)).toEqual([])
expect(readFileSync(join(preparedDirectory, 'resources/package-type'), 'utf8')).toBe(
'AppImage'
)
}
)
it('rejects missing artifacts even when the builder reports success', async () => {
await expect(
packageLinuxFormats({
preparedDirectory,
outputDirectory,
prepareAppImageTools: async () => ({}),
runBuilder: async (args) => {
const result = emitPackage(args)
if (result.format === 'rpm') {
writeFileSync(join(result.output, 'orca.rpm'), '')
}
}
})
).rejects.toThrow('Linux package formats failed')
expect(readdirSync(outputDirectory)).toEqual([])
})
it('does not replace existing output packages', async () => {
writeFileSync(join(outputDirectory, 'orca.deb'), 'previous package')
await expect(
packageLinuxFormats({
preparedDirectory,
outputDirectory,
prepareAppImageTools: async () => ({}),
runBuilder: async (args) => {
emitPackage(args)
}
})
).rejects.toThrow('Refusing to replace existing package output')
expect(readdirSync(outputDirectory)).toEqual(['orca.deb'])
expect(readFileSync(join(outputDirectory, 'orca.deb'), 'utf8')).toBe('previous package')
})
it('rejects a tree already mutated by a previous root-package build', async () => {
writeFileSync(join(preparedDirectory, 'resources/package-type'), 'rpm')
await expect(
packageLinuxFormats({
preparedDirectory,
outputDirectory,
prepareAppImageTools: async () => ({}),
runBuilder: async () => {
throw new Error('must not run')
}
})
).rejects.toThrow('Expected a fresh Linux directory build')
expect(readdirSync(outputDirectory)).toEqual([])
})
})