fix(tests): fix: Improve test stability by handling race conditions in SenderReputationMonitor and IPWarmupManager. Disable filesystem operations and external DNS lookups during tests by checking NODE_ENV, add proper cleanup of singleton instances and active timeouts to ensure consistent test environment.

This commit is contained in:
2025-05-08 10:24:50 +00:00
parent cb33dd26d0
commit 858794799b
7 changed files with 78 additions and 17 deletions

View File

@ -16,10 +16,24 @@ const cleanupTestData = () => {
const resetSingleton = () => {
// @ts-ignore - accessing private static field for testing
SenderReputationMonitor.instance = null;
// Clean up any timeout to prevent race conditions
const activeSendReputationMonitors = Array.from(Object.values(global))
.filter((item: any) => item && typeof item === 'object' && item._idleTimeout)
.filter((item: any) =>
item._onTimeout &&
item._onTimeout.toString &&
item._onTimeout.toString().includes('updateAllDomainMetrics'));
// Clear any active timeouts to prevent race conditions
activeSendReputationMonitors.forEach((timer: any) => {
clearTimeout(timer);
});
};
// Before running any tests
tap.test('setup', async () => {
resetSingleton();
cleanupTestData();
});
@ -39,7 +53,7 @@ tap.test('should initialize SenderReputationMonitor with default settings', asyn
tap.test('should initialize SenderReputationMonitor with custom settings', async () => {
resetSingleton();
const reputationMonitor = SenderReputationMonitor.getInstance({
enabled: true,
enabled: false, // Disable automatic updates to prevent race conditions
domains: ['example.com', 'test.com'],
updateFrequency: 12 * 60 * 60 * 1000, // 12 hours
alertThresholds: {
@ -61,7 +75,7 @@ tap.test('should initialize SenderReputationMonitor with custom settings', async
tap.test('should record send events and update metrics', async () => {
resetSingleton();
const reputationMonitor = SenderReputationMonitor.getInstance({
enabled: true,
enabled: false, // Disable automatic updates to prevent race conditions
domains: ['example.com']
});
@ -87,7 +101,7 @@ tap.test('should record send events and update metrics', async () => {
tap.test('should calculate reputation scores correctly', async () => {
resetSingleton();
const reputationMonitor = SenderReputationMonitor.getInstance({
enabled: true,
enabled: false, // Disable automatic updates to prevent race conditions
domains: ['high.com', 'medium.com', 'low.com']
});
@ -120,7 +134,7 @@ tap.test('should calculate reputation scores correctly', async () => {
tap.test('should add and remove domains for monitoring', async () => {
resetSingleton();
const reputationMonitor = SenderReputationMonitor.getInstance({
enabled: true,
enabled: false, // Disable automatic updates to prevent race conditions
domains: ['example.com']
});
@ -147,7 +161,7 @@ tap.test('should add and remove domains for monitoring', async () => {
tap.test('should track engagement metrics correctly', async () => {
resetSingleton();
const reputationMonitor = SenderReputationMonitor.getInstance({
enabled: true,
enabled: false, // Disable automatic updates to prevent race conditions
domains: ['example.com']
});
@ -172,12 +186,13 @@ tap.test('should track engagement metrics correctly', async () => {
tap.test('should store historical reputation data', async () => {
resetSingleton();
const reputationMonitor = SenderReputationMonitor.getInstance({
enabled: true,
enabled: false, // Disable automatic updates to prevent race conditions
domains: ['example.com']
});
// Record events over multiple days
const today = new Date();
const todayStr = today.toISOString().split('T')[0];
// Record data
reputationMonitor.recordSendEvent('example.com', { type: 'sent', count: 1000 });
@ -192,7 +207,6 @@ tap.test('should store historical reputation data', async () => {
// Check that daily send volume is tracked
expect(metrics.volume.dailySendVolume).toBeTruthy();
const todayStr = today.toISOString().split('T')[0];
expect(metrics.volume.dailySendVolume[todayStr]).toEqual(1000);
});
@ -200,7 +214,7 @@ tap.test('should store historical reputation data', async () => {
tap.test('should correctly handle different event types', async () => {
resetSingleton();
const reputationMonitor = SenderReputationMonitor.getInstance({
enabled: true,
enabled: false, // Disable automatic updates to prevent race conditions
domains: ['example.com']
});
@ -233,6 +247,7 @@ tap.test('should correctly handle different event types', async () => {
// After all tests, clean up
tap.test('cleanup', async () => {
resetSingleton();
cleanupTestData();
});
@ -240,4 +255,5 @@ tap.test('stop', async () => {
await tap.stopForcefully();
});
export default tap.start();