fix(test): 测试强制使用假引擎,不读本机真实配置

真引擎点亮后自动化测试开始真调模型(测试通过 startServer 默认读到 ~/.aps/config.json 里的密钥),verify 从 6 秒变成挂住。现在 StartOptions 支持显式 engine 覆盖,六个测试文件统一传 engine: 'fake';CI 再加 APS_ENGINE=fake 双保险。verify 恢复到 6 秒、60 条测试(59 通过 + 1 跳过)。
This commit is contained in:
zh 2026-09-28 20:30:40 +08:00
parent e74ca8a131
commit 4f59524d2a
8 changed files with 15 additions and 9 deletions

View File

@ -11,6 +11,9 @@ on:
jobs: jobs:
platform: platform:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env:
# 双保险:CI 里永远不走真引擎(测试自己也注入 fake,见 startServer 的 engine 参数)
APS_ENGINE: fake
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: pnpm/action-setup@v4 - uses: pnpm/action-setup@v4

View File

@ -17,7 +17,7 @@ async function startPlatform(devProvider = true) {
if (devProvider) process.env.APS_DEV_PROVIDER = '1'; if (devProvider) process.env.APS_DEV_PROVIDER = '1';
else delete process.env.APS_DEV_PROVIDER; else delete process.env.APS_DEV_PROVIDER;
const { startServer } = await import('../server/dist/index.js'); const { startServer } = await import('../server/dist/index.js');
const server = await startServer({ host: '127.0.0.1', port: 0, version: 'test', databasePath: ':memory:' }); const server = await startServer({ host: '127.0.0.1', port: 0, version: 'test', databasePath: ':memory:', engine: 'fake' });
return server; return server;
} }

View File

