Files
mailer/test
Juergen Kunz 1698df3a53 feat: Add comprehensive SMTP test suite for Deno
- Implemented SMTP client utilities in `test/helpers/smtp.client.ts` for creating test clients, sending emails, and testing connections.
- Developed SMTP protocol test utilities in `test/helpers/utils.ts` for managing TCP connections, sending commands, and handling responses.
- Created a detailed README in `test/readme.md` outlining the test framework, infrastructure, organization, and running instructions.
- Ported CMD-01: EHLO Command tests in `test/suite/smtpserver_commands/test.cmd-01.ehlo-command.test.ts` with multiple scenarios including valid and invalid hostnames.
- Ported CMD-02: MAIL FROM Command tests in `test/suite/smtpserver_commands/test.cmd-02.mail-from.test.ts` covering valid address acceptance, invalid address rejection, SIZE parameter support, and command sequence enforcement.
2025-10-25 15:05:11 +00:00
..

Mailer SMTP Test Suite (Deno)

Comprehensive SMTP server and client test suite ported from dcrouter to Deno-native testing.

Test Framework

  • Framework: Deno native testing (Deno.test)
  • Assertions: @std/assert from Deno standard library
  • Run Command: deno test --allow-all --no-check test/
  • Run Single Test: deno test --allow-all --no-check test/suite/smtpserver_commands/test.cmd-01.ehlo-command.test.ts

Test Infrastructure

Helpers (test/helpers/)

  • server.loader.ts - Test SMTP server lifecycle management

    • Start/stop test servers with configurable options
    • TLS certificate handling
    • Mock email processing
    • Port management utilities
  • utils.ts - SMTP protocol test utilities

    • TCP connection management (Deno-native)
    • SMTP command sending/receiving
    • Protocol handshake helpers
    • MIME message creation
    • Retry and timing utilities
  • smtp.client.ts - SMTP client test utilities

    • Test client creation with various configurations
    • Email sending helpers
    • Connection pooling testing
    • Throughput measurement

Fixtures (test/fixtures/)

  • test-cert.pem - Self-signed certificate for TLS testing
  • test-key.pem - Private key for TLS testing

Test Suite Organization

All tests follow the naming convention: test.<category-id>.<description>.test.ts

Test Categories

1. Connection Management (CM) - smtpserver_connection/

Tests for SMTP connection handling, TLS support, and connection lifecycle.

ID Test Priority Status
CM-01 TLS Connection High Planned
CM-02 Multiple Simultaneous Connections High Planned
CM-03 Connection Timeout High Planned
CM-06 STARTTLS Upgrade High Planned
CM-10 Plain Connection Low Planned

2. SMTP Commands (CMD) - smtpserver_commands/

Tests for SMTP protocol command implementation.

ID Test Priority Status
CMD-01 EHLO Command High PORTED
CMD-02 MAIL FROM Command High PORTED
CMD-03 RCPT TO Command High Planned
CMD-04 DATA Command High Planned
CMD-06 RSET Command Medium Planned
CMD-13 QUIT Command High Planned

3. Email Processing (EP) - smtpserver_email-processing/

Tests for email content handling, parsing, and delivery.

ID Test Priority Status
EP-01 Basic Email Sending High Planned
EP-02 Invalid Email Address Handling High Planned
EP-04 Large Email Handling High Planned
EP-05 MIME Handling High Planned

4. Security (SEC) - smtpserver_security/

Tests for security features and protections.

ID Test Priority Status
SEC-01 Authentication High Planned
SEC-03 DKIM Processing High Planned
SEC-04 SPF Checking High Planned
SEC-06 IP Reputation Checking High Planned
SEC-08 Rate Limiting High Planned
SEC-10 Header Injection Prevention High Planned

5. Error Handling (ERR) - smtpserver_error-handling/

Tests for proper error handling and recovery.

ID Test Priority Status
ERR-01 Syntax Error Handling High Planned
ERR-02 Invalid Sequence Handling High Planned
ERR-05 Resource Exhaustion High Planned
ERR-07 Exception Handling High Planned

Currently Ported Tests

CMD-01: EHLO Command (test.cmd-01.ehlo-command.test.ts)

Tests: 5 total (5 passing)

  • Server startup/shutdown
  • EHLO response with proper capabilities
  • Invalid hostname handling
  • Command pipelining (multiple EHLO)

Key validations:

  • ✓ Server advertises SIZE capability
  • ✓ Server advertises 8BITMIME capability
  • ✓ Last capability line uses "250 " (space, not hyphen)
  • ✓ Server handles invalid hostnames gracefully
  • ✓ Second EHLO resets session state

CMD-02: MAIL FROM Command (test.cmd-02.mail-from.test.ts)

Tests: 6 total

  • Valid sender address acceptance
  • Invalid sender address rejection
  • SIZE parameter support
  • Command sequence enforcement

