Files
AgentHub/server/__tests__/read-pool.test.js
T
nntrivi2001 198fbb7980 fix: event-loop freezes, plugin-install boot crash, tmux attach/scrollbar, Codex transcripts
- GET /api/workflows: one LEAD() window pass in a read worker (read-pool.js,
  workflow-stats.js); idx_events_session restored, idx_events_tool added
- compat-sqlite gains function/pluck/readonly so a plugin install without a
  better-sqlite3 build boots again; antigravity-usage uses db.js's Database
- install-hooks adds no checkout hooks while the agenthub plugin is enabled
  (events were doubled)
- terminal attach runs the live tmux server's own binary; the pane scrollbar
  gets a visible 2-column style, and claude panes start with
  CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1 so tmux keeps history to scroll
- Codex sessions' conversation in GET /api/sessions/:id/transcript
- Codex/Antigravity sessions claimed by their workspace without hooks
- UI-audit follow-ups, docs and OpenAPI
2026-10-05 17:01:05 +07:00

73 lines
2.7 KiB
JavaScript

/**
* @file Tests server/lib/read-pool.js: a read job runs in the worker on its own
* connection, identical calls in flight share one run, a job over the timeout
* is refused with EREADTIMEOUT and the next one gets a fresh worker, and
* AGENTHUB_READ_WORKER=0 runs the job inline.
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
*/
const { describe, it, before, after, afterEach } = require("node:test");
const assert = require("node:assert/strict");
const fs = require("fs");
const os = require("os");
const path = require("path");
const TEST_DB = path.join(os.tmpdir(), `dashboard-readpool-test-${Date.now()}-${process.pid}.db`);
process.env.DASHBOARD_DB_PATH = TEST_DB;
const { db } = require("../db");
const { runRead } = require("../lib/read-pool");
before(() => {
db.prepare("INSERT INTO sessions (id, status) VALUES ('rp-1', 'completed')").run();
const ins = db.prepare(
"INSERT INTO events (session_id, event_type, tool_name) VALUES ('rp-1', 'PreToolUse', ?)"
);
for (const t of ["Read", "Edit", "Read", "Edit"]) ins.run(t);
});
afterEach(() => {
delete process.env.AGENTHUB_READ_TIMEOUT_MS;
delete process.env.AGENTHUB_READ_WORKER;
});
after(() => {
try {
db.close();
} catch {}
for (const s of ["", "-wal", "-shm"]) fs.rmSync(TEST_DB + s, { force: true });
});
describe("read-pool", () => {
it("runs a job in the worker and sees the main connection's committed rows", async () => {
const data = await runRead("workflows", { sections: ["toolFlow"] });
assert.deepEqual(data.toolFlow.transitions.map((t) => [t.source, t.target, t.value]).sort(), [
["Edit", "Read", 1],
["Read", "Edit", 2],
]);
});
it("shares one run between identical calls in flight", async () => {
const a = runRead("workflows", { sections: ["stats"] });
const b = runRead("workflows", { sections: ["stats"] });
assert.equal(a, b);
assert.notEqual(a, runRead("workflows", { sections: ["toolFlow"] }));
await Promise.all([a, b]);
});
it("refuses a job over the timeout, then recovers with a fresh worker", async () => {
process.env.AGENTHUB_READ_TIMEOUT_MS = "1";
await assert.rejects(runRead("workflows", { tag: "slow" }), { code: "EREADTIMEOUT" });
delete process.env.AGENTHUB_READ_TIMEOUT_MS;
const data = await runRead("workflows", { sections: ["stats"] });
assert.equal(data.stats.totalSessions, 1);
});
it("runs inline with AGENTHUB_READ_WORKER=0, and rejects an unknown job", async () => {
process.env.AGENTHUB_READ_WORKER = "0";
const data = await runRead("workflows", { sections: ["stats"], tag: "inline" });
assert.equal(data.stats.topFlow.source, "Read");
await assert.rejects(runRead("nope"), { code: "EBADJOB" });
});
});