import { tap, expect } from '@git.zone/tstest/tapbundle'; import { startTestServer, stopTestServer, type ITestServer } from '../../helpers/server.loader.js'; import { createSmtpClient, createPooledSmtpClient } from '../../../ts/mail/delivery/smtpclient/index.js'; import { Email } from '../../../ts/mail/core/classes.email.js'; tap.test('setup - start SMTP server for caching tests', async () => { // Just a placeholder to ensure server starts properly }); tap.test('CPERF-06: caching strategies - connection caching', async () => { const testServer = await startTestServer({ secure: false, authOptional: true, }); console.log('Testing connection caching strategies...'); // Create a pooled client with connection caching const poolClient = createPooledSmtpClient({ host: 'localhost', port: 2525, secure: false, authOptional: true, maxConnections: 2, }); // First batch - establish connections console.log('Sending first batch to establish cached connections...'); const firstBatchStart = Date.now(); const firstBatch = Array(4).fill(null).map((_, i) => new Email({ from: 'sender@example.com', to: [`cached${i}@example.com`], subject: `Cache test ${i}`, text: `Testing connection caching - message ${i}`, }) ); const firstResults = await Promise.all( firstBatch.map(email => poolClient.sendMail(email)) ); firstResults.forEach(result => expect(result.success).toBeTrue()); const firstBatchTime = Date.now() - firstBatchStart; // Small delay to ensure connections are properly cached await new Promise(resolve => setTimeout(resolve, 100)); // Second batch - should use cached connections console.log('Sending second batch using cached connections...'); const secondBatchStart = Date.now(); const secondBatch = Array(4).fill(null).map((_, i) => new Email({ from: 'sender@example.com', to: [`cached2-${i}@example.com`], subject: `Cache test 2-${i}`, text: `Testing cached connections - message ${i}`, }) ); const secondResults = await Promise.all( secondBatch.map(email => poolClient.sendMail(email)) ); secondResults.forEach(result => expect(result.success).toBeTrue()); const secondBatchTime = Date.now() - secondBatchStart; console.log(`First batch (cold): ${firstBatchTime}ms`); console.log(`Second batch (cached): ${secondBatchTime}ms`); console.log(`Performance improvement: ${((firstBatchTime - secondBatchTime) / firstBatchTime * 100).toFixed(1)}%`); // Cached connections should be faster (allowing some variance) expect(secondBatchTime).toBeLessThanOrEqual(firstBatchTime + 100); await poolClient.close(); await stopTestServer(testServer); }); tap.test('CPERF-06: caching strategies - server capability caching', async () => { const testServer = await startTestServer({ secure: false, authOptional: true, }); console.log('Testing server capability caching...'); const client = createSmtpClient({ host: 'localhost', port: 2525, secure: false, authOptional: true, }); // First email - discovers capabilities console.log('First email - discovering server capabilities...'); const firstStart = Date.now(); const email1 = new Email({ from: 'sender@example.com', to: ['recipient1@example.com'], subject: 'Capability test 1', text: 'Testing capability discovery', }); const result1 = await client.sendMail(email1); expect(result1.success).toBeTrue(); const firstTime = Date.now() - firstStart; // Second email - uses cached capabilities console.log('Second email - using cached capabilities...'); const secondStart = Date.now(); const email2 = new Email({ from: 'sender@example.com', to: ['recipient2@example.com'], subject: 'Capability test 2', text: 'Testing cached capabilities', }); const result2 = await client.sendMail(email2); expect(result2.success).toBeTrue(); const secondTime = Date.now() - secondStart; console.log(`First email (capability discovery): ${firstTime}ms`); console.log(`Second email (cached capabilities): ${secondTime}ms`); // Both should complete quickly expect(firstTime).toBeLessThan(1000); expect(secondTime).toBeLessThan(1000); await client.close(); await stopTestServer(testServer); }); tap.test('CPERF-06: caching strategies - message batching', async () => { const testServer = await startTestServer({ secure: false, authOptional: true, }); console.log('Testing message batching for cache efficiency...'); const poolClient = createPooledSmtpClient({ host: 'localhost', port: 2525, secure: false, authOptional: true, maxConnections: 3, }); // Test sending messages in batches const batchSizes = [2, 4, 6]; for (const batchSize of batchSizes) { console.log(`\nTesting batch size: ${batchSize}`); const batchStart = Date.now(); const emails = Array(batchSize).fill(null).map((_, i) => new Email({ from: 'sender@example.com', to: [`batch${batchSize}-${i}@example.com`], subject: `Batch ${batchSize} message ${i}`, text: `Testing batching strategies - batch size ${batchSize}`, }) ); const results = await Promise.all( emails.map(email => poolClient.sendMail(email)) ); results.forEach(result => expect(result.success).toBeTrue()); const batchTime = Date.now() - batchStart; const avgTime = batchTime / batchSize; console.log(` Batch completed in ${batchTime}ms`); console.log(` Average time per message: ${avgTime.toFixed(1)}ms`); // Larger batches should have better average time per message expect(avgTime).toBeLessThan(500); } await poolClient.close(); await stopTestServer(testServer); }); tap.test('cleanup - stop SMTP server', async () => { // Cleanup is handled in individual tests }); tap.start();