75 lines
3.1 KiB
JavaScript
75 lines
3.1 KiB
JavaScript
/**
|
||
* 落库用例(任务 A3.7):会话、消息与幂等键要在进程重启后仍然可查。
|
||
*
|
||
* 用同一个 SQLite 文件起两次服务,模拟「平台重启」。
|
||
*/
|
||
import assert from 'node:assert/strict';
|
||
import { mkdtemp, rm } from 'node:fs/promises';
|
||
import { tmpdir } from 'node:os';
|
||
import { join } from 'node:path';
|
||
import { test } from 'node:test';
|
||
|
||
async function startWithDatabase(dbPath) {
|
||
const { startServer } = await import('../server/dist/index.js');
|
||
return startServer({ host: '127.0.0.1', port: 0, version: 'test', databasePath: dbPath, engine: 'fake' });
|
||
}
|
||
|
||
const postJson = (base, path, body) =>
|
||
fetch(`${base}${path}`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) });
|
||
|
||
test('会话、消息与幂等键在重启后可查', async () => {
|
||
const dir = await mkdtemp(join(tmpdir(), 'aps-storage-'));
|
||
const dbPath = join(dir, 'aps.sqlite');
|
||
try {
|
||
let sessionId = '';
|
||
let firstRunId = '';
|
||
{
|
||
const server = await startWithDatabase(dbPath);
|
||
try {
|
||
const created = await (await postJson(server.url, '/v1/sessions', { scope: 'project', projectId: 'p-default', title: '持久化用例' })).json();
|
||
sessionId = created.session.sessionId;
|
||
|
||
const accepted = await (
|
||
await postJson(server.url, `/v1/sessions/${sessionId}/messages`, { text: '试排一版看看', idempotencyKey: 'idem-storage-0001' })
|
||
).json();
|
||
firstRunId = accepted.runId;
|
||
|
||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||
} finally {
|
||
await server.close();
|
||
}
|
||
}
|
||
|
||
// 重启:同一个库文件,新的服务实例
|
||
{
|
||
const server = await startWithDatabase(dbPath);
|
||
try {
|
||
const sessions = await (await fetch(`${server.url}/v1/sessions`)).json();
|
||
assert.equal(sessions.sessions.length, 1, '重启后应还能列出会话');
|
||
assert.equal(sessions.sessions[0].sessionId, sessionId);
|
||
assert.equal(sessions.sessions[0].title, '持久化用例');
|
||
|
||
const detail = await (await fetch(`${server.url}/v1/sessions/${sessionId}`)).json();
|
||
assert.ok(detail.messages.length >= 2, `重启后应还能读到消息,实际 ${detail.messages.length} 条`);
|
||
assert.equal(detail.messages[0].role, 'user');
|
||
assert.equal(detail.messages.at(-1).role, 'assistant');
|
||
|
||
// 幂等键也持久化了:同一 key 重试仍返回同一个 run
|
||
const retry = await (
|
||
await postJson(server.url, `/v1/sessions/${sessionId}/messages`, { text: '试排一版看看', idempotencyKey: 'idem-storage-0001' })
|
||
).json();
|
||
assert.equal(retry.runId, firstRunId, '重启后重试应命中同一条受理记录');
|
||
} finally {
|
||
await server.close();
|
||
}
|
||
}
|
||
} finally {
|
||
await rm(dir, { recursive: true, force: true });
|
||
}
|
||
});
|
||
|
||
test('默认数据库路径来自配置(~/.aps/aps.sqlite)', async () => {
|
||
const { loadConfig } = await import('@aps/server/config');
|
||
const config = loadConfig({ env: {}, homeDir: 'C:/Users/example' });
|
||
assert.equal(config.database.path.replace(/\\/g, '/'), 'C:/Users/example/.aps/aps.sqlite');
|
||
}); |