chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user