172 lines
6.7 KiB
TypeScript
172 lines
6.7 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { Readable } from "node:stream";
|
|
import { test } from "bun:test";
|
|
|
|
import { handleWorkbenchLaunchHttp } from "./server-workbench-launch-http.ts";
|
|
|
|
test("workbench launch records OTel stage for Project Management link write 404", async () => {
|
|
const originalFetch = globalThis.fetch;
|
|
const request = jsonRequest({
|
|
projectId: "project_hwlab_v03",
|
|
taskRef: "mdtodo:hwlab-v03-mdtodo:file_demo:t4_open",
|
|
sessionId: "ses_launch_otel",
|
|
conversationId: "cnv_launch_otel"
|
|
});
|
|
const response = jsonResponse();
|
|
const fetchCalls = [];
|
|
const factWrites = [];
|
|
globalThis.fetch = async (url, init) => {
|
|
fetchCalls.push({ url: String(url), method: init?.method, body: init?.body });
|
|
if (String(url).includes("/v1/project-management/mdtodo/launch-context")) {
|
|
return new Response(JSON.stringify(projectManagementLaunchContextPayload()), {
|
|
status: 200,
|
|
headers: { "content-type": "application/json" }
|
|
});
|
|
}
|
|
return new Response(JSON.stringify({ error: { code: "not_found", message: "Project link route was not found." } }), {
|
|
status: 404,
|
|
headers: { "content-type": "application/json" }
|
|
});
|
|
};
|
|
try {
|
|
await handleWorkbenchLaunchHttp(request, response, {
|
|
env: { HWLAB_PROJECT_MANAGEMENT_URL: "http://project-management.test" },
|
|
accessController: {
|
|
async authenticate() {
|
|
return { ok: true, authMethod: "web-session", actor: { id: "usr_launch_otel", role: "admin" } };
|
|
},
|
|
async recordAgentSessionOwner(input) {
|
|
return {
|
|
id: input.sessionId,
|
|
ownerUserId: input.ownerUserId,
|
|
ownerRole: input.ownerRole,
|
|
projectId: input.projectId,
|
|
conversationId: input.conversationId,
|
|
threadId: input.threadId,
|
|
traceId: input.traceId,
|
|
status: input.status,
|
|
session: input.session,
|
|
createdAt: "2026-06-25T10:00:00.000Z",
|
|
updatedAt: "2026-06-25T10:00:00.000Z"
|
|
};
|
|
}
|
|
},
|
|
runtimeStore: {
|
|
async writeWorkbenchSessionAdmissionFact(params, requestMeta) {
|
|
factWrites.push({ params, requestMeta });
|
|
return { ok: true, fact: params.fact, admissionOnly: true };
|
|
}
|
|
}
|
|
});
|
|
} finally {
|
|
globalThis.fetch = originalFetch;
|
|
}
|
|
|
|
assert.equal(response.statusCode, 404);
|
|
assert.equal(fetchCalls.length, 2);
|
|
assert.equal(fetchCalls[0].method, "GET");
|
|
assert.match(fetchCalls[0].url, /\/v1\/project-management\/mdtodo\/launch-context/u);
|
|
assert.equal(fetchCalls[1].method, "POST");
|
|
const body = JSON.parse(response.body);
|
|
assert.equal(body.error.code, "not_found");
|
|
const context = request.hwlabHttpRequestContext;
|
|
assert.equal(context.route, "/v1/workbench/launches");
|
|
assert.equal(context.lastHttpError.code, "not_found");
|
|
assert.equal(context.lastHttpError.category, "workbench_launch");
|
|
assert.equal(context.lastHttpError.layer, "workbench.launch.project_link_write");
|
|
assert.equal(context.otelAttributes["workbench.launch.stage"], "project_link_write");
|
|
assert.equal(context.otelAttributes["workbench.launch.result"], "failed");
|
|
assert.equal(context.otelAttributes["workbench.launch.upstream_status"], 404);
|
|
assert.equal(context.otelAttributes["workbench.launch.session_id"], "ses_launch_otel");
|
|
assert.equal(context.otelAttributes["workbench.launch.task_ref"], "mdtodo:hwlab-v03-mdtodo:file_demo:t4_open");
|
|
assert.equal(context.otelAttributes["workbench.launch.source_id"], "hwlab-v03-mdtodo");
|
|
assert.equal(context.otelAttributes["workbench.launch.hwpod_id"], "constart-71freq-c");
|
|
assert.equal(context.otelAttributes["workbench.launch.workspace_root_hash"], "workspace-hash");
|
|
assert.equal(context.otelAttributes["workbench.launch.context_fingerprint"], "ctx_launch_otel");
|
|
assert.match(context.otelAttributes["workbench.launch.task_ref_hash"], /^[0-9a-f]{24}$/u);
|
|
assert.equal(context.otelAttributes["workbench.launch.values_redacted"], true);
|
|
assert.equal(factWrites.length, 1);
|
|
const sessionJson = factWrites[0].params.fact.sessionJson;
|
|
assert.equal(sessionJson.launchContext.sourceId, "hwlab-v03-mdtodo");
|
|
assert.equal(sessionJson.launchContext.hwpodId, "constart-71freq-c");
|
|
assert.equal(sessionJson.launchContext.contextFingerprint, "ctx_launch_otel");
|
|
assert.equal(sessionJson.launchContext.executionContext.hwpodWorkspaceArgs, "--hwpod-id constart-71freq-c --workspace-path 'F:\\Work\\ConStart'");
|
|
assert.equal(sessionJson.launchContext.valuesRedacted, true);
|
|
});
|
|
|
|
function jsonRequest(body) {
|
|
const request = Readable.from([JSON.stringify(body)]);
|
|
request.method = "POST";
|
|
request.url = "/v1/workbench/launches";
|
|
request.headers = { "content-type": "application/json" };
|
|
request.hwlabHttpRequestContext = {
|
|
requestId: "req_launch_otel",
|
|
startedAtMs: Date.now(),
|
|
traceId: "11111111111111111111111111111111",
|
|
parentSpanId: null,
|
|
spanId: "2222222222222222",
|
|
traceparent: "00-11111111111111111111111111111111-2222222222222222-01",
|
|
method: "POST",
|
|
route: "/v1/workbench/launches",
|
|
valuesPrinted: false
|
|
};
|
|
return request;
|
|
}
|
|
|
|
function jsonResponse() {
|
|
return {
|
|
headersSent: false,
|
|
writableEnded: false,
|
|
statusCode: 0,
|
|
headers: {},
|
|
body: "",
|
|
writeHead(statusCode, headers) {
|
|
this.statusCode = statusCode;
|
|
this.headers = headers;
|
|
this.headersSent = true;
|
|
},
|
|
end(chunk) {
|
|
this.body += String(chunk ?? "");
|
|
this.writableEnded = true;
|
|
}
|
|
};
|
|
}
|
|
|
|
function projectManagementLaunchContextPayload() {
|
|
return {
|
|
ok: true,
|
|
launchContext: {
|
|
source: "project-management",
|
|
projectId: "project_hwlab_v03",
|
|
taskRef: "mdtodo:hwlab-v03-mdtodo:file_demo:t4_open",
|
|
sourceId: "hwlab-v03-mdtodo",
|
|
sourceKind: "hwpod-workspace",
|
|
fileRef: "file_demo",
|
|
taskId: "t4_open",
|
|
hwpodId: "constart-71freq-c",
|
|
nodeId: "D518",
|
|
mdtodoRootRef: "docs/MDTODO",
|
|
workspaceRootHash: "workspace-hash",
|
|
hwpodWorkspaceArgs: "--hwpod-id constart-71freq-c --workspace-path 'F:\\Work\\ConStart'",
|
|
contextFingerprint: "ctx_launch_otel",
|
|
executionContext: {
|
|
sourceId: "hwlab-v03-mdtodo",
|
|
sourceKind: "hwpod-workspace",
|
|
projectId: "project_hwlab_v03",
|
|
taskRef: "mdtodo:hwlab-v03-mdtodo:file_demo:t4_open",
|
|
fileRef: "file_demo",
|
|
taskId: "t4_open",
|
|
hwpodId: "constart-71freq-c",
|
|
nodeId: "D518",
|
|
mdtodoRootRef: "docs/MDTODO",
|
|
workspaceRootHash: "workspace-hash",
|
|
hwpodWorkspaceArgs: "--hwpod-id constart-71freq-c --workspace-path 'F:\\Work\\ConStart'",
|
|
contextFingerprint: "ctx_launch_otel",
|
|
valuesRedacted: true
|
|
},
|
|
valuesRedacted: true
|
|
},
|
|
valuesRedacted: true
|
|
};
|
|
}
|