test(e2e): require kitchen sink tool coverage

This commit is contained in:
Vincent Koc
2026-06-03 13:25:46 +02:00
parent 6ec579a0c2
commit eddf1c776d
3 changed files with 149 additions and 17 deletions

View File

@@ -15,6 +15,9 @@ import {
appendBoundedOutput,
assertCommandResourceCeiling,
assertDiagnosticStabilityClean,
assertExpectedKitchenSinkToolEntries,
assertKitchenSinkSearchInvokeResult,
assertKitchenSinkTextInvokeResult,
assertResourceCeiling,
cleanupKitchenSinkEnv,
createGatewayReadyLogScanner,
@@ -92,7 +95,7 @@ describe("kitchen-sink RPC isolated state", () => {
});
it("can fail the walk when generated temp cleanup cannot remove the root", async () => {
const rmSync = vi.spyOn(fs, "rmSync").mockImplementation(() => {
const rmSyncSpy = vi.spyOn(fs, "rmSync").mockImplementation(() => {
throw new Error("device busy");
});
@@ -107,9 +110,9 @@ describe("kitchen-sink RPC isolated state", () => {
).rejects.toThrow(
"failed to remove Kitchen Sink RPC temp root: /tmp/openclaw-kitchen-sink-rpc-stuck",
);
expect(rmSync).toHaveBeenCalledTimes(3);
expect(rmSyncSpy).toHaveBeenCalledTimes(3);
} finally {
rmSync.mockRestore();
rmSyncSpy.mockRestore();
}
});
});
@@ -522,6 +525,81 @@ describe("kitchen-sink RPC command catalog assertions", () => {
}),
).toEqual(["kitchen", "kitchen-sink"]);
});
it("requires every expected Kitchen Sink plugin tool", () => {
expect(() =>
assertExpectedKitchenSinkToolEntries(
[
{ id: "kitchen_sink_text", source: "plugin", pluginId: "openclaw-kitchen-sink-fixture" },
],
"tools.catalog plugin tools",
{ requirePluginProvenance: true },
),
).toThrow("tools.catalog plugin tools missing kitchen_sink_search, kitchen_sink_image_job");
});
it("requires plugin provenance for expected catalog tools", () => {
expect(() =>
assertExpectedKitchenSinkToolEntries(
[
{ id: "kitchen_sink_text", source: "plugin", pluginId: "openclaw-kitchen-sink-fixture" },
{ id: "kitchen_sink_search", source: "core", pluginId: "openclaw-kitchen-sink-fixture" },
{ id: "kitchen_sink_image_job", source: "plugin", pluginId: "other-plugin" },
],
"tools.catalog plugin tools",
{ requirePluginProvenance: true },
),
).toThrow("tools.catalog plugin tools plugin provenance mismatch");
});
it("accepts complete expected tool coverage", () => {
expect(
assertExpectedKitchenSinkToolEntries(
[
{ id: "kitchen_sink_text", source: "plugin", pluginId: "openclaw-kitchen-sink-fixture" },
{
id: "kitchen_sink_search",
source: "plugin",
pluginId: "openclaw-kitchen-sink-fixture",
},
{
id: "kitchen_sink_image_job",
source: "plugin",
pluginId: "openclaw-kitchen-sink-fixture",
},
],
"tools.catalog plugin tools",
{ requirePluginProvenance: true },
),
).toEqual(["kitchen_sink_text", "kitchen_sink_search", "kitchen_sink_image_job"]);
});
it("checks search and text tool invocation fixtures separately", () => {
expect(() =>
assertKitchenSinkSearchInvokeResult({
ok: true,
source: "plugin",
output: { results: [{ title: "Kitchen Sink image fixture" }] },
}),
).not.toThrow();
expect(() =>
assertKitchenSinkTextInvokeResult({
ok: true,
source: "plugin",
output: {
route: "tool:kitchen_sink_text",
text: "Kitchen Sink text provider produced a deterministic reply.",
},
}),
).not.toThrow();
expect(() =>
assertKitchenSinkTextInvokeResult({
ok: true,
source: "plugin",
output: { route: "tool:kitchen_sink_search" },
}),
).toThrow("Kitchen Sink text tool output missed expected fixture");
});
});
describe("kitchen-sink RPC diagnostics assertions", () => {