pediatric-ai-scribe-v3/test/build-id.test.js

92 lines
4.8 KiB
JavaScript

'use strict';
const { test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');
const { execFileSync } = require('node:child_process');
const { getBuildId, isGitRevision } = require('../src/utils/buildId');
test('build ID resolves real Git checkouts, packed refs, worktrees, baked images and unknown sources', t => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'ped-build-id-'));
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
const repo = path.join(root, 'repo');
fs.mkdirSync(repo);
const git = (...args) => execFileSync('git', ['-C', repo, ...args], {
encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'],
}).trim();
git('init');
git('-c', 'user.name=Build Test', '-c', 'user.email=build@example.invalid',
'-c', 'commit.gpgsign=false', 'commit', '--allow-empty', '-m', 'test');
const sha = git('rev-parse', 'HEAD');
assert.equal(sha.length, 40);
assert.equal(getBuildId(repo), sha);
git('pack-refs', '--all', '--prune');
assert.equal(fs.existsSync(path.join(repo, '.git', git('symbolic-ref', 'HEAD'))), false);
assert.equal(getBuildId(repo), sha);
const worktree = path.join(root, 'worktree');
git('worktree', 'add', '--detach', worktree, 'HEAD');
assert.equal(fs.statSync(path.join(worktree, '.git')).isFile(), true);
assert.equal(getBuildId(worktree), sha);
git('checkout', '--detach', 'HEAD');
assert.equal(getBuildId(repo), sha);
// No accidental ancestor Git discovery for an unversioned source directory.
const plain = path.join(repo, 'plain');
fs.mkdirSync(plain);
assert.equal(getBuildId(plain), 'unknown');
const baked = 'b'.repeat(40);
fs.writeFileSync(path.join(plain, 'BUILD_ID'), baked + '\n');
assert.equal(getBuildId(plain), baked);
fs.writeFileSync(path.join(worktree, 'BUILD_ID'), baked);
assert.equal(getBuildId(worktree), baked, 'baked metadata takes precedence');
for (const invalid of ['unknown', '', 'abc1234', 'z'.repeat(40), '<script>', sha + '\r\nInjected: yes']) {
fs.writeFileSync(path.join(worktree, 'BUILD_ID'), invalid);
assert.equal(getBuildId(worktree), 'unknown');
assert.equal(isGitRevision(invalid), false);
}
assert.equal(isGitRevision(sha + '\n'), false);
assert.equal(isGitRevision(sha.toUpperCase()), false);
fs.writeFileSync(path.join(plain, '.git'), 'gitdir: /nonexistent/ped-build-test\n');
fs.unlinkSync(path.join(plain, 'BUILD_ID'));
assert.equal(getBuildId(plain), 'unknown');
});
test('manual build script passes the full revision to Compose without starting services', t => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'ped-build-script-'));
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
fs.mkdirSync(path.join(root, 'scripts'));
fs.copyFileSync(path.join(__dirname, '../scripts/build-image.sh'), path.join(root, 'scripts/build-image.sh'));
const bin = path.join(root, 'bin');
fs.mkdirSync(bin);
fs.writeFileSync(path.join(bin, 'docker'), '#!/bin/sh\nprintf "%s\\n" "$GIT_REVISION" "$@"\n', { mode: 0o755 });
const build = (env = {}) => execFileSync('/bin/sh', [path.join(root, 'scripts/build-image.sh'), '--no-cache'], {
encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'],
env: { ...process.env, PATH: bin + path.delimiter + process.env.PATH, GIT_REVISION: 'bad-override', ...env },
}).trim().split('\n');
assert.deepEqual(build(), ['unknown', 'compose', 'build', '--no-cache', 'pediatric-scribe']);
const git = (...args) => execFileSync('git', ['-C', root, ...args], {
encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'],
}).trim();
git('init');
git('-c', 'user.name=Build Test', '-c', 'user.email=build@example.invalid',
'-c', 'commit.gpgsign=false', 'commit', '--allow-empty', '-m', 'test');
const sha = git('rev-parse', 'HEAD');
assert.deepEqual(build(), [sha, 'compose', 'build', '--no-cache', 'pediatric-scribe']);
const foreign = path.join(root, 'foreign');
git('init', foreign);
git('-C', foreign, '-c', 'user.name=Build Test', '-c', 'user.email=build@example.invalid',
'-c', 'commit.gpgsign=false', 'commit', '--allow-empty', '-m', 'foreign');
assert.notEqual(git('-C', foreign, 'rev-parse', 'HEAD'), sha);
const controls = { GIT_DIR: path.join(foreign, '.git'), GIT_WORK_TREE: foreign,
GIT_CONFIG_COUNT: '1', GIT_CONFIG_KEY_0: 'core.bare', GIT_CONFIG_VALUE_0: 'true' };
assert.deepEqual(build(controls), [sha, 'compose', 'build', '--no-cache', 'pediatric-scribe']);
// A Docker-only source archive still works without Git installed.
fs.rmSync(path.join(root, '.git'), { recursive: true });
fs.symlinkSync('/usr/bin/dirname', path.join(bin, 'dirname'));
assert.deepEqual(build({ ...controls, PATH: bin }), ['unknown', 'compose', 'build', '--no-cache', 'pediatric-scribe']);
});