FN-9190: Add invalid concurrency resolver regression coverage
Cover invalid persisted maxConcurrent values across both public resolver entry points. - Add a shared matrix for zero, negative, non-finite, missing, and wrong-type values. - Verify effective ceilings remain finite and positive after fallback resolution. - Preserve binding and disabled worktree-limit behavior for every invalid value. Files changed: .../concurrency-capacity-resolver.test.ts | 68 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) Fusion-Task-Id: FN-9190 Fusion-Task-Lineage: aeb0daad-8f03-4835-a218-f45448c66c33 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
@@ -7,6 +7,26 @@ import {
|
||||
resolveMaxConcurrentSetting,
|
||||
} from "../workflows/workflow-capacity.js";
|
||||
|
||||
/*
|
||||
FNXC:CapacityModel 2026-08-22-00:09:
|
||||
FN-9189's surface audit requires invalid persisted maxConcurrent values to resolve identically through both exported entry points. Production callers use the effective ceiling, so this shared matrix protects it from leaking an invalid scalar after the fallback resolver sanitizes it.
|
||||
*/
|
||||
const INVALID_MAX_CONCURRENT_CASES = [
|
||||
["zero", 0],
|
||||
["negative", -3],
|
||||
["NaN", Number.NaN],
|
||||
["Infinity", Infinity],
|
||||
["-Infinity", -Infinity],
|
||||
["numeric string", "2"],
|
||||
["null", null],
|
||||
["undefined", undefined],
|
||||
["missing key", {}],
|
||||
] as const;
|
||||
|
||||
function invalidMaxConcurrentSettings(value: unknown) {
|
||||
return (value !== null && typeof value === "object" ? value : { maxConcurrent: value }) as never;
|
||||
}
|
||||
|
||||
describe("resolveEffectiveConcurrency", () => {
|
||||
it("uses shipped defaults for absent values", () => {
|
||||
expect(resolveEffectiveConcurrency(undefined)).toEqual({
|
||||
@@ -17,8 +37,52 @@ describe("resolveEffectiveConcurrency", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it.each([0, -3, Number.NaN, Infinity, "2", null])("rejects invalid maxConcurrent %j", (maxConcurrent) => {
|
||||
expect(resolveMaxConcurrentSetting({ maxConcurrent } as never)).toBe(DEFAULT_PROJECT_SETTINGS.maxConcurrent);
|
||||
it.each(INVALID_MAX_CONCURRENT_CASES)("falls back for invalid maxConcurrent: %s", (_label, value) => {
|
||||
expect(resolveMaxConcurrentSetting(invalidMaxConcurrentSettings(value))).toBe(DEFAULT_PROJECT_SETTINGS.maxConcurrent);
|
||||
});
|
||||
|
||||
it.each(INVALID_MAX_CONCURRENT_CASES)("returns a finite default effective ceiling for invalid maxConcurrent: %s", (_label, value) => {
|
||||
const resolved = resolveEffectiveConcurrency(invalidMaxConcurrentSettings(value));
|
||||
|
||||
expect(resolved).toEqual({
|
||||
maxConcurrent: DEFAULT_PROJECT_SETTINGS.maxConcurrent,
|
||||
worktreeLimit: DEFAULT_PROJECT_SETTINGS.maxWorktrees,
|
||||
effectiveLimit: DEFAULT_PROJECT_SETTINGS.maxConcurrent,
|
||||
bindingKnob: "maxConcurrent",
|
||||
});
|
||||
expect(Number.isFinite(resolved.maxConcurrent)).toBe(true);
|
||||
expect(resolved.maxConcurrent).toBeGreaterThan(0);
|
||||
expect(Number.isFinite(resolved.effectiveLimit)).toBe(true);
|
||||
expect(resolved.effectiveLimit).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it.each(INVALID_MAX_CONCURRENT_CASES)("keeps a binding worktree ceiling for invalid maxConcurrent: %s", (_label, value) => {
|
||||
const resolved = resolveEffectiveConcurrency({
|
||||
...invalidMaxConcurrentSettings(value),
|
||||
maxWorktrees: 1,
|
||||
worktreeLimitEnabled: true,
|
||||
});
|
||||
|
||||
expect(resolved).toEqual({
|
||||
maxConcurrent: DEFAULT_PROJECT_SETTINGS.maxConcurrent,
|
||||
worktreeLimit: 1,
|
||||
effectiveLimit: 1,
|
||||
bindingKnob: "maxWorktrees",
|
||||
});
|
||||
});
|
||||
|
||||
it.each(INVALID_MAX_CONCURRENT_CASES)("removes the worktree ceiling when disabled for invalid maxConcurrent: %s", (_label, value) => {
|
||||
const resolved = resolveEffectiveConcurrency({
|
||||
...invalidMaxConcurrentSettings(value),
|
||||
worktreeLimitEnabled: false,
|
||||
});
|
||||
|
||||
expect(resolved).toEqual({
|
||||
maxConcurrent: DEFAULT_PROJECT_SETTINGS.maxConcurrent,
|
||||
worktreeLimit: null,
|
||||
effectiveLimit: DEFAULT_PROJECT_SETTINGS.maxConcurrent,
|
||||
bindingKnob: "maxConcurrent",
|
||||
});
|
||||
});
|
||||
|
||||
it("honors configured values and names a binding worktree limit", () => {
|
||||
|
||||
Reference in New Issue
Block a user