import { expect, test } from "vitest"; import { CatalogOperationCoordinator } from "../src/catalog/operation-coordinator.js"; test("releases earlier database reservations when a batch reservation cannot be completed", async () => { const coordinator = new CatalogOperationCoordinator(); const releaseBusyDatabase = coordinator.reserve("database-b"); await expect(coordinator.runMany(["database-a", "database-b"], async () => "unreachable")) .rejects.toThrow("A database operation is already in progress"); expect(await coordinator.run("database-a", async () => "available")).toBe("available"); releaseBusyDatabase(); }); test("reserves duplicate database ids only once for a batch operation", async () => { const coordinator = new CatalogOperationCoordinator(); expect(await coordinator.runMany(["database-a", "database-a"], async () => "completed")) .toBe("completed"); }); test("stale generation recovery releases only its own reservation token", () => { const coordinator = new CatalogOperationCoordinator(); const releaseOtherOperation = coordinator.reserve("database-a"); coordinator.releaseStale("database-a", "description_generation"); expect(() => coordinator.reserve("database-a")).toThrow( "A database operation is already in progress", ); releaseOtherOperation(); const releaseStaleGeneration = coordinator.reserve("database-a", "description_generation"); coordinator.releaseStale("database-a", "description_generation"); const releaseNewOperation = coordinator.reserve("database-a"); releaseStaleGeneration(); expect(() => coordinator.reserve("database-a")).toThrow( "A database operation is already in progress", ); releaseNewOperation(); });