Replace instance metrics with map lobby counts (Refs #139)
CI / checks (push) Successful in 4m55s
CI / checks (push) Successful in 4m55s
This commit is contained in:
@@ -77,6 +77,7 @@ describe('historical metrics', () => {
|
||||
});
|
||||
expect(result.maps).toHaveLength(1);
|
||||
expect(result.maps[0].matches).toEqual(result.matches);
|
||||
expect(result.maps[0].running).toEqual({ average: null, peak: 0, capturedHours: 0 });
|
||||
expect(result.registeredServerCount).toBe(0);
|
||||
expect(result.servers).toEqual([]);
|
||||
expect(result.scopeOptions.maps).not.toContainEqual({ game: 't5', map: 'Future Map' });
|
||||
@@ -365,6 +366,8 @@ describe('historical metrics', () => {
|
||||
expect(later.maps[0].availabilityUnknown * 3600).toBeCloseTo(90);
|
||||
expect(later.pooledAvailability.value).toBeNull();
|
||||
expect(initial.running).toEqual({ average: null, peak: 0, capturedHours: 0 });
|
||||
expect(initial.maps[0].running).toEqual(initial.running);
|
||||
expect(later.maps[0].running).toEqual({ average: 1, peak: 1, capturedHours: 90 / 3600 });
|
||||
});
|
||||
|
||||
it('returns clipped interval boundaries and marks only partial UTC buckets', async () => {
|
||||
@@ -597,6 +600,7 @@ describe('historical metrics', () => {
|
||||
expect(result.running.average).toBeCloseTo(1.6);
|
||||
expect(result.running.peak).toBe(3);
|
||||
expect(result.running.capturedHours * 3600).toBeCloseTo(150);
|
||||
expect(result.maps[0].running).toEqual(result.running);
|
||||
expect(result.previous.running.average).toBe(4);
|
||||
expect(result.previous.running.peak).toBe(4);
|
||||
expect(result.previous.running.capturedHours * 3600).toBeCloseTo(90);
|
||||
@@ -610,6 +614,50 @@ describe('historical metrics', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('counts concurrent lobbies per recorded game/map across reused names, clipped intervals and collection gaps', async () => {
|
||||
const { recordMetrics, readMetrics } =
|
||||
await import('../../src/lib/server/fleet/metrics.js');
|
||||
const now = Date.UTC(2026, 0, 3, 12);
|
||||
const since = now - 86400_000;
|
||||
const one = { server: 'one', game: 't5', map: 'Moon', players: 0, capacity: null };
|
||||
const two = { ...one, server: 'two', players: null };
|
||||
const otherGame = { ...one, server: 't6-one', game: 't6' };
|
||||
recordMetrics([one, two, otherGame], since - 30_000);
|
||||
recordMetrics([{ ...one, server: 'three', players: 2 }], since + 15_000);
|
||||
recordMetrics(
|
||||
[
|
||||
otherGame,
|
||||
{ ...otherGame, server: 't6-two' },
|
||||
{ ...otherGame, server: 't6-three' },
|
||||
{ ...one, map: 'Kino Der Toten' }
|
||||
],
|
||||
since + 45_000
|
||||
);
|
||||
// Both lobby names are reused after the map was absent from a collection.
|
||||
recordMetrics([one, { ...two, players: 0 }], now - 30_000);
|
||||
// A snapshot with no elapsed time must not inflate the captured peak.
|
||||
recordMetrics([one, two, { ...one, server: 'three' }], now);
|
||||
const result = readMetrics(1, now);
|
||||
const moon = result.maps.find((map) => map.game === 't5' && map.map === 'Moon')!;
|
||||
expect(moon.running.average).toBeCloseTo(1.6);
|
||||
expect(moon.running.peak).toBe(2);
|
||||
expect(moon.running.capturedHours * 3600).toBeCloseTo(75);
|
||||
expect(moon.idle * 3600).toBeCloseTo(75);
|
||||
expect(moon.unknown * 3600).toBeCloseTo(15);
|
||||
expect(moon.observed + moon.unknown).toBeCloseTo(
|
||||
moon.running.average! * moon.running.capturedHours
|
||||
);
|
||||
const t6 = result.maps.find((map) => map.game === 't6')!;
|
||||
expect(t6.running.average).toBeCloseTo(285 / 105);
|
||||
expect(t6.running.peak).toBe(3);
|
||||
expect(t6.running.capturedHours * 3600).toBeCloseTo(105);
|
||||
const kino = result.maps.find((map) => map.map === 'Kino Der Toten')!;
|
||||
expect(kino.running).toEqual({ average: 1, peak: 1, capturedHours: 90 / 3600 });
|
||||
const scoped = readMetrics({ days: 1, game: 't5', map: 'Moon', timeZone: 'UTC' }, now);
|
||||
expect(scoped.maps).toEqual([moon]);
|
||||
expect(scoped.running).toEqual(moon.running);
|
||||
});
|
||||
|
||||
it('matches current policy context through map aliases and prefers the durable owner', async () => {
|
||||
const { recordMetrics, readMetrics } =
|
||||
await import('../../src/lib/server/fleet/metrics.js');
|
||||
|
||||
Reference in New Issue
Block a user