Make metrics reflect autoscaling policies (Refs #137)
CI / checks (push) Successful in 4m49s
CI / checks (push) Successful in 4m49s
This commit is contained in:
@@ -8,6 +8,7 @@ const report = (days: number) => ({
|
||||
now: 1000,
|
||||
since: 0,
|
||||
summary: totals,
|
||||
running: { average: null, peak: 0, capturedHours: 0 },
|
||||
points: [],
|
||||
maps: [],
|
||||
servers: [],
|
||||
@@ -22,12 +23,20 @@ const report = (days: number) => ({
|
||||
since: -1000,
|
||||
until: 0,
|
||||
summary: totals,
|
||||
running: { average: null, peak: 0, capturedHours: 0 },
|
||||
firstSampleAt: null,
|
||||
lastSampleAt: null,
|
||||
partialHistory: true
|
||||
},
|
||||
heatmap: { timeZone: 'UTC', cells: [] },
|
||||
pooledPressure: { value: null, fullMapHours: 0, knownMapHours: 0, coveredMaps: 0, totalMaps: 0 }
|
||||
pooledAvailability: {
|
||||
value: null,
|
||||
noEmptyMapHours: 0,
|
||||
knownMapHours: 0,
|
||||
unknownMapHours: 0,
|
||||
coveredMaps: 0,
|
||||
totalMaps: 0
|
||||
}
|
||||
});
|
||||
function setup(fetcher: typeof fetch) {
|
||||
let query = 'days=7';
|
||||
@@ -124,6 +133,63 @@ describe('metrics background refresh', () => {
|
||||
expect(refresh.onLoading).toHaveBeenLastCalledWith(false);
|
||||
});
|
||||
|
||||
it('accepts availability reports and rejects incomplete running or policy evidence', async () => {
|
||||
const value = {
|
||||
...report(7),
|
||||
maps: [
|
||||
{
|
||||
...totals,
|
||||
game: 't5',
|
||||
map: 'Moon',
|
||||
noEmpty: 0,
|
||||
availabilityObserved: 0,
|
||||
availabilityUnknown: 1,
|
||||
noEmptyAtMaximum: 0,
|
||||
noEmptyBelowMaximum: 0,
|
||||
policy: {
|
||||
id: 'moon',
|
||||
mode: 'create-destroy',
|
||||
minimum: 1,
|
||||
maximum: 3,
|
||||
spares: 1,
|
||||
pausedReason: null
|
||||
}
|
||||
}
|
||||
],
|
||||
points: [
|
||||
{
|
||||
...totals,
|
||||
at: 0,
|
||||
startAt: 0,
|
||||
endAt: 1000,
|
||||
partial: true,
|
||||
capturedHours: 1 / 3600
|
||||
}
|
||||
]
|
||||
};
|
||||
const invalid = [
|
||||
{ ...value, running: undefined },
|
||||
{ ...value, previous: { ...value.previous, running: undefined } },
|
||||
{ ...value, maps: [{ ...value.maps[0], policy: { id: 'moon' } }] },
|
||||
{ ...value, maps: [{ ...value.maps[0], availabilityUnknown: undefined }] },
|
||||
{ ...value, points: [{ ...value.points[0], capturedHours: undefined }] },
|
||||
{ ...value, pooledAvailability: undefined }
|
||||
];
|
||||
const fetcher = vi.fn();
|
||||
for (const incomplete of invalid) fetcher.mockResolvedValueOnce(Response.json(incomplete));
|
||||
fetcher.mockResolvedValueOnce(Response.json(value));
|
||||
const refresh = setup(fetcher);
|
||||
for (const _ of invalid) {
|
||||
await refresh.refresh();
|
||||
expect(refresh.onData).not.toHaveBeenCalled();
|
||||
expect(refresh.onError).toHaveBeenLastCalledWith(
|
||||
'The metrics response was incomplete.'
|
||||
);
|
||||
}
|
||||
await refresh.refresh();
|
||||
expect(refresh.onData).toHaveBeenLastCalledWith(value);
|
||||
});
|
||||
|
||||
it('times out with retry feedback and clears loading', async () => {
|
||||
vi.useFakeTimers();
|
||||
const fetcher = vi.fn(
|
||||
|
||||
Reference in New Issue
Block a user