dcrouter/test/suite/smtpclient_connection/test.ccm-08.dns-resolution.ts
2025-05-25 19:05:43 +00:00

139 lines
4.4 KiB
TypeScript

import { tap, expect } from '@git.zone/tstest/tapbundle';
import { startTestServer, stopTestServer, type ITestServer } from '../../helpers/server.loader.js';
import * as dns from 'dns';
import { promisify } from 'util';
const resolveMx = promisify(dns.resolveMx);
const resolve4 = promisify(dns.resolve4);
const resolve6 = promisify(dns.resolve6);
let testServer: ITestServer;
tap.test('setup test SMTP server', async () => {
testServer = await startTestServer({
port: 2534,
tlsEnabled: false,
authRequired: false
});
expect(testServer).toBeTruthy();
expect(testServer.port).toEqual(2534);
});
tap.test('CCM-08: DNS resolution and MX record lookup', async () => {
// Test basic DNS resolution
try {
const ipv4Addresses = await resolve4('example.com');
expect(ipv4Addresses).toBeArray();
expect(ipv4Addresses.length).toBeGreaterThan(0);
console.log('IPv4 addresses for example.com:', ipv4Addresses);
} catch (error) {
console.log('IPv4 resolution failed (may be expected in test environment):', error.message);
}
// Test IPv6 resolution
try {
const ipv6Addresses = await resolve6('example.com');
expect(ipv6Addresses).toBeArray();
console.log('IPv6 addresses for example.com:', ipv6Addresses);
} catch (error) {
console.log('IPv6 resolution failed (common for many domains):', error.message);
}
// Test MX record lookup
try {
const mxRecords = await resolveMx('example.com');
expect(mxRecords).toBeArray();
if (mxRecords.length > 0) {
expect(mxRecords[0]).toHaveProperty('priority');
expect(mxRecords[0]).toHaveProperty('exchange');
console.log('MX records for example.com:', mxRecords);
}
} catch (error) {
console.log('MX record lookup failed (may be expected in test environment):', error.message);
}
// Test local resolution (should work in test environment)
try {
const localhostIpv4 = await resolve4('localhost');
expect(localhostIpv4).toContain('127.0.0.1');
} catch (error) {
// Fallback for environments where localhost doesn't resolve via DNS
console.log('Localhost DNS resolution not available, using direct IP');
}
// Test invalid domain handling
try {
await resolve4('this-domain-definitely-does-not-exist-12345.com');
expect(true).toBeFalsy(); // Should not reach here
} catch (error) {
expect(error.code).toMatch(/ENOTFOUND|ENODATA/);
}
// Test MX record priority sorting
const mockMxRecords = [
{ priority: 20, exchange: 'mx2.example.com' },
{ priority: 10, exchange: 'mx1.example.com' },
{ priority: 30, exchange: 'mx3.example.com' }
];
const sortedRecords = mockMxRecords.sort((a, b) => a.priority - b.priority);
expect(sortedRecords[0].exchange).toEqual('mx1.example.com');
expect(sortedRecords[1].exchange).toEqual('mx2.example.com');
expect(sortedRecords[2].exchange).toEqual('mx3.example.com');
});
tap.test('CCM-08: DNS caching behavior', async () => {
const startTime = Date.now();
// First resolution (cold cache)
try {
await resolve4('example.com');
} catch (error) {
// Ignore errors, we're testing timing
}
const firstResolutionTime = Date.now() - startTime;
// Second resolution (potentially cached)
const secondStartTime = Date.now();
try {
await resolve4('example.com');
} catch (error) {
// Ignore errors, we're testing timing
}
const secondResolutionTime = Date.now() - secondStartTime;
console.log(`First resolution: ${firstResolutionTime}ms, Second resolution: ${secondResolutionTime}ms`);
// Note: We can't guarantee caching behavior in all environments
// so we just log the times for manual inspection
});
tap.test('CCM-08: Multiple A record handling', async () => {
// Test handling of domains with multiple A records
try {
const googleIps = await resolve4('google.com');
if (googleIps.length > 1) {
expect(googleIps).toBeArray();
expect(googleIps.length).toBeGreaterThan(1);
console.log('Multiple A records found for google.com:', googleIps);
// Verify all are valid IPv4 addresses
const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
for (const ip of googleIps) {
expect(ip).toMatch(ipv4Regex);
}
}
} catch (error) {
console.log('Could not resolve google.com:', error.message);
}
});
tap.test('cleanup test SMTP server', async () => {
if (testServer) {
await stopTestServer(testServer);
}
});
export default tap.start();