FN-8077: stabilize quarantined test timing

Make previously quarantined CLI and dashboard tests deterministic.

- Use the shared PostgreSQL harness for project-context integration coverage.
- Control dashboard CPU sampling time with a fake Date-only clock.
- Remove both repaired tests from quarantine configuration and ledger.

Files changed:
 packages/cli/src/__tests__/project-context.test.ts | 103 +++++++++++++--------
 packages/cli/vitest.config.ts                      |   5 +-
 .../dashboard/src/__tests__/routes-system.test.ts  |  17 ++--
 packages/dashboard/vitest.config.ts                |   6 +-
 scripts/lib/test-quarantine.json                   |  10 --
 5 files changed, 76 insertions(+), 65 deletions(-)

Fusion-Task-Id: FN-8077

Fusion-Task-Lineage: 9a057928-3258-459a-9802-52f58df39c9a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-07-16 06:20:20 -07:00
parent de1638e262
commit 78245a48a3
5 changed files with 76 additions and 65 deletions

View File

@@ -24,16 +24,32 @@ import {
} from "../../../core/src/__test-utils__/pg-test-harness.js";
import { beforeAll, afterAll } from "vitest";
describe("project-context", () => {
/*
FNXC:ProjectContextTests 2026-07-16-09:00:
CentralCore tests require PostgreSQL, but booting its embedded postmaster for every test races other forked CLI files under load. Use the shared external pg test harness and skip only CentralCore coverage when PostgreSQL is unavailable; pure formatting coverage remains ungated below.
*/
pgDescribe("project-context (PostgreSQL-backed detection)", () => {
let h: PgTestHarness;
let tempDir: string;
let homeDir: string;
let central: CentralCore;
let previousDatabaseUrl: string | undefined;
const createdProjectIds: string[] = [];
beforeAll(async () => {
h = await createTaskStoreForTest({ prefix: "fusion_cli_project_ctx_detection" });
});
afterAll(async () => {
await h.teardown();
});
beforeEach(async () => {
previousDatabaseUrl = process.env.DATABASE_URL;
process.env.DATABASE_URL = h.testUrl;
tempDir = mkdtempSync(join(tmpdir(), "kb-test-"));
homeDir = mkdtempSync(join(tmpdir(), "kb-home-"));
central = new CentralCore(homeDir);
central = new CentralCore(homeDir, { asyncLayer: h.layer });
await central.init();
});
@@ -56,6 +72,11 @@ describe("project-context", () => {
// Ignore close errors
}
await clearStoreCache();
if (previousDatabaseUrl === undefined) {
delete process.env.DATABASE_URL;
} else {
process.env.DATABASE_URL = previousDatabaseUrl;
}
// Filesystem cleanup last
try {
@@ -132,45 +153,6 @@ describe("project-context", () => {
});
});
describe("formatProjectLine", () => {
it("should format default project with asterisk", () => {
const project: RegisteredProject = {
id: "proj_123",
name: "my-app",
path: "/path/to/app",
status: "active",
isolationMode: "in-process",
createdAt: "2024-01-01T00:00:00Z",
updatedAt: "2024-01-01T00:00:00Z",
};
const line = formatProjectLine(project, true);
expect(line).toContain("* ");
expect(line).toContain("my-app");
expect(line).toContain("/path/to/app");
expect(line).toContain("[active]");
});
it("should format non-default project without asterisk", () => {
const project: RegisteredProject = {
id: "proj_456",
name: "other-app",
path: "/path/to/other",
status: "paused",
isolationMode: "child-process",
createdAt: "2024-01-01T00:00:00Z",
updatedAt: "2024-01-01T00:00:00Z",
};
const line = formatProjectLine(project, false);
expect(line).not.toContain("*");
expect(line).toContain("other-app");
expect(line).toContain("[paused]");
});
});
describe("resolveProject", () => {
it("should throw for unknown project name", async () => {
await expect(resolveProject("unknown-project", tempDir, homeDir)).rejects.toThrow(
@@ -195,6 +177,45 @@ describe("project-context", () => {
});
});
describe("formatProjectLine", () => {
it("should format default project with asterisk", () => {
const project: RegisteredProject = {
id: "proj_123",
name: "my-app",
path: "/path/to/app",
status: "active",
isolationMode: "in-process",
createdAt: "2024-01-01T00:00:00Z",
updatedAt: "2024-01-01T00:00:00Z",
};
const line = formatProjectLine(project, true);
expect(line).toContain("* ");
expect(line).toContain("my-app");
expect(line).toContain("/path/to/app");
expect(line).toContain("[active]");
});
it("should format non-default project without asterisk", () => {
const project: RegisteredProject = {
id: "proj_456",
name: "other-app",
path: "/path/to/other",
status: "paused",
isolationMode: "child-process",
createdAt: "2024-01-01T00:00:00Z",
updatedAt: "2024-01-01T00:00:00Z",
};
const line = formatProjectLine(project, false);
expect(line).not.toContain("*");
expect(line).toContain("other-app");
expect(line).toContain("[paused]");
});
});
/*
FNXC:PostgresCutover 2026-07-05-17:30:
PostgreSQL-backed CentralCore coverage for project-context. The legacy SQLite

View File

@@ -93,10 +93,9 @@ const quarantinedCliTests: string[] = [
*/
"src/__tests__/extension-dist-barrel.test.ts",
/*
FNXC:CliTests 2026-07-14-23:05:
project-context.test.ts lost its embedded PostgreSQL postmaster and timed out only in a combined focused lane, then passed 12/12 in isolation. Quarantine the loaded-lane cluster interference on sight instead of widening hooks, retrying, or weakening lifecycle assertions; mirrored in scripts/lib/test-quarantine.json.
FNXC:CliTests 2026-07-16-09:00:
FN-8077 removed project-context.test.ts from this list and the ledger in lockstep. Its CentralCore coverage now uses the external PostgreSQL test harness under pgDescribe rather than launching an embedded postmaster for each test in forked loaded lanes; pure formatting coverage remains ungated.
*/
"src/__tests__/project-context.test.ts",
];
export default defineConfig({

View File

@@ -429,7 +429,13 @@ describe("GET /api/system-stats", () => {
it("returns process/system metrics with task and agent aggregates", async () => {
const cpuUsageSpy = vi.spyOn(process, "cpuUsage");
const dateNowSpy = vi.spyOn(Date, "now");
/*
FNXC:DashboardCpuSampling 2026-07-16-09:00:
CPU sampling measures the delta between two route-owned Date.now() values. Fake only Date and explicitly advance it between requests so unrelated Express and I/O clock reads cannot inflate the sampling interval under a loaded lane.
*/
vi.useFakeTimers({ toFake: ["Date"] });
const sampleStart = new Date("2026-07-16T00:00:00.000Z");
vi.setSystemTime(sampleStart);
cpuUsageSpy
.mockReturnValueOnce({ user: 1_000_000, system: 500_000 })
.mockImplementation((previousValue?: NodeJS.CpuUsage) => {
@@ -438,12 +444,6 @@ describe("GET /api/system-stats", () => {
}
return { user: 1_200_000, system: 600_000 };
});
let now = 1_000;
dateNowSpy.mockImplementation(() => {
now += 1_000;
return now;
});
const store = createMockStore({
listTasks: vi.fn().mockResolvedValue([
{ id: "FN-1", column: "triage" },
@@ -495,6 +495,7 @@ describe("GET /api/system-stats", () => {
}),
);
vi.setSystemTime(new Date(sampleStart.getTime() + 1_000));
const secondRes = await GET(app, "/api/system-stats");
expect(secondRes.status).toBe(200);
expect(secondRes.body.systemStats.cpuPercent).toBe(30);
@@ -521,7 +522,7 @@ describe("GET /api/system-stats", () => {
expect(res.body.vitestLastAutoKillAt).toBeNull();
cpuUsageSpy.mockRestore();
dateNowSpy.mockRestore();
vi.useRealTimers();
mockExecFile.mockClear();
});

View File

@@ -328,10 +328,10 @@ deleted per the AGENTS.md deletion ratchet (14 days expired, not rescued).
Ledger entries removed from scripts/lib/test-quarantine.json in the same commit.
The array stays empty; add new entries here only with a matching ledger row.
FNXC:DashboardTestQuarantine 2026-07-14-18:48:
PostgreSQL maintainability verification observed routes-system.test.ts return a timing-sensitive CPU sample of 10 where the test expected 30. Quarantine the unrelated flake under the deletion ratchet without changing its timeout, retries, or assertion; mirror the entry in scripts/lib/test-quarantine.json.
FNXC:DashboardTestQuarantine 2026-07-16-09:00:
FN-8077 removed routes-system.test.ts from this list and the ledger in lockstep. Its test now explicitly advances a fake Date-only clock between CPU samples, so unrelated route clock reads cannot stretch elapsed time under the loaded API lane; assertions and timeout policy are unchanged.
*/
const quarantinedDashboardTests: string[] = ["src/__tests__/routes-system.test.ts"];
const quarantinedDashboardTests: string[] = [];
const qualityApiTests = [
// Critical HTTP/server behavior: auth, task/project/settings mutation,

View File

@@ -150,16 +150,6 @@
"file": "packages/engine/src/__tests__/reliability-interactions/post-done-continuation-no-wedge.test.ts",
"reason": "VAL-REMOVAL-005 PG migration: reliability fixture uses PG-backed store but sync APIs (getRunAuditEvents, getDatabase) fail in backend mode. Failing run: https://github.com/Runfusion/Fusion/actions/runs/29344576232. Mirrored in packages/engine/vitest.config.ts.",
"quarantinedAt": "2026-07-14"
},
{
"file": "packages/dashboard/src/__tests__/routes-system.test.ts",
"reason": "PostgreSQL maintainability verification on 2026-07-14 observed the CPU sampling assertion near line 500 receive 10 when 30 was expected during the local file-scoped `pnpm --filter @fusion/dashboard exec vitest run packages/dashboard/src/__tests__/routes-system.test.ts` run. Archived local-run evidence: https://github.com/Runfusion/Fusion/pull/2109#discussion_r3584473782. The unrelated sampling result is timing/load-sensitive, so quarantine the file on sight instead of changing its timeout, retries, or assertion. Mirrored in packages/dashboard/vitest.config.ts quarantinedDashboardTests.",
"quarantinedAt": "2026-07-14"
},
{
"file": "packages/cli/src/__tests__/project-context.test.ts",
"reason": "PR #2110 feedback verification on 2026-07-14 observed the embedded PostgreSQL postmaster exit unexpectedly in a combined file-scoped CLI run, followed by ECONNREFUSED, 10s hook timeouts, and the subprocess guard; the unchanged suite passed 12/12 immediately in isolation. Archived local-run evidence: https://github.com/Runfusion/Fusion/pull/2110#issuecomment-4977406152. The loaded-lane embedded-cluster interference is timing/resource-sensitive, so quarantine the file on sight instead of widening timeouts, adding retries, or weakening assertions. Mirrored in packages/cli/vitest.config.ts quarantinedCliTests.",
"quarantinedAt": "2026-07-14"
}
]
}