feat: complete catalog-driven preprocessing
Publish documentation / publish (push) Successful in 2m12s
Publish documentation / publish (push) Successful in 2m12s
This commit is contained in:
@@ -12,6 +12,7 @@ import { PiProcessManager } from "../src/pi/pi-process-manager.js";
|
||||
import { validateDeclarativePiConfig } from "../src/pi/managed-config.js";
|
||||
import Fastify from "fastify";
|
||||
import { sessionRoutes } from "../src/routes/sessions.js";
|
||||
import { MemoryCatalogRepository } from "../src/catalog/memory-repository.js";
|
||||
|
||||
const FAKE = path.resolve("../harness/tests/fake_pi/fake_pi_rpc.mjs");
|
||||
const SCRIPT = path.resolve("../harness/tests/fake_pi/scripts/f1_disambiguation.json");
|
||||
@@ -517,7 +518,7 @@ test("creates a session from the active immutable workspace revision", async ()
|
||||
}));
|
||||
});
|
||||
|
||||
test("hands one effective relationship snapshot to both retrieval and Pi", async () => {
|
||||
test("hands one Catalog-backed runtime to both retrieval and Pi", async () => {
|
||||
const effective = JSON.stringify({
|
||||
schemaVersion: 1,
|
||||
workspaceId: "default",
|
||||
@@ -556,10 +557,9 @@ test("hands one effective relationship snapshot to both retrieval and Pi", async
|
||||
});
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(render).toHaveBeenCalledWith("default");
|
||||
expect(render).not.toHaveBeenCalled();
|
||||
expect(acquireWorkspaceRuntime).toHaveBeenCalledWith(
|
||||
expect.stringContaining("/default.yaml"),
|
||||
effective,
|
||||
);
|
||||
expect(createFor).toHaveBeenCalledWith(
|
||||
"effective-map",
|
||||
@@ -574,27 +574,103 @@ test("hands one effective relationship snapshot to both retrieval and Pi", async
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects an SSH-only workspace before persisting or starting a session", async () => {
|
||||
test("refuses core admission when the workspace preprocessing fingerprint is stale", async () => {
|
||||
const sessionNew = vi.fn();
|
||||
const workspaceInputFingerprint = vi.fn(async () => "sha256:current");
|
||||
const revision = {
|
||||
id: "default",
|
||||
commit: "a".repeat(40),
|
||||
blob: "b".repeat(40),
|
||||
snapshotPath: `/data/workspace-registry/snapshots/${"a".repeat(40)}/default.yaml`,
|
||||
};
|
||||
const catalogRepository = new MemoryCatalogRepository();
|
||||
const database = await catalogRepository.create({
|
||||
workspaceId: "default",
|
||||
engine: "postgres",
|
||||
databaseName: "warehouse",
|
||||
schema: "public",
|
||||
binding: {
|
||||
transport: "postgres_direct",
|
||||
host: "db.internal",
|
||||
port: 5432,
|
||||
username: "reader",
|
||||
},
|
||||
});
|
||||
await catalogRepository.applySchemaSync(database.id, database.version, "all", [], {
|
||||
schemaVersion: 1,
|
||||
capabilities: { tables: "available", columns: "available", relationships: "available" },
|
||||
tables: [],
|
||||
columns: [],
|
||||
relationships: [],
|
||||
});
|
||||
const started = await catalogRepository.beginPreprocessing("default", "sha256:previous");
|
||||
expect(started.kind).toBe("started");
|
||||
await catalogRepository.finishPreprocessing(
|
||||
"default",
|
||||
0,
|
||||
"sha256:previous",
|
||||
{ status: "succeeded" },
|
||||
);
|
||||
const app = buildApp(loadConfig({ THT_HARNESS_DIR: "../harness" }), {
|
||||
thtRunner: { sessionNew, workspaceInputFingerprint } as any,
|
||||
catalogRepository,
|
||||
workspaceRegistry: {
|
||||
acquireSessionRevision: async () => ({
|
||||
workspace: operationalWorkspace("default"),
|
||||
revision,
|
||||
abort: async () => {},
|
||||
markPersisted: async () => {},
|
||||
}),
|
||||
} as any,
|
||||
readiness: { ensure: async () => ({ ok: true }) } as any,
|
||||
getSettings: () => ({ workspace: "default", thinking: "low" }) as any,
|
||||
});
|
||||
|
||||
const response = await app.inject({
|
||||
method: "POST",
|
||||
url: "/sessions",
|
||||
payload: { question: "q", workspaceId: "default" },
|
||||
});
|
||||
|
||||
expect(response.statusCode).toBe(409);
|
||||
expect(response.json()).toMatchObject({ code: "preprocessing_required" });
|
||||
expect(workspaceInputFingerprint).toHaveBeenCalledWith(revision.snapshotPath);
|
||||
expect(sessionNew).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("rejects an SSH-only Catalog binding before persisting or starting a session", async () => {
|
||||
const sessionNew = vi.fn(async () => ({ id: "must-not-exist" }));
|
||||
const workspaceInputFingerprint = vi.fn(async () => "sha256:unused");
|
||||
const ensure = vi.fn(async () => ({ ok: true }));
|
||||
const createFor = vi.fn();
|
||||
const abort = vi.fn(async () => {});
|
||||
const markPersisted = vi.fn(async () => {});
|
||||
const catalogRepository = new MemoryCatalogRepository();
|
||||
await catalogRepository.create({
|
||||
workspaceId: "ssh-workspace",
|
||||
engine: "postgres",
|
||||
databaseName: "postgres",
|
||||
schema: "public",
|
||||
binding: {
|
||||
transport: "ssh_tunnel",
|
||||
username: "reader",
|
||||
sshHost: "bastion.internal",
|
||||
sshPort: 22,
|
||||
sshUsername: "tunnel",
|
||||
sshTargetHost: "postgres.internal",
|
||||
sshTargetPort: 5432,
|
||||
},
|
||||
});
|
||||
const app = buildApp(loadConfig({ THT_HARNESS_DIR: "../harness" }), {
|
||||
thtRunner: { sessionNew, searchPack: async () => {} } as any,
|
||||
thtRunner: { sessionNew, searchPack: async () => {}, workspaceInputFingerprint } as any,
|
||||
catalogRepository,
|
||||
readiness: { ensure } as any,
|
||||
mgr: { get: () => undefined, createFor } as any,
|
||||
getSettings: () => ({ workspace: "ssh-workspace" }) as any,
|
||||
workspaceRuntimeSupport: vi.fn(() => false),
|
||||
workspaceRuntimeSupport: vi.fn(() => true),
|
||||
workspaceRegistry: {
|
||||
acquireSessionRevision: vi.fn(async () => ({
|
||||
workspace: {
|
||||
workspace: { schema_version: 4, id: "ssh-workspace", name: "SSH", language: "en" },
|
||||
dwh: {
|
||||
engine: "postgres", database: "postgres", schema: "public",
|
||||
supported_transports: ["ssh_tunnel"],
|
||||
},
|
||||
},
|
||||
workspace: operationalWorkspace("ssh-workspace"),
|
||||
revision: {
|
||||
id: "ssh-workspace", commit: "a".repeat(40), blob: "b".repeat(40),
|
||||
snapshotPath: `/data/workspace-registry/snapshots/${"a".repeat(40)}/ssh-workspace.yaml`,
|
||||
@@ -610,6 +686,7 @@ test("rejects an SSH-only workspace before persisting or starting a session", as
|
||||
expect(response.statusCode).toBe(409);
|
||||
expect(response.json()).toMatchObject({ code: "workspace_not_activatable" });
|
||||
expect(ensure).not.toHaveBeenCalled();
|
||||
expect(workspaceInputFingerprint).not.toHaveBeenCalled();
|
||||
expect(sessionNew).not.toHaveBeenCalled();
|
||||
expect(createFor).not.toHaveBeenCalled();
|
||||
expect(abort).toHaveBeenCalledOnce();
|
||||
|
||||
Reference in New Issue
Block a user