import { test } from 'node:test'; import assert from 'node:assert/strict'; import { dirname, join } from 'node:path'; import { orgPaths } from '../src/config.mjs'; test('organization paths are rooted together and reject overlong sockets', () => { const root = '/var/mosaic/org-runtime/alpha'; assert.deepEqual(orgPaths(root), { socket: join(root, 'bus/broker.sock'), busDir: join(root, 'bus'), runs: join(root, 'runs'), launches: join(root, 'launches'), sessions: join(root, 'sessions'), workspaces: join(root, 'workspaces'), threads: join(root, 'threads'), hostDir: join(root, 'bus-host'), }); assert.throws(() => orgPaths('/' + 'a'.repeat(110)), /socket.*long/i); assert.throws(() => orgPaths('relative'), /absolute/i); }); import { bootConfig, loadSystem } from '../src/config.mjs'; import { fixture, tmp } from './helpers.mjs'; test('broker boot keeps instance and organization roots distinct', (t) => { const f = fixture(tmp(t)); const root = join(f.dataRoot, 'org-runtime', 'acme'); const boot = bootConfig({ system: loadSystem({ env: f.env }), businessId: 'acme', orgRoot: root, env: f.env }); assert.equal(boot.dataRoot, root); assert.equal(boot.instanceRoot, f.dataRoot); assert.deepEqual(boot.org, { id: 'acme' }); assert.equal(boot.instanceDataRoot, f.dataRoot); assert.equal(boot.instanceConfigDir, dirname(f.config)); }); import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'; import { claimHostLock, hostLock, startTimeOf } from '../src/host.mjs'; test('organization host claim refuses a stale lock without removing it', t => { const root = tmp(t); mkdirSync(join(root, 'bus-host'), { mode: 0o700 }); const stale = { pid: 99999999, startTime: '0', business: 'alpha', startedAt: 'old' }; writeFileSync(hostLock(root), JSON.stringify(stale), { mode: 0o600 }); const mine = { pid: process.pid, startTime: startTimeOf(process.pid), business: 'alpha', startedAt: 'now' }; // E2E6 fix 1: the message stays; the next line names the verb that clears the dead host. assert.throws(() => claimHostLock(root, mine, { refuseStale: true }), e => e.message === 'stale bus host lock' && e.exitCode === 3 && e.next === 'if the bus host died, clear it with mosaic bus recover alpha; recover refuses while the host still runs'); assert.deepEqual(JSON.parse(readFileSync(hostLock(root), 'utf8')), stale); // A lock naming no valid organization id still names the verb, with a placeholder. writeFileSync(hostLock(root), JSON.stringify({ ...stale, business: '../x\nsecret' }), { mode: 0o600 }); assert.throws(() => claimHostLock(root, mine, { refuseStale: true }), e => e.next === 'if the bus host died, clear it with mosaic bus recover ; recover refuses while the host still runs'); }); import { busStatus } from '../src/org-bus.mjs'; test('an inaccessible registry refuses as a configuration error', async t => { const root = tmp(t); await assert.rejects(busStatus({ configDir: join(root, 'missing'), dataRoot: root, instance: 'test' }, 'alpha'), error => error.exitCode === 3 && /registry/i.test(error.message)); });