This commit is contained in:
Boki 2025-06-25 11:38:23 -04:00
parent 3a7254708e
commit b63e58784c
41 changed files with 5762 additions and 4477 deletions

View file

@ -1,6 +1,6 @@
import type { Job, Queue, QueueEvents } from 'bullmq';
import { beforeEach, describe, expect, it, mock, type Mock } from 'bun:test';
import { QueueMetricsCollector } from '../src/queue-metrics';
import type { Queue, QueueEvents, Job } from 'bullmq';
describe('QueueMetricsCollector', () => {
let metrics: QueueMetricsCollector;
@ -34,7 +34,10 @@ describe('QueueMetricsCollector', () => {
on: mock(() => {}),
};
metrics = new QueueMetricsCollector(mockQueue as unknown as Queue, mockQueueEvents as unknown as QueueEvents);
metrics = new QueueMetricsCollector(
mockQueue as unknown as Queue,
mockQueueEvents as unknown as QueueEvents
);
});
describe('collect metrics', () => {
@ -46,7 +49,9 @@ describe('QueueMetricsCollector', () => {
mockQueue.getDelayedCount.mockImplementation(() => Promise.resolve(1));
// Add some completed timestamps to avoid 100% failure rate
const completedHandler = mockQueueEvents.on.mock.calls.find(call => call[0] === 'completed')?.[1];
const completedHandler = mockQueueEvents.on.mock.calls.find(
call => call[0] === 'completed'
)?.[1];
if (completedHandler) {
for (let i = 0; i < 50; i++) {
completedHandler();
@ -118,17 +123,14 @@ describe('QueueMetricsCollector', () => {
completedTimestamps: number[];
failedTimestamps: number[];
};
const now = Date.now();
metricsWithPrivate.completedTimestamps = [
now - 30000, // 30 seconds ago
now - 20000,
now - 10000,
];
metricsWithPrivate.failedTimestamps = [
now - 25000,
now - 5000,
];
metricsWithPrivate.failedTimestamps = [now - 25000, now - 5000];
const result = await metrics.collect();
@ -146,7 +148,9 @@ describe('QueueMetricsCollector', () => {
mockQueue.getFailedCount.mockImplementation(() => Promise.resolve(3));
// Add some completed timestamps to make it healthy
const completedHandler = mockQueueEvents.on.mock.calls.find(call => call[0] === 'completed')?.[1];
const completedHandler = mockQueueEvents.on.mock.calls.find(
call => call[0] === 'completed'
)?.[1];
if (completedHandler) {
for (let i = 0; i < 50; i++) {
completedHandler();
@ -174,9 +178,13 @@ describe('QueueMetricsCollector', () => {
const prometheusMetrics = await metrics.getPrometheusMetrics();
expect(prometheusMetrics).toContain('# HELP queue_jobs_total');
expect(prometheusMetrics).toContain('queue_jobs_total{queue="test-queue",status="waiting"} 5');
expect(prometheusMetrics).toContain(
'queue_jobs_total{queue="test-queue",status="waiting"} 5'
);
expect(prometheusMetrics).toContain('queue_jobs_total{queue="test-queue",status="active"} 2');
expect(prometheusMetrics).toContain('queue_jobs_total{queue="test-queue",status="completed"} 100');
expect(prometheusMetrics).toContain(
'queue_jobs_total{queue="test-queue",status="completed"} 100'
);
expect(prometheusMetrics).toContain('# HELP queue_processing_time_seconds');
expect(prometheusMetrics).toContain('# HELP queue_throughput_per_minute');
expect(prometheusMetrics).toContain('# HELP queue_health');
@ -189,7 +197,10 @@ describe('QueueMetricsCollector', () => {
on: mock<(event: string, handler: Function) => void>(() => {}),
};
new QueueMetricsCollector(mockQueue as unknown as Queue, newMockQueueEvents as unknown as QueueEvents);
new QueueMetricsCollector(
mockQueue as unknown as Queue,
newMockQueueEvents as unknown as QueueEvents
);
expect(newMockQueueEvents.on).toHaveBeenCalledWith('completed', expect.any(Function));
expect(newMockQueueEvents.on).toHaveBeenCalledWith('failed', expect.any(Function));
@ -219,4 +230,4 @@ describe('QueueMetricsCollector', () => {
expect(result.oldestWaitingJob).toBeNull();
});
});
});
});