Files
Agent-System/web/src/lib/initialLoadMetrics.test.ts
T

84 lines
3.0 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
countInitRequests,
firstPaintHeavyHits,
percentile,
redactResourceUrl,
summarizeLatencies,
summarizeResources,
} from './initialLoadMetrics';
test('redactResourceUrl drops query and origin', () => {
assert.equal(
redactResourceUrl('http://127.0.0.1:8080/api/v1/chat/sessions?project_id=1&token=secret'),
'/api/v1/chat/sessions',
);
assert.equal(redactResourceUrl('/assets/index-abc.js'), '/assets/index-abc.js');
});
test('summarizeResources flags deferred heavy chunks', () => {
const summary = summarizeResources([
{ path: '/assets/index-abc.js', initiator: 'script', durationMs: 12, transferBytes: 100, decodedBytes: 400 },
{ path: '/assets/katex-xyz.js', initiator: 'script', durationMs: 4, transferBytes: 50, decodedBytes: 200 },
]);
assert.equal(summary.jsCount, 2);
assert.equal(summary.transferBytes, 150);
assert.deepEqual(summary.heavyChunks, ['/assets/katex-xyz.js']);
});
test('firstPaintHeavyHits lists only deferred module paths', () => {
assert.deepEqual(
firstPaintHeavyHits([
{ path: '/assets/index-abc.js', initiator: 'script', durationMs: 1, transferBytes: 10, decodedBytes: 40 },
{ path: '/assets/mermaid-abc.js', initiator: 'script', durationMs: 2, transferBytes: 20, decodedBytes: 80 },
{ path: '/assets/docx-abc.js', initiator: 'script', durationMs: 3, transferBytes: 30, decodedBytes: 120 },
]),
['/assets/mermaid-abc.js', '/assets/docx-abc.js'],
);
assert.deepEqual(
firstPaintHeavyHits([
{ path: '/assets/index-abc.js', initiator: 'script', durationMs: 1, transferBytes: 10, decodedBytes: 40 },
]),
[],
);
});
test('countInitRequests separates member fanout from session lists', () => {
const counts = countInitRequests([
{ method: 'GET', path: '/api/v1/projects/1/members' },
{ method: 'GET', path: '/api/v1/projects/2/members' },
{ method: 'POST', path: '/api/v1/projects/2/members' },
{ method: 'GET', path: '/api/v1/chat/sessions' },
{ method: 'GET', path: '/api/v1/chat/sessions' },
]);
assert.equal(counts.memberGetCount, 2);
assert.equal(counts.distinctMemberProjects, 2);
assert.equal(counts.sessionListGetCount, 2);
});
test('percentile uses nearest-rank and stays null on empty input', () => {
assert.equal(percentile([], 75), null);
assert.equal(percentile([10, 20, 30, 40], 75), 30);
});
test('summarizeLatencies reports p50/p75/p95', () => {
assert.deepEqual(summarizeLatencies([]), {
n: 0,
p50: null,
p75: null,
p95: null,
min: null,
max: null,
});
// 20 samples: p50=rank10 → 1000; p75=rank15 → 1500; p95=rank19 → 1900
const values = Array.from({ length: 20 }, (_, i) => (i + 1) * 100);
const summary = summarizeLatencies(values);
assert.equal(summary.n, 20);
assert.equal(summary.p50, 1000);
assert.equal(summary.p75, 1500);
assert.equal(summary.p95, 1900);
assert.equal(summary.min, 100);
assert.equal(summary.max, 2000);
});