Skip to content

Commit fe25cf5

Browse files
committed
fix(capacity): parse scheduling-row quantities with the shared Quantity parser
The byte parser's suffix table stops at Ti and falls back to the bare number, so a 1PiB aggregate memory capacity read as 1 byte. The shared parser covers Pi/Ei and exponent forms; a zero-test on the raw string preserves the card's null-means-unknown contract.
1 parent db430c7 commit fe25cf5

2 files changed

Lines changed: 18 additions & 9 deletions

File tree

web/src/components/capacity/ClusterSchedulingCard.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
import { Badge } from "@skyhook-io/k8s-ui/components/ui/Badge";
88
import {
99
parseCPUToNanocores,
10-
parseMemoryToBytes,
10+
parseQuantityToNumber,
1111
} from "@skyhook-io/k8s-ui/utils/format";
1212
import {
1313
CertaintyGlyph,
@@ -96,16 +96,15 @@ export function quantityToNumber(
9696
}
9797
return null;
9898
}
99-
// Milli quantities before the byte parser — it ignores the `m` suffix and
100-
// would read 3000m as 3000, a 1000× distortion.
101-
const milli = /^(-?\d+(?:\.\d+)?)m$/.exec(value);
102-
if (milli) return Number(milli[1]) / 1000;
103-
const parsed = parseMemoryToBytes(value);
104-
if (Number.isFinite(parsed) && (parsed !== 0 || /^[0.]+\D*$/.test(value))) {
99+
// The shared parser knows the full suffix table — the byte parser stops at
100+
// Ti, so a 1PiB aggregate would read as 1 byte. It returns 0 for input it
101+
// cannot parse, so distinguish a real zero to preserve the null (= unknown,
102+
// not zero) contract of this card.
103+
const parsed = parseQuantityToNumber(value);
104+
if (parsed !== 0 || /^[+-]?[0.]+\D*$/.test(value)) {
105105
return parsed;
106106
}
107-
const plain = Number(value);
108-
return Number.isFinite(plain) ? plain : null;
107+
return null;
109108
}
110109

111110
function worstCertainty(

web/src/components/capacity/schedulingBar.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,16 @@ describe("quantityToNumber", () => {
202202
expect(quantityToNumber("example.com/widget", "3000m")).toBe(3);
203203
expect(quantityToNumber("cpu", "1500m")).toBe(1.5e9);
204204
});
205+
206+
// Aggregate memory on a large cluster reaches suffixes the byte parser
207+
// never knew (its table stops at Ti) — "1Pi" must not read as 1 byte.
208+
it("parses the large suffixes an aggregate capacity can carry", () => {
209+
expect(quantityToNumber("memory", "1Pi")).toBe(1024 ** 5);
210+
expect(quantityToNumber("memory", "1Ei")).toBe(1024 ** 6);
211+
expect(quantityToNumber("pods", "1k")).toBe(1000);
212+
expect(quantityToNumber("pods", "1e3")).toBe(1000);
213+
expect(quantityToNumber("memory", "0Gi")).toBe(0);
214+
});
205215
});
206216

207217
describe("claimStagesDetail", () => {

0 commit comments

Comments
 (0)