91 lines
2.7 KiB
JavaScript
91 lines
2.7 KiB
JavaScript
#!/usr/bin/env node
|
|
import { spawn } from 'node:child_process';
|
|
import path from 'node:path';
|
|
|
|
import {
|
|
createLocalGateStack,
|
|
selectBackendLlmProvider,
|
|
seedSelectedProviderKeys,
|
|
} from '../release-gate/local-stack.mjs';
|
|
|
|
const root = path.resolve(new URL('..', import.meta.url).pathname);
|
|
const scenarioIds = [
|
|
'john2-suzhou-page',
|
|
'long-content-rich-page',
|
|
];
|
|
|
|
async function runScenario(scenarioId, port) {
|
|
const childTimeoutMs = Math.max(
|
|
30_000,
|
|
Number(process.env.RELEASE_GATE_SCENARIO_PROCESS_TIMEOUT_MS ?? 360_000) || 360_000,
|
|
);
|
|
const code = await new Promise((resolve, reject) => {
|
|
const child = spawn(
|
|
process.execPath,
|
|
['scripts/run-scenario-test.mjs', '--scenario', scenarioId, '--port', String(port)],
|
|
{
|
|
cwd: root,
|
|
env: {
|
|
...process.env,
|
|
JOHN_PASSWORD: '888888',
|
|
RELEASE_GATE_SCENARIO_TIMEOUT_MS: String(
|
|
Number(process.env.RELEASE_GATE_SCENARIO_TIMEOUT_MS ?? 300_000) || 300_000,
|
|
),
|
|
},
|
|
stdio: 'inherit',
|
|
},
|
|
);
|
|
const timeout = setTimeout(() => {
|
|
child.kill('SIGTERM');
|
|
setTimeout(() => child.kill('SIGKILL'), 3_000).unref();
|
|
}, childTimeoutMs);
|
|
timeout.unref();
|
|
child.once('error', reject);
|
|
child.once('close', (status) => {
|
|
clearTimeout(timeout);
|
|
resolve(status ?? 1);
|
|
});
|
|
});
|
|
return code;
|
|
}
|
|
|
|
const runId = `page-${new Date().toISOString().replace(/[-:.TZ]/g, '').slice(0, 14)}`;
|
|
const stack = await createLocalGateStack({
|
|
root,
|
|
runId,
|
|
port: Number(process.env.MEMIND_RELEASE_GATE_PAGE_PORT ?? 19087),
|
|
portalRoot: path.join(root, '.runtime', 'portal'),
|
|
nodeEnv: 'test',
|
|
runtimeProfile: 'local',
|
|
});
|
|
await seedSelectedProviderKeys({ sourceUrl: stack.sourceDatabaseUrl, targetUrl: stack.mysqlUrl });
|
|
await selectBackendLlmProvider({ targetUrl: stack.mysqlUrl });
|
|
|
|
async function register(username) {
|
|
const response = await fetch(`${stack.baseUrl}/auth/register`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
username,
|
|
password: '888888',
|
|
displayName: `Release Gate ${username}`,
|
|
email: `${username}@example.invalid`,
|
|
}),
|
|
});
|
|
if (!response.ok) throw new Error(`register ${username} failed: ${response.status}`);
|
|
}
|
|
|
|
try {
|
|
await register('john2');
|
|
const results = await Promise.all(scenarioIds.map(async (scenarioId) => ({
|
|
scenarioId,
|
|
code: await runScenario(scenarioId, new URL(stack.baseUrl).port),
|
|
})));
|
|
for (const result of results) {
|
|
console.log(`${result.code === 0 ? 'PASS' : 'FAIL'} ${result.scenarioId}`);
|
|
}
|
|
if (results.some((result) => result.code !== 0)) process.exitCode = 1;
|
|
} finally {
|
|
await stack.cleanup();
|
|
}
|