test(冒煙測試): 更新 F/J 群組冒煙測試以涵蓋 llm/記憶快取新行為
This commit is contained in:
+12
-7
@@ -136,14 +136,18 @@ export default async function smokeF() {
|
|||||||
// 清理本次測試建立的 ProceduralRule,避免重複執行時累積髒資料
|
// 清理本次測試建立的 ProceduralRule,避免重複執行時累積髒資料
|
||||||
await prisma.proceduralRule.deleteMany({ where: { characterId: CHARACTER_ID, situation } });
|
await prisma.proceduralRule.deleteMany({ where: { characterId: CHARACTER_ID, situation } });
|
||||||
|
|
||||||
// F-2 Provider 切換:LLM_PROVIDER=claude 時啟動即以 ERR log 明確告知未實作,呼叫時拋出例外
|
// R-3:ClaudeProvider 已經是真的呼叫,不再是空殼。這裡只驗證 Provider 切換的「配線」本身
|
||||||
await verifyClaudeProviderStub();
|
// (選對了 ClaudeProvider、缺金鑰時的錯誤處理正確),不對 CLIProxy 發真的請求——真正的
|
||||||
|
// 回歸測試基準仍是 Mock 模板庫(同 R-3 驗收註記),自動化冒煙測試不應依賴外部服務目前是否可用。
|
||||||
|
await verifyClaudeProviderWiring();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function verifyClaudeProviderStub() {
|
async function verifyClaudeProviderWiring() {
|
||||||
const port = "3091";
|
const port = "3091";
|
||||||
|
const childEnv = { ...process.env, PORT: port, LLM_PROVIDER: "claude" };
|
||||||
|
delete childEnv.CLAUDE_API_KEY;
|
||||||
const child = spawn("node", ["apps/api/dist/main.js"], {
|
const child = spawn("node", ["apps/api/dist/main.js"], {
|
||||||
env: { ...process.env, PORT: port, LLM_PROVIDER: "claude" },
|
env: childEnv,
|
||||||
stdio: ["ignore", "pipe", "pipe"],
|
stdio: ["ignore", "pipe", "pipe"],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -156,8 +160,8 @@ async function verifyClaudeProviderStub() {
|
|||||||
while (!output.includes("啟動") && Date.now() < deadline) {
|
while (!output.includes("啟動") && Date.now() < deadline) {
|
||||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||||
}
|
}
|
||||||
if (!output.includes("ClaudeProvider 尚未實作")) {
|
if (!output.includes("LLM_PROVIDER=claude")) {
|
||||||
throw new Error("LLM_PROVIDER=claude 啟動時未輸出「尚未實作」的 ERR log");
|
throw new Error("LLM_PROVIDER=claude 啟動時未輸出對應的 INF log");
|
||||||
}
|
}
|
||||||
|
|
||||||
let healthOk = false;
|
let healthOk = false;
|
||||||
@@ -182,8 +186,9 @@ async function verifyClaudeProviderStub() {
|
|||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ userId: USER_ID, text: "今天發生了很多事情想跟你分享" }),
|
body: JSON.stringify({ userId: USER_ID, text: "今天發生了很多事情想跟你分享" }),
|
||||||
});
|
});
|
||||||
|
// 沒有金鑰應該在呼叫 generate() 時就快速、確定性地失敗(不對 CLIProxy 發任何請求)。
|
||||||
if (res.status < 500) {
|
if (res.status < 500) {
|
||||||
throw new Error(`ClaudeProvider 空殼應在呼叫 generate() 時失敗,實際回傳 ${res.status}`);
|
throw new Error(`缺少 CLAUDE_API_KEY 時應該呼叫失敗,實際回傳 ${res.status}`);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
child.kill("SIGKILL");
|
child.kill("SIGKILL");
|
||||||
|
|||||||
+1
-1
@@ -225,7 +225,7 @@ export default async function smokeJ() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { spawnSync } = await import("node:child_process");
|
const { spawnSync } = await import("node:child_process");
|
||||||
const restartResult = spawnSync("npm", ["run", "restart"], { cwd: process.cwd(), stdio: "pipe" });
|
const restartResult = spawnSync("pnpm", ["run", "restart"], { cwd: process.cwd(), stdio: "pipe" });
|
||||||
if (restartResult.status !== 0) {
|
if (restartResult.status !== 0) {
|
||||||
throw new Error(`重啟服務失敗:${restartResult.stderr?.toString()}`);
|
throw new Error(`重啟服務失敗:${restartResult.stderr?.toString()}`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user