clawdie-ai/setup/service.test.ts
Operator & Codex 6de0ed87ab Remove legacy Mevy references (Sam & Codex)
Sweep active code, tests, identity files, public docs, CMS seed content, and stale handoffs so old assistant-name fixtures no longer leak into current Clawdie/system-namespace behavior. Keep the skills-memory SQL artifact unchanged per regeneration policy.

---

Build: pass

Tests: pass — 2197 passed (164 files)

---
Build: pass | Tests: pass — 2197 passed (650 files)
2026-05-07 11:16:40 +02:00

138 lines
4.3 KiB
TypeScript

import { afterEach, describe, it, expect, vi } from 'vitest';
import fs from 'fs';
import path from 'path';
import { execFileSync } from 'child_process';
const ENV_KEYS = [
'PLATFORM_ID',
'PLATFORM_SERVICE_NAME',
'PLATFORM_RUNTIME_USER',
'PLATFORM_RUNTIME_HOME',
'TENANT_ID',
] as const;
afterEach(() => {
for (const key of ENV_KEYS) delete process.env[key];
vi.resetModules();
});
function generateStartWrapper(
nodePath: string,
projectRoot: string,
pidFile: string,
): string {
return [
'#!/bin/sh',
'set -eu',
`cd ${JSON.stringify(projectRoot)}`,
`if [ -f ${JSON.stringify(pidFile)} ]; then`,
` OLD_PID=$(cat ${JSON.stringify(pidFile)} 2>/dev/null || true)`,
' if [ -n "${OLD_PID:-}" ] && kill -0 "$OLD_PID" 2>/dev/null; then',
' echo "Clawdie is already running" >&2',
' exit 1',
' fi',
'fi',
`nohup ${JSON.stringify(nodePath)} ${JSON.stringify(projectRoot + '/dist/index.js')} >> ${JSON.stringify(projectRoot + '/logs/clawdie.log')} 2>> ${JSON.stringify(projectRoot + '/logs/clawdie.error.log')} &`,
`echo $! > ${JSON.stringify(pidFile)}`,
'echo "Started Clawdie"',
'',
].join('\n');
}
function generateStopWrapper(pidFile: string): string {
return [
'#!/bin/sh',
'set -eu',
`if [ ! -f ${JSON.stringify(pidFile)} ]; then`,
' echo "No PID file found" >&2',
' exit 1',
'fi',
`PID=$(cat ${JSON.stringify(pidFile)})`,
'kill "$PID"',
`rm -f ${JSON.stringify(pidFile)}`,
'echo "Stopped Clawdie"',
'',
].join('\n');
}
describe('FreeBSD wrapper generation', () => {
it('start wrapper points to dist/index.js', () => {
const script = generateStartWrapper(
'/usr/local/bin/node',
'/home/clawdie/clawdie-ai',
'/home/clawdie/clawdie-ai/clawdie.pid',
);
expect(script).toContain('/home/clawdie/clawdie-ai/dist/index.js');
});
it('start wrapper writes pid file', () => {
const script = generateStartWrapper(
'/usr/local/bin/node',
'/home/clawdie/clawdie-ai',
'/home/clawdie/clawdie-ai/clawdie.pid',
);
expect(script).toContain(
'echo $! > "/home/clawdie/clawdie-ai/clawdie.pid"',
);
});
it('stop wrapper removes pid file', () => {
const script = generateStopWrapper('/home/clawdie/clawdie-ai/clawdie.pid');
expect(script).toContain('rm -f "/home/clawdie/clawdie-ai/clawdie.pid"');
});
it('resolves platform runtime from constants separately from the tenant', async () => {
process.env.PLATFORM_ID = 'ignored-platform';
process.env.PLATFORM_SERVICE_NAME = 'ignored-service';
process.env.PLATFORM_RUNTIME_USER = 'ignored-user';
process.env.PLATFORM_RUNTIME_HOME = '/srv/ignored';
process.env.TENANT_ID = 'alpha';
const { resolvePlatformServiceRuntime } =
await import('../setup/service.js');
expect(resolvePlatformServiceRuntime()).toEqual({
serviceName: 'clawdie',
runtimeUser: 'clawdie',
runtimeHome: '/home/clawdie',
});
});
it('generates a shell-valid run wrapper and uses PI_TUI_PROFILE', async () => {
const { generateRunScript, generateRcdService } =
await import('../setup/service.js');
const script = generateRunScript(
{
serviceName: 'alpha',
runtimeUser: 'alpha',
runtimeHome: '/home/alpha',
},
'/usr/local/bin/node',
'/home/alpha/alpha-ai',
);
expect(script).toContain('PI_TUI_PROFILE');
expect(script).not.toContain('PI_PROFILE=');
const tmpRoot = path.join(process.cwd(), 'tmp');
fs.mkdirSync(tmpRoot, { recursive: true });
const tempDir = fs.mkdtempSync(path.join(tmpRoot, 'alpha-service-test-'));
const scriptPath = path.join(tempDir, 'run-alpha.sh');
fs.writeFileSync(scriptPath, script, { mode: 0o755 });
expect(() => execFileSync('sh', ['-n', scriptPath])).not.toThrow();
fs.rmSync(tempDir, { recursive: true, force: true });
const rcd = generateRcdService(
{
serviceName: 'alpha',
runtimeUser: 'alpha',
runtimeHome: '/home/alpha',
},
'/home/alpha/alpha-ai',
'/home/alpha/alpha-ai/logs/alpha.log',
);
expect(rcd).toContain(
'command_args="-u alpha -P ${pidfile} -r -f -o \\"/home/alpha/alpha-ai/logs/alpha.log\\" \\"/home/alpha/alpha-ai/run-alpha.sh\\""',
);
});
});