Files
memind/scripts/deep-search-runtime-package.test.mjs
T
john 3fd1db8c2f
Memind CI / Test, build, and release guards (pull_request) Successful in 3m48s
Memind CI / Test, build, and release guards (push) Successful in 4m2s
fix: resolve deep search runtime symlink
2026-07-24 10:39:45 +08:00

87 lines
3.1 KiB
JavaScript

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, /<string>\/bin\/bash<\/string>/);
assert.match(installer, /<key>WorkingDirectory<\/key><string>\$\{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'),
);
});