update
This commit is contained in:
133
test/suite/connection/test.connection-timeout.ts
Normal file
133
test/suite/connection/test.connection-timeout.ts
Normal file
@ -0,0 +1,133 @@
|
||||
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
||||
import { startTestServer, stopTestServer, type ITestServer } from './helpers/server.loader.js';
|
||||
import * as plugins from '../ts/plugins.js';
|
||||
|
||||
let testServer: ITestServer;
|
||||
|
||||
tap.test('setup - start SMTP server with short timeout', async () => {
|
||||
testServer = await startTestServer({
|
||||
port: 2533,
|
||||
hostname: 'localhost',
|
||||
timeout: 5000 // 5 second timeout for testing
|
||||
});
|
||||
expect(testServer).toBeInstanceOf(Object);
|
||||
});
|
||||
|
||||
tap.test('CM-03: Connection Timeout - idle connections are closed after timeout', async (tools) => {
|
||||
const startTime = Date.now();
|
||||
|
||||
// Create connection
|
||||
const socket = await new Promise<plugins.net.Socket>((resolve, reject) => {
|
||||
const client = plugins.net.createConnection({
|
||||
host: testServer.hostname,
|
||||
port: testServer.port
|
||||
});
|
||||
|
||||
client.on('connect', () => resolve(client));
|
||||
client.on('error', reject);
|
||||
|
||||
setTimeout(() => reject(new Error('Connection timeout')), 3000);
|
||||
});
|
||||
|
||||
// Wait for greeting
|
||||
await new Promise<void>((resolve) => {
|
||||
socket.once('data', (data) => {
|
||||
const response = data.toString();
|
||||
expect(response).toInclude('220');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
console.log('✅ Connected and received greeting');
|
||||
|
||||
// Now stay idle and wait for server to timeout the connection
|
||||
const disconnectPromise = new Promise<number>((resolve) => {
|
||||
socket.on('close', () => {
|
||||
const duration = Date.now() - startTime;
|
||||
resolve(duration);
|
||||
});
|
||||
|
||||
socket.on('end', () => {
|
||||
console.log('📡 Server initiated connection close');
|
||||
});
|
||||
|
||||
socket.on('error', (err) => {
|
||||
console.log('⚠️ Socket error:', err.message);
|
||||
});
|
||||
});
|
||||
|
||||
// Wait for timeout (should be around 5 seconds)
|
||||
const duration = await disconnectPromise;
|
||||
|
||||
console.log(`⏱️ Connection closed after ${duration}ms`);
|
||||
|
||||
// Verify timeout happened within expected range (4-6 seconds)
|
||||
expect(duration).toBeGreaterThan(4000);
|
||||
expect(duration).toBeLessThan(7000);
|
||||
|
||||
console.log('✅ Connection timeout test passed');
|
||||
});
|
||||
|
||||
tap.test('CM-03: Active connection should not timeout', async () => {
|
||||
// Create new connection
|
||||
const socket = plugins.net.createConnection({
|
||||
host: testServer.hostname,
|
||||
port: testServer.port
|
||||
});
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
socket.on('connect', resolve);
|
||||
});
|
||||
|
||||
// Wait for greeting
|
||||
await new Promise<void>((resolve) => {
|
||||
socket.once('data', resolve);
|
||||
});
|
||||
|
||||
// Keep connection active with NOOP commands
|
||||
let isConnected = true;
|
||||
socket.on('close', () => {
|
||||
isConnected = false;
|
||||
});
|
||||
|
||||
// Send NOOP every 2 seconds for 8 seconds
|
||||
for (let i = 0; i < 4; i++) {
|
||||
if (!isConnected) break;
|
||||
|
||||
socket.write('NOOP\r\n');
|
||||
|
||||
// Wait for response
|
||||
await new Promise<void>((resolve) => {
|
||||
socket.once('data', (data) => {
|
||||
const response = data.toString();
|
||||
expect(response).toInclude('250');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
console.log(`✅ NOOP ${i + 1}/4 successful`);
|
||||
|
||||
// Wait 2 seconds before next NOOP
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
}
|
||||
|
||||
// Connection should still be active
|
||||
expect(isConnected).toBeTrue();
|
||||
|
||||
// Close connection gracefully
|
||||
socket.write('QUIT\r\n');
|
||||
await new Promise<void>((resolve) => {
|
||||
socket.once('data', () => {
|
||||
socket.end();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
console.log('✅ Active connection did not timeout');
|
||||
});
|
||||
|
||||
tap.test('cleanup - stop SMTP server', async () => {
|
||||
await stopTestServer(testServer);
|
||||
});
|
||||
|
||||
tap.start();
|
Reference in New Issue
Block a user