fix(smartproxy): upgrade @push.rocks/smartproxy to ^23.1.0 and adapt code/tests for its async getStatistics() API
This commit is contained in:
@@ -197,65 +197,55 @@ tap.test('CERR-03: Network Failures - should handle EHOSTUNREACH', async () => {
|
||||
});
|
||||
|
||||
tap.test('CERR-03: Network Failures - should handle packet loss simulation', async () => {
|
||||
// Create a server that randomly drops data
|
||||
let packetCount = 0;
|
||||
// Create a server that sends a greeting but never responds to commands,
|
||||
// simulating complete packet loss after the initial connection.
|
||||
const lossyServer = net.createServer((socket) => {
|
||||
socket.on('error', () => {});
|
||||
socket.write('220 Lossy server ready\r\n');
|
||||
|
||||
socket.on('data', (data) => {
|
||||
packetCount++;
|
||||
|
||||
// Simulate 30% packet loss
|
||||
if (Math.random() > 0.3) {
|
||||
const command = data.toString().trim();
|
||||
if (command.startsWith('EHLO')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command === 'QUIT') {
|
||||
socket.write('221 Bye\r\n');
|
||||
socket.end();
|
||||
}
|
||||
}
|
||||
// Otherwise, don't respond (simulate packet loss)
|
||||
|
||||
// Never respond to any commands - simulates total packet loss
|
||||
socket.on('data', () => {
|
||||
// Intentionally drop all data to simulate packet loss
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
lossyServer.listen(2558, () => resolve());
|
||||
});
|
||||
|
||||
|
||||
const client = createSmtpClient({
|
||||
host: 'localhost',
|
||||
port: 2558,
|
||||
secure: false,
|
||||
connectionTimeout: 1000,
|
||||
socketTimeout: 1000 // Short timeout to detect loss
|
||||
connectionTimeout: 2000,
|
||||
socketTimeout: 2000 // Short timeout to detect loss
|
||||
});
|
||||
|
||||
|
||||
let verifyResult = false;
|
||||
let errorOccurred = false;
|
||||
|
||||
|
||||
try {
|
||||
verifyResult = await client.verify();
|
||||
if (verifyResult) {
|
||||
console.log('✅ Connected despite simulated packet loss');
|
||||
console.log('Connection succeeded unexpectedly');
|
||||
} else {
|
||||
console.log('✅ Connection failed due to packet loss');
|
||||
}
|
||||
} catch (error) {
|
||||
errorOccurred = true;
|
||||
console.log(`✅ Packet loss detected after ${packetCount} packets: ${error.message}`);
|
||||
console.log(`✅ Packet loss detected: ${error.message}`);
|
||||
}
|
||||
|
||||
// Either verification failed or an error occurred - both are expected with packet loss
|
||||
|
||||
// verify() must have returned false or thrown - both indicate packet loss was detected
|
||||
expect(!verifyResult || errorOccurred).toBeTrue();
|
||||
|
||||
|
||||
// Clean up client first
|
||||
try {
|
||||
await client.close();
|
||||
} catch (closeError) {
|
||||
// Ignore close errors in this test
|
||||
}
|
||||
|
||||
|
||||
// Then close server
|
||||
await new Promise<void>((resolve) => {
|
||||
lossyServer.close(() => resolve());
|
||||
|
||||
@@ -19,23 +19,31 @@ tap.test('setup - start SMTP server for greylisting tests', async () => {
|
||||
tap.test('CERR-04: Basic greylisting response handling', async () => {
|
||||
// Create server that simulates greylisting
|
||||
const greylistServer = net.createServer((socket) => {
|
||||
socket.on('error', () => {});
|
||||
socket.write('220 Greylist Test Server\r\n');
|
||||
|
||||
socket.on('data', (data) => {
|
||||
const command = data.toString().trim();
|
||||
|
||||
if (command.startsWith('EHLO') || command.startsWith('HELO')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('MAIL FROM')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('RCPT TO')) {
|
||||
// Simulate greylisting response
|
||||
socket.write('451 4.7.1 Greylisting in effect, please retry later\r\n');
|
||||
} else if (command === 'QUIT') {
|
||||
socket.write('221 Bye\r\n');
|
||||
socket.end();
|
||||
} else {
|
||||
socket.write('250 OK\r\n');
|
||||
const lines = data.toString().split('\r\n').filter((l: string) => l.trim());
|
||||
for (const line of lines) {
|
||||
const command = line.trim();
|
||||
|
||||
if (command.startsWith('EHLO') || command.startsWith('HELO')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('MAIL FROM')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('RCPT TO')) {
|
||||
// Simulate greylisting response
|
||||
socket.write('451 4.7.1 Greylisting in effect, please retry later\r\n');
|
||||
} else if (command.startsWith('RSET')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('DATA')) {
|
||||
socket.write('503 Bad sequence of commands\r\n');
|
||||
} else if (command === 'QUIT') {
|
||||
socket.write('221 Bye\r\n');
|
||||
socket.end();
|
||||
} else if (command.length > 0) {
|
||||
socket.write('250 OK\r\n');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -48,7 +56,8 @@ tap.test('CERR-04: Basic greylisting response handling', async () => {
|
||||
host: '127.0.0.1',
|
||||
port: 2560,
|
||||
secure: false,
|
||||
connectionTimeout: 5000
|
||||
connectionTimeout: 5000,
|
||||
socketTimeout: 5000
|
||||
});
|
||||
|
||||
const email = new Email({
|
||||
@@ -59,7 +68,7 @@ tap.test('CERR-04: Basic greylisting response handling', async () => {
|
||||
});
|
||||
|
||||
const result = await smtpClient.sendMail(email);
|
||||
|
||||
|
||||
// Should get a failed result due to greylisting
|
||||
expect(result.success).toBeFalse();
|
||||
console.log('Actual error:', result.error?.message);
|
||||
@@ -107,20 +116,30 @@ tap.test('CERR-04: Different greylisting response codes', async () => {
|
||||
tap.test('CERR-04: Greylisting with temporary failure', async () => {
|
||||
// Create server that sends 450 response (temporary failure)
|
||||
const tempFailServer = net.createServer((socket) => {
|
||||
socket.on('error', () => {});
|
||||
socket.write('220 Temp Fail Server\r\n');
|
||||
|
||||
socket.on('data', (data) => {
|
||||
const command = data.toString().trim();
|
||||
|
||||
if (command.startsWith('EHLO')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('MAIL FROM')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('RCPT TO')) {
|
||||
socket.write('450 4.7.1 Mailbox temporarily unavailable\r\n');
|
||||
} else if (command === 'QUIT') {
|
||||
socket.write('221 Bye\r\n');
|
||||
socket.end();
|
||||
const lines = data.toString().split('\r\n').filter((l: string) => l.trim());
|
||||
for (const line of lines) {
|
||||
const command = line.trim();
|
||||
|
||||
if (command.startsWith('EHLO') || command.startsWith('HELO')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('MAIL FROM')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('RCPT TO')) {
|
||||
socket.write('450 4.7.1 Mailbox temporarily unavailable\r\n');
|
||||
} else if (command.startsWith('RSET')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('DATA')) {
|
||||
socket.write('503 Bad sequence of commands\r\n');
|
||||
} else if (command === 'QUIT') {
|
||||
socket.write('221 Bye\r\n');
|
||||
socket.end();
|
||||
} else if (command.length > 0) {
|
||||
socket.write('250 OK\r\n');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -133,7 +152,8 @@ tap.test('CERR-04: Greylisting with temporary failure', async () => {
|
||||
host: '127.0.0.1',
|
||||
port: 2561,
|
||||
secure: false,
|
||||
connectionTimeout: 5000
|
||||
connectionTimeout: 5000,
|
||||
socketTimeout: 5000
|
||||
});
|
||||
|
||||
const email = new Email({
|
||||
@@ -144,7 +164,7 @@ tap.test('CERR-04: Greylisting with temporary failure', async () => {
|
||||
});
|
||||
|
||||
const result = await smtpClient.sendMail(email);
|
||||
|
||||
|
||||
expect(result.success).toBeFalse();
|
||||
console.log('Actual error:', result.error?.message);
|
||||
expect(result.error?.message).toMatch(/450|temporary|rejected/i);
|
||||
@@ -199,20 +219,30 @@ tap.test('CERR-04: Basic connection verification', async () => {
|
||||
tap.test('CERR-04: Server with RCPT rejection', async () => {
|
||||
// Test server rejecting at RCPT TO stage
|
||||
const rejectServer = net.createServer((socket) => {
|
||||
socket.on('error', () => {});
|
||||
socket.write('220 Reject Server\r\n');
|
||||
|
||||
socket.on('data', (data) => {
|
||||
const command = data.toString().trim();
|
||||
|
||||
if (command.startsWith('EHLO')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('MAIL FROM')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('RCPT TO')) {
|
||||
socket.write('451 4.2.1 Recipient rejected temporarily\r\n');
|
||||
} else if (command === 'QUIT') {
|
||||
socket.write('221 Bye\r\n');
|
||||
socket.end();
|
||||
const lines = data.toString().split('\r\n').filter((l: string) => l.trim());
|
||||
for (const line of lines) {
|
||||
const command = line.trim();
|
||||
|
||||
if (command.startsWith('EHLO') || command.startsWith('HELO')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('MAIL FROM')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('RCPT TO')) {
|
||||
socket.write('451 4.2.1 Recipient rejected temporarily\r\n');
|
||||
} else if (command.startsWith('RSET')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('DATA')) {
|
||||
socket.write('503 Bad sequence of commands\r\n');
|
||||
} else if (command === 'QUIT') {
|
||||
socket.write('221 Bye\r\n');
|
||||
socket.end();
|
||||
} else if (command.length > 0) {
|
||||
socket.write('250 OK\r\n');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -225,7 +255,8 @@ tap.test('CERR-04: Server with RCPT rejection', async () => {
|
||||
host: '127.0.0.1',
|
||||
port: 2562,
|
||||
secure: false,
|
||||
connectionTimeout: 5000
|
||||
connectionTimeout: 5000,
|
||||
socketTimeout: 5000
|
||||
});
|
||||
|
||||
const email = new Email({
|
||||
@@ -236,7 +267,7 @@ tap.test('CERR-04: Server with RCPT rejection', async () => {
|
||||
});
|
||||
|
||||
const result = await smtpClient.sendMail(email);
|
||||
|
||||
|
||||
expect(result.success).toBeFalse();
|
||||
console.log('Actual error:', result.error?.message);
|
||||
expect(result.error?.message).toMatch(/451|reject|recipient/i);
|
||||
|
||||
Reference in New Issue
Block a user