112 lines
3.1 KiB
TypeScript
112 lines
3.1 KiB
TypeScript
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
|
import { LogDeduplicator } from '../ts/core/utils/log-deduplicator.js';
|
|
|
|
let deduplicator: LogDeduplicator;
|
|
|
|
tap.test('Setup log deduplicator', async () => {
|
|
deduplicator = new LogDeduplicator(1000); // 1 second flush interval for testing
|
|
});
|
|
|
|
tap.test('Connection rejection deduplication', async (tools) => {
|
|
// Simulate multiple connection rejections
|
|
for (let i = 0; i < 10; i++) {
|
|
deduplicator.log(
|
|
'connection-rejected',
|
|
'warn',
|
|
'Connection rejected',
|
|
{ reason: 'global-limit', component: 'test' },
|
|
'global-limit'
|
|
);
|
|
}
|
|
|
|
for (let i = 0; i < 5; i++) {
|
|
deduplicator.log(
|
|
'connection-rejected',
|
|
'warn',
|
|
'Connection rejected',
|
|
{ reason: 'route-limit', component: 'test' },
|
|
'route-limit'
|
|
);
|
|
}
|
|
|
|
// Force flush
|
|
deduplicator.flush('connection-rejected');
|
|
|
|
// The logs should have been aggregated
|
|
// (Can't easily test the actual log output, but we can verify the mechanism works)
|
|
expect(deduplicator).toBeInstanceOf(LogDeduplicator);
|
|
});
|
|
|
|
tap.test('IP rejection deduplication', async (tools) => {
|
|
// Simulate rejections from multiple IPs
|
|
const ips = ['192.168.1.100', '192.168.1.101', '192.168.1.100', '10.0.0.1'];
|
|
const reasons = ['per-ip-limit', 'rate-limit', 'per-ip-limit', 'global-limit'];
|
|
|
|
for (let i = 0; i < ips.length; i++) {
|
|
deduplicator.log(
|
|
'ip-rejected',
|
|
'warn',
|
|
`Connection rejected from ${ips[i]}`,
|
|
{ remoteIP: ips[i], reason: reasons[i] },
|
|
ips[i]
|
|
);
|
|
}
|
|
|
|
// Add more rejections from the same IP
|
|
for (let i = 0; i < 20; i++) {
|
|
deduplicator.log(
|
|
'ip-rejected',
|
|
'warn',
|
|
'Connection rejected from 192.168.1.100',
|
|
{ remoteIP: '192.168.1.100', reason: 'rate-limit' },
|
|
'192.168.1.100'
|
|
);
|
|
}
|
|
|
|
// Force flush
|
|
deduplicator.flush('ip-rejected');
|
|
|
|
// Verify the deduplicator exists and works
|
|
expect(deduplicator).toBeInstanceOf(LogDeduplicator);
|
|
});
|
|
|
|
tap.test('Connection cleanup deduplication', async (tools) => {
|
|
// Simulate various cleanup events
|
|
const reasons = ['normal', 'timeout', 'error', 'normal', 'zombie'];
|
|
|
|
for (const reason of reasons) {
|
|
for (let i = 0; i < 5; i++) {
|
|
deduplicator.log(
|
|
'connection-cleanup',
|
|
'info',
|
|
`Connection cleanup: ${reason}`,
|
|
{ connectionId: `conn-${i}`, reason },
|
|
reason
|
|
);
|
|
}
|
|
}
|
|
|
|
// Wait for automatic flush
|
|
await tools.delayFor(1500);
|
|
|
|
// Verify deduplicator is working
|
|
expect(deduplicator).toBeInstanceOf(LogDeduplicator);
|
|
});
|
|
|
|
tap.test('Automatic periodic flush', async (tools) => {
|
|
// Add some events
|
|
deduplicator.log('test-event', 'info', 'Test message', {}, 'test');
|
|
|
|
// Wait for automatic flush (should happen within 2x flush interval = 2 seconds)
|
|
await tools.delayFor(2500);
|
|
|
|
// Events should have been flushed automatically
|
|
expect(deduplicator).toBeInstanceOf(LogDeduplicator);
|
|
});
|
|
|
|
tap.test('Cleanup deduplicator', async () => {
|
|
deduplicator.cleanup();
|
|
expect(deduplicator).toBeInstanceOf(LogDeduplicator);
|
|
});
|
|
|
|
tap.start(); |