Files
fusion/packages/dashboard/scripts/__tests__/run-quality-tests.test.ts
gsxdsm 8f66a41c1c FN-6308: parallelize dashboard quality lanes
Reduce dashboard quality gate wall-clock by orchestrating existing Vitest lanes with bounded concurrency.

- Add a dashboard quality orchestrator that runs app/API lanes through the existing heap wrapper with safe concurrency and failure short-circuiting.
- Route dashboard quality scripts through the orchestrator while preserving compatibility lane scripts and shard boundaries.
- Export project glob metadata and strengthen guards for lane parity, heap usage, and settings route response expectations.
- Document the new dashboard quality orchestration model and measured FN-6308 timing results.

Files changed:
 docs/test-speed-audit-FN-5048.md                   |   8 +-
 docs/testing.md                                    |  35 +++-
 packages/dashboard/package.json                    |  14 +-
 .../scripts/__tests__/run-quality-tests.test.ts    | 110 ++++++++++
 packages/dashboard/scripts/run-quality-tests.mjs   | 221 +++++++++++++++++++++
 .../__tests__/dashboard-test-config-guard.test.ts  | 134 ++++++++++---
 .../src/__tests__/routes-settings.test.ts          |  14 +-
 packages/dashboard/vitest.config.ts                |  49 ++++-
 8 files changed, 540 insertions(+), 45 deletions(-)

Fusion-Task-Id: FN-6308

Fusion-Task-Lineage: 05a465fd-8eef-4c03-baa3-2b7cb024fef0
2026-06-12 18:18:24 -07:00

111 lines
3.7 KiB
TypeScript

// @vitest-environment node
import { describe, expect, it } from "vitest";
interface QualityLane {
name: string;
group: "app" | "api";
args: string[];
}
interface LaneResult {
lane: QualityLane;
ok: boolean;
code?: number;
signal?: NodeJS.Signals;
}
interface RunQualityTestsModule {
qualityLanes: QualityLane[];
resolveConcurrency(env?: Record<string, string | undefined>): number;
runQualityTests(options?: {
group?: "all" | "app" | "api";
concurrency?: number;
lanes?: QualityLane[];
runner?: (lane: QualityLane) => Promise<LaneResult>;
}): Promise<{ ok: boolean; failed: LaneResult[]; completed: number; skipped: number }>;
}
async function loadModule(): Promise<RunQualityTestsModule> {
return (await import("../run-quality-tests.mjs")) as RunQualityTestsModule;
}
function lane(name: string): QualityLane {
return { name, group: "app", args: ["--heap=6144", "run", "--project", name] };
}
describe("dashboard quality orchestrator", () => {
it("clamps dashboard quality concurrency to the safe bound", async () => {
const { resolveConcurrency } = await loadModule();
expect(resolveConcurrency({})).toBe(2);
expect(resolveConcurrency({ FUSION_DASHBOARD_TEST_CONCURRENCY: "1" })).toBe(1);
expect(resolveConcurrency({ FUSION_DASHBOARD_TEST_CONCURRENCY: "5" })).toBe(2);
expect(resolveConcurrency({ FUSION_DASHBOARD_TEST_CONCURRENCY: "not-a-number" })).toBe(2);
});
it("runs only up to the configured concurrency and does not invoke artifact bootstrap per lane", async () => {
const { runQualityTests } = await loadModule();
const lanes = [lane("one"), lane("two"), lane("three")];
const running = new Set<string>();
let maxRunning = 0;
const launched: string[] = [];
const result = await runQualityTests({
lanes,
concurrency: 2,
runner: async (qualityLane) => {
launched.push(qualityLane.name);
expect(qualityLane.args.join(" ")).not.toContain("ensure-test-artifacts");
running.add(qualityLane.name);
maxRunning = Math.max(maxRunning, running.size);
await Promise.resolve();
running.delete(qualityLane.name);
return { lane: qualityLane, ok: true };
},
});
expect(result).toMatchObject({ ok: true, completed: 3, skipped: 0 });
expect(result.failed).toEqual([]);
expect(launched).toEqual(["one", "two", "three"]);
expect(maxRunning).toBeLessThanOrEqual(2);
});
it("stops scheduling new lanes after a failed lane", async () => {
const { runQualityTests } = await loadModule();
const lanes = [lane("one"), lane("two"), lane("three")];
const launched: string[] = [];
const result = await runQualityTests({
lanes,
concurrency: 1,
runner: async (qualityLane) => {
launched.push(qualityLane.name);
return { lane: qualityLane, ok: qualityLane.name !== "two", code: qualityLane.name === "two" ? 1 : 0 };
},
});
expect(result.ok).toBe(false);
expect(result.failed).toHaveLength(1);
expect(result.failed[0].lane.name).toBe("two");
expect(result.skipped).toBe(1);
expect(launched).toEqual(["one", "two"]);
});
it("treats signal-terminated lanes as failed", async () => {
const { runQualityTests } = await loadModule();
const killedLane = lane("killed");
const result = await runQualityTests({
lanes: [killedLane],
concurrency: 2,
runner: async (qualityLane) => ({ lane: qualityLane, ok: false, signal: "SIGKILL" }),
});
expect(result.ok).toBe(false);
expect(result.failed).toEqual([{ lane: killedLane, ok: false, signal: "SIGKILL" }]);
expect(result.completed).toBe(1);
expect(result.skipped).toBe(0);
});
});