fix: harden pi maintenance lifecycle
This commit is contained in:
@@ -2,7 +2,8 @@ import { test, expect, vi } from "vitest";
|
||||
import { spawn as nodeSpawn } from "node:child_process";
|
||||
import path from "node:path";
|
||||
import os from "node:os";
|
||||
import { chmodSync, unlinkSync, writeFileSync } from "node:fs";
|
||||
import { chmodSync, unlinkSync, writeFileSync, mkdtempSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { buildApp as buildRealApp } from "../src/app.js";
|
||||
import { loadConfig } from "../src/config.js";
|
||||
import { SseHub } from "../src/sse/sse-hub.js";
|
||||
@@ -74,6 +75,43 @@ test("upstream requests without a principal fail before a Pi runtime can be crea
|
||||
expect(created).toBe(false);
|
||||
});
|
||||
|
||||
test("maintenance rejects new and resumed session admission without interrupting running sessions", async () => {
|
||||
const app = buildApp(loadConfig({ AUTH_MODE: "upstream", THT_HARNESS_DIR: "../harness" }), {
|
||||
maintenanceGate: () => true,
|
||||
thtRunner: { withPrincipal: () => ({ sessionShow: async () => ({ id: "open", status: "open" }) }) } as any,
|
||||
});
|
||||
|
||||
const create = await app.inject({
|
||||
method: "POST", url: "/sessions", headers: aliceHeaders, payload: { question: "q" },
|
||||
});
|
||||
const resume = await app.inject({ method: "POST", url: "/sessions/open/resume", headers: aliceHeaders });
|
||||
|
||||
expect(create.statusCode).toBe(503);
|
||||
expect(resume.statusCode).toBe(503);
|
||||
expect(create.json()).toEqual({
|
||||
code: "maintenance", error: "Session admission is temporarily paused for maintenance. Try again shortly.",
|
||||
});
|
||||
expect(resume.json()).toEqual(create.json());
|
||||
});
|
||||
|
||||
test("the on-disk maintenance marker gates admission in an upstream server profile", async () => {
|
||||
const dir = mkdtempSync(path.join(tmpdir(), "tht-maintenance-"));
|
||||
try {
|
||||
const marker = path.join(dir, "maintenance.json");
|
||||
writeFileSync(marker, '{"transaction":"test"}\n');
|
||||
const app = buildApp(loadConfig({
|
||||
AUTH_MODE: "upstream", THT_HARNESS_DIR: "../harness", THT_MAINTENANCE_FILE: marker,
|
||||
}), { thtRunner: {} as any });
|
||||
const response = await app.inject({
|
||||
method: "POST", url: "/sessions", headers: aliceHeaders, payload: { question: "q" },
|
||||
});
|
||||
expect(response.statusCode).toBe(503);
|
||||
expect(response.json().code).toBe("maintenance");
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("session routes conceal foreign or missing sessions and deny SSE before it subscribes", async () => {
|
||||
let subscribed = false;
|
||||
const app = buildApp(loadConfig({ AUTH_MODE: "upstream", THT_HARNESS_DIR: "../harness" }), {
|
||||
|
||||
Reference in New Issue
Block a user