fix: make cutover restart argv upgrade-safe and tests platform-honest
- cutover-orchestrator: restart via 'node --import tsx' (matching install.sh) instead of a hardcoded .pnpm/tsx@4.22.4 loader path that breaks on tsx bumps - production-gateway: use process.execPath for the legacy-start fixture; POSIX-only 0600 mode assertion now win32-guarded - cli-runtime + installer suites: skip where they require POSIX-only process-group SIGTERM, lsof, or /bin/sh - fixture-safety: fall back to config.example.json when config.json is absent on a fresh clone
This commit is contained in:
@@ -131,7 +131,9 @@ afterEach(async () => {
|
||||
await Promise.all(cleanup.splice(0).map((fn) => fn()));
|
||||
});
|
||||
|
||||
describe.sequential('executable package runtimes', () => {
|
||||
// The runtime lifecycle under test is macOS/POSIX-only: process-group SIGTERM,
|
||||
// lsof port inspection, and corepack as a direct spawn target.
|
||||
describe.sequential('executable package runtimes', { skip: process.platform === 'win32' }, () => {
|
||||
it('makes the exact production gateway executable attempt 8788 only with acknowledgement', async () => {
|
||||
await expectPortFree(8788);
|
||||
const fixture = await listenOn(8788);
|
||||
|
||||
@@ -23,7 +23,7 @@ const STATE_FILE = 'cutover-state.json';
|
||||
const GATEWAY_ARGV = [
|
||||
process.execPath,
|
||||
'--import',
|
||||
resolve(process.cwd(), 'node_modules/.pnpm/tsx@4.22.4/node_modules/tsx/dist/loader.mjs'),
|
||||
'tsx',
|
||||
resolve(process.cwd(), 'apps/api/src/production-gateway-cli.ts'),
|
||||
] as const;
|
||||
const DIGEST = /^[a-f0-9]{64}$/u;
|
||||
|
||||
@@ -45,9 +45,9 @@ async function fixture(name = 'cutover'): Promise<CutoverPlan> {
|
||||
drillEvidence: drill,
|
||||
drillEvidenceSha256: createHash('sha256').update(drillContent).digest('hex'),
|
||||
legacyPid: 41,
|
||||
legacyCommand: '/usr/local/bin/node /absolute/legacy/server.js',
|
||||
legacyCommand: `${process.execPath} /absolute/legacy/server.js`,
|
||||
legacyIdentity: 'legacy-start-1',
|
||||
legacyStart: ['/usr/local/bin/node', '/absolute/legacy/server.js'],
|
||||
legacyStart: [process.execPath, '/absolute/legacy/server.js'],
|
||||
stateDir: join(root, 'state'),
|
||||
};
|
||||
}
|
||||
@@ -130,11 +130,12 @@ describe('cutover validation and reversible orchestration', () => {
|
||||
expect(signals).toEqual([41]);
|
||||
expect(starts[0]?.environment?.MULTI_SIMADMIN_GATEWAY_TOKEN).toBe(token);
|
||||
const statePath = join(plan.stateDir, 'cutover-state.json');
|
||||
expect((await lstat(statePath)).mode & 0o777).toBe(0o600);
|
||||
if (process.platform !== 'win32')
|
||||
expect((await lstat(statePath)).mode & 0o777).toBe(0o600);
|
||||
expect(await readFile(statePath, 'utf8')).not.toContain(token);
|
||||
expect(await rollback(plan, system)).toBe(43);
|
||||
expect(signals).toEqual([41, 42]);
|
||||
expect(starts[1]?.argv).toEqual(['/usr/local/bin/node', '/absolute/legacy/server.js']);
|
||||
expect(starts[1]?.argv).toEqual([process.execPath, '/absolute/legacy/server.js']);
|
||||
});
|
||||
|
||||
it('automatically restarts legacy if the gateway fails to own authenticated 8788', async () => {
|
||||
@@ -146,10 +147,10 @@ describe('cutover validation and reversible orchestration', () => {
|
||||
[
|
||||
process.execPath,
|
||||
'--import',
|
||||
resolve(process.cwd(), 'node_modules/.pnpm/tsx@4.22.4/node_modules/tsx/dist/loader.mjs'),
|
||||
'tsx',
|
||||
resolve(process.cwd(), 'apps/api/src/production-gateway-cli.ts'),
|
||||
],
|
||||
['/usr/local/bin/node', '/absolute/legacy/server.js'],
|
||||
[process.execPath, '/absolute/legacy/server.js'],
|
||||
]);
|
||||
const state = JSON.parse(await readFile(join(plan.stateDir, 'cutover-state.json'), 'utf8')) as {
|
||||
phase: string;
|
||||
|
||||
Reference in New Issue
Block a user