feat(backend): support container runtime paths
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { expect, test } from "vitest";
|
||||
import { loadConfig } from "../src/config.js";
|
||||
|
||||
test("loadConfig accepts container listening and runtime paths", () => {
|
||||
expect(loadConfig({
|
||||
HOST: "0.0.0.0",
|
||||
PORT: "9000",
|
||||
THT_HARNESS_DIR: "/app/harness",
|
||||
THT_BIN: "/opt/venv/bin/tht",
|
||||
PI_BIN: "/usr/local/bin/pi",
|
||||
SETTINGS_FILE: "/data/settings/settings.json",
|
||||
THT_DATA_ROOT: "/data",
|
||||
})).toMatchObject({
|
||||
host: "0.0.0.0",
|
||||
port: 9000,
|
||||
harnessDir: "/app/harness",
|
||||
thtBin: "/opt/venv/bin/tht",
|
||||
piBin: "/usr/local/bin/pi",
|
||||
settingsFile: "/data/settings/settings.json",
|
||||
dataRoot: "/data",
|
||||
});
|
||||
});
|
||||
|
||||
test("loadConfig keeps local development defaults", () => {
|
||||
expect(loadConfig({})).toMatchObject({
|
||||
host: "127.0.0.1",
|
||||
port: 8787,
|
||||
harnessDir: "../harness",
|
||||
thtBin: "tht",
|
||||
piBin: "pi",
|
||||
settingsFile: "data/settings.json",
|
||||
});
|
||||
expect(loadConfig({}).dataRoot).toBeUndefined();
|
||||
});
|
||||
@@ -51,3 +51,33 @@ test("createPiModelLister caches within ttl (spawns once for two calls)", async
|
||||
rmSync(path.dirname(script), { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("production model-list spawn preserves PATH and passes the portable data root", async () => {
|
||||
const script = scriptWith([]);
|
||||
const calls: any[][] = [];
|
||||
const previousPath = process.env.PATH;
|
||||
process.env.PATH = "/usr/local/bin:/usr/bin";
|
||||
try {
|
||||
const lister = createPiModelLister(loadConfig({
|
||||
THT_HARNESS_DIR: "/app/harness",
|
||||
PI_BIN: "/usr/local/bin/pi",
|
||||
THT_DATA_ROOT: "/data",
|
||||
}), {
|
||||
spawnFn: (...args: any[]) => {
|
||||
calls.push(args);
|
||||
return spawn("node", [FAKE, script]) as any;
|
||||
},
|
||||
});
|
||||
await lister();
|
||||
expect(calls[0][0]).toBe("/usr/local/bin/pi");
|
||||
expect(calls[0][1]).toEqual(["--mode", "rpc"]);
|
||||
expect(calls[0][2]).toMatchObject({
|
||||
cwd: "/app/harness",
|
||||
env: expect.objectContaining({ PATH: "/usr/local/bin:/usr/bin", THT_DATA_ROOT: "/data" }),
|
||||
});
|
||||
} finally {
|
||||
if (previousPath === undefined) delete process.env.PATH;
|
||||
else process.env.PATH = previousPath;
|
||||
rmSync(path.dirname(script), { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { test, expect } from "vitest";
|
||||
import { test, expect, vi } from "vitest";
|
||||
import { spawn } from "node:child_process";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
@@ -125,3 +125,38 @@ test("spawnFor default (new) mode sends /nuova-domanda", async () => {
|
||||
expect(child._writes.join("")).toContain("/nuova-domanda");
|
||||
mgr.teardown("sid-10");
|
||||
});
|
||||
|
||||
test("production spawn uses explicit Pi path and passes portable data root without rewriting PATH", async () => {
|
||||
vi.stubEnv("PATH", "/usr/local/bin:/usr/bin");
|
||||
vi.stubEnv("PI_PROVIDER_API_KEY", "provider-secret");
|
||||
vi.stubEnv("NODE_EXTRA_CA_CERTS", "/certs/company-ca.pem");
|
||||
const calls: any[][] = [];
|
||||
const child = recordingChild();
|
||||
child.stderr.resume = () => {};
|
||||
const spawnFn = (...args: any[]) => { calls.push(args); return child as any; };
|
||||
const cfg = loadConfig({
|
||||
THT_HARNESS_DIR: "/app/harness",
|
||||
PI_BIN: "/usr/local/bin/pi",
|
||||
THT_DATA_ROOT: "/data",
|
||||
});
|
||||
const mgr = new PiProcessManager(cfg, { spawnFn });
|
||||
|
||||
try {
|
||||
await mgr.spawnFor("portable-session", { author: "user@example.test" });
|
||||
const [bin, args, options] = calls[0];
|
||||
expect(bin).toBe("/usr/local/bin/pi");
|
||||
expect(args).toEqual(["--mode", "rpc"]);
|
||||
expect(options.cwd).toBe("/app/harness");
|
||||
expect(options.env).toMatchObject({
|
||||
PATH: "/usr/local/bin:/usr/bin",
|
||||
PI_PROVIDER_API_KEY: "provider-secret",
|
||||
NODE_EXTRA_CA_CERTS: "/certs/company-ca.pem",
|
||||
THT_DATA_ROOT: "/data",
|
||||
THT_SESSION: "portable-session",
|
||||
THT_AUTHOR: "user@example.test",
|
||||
});
|
||||
} finally {
|
||||
mgr.teardown("portable-session");
|
||||
vi.unstubAllEnvs();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user