feat(api): enforce per-minute request rate limits

This commit is contained in:
2026-04-21 13:30:20 +00:00
parent 3762fc661e
commit 9608540792
2 changed files with 118 additions and 0 deletions
+76
View File
@@ -173,3 +173,79 @@ Deno.test('ApiServer metrics expose 5xx counts for failing endpoints', async ()
await server.stop();
}
});
Deno.test('ApiServer enforces api rate limits while exempting health and metrics', async () => {
const port = 19200 + Math.floor(Math.random() * 1000);
const server = new ApiServer(
{
host: '127.0.0.1',
port,
apiKeys: ['valid-key'],
rateLimit: 2,
cors: false,
corsOrigins: [],
},
{
async getAllStatus() {
return new Map();
},
async getAllAvailableModels() {
return new Map();
},
} as never,
{
async getAllModels() {
return [];
},
} as never,
{} as never,
{
getStatus() {
return {
localNode: null,
nodes: [],
models: {},
desiredDeployments: [],
};
},
} as never,
);
(server as unknown as {
gpuDetector: { detectGpus: () => Promise<unknown[]> };
}).gpuDetector = {
async detectGpus() {
return [];
},
};
await server.start();
try {
const requestHeaders = {
Authorization: 'Bearer valid-key',
};
const first = await fetch(`http://127.0.0.1:${port}/v1/models`, { headers: requestHeaders });
assertEquals(first.status, 200);
await first.text();
const second = await fetch(`http://127.0.0.1:${port}/v1/models`, { headers: requestHeaders });
assertEquals(second.status, 200);
await second.text();
const third = await fetch(`http://127.0.0.1:${port}/v1/models`, { headers: requestHeaders });
assertEquals(third.status, 429);
assertEquals((await third.json()).error.type, 'rate_limit_exceeded');
const health = await fetch(`http://127.0.0.1:${port}/health`);
assertEquals(health.status, 200);
await health.text();
const metrics = await fetch(`http://127.0.0.1:${port}/metrics`);
assertEquals(metrics.status, 200);
await metrics.text();
} finally {
await server.stop();
}
});