@ -10,7 +10,7 @@ import { test } from 'node:test';
async function startWithProvider() { async function startWithProvider() {
process.env.APS_DEV_PROVIDER = '1'; process.env.APS_DEV_PROVIDER = '1';
const { startServer } = await import('../server/dist/index.js'); const { startServer } = await import('../server/dist/index.js');
const server = await startServer({ host: '127.0.0.1', port: 0, version: 'test', databasePath: ':memory:' }); const server = await startServer({ host: '127.0.0.1', port: 0, version: 'test', databasePath: ':memory:', engine: 'fake' });
const created = await fetch(`${server.url}/v1/sessions`, { const created = await fetch(`${server.url}/v1/sessions`, {
method: 'POST', method: 'POST',
headers: { 'content-type': 'application/json' }, headers: { 'content-type': 'application/json' },

View File

@ -23,7 +23,7 @@ test('假引擎发起工具调用,经 Core.invoke 到假 Provider 并把回执
], ],
}); });
const server = await startServer({ host: '127.0.0.1', port: 0, version: 'test', databasePath: ':memory:', runtime }); const server = await startServer({ host: '127.0.0.1', port: 0, version: 'test', databasePath: ':memory:', engine: 'fake', runtime });
try { try {
const created = await fetch(`${server.url}/v1/sessions`, { const created = await fetch(`${server.url}/v1/sessions`, {
method: 'POST', method: 'POST',

View File

@ -16,7 +16,7 @@ test('平台服务托管客户端产物,且 API 不受影响', async () => {
execFileSync('pnpm', ['--filter', '@aps/client-app', 'run', 'build'], { cwd: ROOT, stdio: 'pipe', shell: isWindows }); execFileSync('pnpm', ['--filter', '@aps/client-app', 'run', 'build'], { cwd: ROOT, stdio: 'pipe', shell: isWindows });
const { startServer } = await import('../server/dist/index.js'); const { startServer } = await import('../server/dist/index.js');
const server = await startServer({ host: '127.0.0.1', port: 0, version: 'test', databasePath: ':memory:' }); const server = await startServer({ host: '127.0.0.1', port: 0, version: 'test', databasePath: ':memory:', engine: 'fake' });
try { try {
const page = await fetch(`${server.url}/`); const page = await fetch(`${server.url}/`);
assert.equal(page.status, 200, 'GET / 应返回客户端页面'); assert.equal(page.status, 200, 'GET / 应返回客户端页面');

View File

@ -31,7 +31,7 @@ async function validator() {
async function startServer(options = {}) { async function startServer(options = {}) {
const { startServer: start } = await import('../server/dist/index.js'); const { startServer: start } = await import('../server/dist/index.js');
return start({ host: '127.0.0.1', port: 0, version: 'test', databasePath: ':memory:', ...options }); return start({ host: '127.0.0.1', port: 0, version: 'test', databasePath: ':memory:', engine: 'fake', ...options });
} }
const json = (method, body) => ({ method, headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) }); const json = (method, body) => ({ method, headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) });

View File

@ -11,7 +11,7 @@ import { test } from 'node:test';
async function startWithDatabase(dbPath) { async function startWithDatabase(dbPath) {
const { startServer } = await import('../server/dist/index.js'); const { startServer } = await import('../server/dist/index.js');
return startServer({ host: '127.0.0.1', port: 0, version: 'test', databasePath: dbPath }); return startServer({ host: '127.0.0.1', port: 0, version: 'test', databasePath: dbPath, engine: 'fake' });
} }
const postJson = (base, path, body) => const postJson = (base, path, body) =>

View File

@ -26,6 +26,8 @@ export interface StartOptions {
runtime?: AgentRuntime; runtime?: AgentRuntime;
/** 数据库路径:默认取配置;测试传 ':memory:' 以隔离 */ /** 数据库路径:默认取配置;测试传 ':memory:' 以隔离 */
databasePath?: string; databasePath?: string;
/** 引擎覆盖:测试必须传 'fake',避免读到本机的真实模型配置 */
engine?: 'fake' | 'pi';
} }
export interface RunningServer { export interface RunningServer {
@ -41,7 +43,7 @@ export async function startServer(options: StartOptions = {}): Promise<RunningSe
const config = loadConfig(); const config = loadConfig();
const host = options.host ?? config.server.host; const host = options.host ?? config.server.host;
const port = options.port ?? config.server.port; const port = options.port ?? config.server.port;
const runtime = options.runtime ?? (await selectRuntime(config)); const runtime = options.runtime ?? (await selectRuntime(config, options.engine));
const database: Database = openDatabase(options.databasePath ?? config.database.path); const database: Database = openDatabase(options.databasePath ?? config.database.path);
const service = new ApplicationService({ const service = new ApplicationService({
...(options.version === undefined ? {} : { version: options.version }), ...(options.version === undefined ? {} : { version: options.version }),
@ -81,8 +83,9 @@ export async function startServer(options: StartOptions = {}): Promise<RunningSe
}; };
} }
/** 引擎选择:显式注入 > 配置里的 engine.kind;选 pi 但没密钥时明确回退到假引擎 */ /** 引擎选择:显式注入 > 配置里的 engine.kind;选 pi 但没密钥时明确回退到假引擎 */
async function selectRuntime(config: ReturnType<typeof loadConfig>): Promise<AgentRuntime> { async function selectRuntime(config: ReturnType<typeof loadConfig>, override?: 'fake' | 'pi'): Promise<AgentRuntime> {
if (config.engine.kind !== 'pi') { const kind = override ?? config.engine.kind;
if (kind !== 'pi') {
const { createFakeRuntime } = await import('./agent/fake-runtime.js'); const { createFakeRuntime } = await import('./agent/fake-runtime.js');
const { createRulePlanner, plannerToFakeTurn } = await import('./agent/rule-planner.js'); const { createRulePlanner, plannerToFakeTurn } = await import('./agent/rule-planner.js');
return createFakeRuntime({ name: 'fake', planner: plannerToFakeTurn(createRulePlanner()) }); return createFakeRuntime({ name: 'fake', planner: plannerToFakeTurn(createRulePlanner()) });