Key validations:

  • ✓ Accepts valid email formats
  • ✓ Accepts IP literals (user@[192.168.1.1])
  • ✓ Rejects malformed addresses
  • ✓ Supports SIZE parameter
  • ✓ Enforces EHLO before MAIL FROM

Running Tests

Run All Tests

deno test --allow-all --no-check test/

Run Specific Category

# SMTP commands tests
deno test --allow-all --no-check test/suite/smtpserver_commands/

# Connection tests
deno test --allow-all --no-check test/suite/smtpserver_connection/

Run Single Test File

deno test --allow-all --no-check test/suite/smtpserver_commands/test.cmd-01.ehlo-command.test.ts

Run with Verbose Output

deno test --allow-all --no-check --trace-leaks test/

Test Development Guidelines

Writing New Tests

  1. Use Deno.test() format:
Deno.test({
  name: 'CMD-XX: Description of test',
  async fn() {
    // Test implementation
  },
  sanitizeResources: false,  // Required for network tests
  sanitizeOps: false,        // Required for network tests
});
  1. Import assertions from @std/assert:
import { assert, assertEquals, assertMatch } from '@std/assert';
  1. Use test helpers:
import { startTestServer, stopTestServer } from '../../helpers/server.loader.ts';
import { connectToSmtp, sendSmtpCommand } from '../../helpers/utils.ts';
  1. Always cleanup:
  • Close connections with closeSmtpConnection() or conn.close()
  • Stop test servers with stopTestServer()
  • Use try/finally blocks for guaranteed cleanup
  1. Test isolation:
  • Each test file uses its own port (e.g., CMD-01 uses 25251, CMD-02 uses 25252)
  • Setup and cleanup tests ensure clean state

Key Differences from dcrouter Tests

Framework

  • Before: @git.zone/tstest/tapbundle (Node.js)
  • After: Deno.test (native)

Assertions

  • Before: expect(x).toBeTruthy(), expect(x).toEqual(y)
  • After: assert(x), assertEquals(x, y), assertMatch(x, regex)

Network I/O

  • Before: Node.js net module
  • After: Deno Deno.connect() / Deno.listen()

Imports

  • Before: .js extensions, Node-style imports
  • After: .ts extensions, Deno-style imports

Test Priorities

Phase 1: Core SMTP Functionality (High Priority)

  • CMD-01: EHLO Command
  • CMD-02: MAIL FROM Command
  • 🔄 CMD-03: RCPT TO Command
  • 🔄 CMD-04: DATA Command
  • 🔄 CMD-13: QUIT Command
  • 🔄 CM-01: TLS Connection
  • 🔄 EP-01: Basic Email Sending

Phase 2: Security & Validation (High Priority)

  • 🔄 SEC-01: Authentication
  • 🔄 SEC-06: IP Reputation
  • 🔄 SEC-08: Rate Limiting
  • 🔄 SEC-10: Header Injection Prevention
  • 🔄 ERR-01: Syntax Error Handling
  • 🔄 ERR-02: Invalid Sequence Handling

Phase 3: Advanced Features (Medium Priority)

  • 🔄 SEC-03: DKIM Processing
  • 🔄 SEC-04: SPF Checking
  • 🔄 EP-04: Large Email Handling
  • 🔄 EP-05: MIME Handling
  • 🔄 CM-02: Multiple Connections
  • 🔄 CM-06: STARTTLS Upgrade

Phase 4: Complete Coverage (All Remaining)

  • All performance tests
  • All reliability tests
  • All edge case tests
  • All RFC compliance tests
  • SMTP client tests

Current Status

Infrastructure: Complete

  • Deno-native test helpers
  • Server lifecycle management
  • SMTP protocol utilities
  • Test certificates

Tests Ported: 2/100+ test files

  • CMD-01: EHLO Command (5 tests passing)
  • CMD-02: MAIL FROM Command (6 tests)

Next Steps:

  1. Port CMD-03 (RCPT TO), CMD-04 (DATA), CMD-13 (QUIT)
  2. Port CM-01 (TLS connection test)
  3. Port EP-01 (Basic email sending)
  4. Port security tests (SEC-01, SEC-06, SEC-08)
  5. Continue with remaining high-priority tests

Production Readiness Criteria

Gate 1: Core Functionality (>90% tests passing)

  • Basic SMTP command handling
  • Connection management
  • Email delivery
  • Error handling

Gate 2: Security (>95% tests passing)

  • Authentication mechanisms
  • TLS/STARTTLS support
  • Rate limiting
  • Injection prevention

Gate 3: Enterprise Ready (>85% tests passing)

  • Full RFC compliance
  • Performance under load
  • Advanced security features
  • Complete edge case handling

Contributing

When porting tests from dcrouter:

  1. Maintain test IDs and organization
  2. Convert to Deno.test() format
  3. Use @std/assert for assertions
  4. Update imports to .ts extensions
  5. Use Deno-native TCP connections
  6. Preserve test logic and validations
  7. Add sanitizeResources: false, sanitizeOps: false for network tests
  8. Update this README with ported tests

Resources