FN-6447: rescue session reconnect teardown
Rescue the session reconnect SSE test by shutting down route-owned background work before temp cleanup. - Isolate the focused API harness from TaskStore EventEmitter startup workers. - Dispose API routes and scheduled AI session cleanup before deleting the test temp root. - Remove session-reconnect from the dashboard quarantine ledger and vitest skip list. Files changed: .../src/__tests__/session-reconnect.test.ts | 22 ++++++++++++++++++---- packages/dashboard/vitest.config.ts | 6 ++++-- scripts/lib/test-quarantine.json | 5 ----- 3 files changed, 22 insertions(+), 11 deletions(-) Fusion-Task-Id: FN-6447 Fusion-Task-Lineage: a3fef28c-b92b-4f47-9181-a63bb31e4f48
This commit is contained in:
@@ -9,7 +9,6 @@ import express from "express";
|
||||
import { mkdtempSync } from "node:fs";
|
||||
import { rm } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { setImmediate } from "node:timers";
|
||||
import { join } from "node:path";
|
||||
import { beforeEach, afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { Database, TaskStore } from "@fusion/core";
|
||||
@@ -105,6 +104,7 @@ describe("session reconnect + replay", () => {
|
||||
let db: Database;
|
||||
let aiSessionStore: AiSessionStore;
|
||||
let app: express.Express;
|
||||
let apiRouter: express.Router & { dispose?: () => void };
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.clearAllMocks();
|
||||
@@ -129,7 +129,16 @@ describe("session reconnect + replay", () => {
|
||||
|
||||
app = express();
|
||||
app.use(express.json());
|
||||
app.use("/api", createApiRoutes(store, { aiSessionStore }));
|
||||
/*
|
||||
FNXC:DashboardSessionTests 2026-06-14-12:05:
|
||||
These SSE replay tests exercise planning/subtask/mission routes, not the EventEmitter-driven GitHub tracking services that createApiRoutes starts for a full TaskStore. Hide on/off for this focused harness so unrelated startup reconcile work cannot touch the temp .fusion tree after the test-owned store closes.
|
||||
*/
|
||||
Object.defineProperties(store, {
|
||||
on: { value: undefined, configurable: true },
|
||||
off: { value: undefined, configurable: true },
|
||||
});
|
||||
apiRouter = createApiRoutes(store, { aiSessionStore }) as express.Router & { dispose?: () => void };
|
||||
app.use("/api", apiRouter);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
@@ -138,6 +147,12 @@ describe("session reconnect + replay", () => {
|
||||
__resetSubtaskBreakdownState();
|
||||
__resetMissionInterviewState();
|
||||
|
||||
try {
|
||||
apiRouter.dispose?.();
|
||||
} catch {
|
||||
// no-op
|
||||
}
|
||||
aiSessionStore.stopScheduledCleanup();
|
||||
try {
|
||||
store.close();
|
||||
} catch {
|
||||
@@ -148,8 +163,7 @@ describe("session reconnect + replay", () => {
|
||||
} catch {
|
||||
// no-op
|
||||
}
|
||||
// FNXC:DashboardSessionTests 2026-06-14-09:20: TaskStore.close() closes watcher/database handles synchronously but their filesystem close callbacks settle on the next event-loop turn; drain that turn before deleting .fusion.
|
||||
await new Promise<void>((resolve) => setImmediate(resolve));
|
||||
// FNXC:DashboardSessionTests 2026-06-14-12:07: FN-6447 requires teardown to remove tmpRoot only after route-owned background workers are prevented/disposed and both TaskStore/AiSession DB handles are closed; do not use retry-rm loops that can mask a live writer.
|
||||
await rm(tmpRoot, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
|
||||
@@ -246,7 +246,10 @@ const quarantinedDashboardTests: string[] = [
|
||||
FN-6441 removed the dashboard component orphan batch from the curated skip-list so passing rescues run in backfill and still-failing tests are excluded only through the dated quarantine ledger. Keep these one-line excludes mirrored with scripts/lib/test-quarantine.json until each file is rescued or deleted under the deletion ratchet.
|
||||
|
||||
FNXC:DashboardTests 2026-06-14-09:58:
|
||||
FN-6444 applies the same no-silent-orphan invariant to dashboard src route/API tests: rescued files run in backfill, while broad stale mission/planning suites plus the newly observed FN-6447 reconnect temp-cleanup flake are represented only by the dated quarantine ledger.
|
||||
FN-6444 applies the same no-silent-orphan invariant to dashboard src route/API tests: rescued files run in backfill, while broad stale mission/planning suites are represented only by the dated quarantine ledger.
|
||||
|
||||
FNXC:DashboardSessionTests 2026-06-14-12:10:
|
||||
FN-6447 rescued session-reconnect by isolating the SSE harness from unrelated route background workers, so it must stay out of this quarantine list and run in dashboard-api-quality-backfill.
|
||||
*/
|
||||
"app/components/__tests__/ChatView.regular-composer-no-right-line.test.tsx",
|
||||
"app/components/__tests__/MissionManager.test.tsx",
|
||||
@@ -261,7 +264,6 @@ const quarantinedDashboardTests: string[] = [
|
||||
"app/components/__tests__/mobile-css.test.tsx",
|
||||
"src/__tests__/mission-e2e.test.ts",
|
||||
"src/__tests__/planning.test.ts",
|
||||
"src/__tests__/session-reconnect.test.ts",
|
||||
];
|
||||
|
||||
const qualityApiTests = [
|
||||
|
||||
@@ -65,11 +65,6 @@
|
||||
"file": "packages/dashboard/src/__tests__/planning.test.ts",
|
||||
"reason": "FN-6444: orphaned dashboard planning route/API test is slow and fails standalone across stale agent/session mocks plus temp cleanup leakage. Quarantined instead of widening waits/timeouts or weakening assertions.",
|
||||
"quarantinedAt": "2026-06-14"
|
||||
},
|
||||
{
|
||||
"file": "packages/dashboard/src/__tests__/session-reconnect.test.ts",
|
||||
"reason": "FN-6444/FN-6447: dashboard API backfill shard 1 observed ENOTEMPTY temp cleanup leakage while replaying planning buffered events. Quarantined on sight for focused rescue/delete review instead of adding waits or weakening assertions.",
|
||||
"quarantinedAt": "2026-06-14"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user