Skip to content

Commit 24bc8b5

Browse files
committed
test: quiet expected error logging
1 parent 44c3ff9 commit 24bc8b5

4 files changed

Lines changed: 163 additions & 137 deletions

File tree

src/handlers/event.test.ts

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { assertEquals } from "jsr:@std/assert@^1.0.0";
22
import { describe, it } from "jsr:@std/testing@^1.0.0/bdd";
33
import { createEventHandler } from "./event.ts";
44
import { resolveContextLimit } from "../services/context-limit.ts";
5+
import { setLoggerSilentOverride } from "../services/logger.ts";
56
import type { SessionState } from "../session.ts";
67

78
class FakeClock {
@@ -1187,46 +1188,52 @@ describe("event handler", () => {
11871188
};
11881189
const { handler } = createHandler(sessionManager, { sdkClient });
11891190

1190-
await handler({
1191-
event: {
1192-
type: "message.updated",
1193-
properties: {
1194-
info: {
1195-
id: "m1",
1196-
sessionID: "session-1",
1197-
role: "assistant",
1198-
time: { created: 1, completed: 2 },
1199-
tokens: { output: 10 },
1200-
providerID: "openai",
1201-
modelID: "gpt-5",
1191+
try {
1192+
setLoggerSilentOverride(true);
1193+
1194+
await handler({
1195+
event: {
1196+
type: "message.updated",
1197+
properties: {
1198+
info: {
1199+
id: "m1",
1200+
sessionID: "session-1",
1201+
role: "assistant",
1202+
time: { created: 1, completed: 2 },
1203+
tokens: { output: 10 },
1204+
providerID: "openai",
1205+
modelID: "gpt-5",
1206+
},
12021207
},
1203-
},
1204-
} as never,
1205-
});
1206-
await flushPromises();
1207-
1208-
assertEquals(state.contextLimit, 200_000);
1209-
1210-
await handler({
1211-
event: {
1212-
type: "message.updated",
1213-
properties: {
1214-
info: {
1215-
id: "m2",
1216-
sessionID: "session-1",
1217-
role: "assistant",
1218-
time: { created: 3, completed: 4 },
1219-
tokens: { output: 12 },
1220-
providerID: "openai",
1221-
modelID: "gpt-5",
1208+
} as never,
1209+
});
1210+
await flushPromises();
1211+
1212+
assertEquals(state.contextLimit, 200_000);
1213+
1214+
await handler({
1215+
event: {
1216+
type: "message.updated",
1217+
properties: {
1218+
info: {
1219+
id: "m2",
1220+
sessionID: "session-1",
1221+
role: "assistant",
1222+
time: { created: 3, completed: 4 },
1223+
tokens: { output: 12 },
1224+
providerID: "openai",
1225+
modelID: "gpt-5",
1226+
},
12221227
},
1223-
},
1224-
} as never,
1225-
});
1226-
await flushPromises();
1227-
1228-
assertEquals(providerCalls, 1);
1229-
assertEquals(state.contextLimit, 200_000);
1228+
} as never,
1229+
});
1230+
await flushPromises();
1231+
1232+
assertEquals(providerCalls, 1);
1233+
assertEquals(state.contextLimit, 200_000);
1234+
} finally {
1235+
setLoggerSilentOverride(false);
1236+
}
12301237
});
12311238

12321239
it("caches unknown provider/model misses to avoid repeated lookups", async () => {

src/services/graphiti-mcp.test.ts

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { assertEquals, assertRejects } from "jsr:@std/assert@^1.0.0";
22
import { describe, it } from "jsr:@std/testing@^1.0.0/bdd";
33
import { GraphitiOfflineError } from "./connection-manager.ts";
44
import { GraphitiMcpClient } from "./graphiti-mcp.ts";
5+
import { setLoggerSilentOverride } from "./logger.ts";
56
import {
67
setOpenCodeClient,
78
setSuppressConsoleWarningsDuringTestsOverride,
@@ -44,23 +45,28 @@ describe("GraphitiMcpClient", () => {
4445
});
4546

4647
it("marks unexpected search node failures as degraded", async () => {
47-
const client = new GraphitiMcpClient({
48-
start() {},
49-
stop() {
50-
return Promise.resolve();
51-
},
52-
ready() {
53-
return Promise.resolve(true);
54-
},
55-
callTool() {
56-
return Promise.reject(new Error("boom"));
57-
},
58-
});
48+
try {
49+
setLoggerSilentOverride(true);
50+
const client = new GraphitiMcpClient({
51+
start() {},
52+
stop() {
53+
return Promise.resolve();
54+
},
55+
ready() {
56+
return Promise.resolve(true);
57+
},
58+
callTool() {
59+
return Promise.reject(new Error("boom"));
60+
},
61+
});
5962

60-
assertEquals(await client.searchNodesWithStatus({ query: "test" }), {
61-
nodes: [],
62-
degraded: true,
63-
});
63+
assertEquals(await client.searchNodesWithStatus({ query: "test" }), {
64+
nodes: [],
65+
degraded: true,
66+
});
67+
} finally {
68+
setLoggerSilentOverride(false);
69+
}
6470
});
6571

6672
it("reports searchNodesWithStatus availability warnings with the correct operation name", async () => {

src/services/hot-tier-slice.test.ts

Lines changed: 55 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,7 +1315,7 @@ describe("hot-tier vertical slice", () => {
13151315
}]);
13161316
});
13171317

1318-
it("recovers a stuck same-group drain with one bounded recovery timer", async () => {
1318+
it("keeps one bounded recovery timer for a stuck same-group drain", async () => {
13191319
const redis = new RedisClient({ endpoint: "redis://unused" });
13201320
const redisCache = new RedisCacheService(redis, {
13211321
ttlSeconds: 300,
@@ -1331,8 +1331,7 @@ describe("hot-tier vertical slice", () => {
13311331

13321332
const neverSettles = new Promise<never>(() => {});
13331333
const drainCalls: string[] = [];
1334-
const refreshCalls: Array<{ groupId: string; query: string }> = [];
1335-
let callCount = 0;
1334+
const warnSpy = spy(logger, "warn");
13361335
const graphitiAsync = new GraphitiAsyncService(
13371336
{
13381337
getEpisodes() {
@@ -1341,55 +1340,57 @@ describe("hot-tier vertical slice", () => {
13411340
searchMemoryFacts() {
13421341
return Promise.resolve([]);
13431342
},
1344-
searchNodesWithStatus(input: { query: string; groupIds: string[] }) {
1345-
refreshCalls.push({ groupId: input.groupIds[0], query: input.query });
1343+
searchNodesWithStatus() {
13461344
return Promise.resolve({ nodes: [], degraded: false });
13471345
},
13481346
} as never,
13491347
redisCache,
13501348
{
13511349
drainGroup(groupId: string) {
13521350
drainCalls.push(groupId);
1353-
callCount += 1;
1354-
if (callCount === 1) return neverSettles;
1355-
if (callCount === 2) {
1356-
return Promise.resolve({ status: "success" as const, drained: 1 });
1357-
}
1358-
return Promise.resolve({ status: "empty" as const, drained: 0 });
1351+
return neverSettles;
13591352
},
13601353
} as never,
13611354
1,
1355+
1,
13621356
);
13631357

1364-
const drainRecoveryTimers = (
1365-
graphitiAsync as unknown as {
1366-
drainRecoveryTimers: Map<
1367-
string,
1368-
{ run: Promise<void>; timer: ReturnType<typeof setTimeout> }
1369-
>;
1370-
}
1371-
).drainRecoveryTimers;
1358+
try {
1359+
const drainRecoveryTimers = (
1360+
graphitiAsync as unknown as {
1361+
drainRecoveryTimers: Map<
1362+
string,
1363+
{ run: Promise<void>; timer: ReturnType<typeof setTimeout> }
1364+
>;
1365+
}
1366+
).drainRecoveryTimers;
13721367

1373-
graphitiAsync.scheduleDrain("group-1");
1374-
await new Promise((resolve) => setTimeout(resolve, 0));
1375-
graphitiAsync.scheduleDrain("group-1");
1376-
graphitiAsync.scheduleDrain("group-1");
1368+
graphitiAsync.scheduleDrain("group-1");
1369+
await new Promise((resolve) => setTimeout(resolve, 0));
1370+
graphitiAsync.scheduleDrain("group-1");
1371+
graphitiAsync.scheduleDrain("group-1");
13771372

1378-
assertEquals(drainRecoveryTimers.size, 1);
1373+
assertEquals(drainRecoveryTimers.size, 1);
13791374

1380-
await waitFor(() => drainCalls.length === 3);
1381-
await new Promise((resolve) => setTimeout(resolve, 0));
1382-
await new Promise((resolve) => setTimeout(resolve, 0));
1375+
await waitFor(() => warnSpy.calls.length === 1);
1376+
await new Promise((resolve) => setTimeout(resolve, 0));
13831377

1384-
assertEquals(drainCalls, ["group-1", "group-1", "group-1"]);
1385-
assertEquals(refreshCalls, [{
1386-
groupId: "group-1",
1387-
query: "cached query",
1388-
}]);
1389-
assertEquals(drainRecoveryTimers.size, 0);
1378+
assertEquals(drainCalls, ["group-1"]);
1379+
assertEquals(
1380+
warnSpy.calls[0].args[0],
1381+
"Graphiti drain recovery timeout exceeded; leaving in-flight drain intact",
1382+
);
1383+
assertEquals(warnSpy.calls[0].args[1], {
1384+
groupId: "group-1",
1385+
timeoutMs: 1,
1386+
});
1387+
assertEquals(drainRecoveryTimers.size, 0);
1388+
} finally {
1389+
warnSpy.restore();
1390+
}
13901391
});
13911392

1392-
it("recovers a stuck drain even without a duplicate schedule signal", async () => {
1393+
it("warns on a stuck drain even without a duplicate schedule signal", async () => {
13931394
const redis = new RedisClient({ endpoint: "redis://unused" });
13941395
const redisCache = new RedisCacheService(redis, {
13951396
ttlSeconds: 300,
@@ -1405,8 +1406,7 @@ describe("hot-tier vertical slice", () => {
14051406

14061407
const neverSettles = new Promise<never>(() => {});
14071408
const drainCalls: string[] = [];
1408-
const refreshCalls: Array<{ groupId: string; query: string }> = [];
1409-
let callCount = 0;
1409+
const warnSpy = spy(logger, "warn");
14101410
const graphitiAsync = new GraphitiAsyncService(
14111411
{
14121412
getEpisodes() {
@@ -1415,37 +1415,39 @@ describe("hot-tier vertical slice", () => {
14151415
searchMemoryFacts() {
14161416
return Promise.resolve([]);
14171417
},
1418-
searchNodesWithStatus(input: { query: string; groupIds: string[] }) {
1419-
refreshCalls.push({ groupId: input.groupIds[0], query: input.query });
1418+
searchNodesWithStatus() {
14201419
return Promise.resolve({ nodes: [], degraded: false });
14211420
},
14221421
} as never,
14231422
redisCache,
14241423
{
14251424
drainGroup(groupId: string) {
14261425
drainCalls.push(groupId);
1427-
callCount += 1;
1428-
if (callCount === 1) return neverSettles;
1429-
if (callCount === 2) {
1430-
return Promise.resolve({ status: "success" as const, drained: 1 });
1431-
}
1432-
return Promise.resolve({ status: "empty" as const, drained: 0 });
1426+
return neverSettles;
14331427
},
14341428
} as never,
14351429
1,
1430+
1,
14361431
);
14371432

1438-
graphitiAsync.scheduleDrain("group-1");
1433+
try {
1434+
graphitiAsync.scheduleDrain("group-1");
14391435

1440-
await waitFor(() => drainCalls.length === 3);
1441-
await new Promise((resolve) => setTimeout(resolve, 0));
1442-
await new Promise((resolve) => setTimeout(resolve, 0));
1436+
await waitFor(() => warnSpy.calls.length === 1);
1437+
await new Promise((resolve) => setTimeout(resolve, 0));
14431438

1444-
assertEquals(drainCalls, ["group-1", "group-1", "group-1"]);
1445-
assertEquals(refreshCalls, [{
1446-
groupId: "group-1",
1447-
query: "cached query",
1448-
}]);
1439+
assertEquals(drainCalls, ["group-1"]);
1440+
assertEquals(
1441+
warnSpy.calls[0].args[0],
1442+
"Graphiti drain recovery timeout exceeded; leaving in-flight drain intact",
1443+
);
1444+
assertEquals(warnSpy.calls[0].args[1], {
1445+
groupId: "group-1",
1446+
timeoutMs: 1,
1447+
});
1448+
} finally {
1449+
warnSpy.restore();
1450+
}
14491451
});
14501452

14511453
it("preserves warm cache entry when refresh degrades during node search", async () => {

0 commit comments

Comments
 (0)