test: prove reassignment waits on the human comment transaction

Observe the PostgreSQL lock wait before releasing the competing write, so the race regression does not depend on scheduler timing.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-09-30 18:09:38 -05:00
1 parent 6f17fa0807
commit 7451b075ca
1 file changed
+22 -5
@@ -129,11 +129,28 @@ const support = await getEmbeddedPostgresTestSupport();
await held;
});
await ready;
// Start the competing update while the comment transaction still owns the row.
const reassignment = db.update(issues).set({ assigneeAgentId: f.other.id })
.where(eq(issues.id, issue.id)).execute();
release();
await Promise.all([commentWrite, reassignment]);
let started!: (pid: number) => void;
const waiter = new Promise<number>((resolve) => { started = resolve; });
const reassignment = db.transaction(async (tx) => {
const [backend] = await tx.execute(sql`select pg_backend_pid() as pid`);
started(Number(backend.pid));
await tx.update(issues).set({ assigneeAgentId: f.other.id }).where(eq(issues.id, issue.id));
});
try {
const pid = await waiter;
const deadline = Date.now() + 5_000;
let blocked = false;
// Observe an actual PostgreSQL lock wait, not merely two queued promises.
while (Date.now() < deadline) {
const [state] = await db.execute(sql`select cardinality(pg_blocking_pids(${pid}::int)) > 0 as blocked`);
if (state.blocked === true) { blocked = true; break; }
await new Promise((resolve) => setTimeout(resolve, 10));
}
expect(blocked).toBe(true);
} finally {
release();
await Promise.all([commentWrite, reassignment]);
}
expect(await db.select().from(issueHumanWorkGrants).where(eq(issueHumanWorkGrants.issueId, issue.id))).toHaveLength(0);
await issueService(db).addComment(issue.id, "New instruction", { userId: "owner" }, { humanDirectedByUserId: "owner" });
expect(await db.select().from(issueHumanWorkGrants).where(eq(issueHumanWorkGrants.issueId, issue.id)))