244 lines
6.8 KiB
TypeScript
244 lines
6.8 KiB
TypeScript
import { beforeEach, describe, expect, it, mock } from 'bun:test';
|
|
import { QueueManager } from '../src/queue-manager';
|
|
import type { QueueManagerConfig, RedisConfig } from '../src/types';
|
|
|
|
describe.skip('QueueManager', () => {
|
|
// Skipping these tests as they require real Redis connection
|
|
// TODO: Create mock implementation or use testcontainers
|
|
|
|
const mockRedisConfig: RedisConfig = {
|
|
host: 'localhost',
|
|
port: 6379,
|
|
};
|
|
|
|
const mockLogger = {
|
|
info: mock(() => {}),
|
|
error: mock(() => {}),
|
|
warn: mock(() => {}),
|
|
debug: mock(() => {}),
|
|
trace: mock(() => {}),
|
|
};
|
|
|
|
describe('constructor', () => {
|
|
it('should create queue manager with default config', () => {
|
|
const manager = new QueueManager(mockRedisConfig);
|
|
expect(manager).toBeDefined();
|
|
});
|
|
|
|
it('should create queue manager with custom config', () => {
|
|
const config: QueueManagerConfig = {
|
|
defaultJobOptions: {
|
|
attempts: 5,
|
|
removeOnComplete: 50,
|
|
},
|
|
enableMetrics: true,
|
|
enableScheduler: true,
|
|
};
|
|
|
|
const manager = new QueueManager(mockRedisConfig, config, mockLogger);
|
|
expect(manager).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('queue operations', () => {
|
|
let manager: QueueManager;
|
|
|
|
beforeEach(() => {
|
|
manager = new QueueManager(mockRedisConfig, {}, mockLogger);
|
|
});
|
|
|
|
it('should create or get queue', () => {
|
|
const queue = manager.createQueue('test-queue');
|
|
expect(queue).toBeDefined();
|
|
expect(queue.getName()).toBe('test-queue');
|
|
});
|
|
|
|
it('should return same queue instance', () => {
|
|
const queue1 = manager.createQueue('test-queue');
|
|
const queue2 = manager.createQueue('test-queue');
|
|
expect(queue1).toBe(queue2);
|
|
});
|
|
|
|
it('should create queue with options', () => {
|
|
const queue = manager.createQueue('test-queue', {
|
|
concurrency: 5,
|
|
workers: 2,
|
|
});
|
|
expect(queue).toBeDefined();
|
|
});
|
|
|
|
it('should get existing queue', () => {
|
|
manager.createQueue('test-queue');
|
|
const queue = manager.getQueue('test-queue');
|
|
expect(queue).toBeDefined();
|
|
});
|
|
|
|
it('should return undefined for non-existent queue', () => {
|
|
const queue = manager.getQueue('non-existent');
|
|
expect(queue).toBeUndefined();
|
|
});
|
|
|
|
it('should list all queues', () => {
|
|
manager.createQueue('queue1');
|
|
manager.createQueue('queue2');
|
|
const queues = manager.getQueues();
|
|
expect(queues).toHaveLength(2);
|
|
expect(queues.map(q => q.getName())).toContain('queue1');
|
|
expect(queues.map(q => q.getName())).toContain('queue2');
|
|
});
|
|
|
|
it('should check if queue exists', () => {
|
|
manager.createQueue('test-queue');
|
|
expect(manager.hasQueue('test-queue')).toBe(true);
|
|
expect(manager.hasQueue('non-existent')).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('cache operations', () => {
|
|
let manager: QueueManager;
|
|
|
|
beforeEach(() => {
|
|
manager = new QueueManager(mockRedisConfig, {}, mockLogger);
|
|
});
|
|
|
|
it('should create cache', () => {
|
|
const cache = manager.createCache('test-cache');
|
|
expect(cache).toBeDefined();
|
|
});
|
|
|
|
it('should get existing cache', () => {
|
|
manager.createCache('test-cache');
|
|
const cache = manager.getCache('test-cache');
|
|
expect(cache).toBeDefined();
|
|
});
|
|
|
|
it('should return same cache instance', () => {
|
|
const cache1 = manager.createCache('test-cache');
|
|
const cache2 = manager.createCache('test-cache');
|
|
expect(cache1).toBe(cache2);
|
|
});
|
|
});
|
|
|
|
describe('service discovery', () => {
|
|
let manager: QueueManager;
|
|
|
|
beforeEach(() => {
|
|
manager = new QueueManager(mockRedisConfig, {}, mockLogger);
|
|
});
|
|
|
|
it('should configure service name', () => {
|
|
manager.configureService('test-service');
|
|
expect((manager as any).serviceName).toBe('test-service');
|
|
});
|
|
|
|
it('should register queue route', () => {
|
|
manager.configureService('test-service');
|
|
manager.registerQueueRoute({
|
|
service: 'remote-service',
|
|
handler: 'process',
|
|
queueName: '{remote-service_process}',
|
|
});
|
|
|
|
expect(manager.hasRoute('remote-service', 'process')).toBe(true);
|
|
});
|
|
|
|
it('should send to remote queue', async () => {
|
|
manager.configureService('test-service');
|
|
manager.registerQueueRoute({
|
|
service: 'remote-service',
|
|
handler: 'process',
|
|
queueName: '{remote-service_process}',
|
|
});
|
|
|
|
const jobId = await manager.sendToQueue('remote-service', 'process', { data: 'test' });
|
|
expect(jobId).toBeDefined();
|
|
});
|
|
|
|
it('should send to local queue', async () => {
|
|
manager.configureService('test-service');
|
|
manager.createQueue('{test-service_process}');
|
|
|
|
const jobId = await manager.sendToQueue('test-service', 'process', { data: 'test' });
|
|
expect(jobId).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe('shutdown', () => {
|
|
it('should shutdown gracefully', async () => {
|
|
const manager = new QueueManager(mockRedisConfig, {}, mockLogger);
|
|
manager.createQueue('test-queue');
|
|
|
|
await manager.shutdown();
|
|
expect((manager as any).isShuttingDown).toBe(true);
|
|
});
|
|
|
|
it('should handle multiple shutdown calls', async () => {
|
|
const manager = new QueueManager(mockRedisConfig, {}, mockLogger);
|
|
|
|
const promise1 = manager.shutdown();
|
|
const promise2 = manager.shutdown();
|
|
|
|
expect(promise1).toBe(promise2);
|
|
await promise1;
|
|
});
|
|
});
|
|
|
|
describe('metrics', () => {
|
|
it('should get global stats', async () => {
|
|
const manager = new QueueManager(
|
|
mockRedisConfig,
|
|
{
|
|
enableMetrics: true,
|
|
},
|
|
mockLogger
|
|
);
|
|
|
|
manager.createQueue('queue1');
|
|
manager.createQueue('queue2');
|
|
|
|
const stats = await manager.getGlobalStats();
|
|
expect(stats).toBeDefined();
|
|
expect(stats.totalQueues).toBe(2);
|
|
});
|
|
|
|
it('should get queue stats', async () => {
|
|
const manager = new QueueManager(
|
|
mockRedisConfig,
|
|
{
|
|
enableMetrics: true,
|
|
},
|
|
mockLogger
|
|
);
|
|
|
|
const queue = manager.createQueue('test-queue');
|
|
const stats = await manager.getQueueStats('test-queue');
|
|
|
|
expect(stats).toBeDefined();
|
|
expect(stats.name).toBe('test-queue');
|
|
});
|
|
});
|
|
|
|
describe('rate limiting', () => {
|
|
it('should apply rate limit rules', () => {
|
|
const manager = new QueueManager(
|
|
mockRedisConfig,
|
|
{
|
|
rateLimiter: {
|
|
rules: [
|
|
{
|
|
name: 'api-limit',
|
|
max: 100,
|
|
duration: 60000,
|
|
scope: 'global',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
mockLogger
|
|
);
|
|
|
|
const rateLimiter = (manager as any).rateLimiter;
|
|
expect(rateLimiter).toBeDefined();
|
|
});
|
|
});
|
|
});
|