import test from 'node:test'; import assert from 'node:assert/strict'; import { chmodSync, copyFileSync, mkdirSync, mkdtempSync, realpathSync, readFileSync, rmSync, symlinkSync, writeFileSync, } from 'node:fs'; import { tmpdir } from 'node:os'; import path from 'node:path'; import { spawnSync } from 'node:child_process'; import { fileURLToPath } from 'node:url'; const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const read = (relativePath) => readFileSync(path.join(root, relativePath), 'utf8'); test('Deep Search production runtime is isolated from Portal releases', () => { const builder = read('scripts/build-deep-search-runtime.mjs'); assert.match(builder, /deep-search-server\.mjs/); assert.match(builder, /\.runtime', 'deep-search/); const runner = read('scripts/run-deep-search-prod.sh'); assert.match(runner, /cd -P/); assert.match(runner, /shared\/\.env/); assert.match(runner, /data\/research\.sqlite/); assert.match(runner, /127\.0\.0\.1:20080\/search/); const installer = read('scripts/install-deep-search-runtime-prod.sh'); assert.match(installer, /cn\.tkmind\.memind-deep-search/); assert.match(installer, /\/bin\/bash<\/string>/); assert.match(installer, /WorkingDirectory<\/key>\$\{RUNTIME_BASE\}<\/string>/); assert.match(installer, /chmod 600/); assert.match(installer, /openssl rand -hex 32/); const release = read('scripts/release-deep-search-runtime-prod.sh'); assert.match(release, /branch.*main/); assert.match(release, /CONFIRMED_CI_SHA/); assert.match(release, /shasum -a 256/); assert.match(release, /rollback/); assert.match(release, /launchctl bootout.*label/); assert.doesNotMatch(release, /release-portal-runtime-prod/); }); test('Deep Search runner resolves the physical release behind current symlink', (t) => { const runtimeBase = mkdtempSync(path.join(tmpdir(), 'deep-search-runner-')); t.after(() => rmSync(runtimeBase, { recursive: true, force: true })); const releaseDir = path.join(runtimeBase, 'releases', 'r1'); mkdirSync(path.join(releaseDir, 'scripts'), { recursive: true }); mkdirSync(path.join(runtimeBase, 'shared'), { recursive: true }); copyFileSync( path.join(root, 'scripts', 'run-deep-search-prod.sh'), path.join(releaseDir, 'scripts', 'run-deep-search-prod.sh'), ); writeFileSync(path.join(releaseDir, 'deep-search-server.mjs'), ''); writeFileSync( path.join(runtimeBase, 'shared', '.env'), 'TKMIND_DEEP_SEARCH_SECRET=test-secret\n', ); const fakeNode = path.join(runtimeBase, 'fake-node.sh'); writeFileSync(fakeNode, '#!/bin/sh\nprintf "%s\\n" "$1"\n'); chmodSync(fakeNode, 0o755); symlinkSync(releaseDir, path.join(runtimeBase, 'current')); const result = spawnSync( '/bin/bash', [path.join(runtimeBase, 'current', 'scripts', 'run-deep-search-prod.sh')], { encoding: 'utf8', env: { ...process.env, DEEP_SEARCH_RUNTIME_BASE: runtimeBase, NODE_BIN: fakeNode, }, }, ); assert.equal(result.status, 0, result.stderr); assert.equal( result.stdout.trim(), path.join(realpathSync(releaseDir), 'deep-search-server.mjs'), ); });