import { describe, expect, it, vi } from "vitest"; // Importing `~/v3/mollifier/mollifierDrainer.server` (below) transitively // loads `~/v3/runEngine.server`, whose top-level `singleton(...)` call // eagerly constructs a RunEngine. That spins up Prisma + Redis workers // that try to connect to localhost — which in CI (no PG, no Redis) // produces an unhandled `PrismaClientInitializationError` that fails // the test run even though the assertions all pass. Mocking the // runEngine module short-circuits the singleton so no worker starts. vi.mock("~/v3/runEngine.server", () => ({ engine: {} })); // Same problem: prisma.server.ts's top-level singleton tries to open a // PG client. The test never makes a query; an empty stub is enough. vi.mock("~/db.server", () => ({ prisma: {}, $replica: {} })); import { MollifierConfigurationError } from "~/v3/mollifier/mollifierDrainer.server"; import { initMollifierDrainerWorker } from "~/v3/mollifierDrainerWorker.server"; // Pins the error-classification policy inside the bootstrap's catch: // deterministic misconfig errors propagate (so a deploy fails loud // rather than silently disabling the drainer), and anything else is // logged-and-swallowed (so a transient Redis blip during boot doesn't // take the whole webapp down). The corresponding production-path // integration is the call at `entry.server.tsx`: a sync throw out of // `initMollifierDrainerWorker` propagates to the module top level // BEFORE `process.on("uncaughtException", ...)` is registered, so Node // crashes with a stack trace and exit code 1 — which is exactly what we // want from the orchestrator's health-check perspective. describe("initMollifierDrainerWorker error classification", () => { it("rethrows MollifierConfigurationError so the process can crash on misconfig", () => { const misconfig = new MollifierConfigurationError( "TRIGGER_MOLLIFIER_DRAIN_SHUTDOWN_TIMEOUT_MS must be at least 1000ms below GRACEFUL_SHUTDOWN_TIMEOUT" ); expect(() => initMollifierDrainerWorker({ isEnabled: () => true, getDrainer: () => { throw misconfig; }, }) ).toThrow(MollifierConfigurationError); }); it("rethrows when the error carries the marker name even if instanceof fails (dev-realm hot-reload fallback)", () => { // Simulate the cross-realm case where the consumer's instanceof // check sees a different class instance from the one the throw // site used. The bootstrap's `.name === "MollifierConfigurationError"` // fallback must catch this so dev hot-reload doesn't silently // suppress misconfig errors. const cousin = new Error("buffer not initialised"); cousin.name = "MollifierConfigurationError"; expect(() => initMollifierDrainerWorker({ isEnabled: () => true, getDrainer: () => { throw cousin; }, }) ).toThrow(cousin); }); it("swallows non-configuration errors so transient init failures don't take the webapp down", () => { expect(() => initMollifierDrainerWorker({ isEnabled: () => true, getDrainer: () => { throw new Error("transient redis blip during buffer init"); }, }) ).not.toThrow(); }); it("is a no-op when the drainer is disabled for this replica", () => { let factoryCalled = false; initMollifierDrainerWorker({ isEnabled: () => false, getDrainer: () => { factoryCalled = true; return null; }, }); expect(factoryCalled).toBe(false); }); });