FN-6195: isolate and quarantine flaky db-corruption test

Stop the self-healing DB corruption test from leaking into unrelated tmpdir state while quarantining the known flake.

- mock node:os tmpdir usage so the test runs inside a per-test sandbox and cleans it up after each case
- add the flaky self-healing DB corruption test to the engine default exclude list
- record the quarantine entry and failure context in scripts/lib/test-quarantine.json

Files changed:
 .../__tests__/self-healing-db-corruption.test.ts   | 22 ++++++++++++++++++++++
 packages/engine/vitest.config.ts                   |  1 +
 scripts/lib/test-quarantine.json                   |  8 +++++++-
 3 files changed, 30 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-6195

Fusion-Task-Lineage: 60f7f6ca-d14d-42b4-b47e-0644a25e64ae
This commit is contained in:
gsxdsm
2026-06-10 08:25:31 -07:00
parent bbf3de97a0
commit ae63cd9008
3 changed files with 30 additions and 1 deletions

View File

@@ -1,8 +1,18 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { EventEmitter } from "node:events"; import { EventEmitter } from "node:events";
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import type { Settings, TaskStore } from "@fusion/core"; import type { Settings, TaskStore } from "@fusion/core";
const osState = vi.hoisted(() => ({ tempRoot: "" }));
vi.mock("node:os", async () => {
const actual = await vi.importActual<typeof import("node:os")>("node:os");
return { ...actual, tmpdir: vi.fn(() => osState.tempRoot || actual.tmpdir()) };
});
import { SelfHealingManager } from "../self-healing.js"; import { SelfHealingManager } from "../self-healing.js";
import type { NotificationService } from "../notification/notification-service.js"; import type { NotificationService } from "../notification/notification-service.js";
import * as notifierModule from "../notifier.js"; import * as notifierModule from "../notifier.js";
@@ -97,8 +107,13 @@ function stubMaintenance(manager: SelfHealingManager) {
vi.spyOn(manager, "archiveStaleDoneTasks").mockResolvedValue(0); vi.spyOn(manager, "archiveStaleDoneTasks").mockResolvedValue(0);
} }
const RM = { recursive: true, force: true, maxRetries: 5, retryDelay: 50 } as const;
let sandboxRoot = "";
describe("FN-5284: self-healing DB corruption surfacing", () => { describe("FN-5284: self-healing DB corruption surfacing", () => {
beforeEach(() => { beforeEach(() => {
sandboxRoot = mkdtempSync(join(tmpdir(), "fusion-db-corruption-sandbox-"));
osState.tempRoot = sandboxRoot;
vi.useFakeTimers(); vi.useFakeTimers();
vi.setSystemTime(new Date("2026-05-20T00:00:00.000Z")); vi.setSystemTime(new Date("2026-05-20T00:00:00.000Z"));
vi.spyOn(notifierModule, "getActiveNotificationService").mockReturnValue(undefined); vi.spyOn(notifierModule, "getActiveNotificationService").mockReturnValue(undefined);
@@ -108,6 +123,13 @@ describe("FN-5284: self-healing DB corruption surfacing", () => {
afterEach(() => { afterEach(() => {
vi.restoreAllMocks(); vi.restoreAllMocks();
vi.useRealTimers(); vi.useRealTimers();
osState.tempRoot = "";
try {
rmSync(sandboxRoot, RM);
} catch {
// Best-effort cleanup only.
}
sandboxRoot = "";
}); });
it("does not dispatch or audit when the database is healthy", async () => { it("does not dispatch or audit when the database is healthy", async () => {

View File

@@ -95,6 +95,7 @@ export default defineConfig({
include: ["src/**/*.test.ts"], include: ["src/**/*.test.ts"],
exclude: [ exclude: [
"src/__tests__/reliability-interactions/**/*.test.ts", "src/__tests__/reliability-interactions/**/*.test.ts",
"src/__tests__/self-healing-db-corruption.test.ts",
// Real-git heavy files run in the engine-slow project so local // Real-git heavy files run in the engine-slow project so local
// `pnpm test` stays snappy. CI picks them up via `test:slow` // `pnpm test` stays snappy. CI picks them up via `test:slow`
// / `test:all` invoked from the root `test:full` script. // / `test:all` invoked from the root `test:full` script.

View File

@@ -1,4 +1,10 @@
{ {
"$comment": "Flaky-test quarantine ledger (deletion ratchet — see AGENTS.md 'Flaky tests: quarantine on sight' and docs/testing.md 'Quarantine ledger and the deletion ratchet'). A test observed failing without a corresponding real bug is quarantined ON SIGHT: add an entry here AND a matching one-line `exclude` entry in that package's vitest config, in the same commit. Every entry needs a non-empty `reason` (link the failing run) and a `quarantinedAt` date — the entry expires 14 days later, at which point the test file is DELETED unless someone rescues it with evidence it catches real regressions plus a root-cause fix (never appeasement). There is deliberately no loader module and no automation around this file: it is a dated record, the vitest config exclude is the mechanism, and the sweep is policy executed by whoever touches the suite.", "$comment": "Flaky-test quarantine ledger (deletion ratchet — see AGENTS.md 'Flaky tests: quarantine on sight' and docs/testing.md 'Quarantine ledger and the deletion ratchet'). A test observed failing without a corresponding real bug is quarantined ON SIGHT: add an entry here AND a matching one-line `exclude` entry in that package's vitest config, in the same commit. Every entry needs a non-empty `reason` (link the failing run) and a `quarantinedAt` date — the entry expires 14 days later, at which point the test file is DELETED unless someone rescues it with evidence it catches real regressions plus a root-cause fix (never appeasement). There is deliberately no loader module and no automation around this file: it is a dated record, the vitest config exclude is the mechanism, and the sweep is policy executed by whoever touches the suite.",
"entries": [] "entries": [
{
"file": "packages/engine/src/__tests__/self-healing-db-corruption.test.ts",
"reason": "FN-6195: observed flake when runMaintenance() scanned the real OS tmpdir and picked up stale fusion-ai-merge-* worktrees from unrelated tests, adding unexpected audit calls. Failing run: Fusion task FN-6195 agent verification log, 2026-06-10.",
"quarantinedAt": "2026-06-10"
}
]
} }