- Implement CMD-03 tests for RCPT TO command, validating recipient addresses, handling multiple recipients, and enforcing command sequence. - Implement CMD-04 tests for DATA command, ensuring proper email content transmission, handling of dot-stuffing, large messages, and correct command sequence. - Implement CMD-13 tests for QUIT command, verifying graceful connection termination and idempotency. - Implement CM-01 tests for TLS connections, including STARTTLS capability and direct TLS connections. - Implement EP-01 tests for basic email sending, covering complete SMTP transaction flow, MIME attachments, HTML emails, custom headers, and minimal emails.
12 KiB
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/assertfrom 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 testingtest-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 | ✅ PORTED |
| 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 | ✅ PORTED |
| CMD-04 | DATA Command | High | ✅ PORTED |
| CMD-06 | RSET Command | Medium | Planned |
| CMD-13 | QUIT Command | High | ✅ PORTED |
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 | ✅ PORTED |
| 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 (6 passing)
- 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
✅ CMD-03: RCPT TO Command (test.cmd-03.rcpt-to.test.ts)
Tests: 7 total (7 passing)
- Valid recipient address acceptance
- Multiple recipients support
- Invalid recipient address rejection
- Command sequence enforcement
- RSET clears recipients
Key validations:
- ✓ Accepts valid recipient formats
- ✓ Accepts IP literals and subdomains
- ✓ Supports multiple recipients per transaction
- ✓ Rejects invalid email addresses
- ✓ Enforces RCPT TO after MAIL FROM
- ✓ RSET properly clears recipient list
✅ CMD-04: DATA Command (test.cmd-04.data-command.test.ts)
Tests: 7 total (7 passing)
- Email data transmission after RCPT TO
- Rejection without RCPT TO
- Dot-stuffing handling
- Large message support
- Command sequence enforcement
Key validations:
- ✓ Accepts email data with proper terminator
- ✓ Returns 354 to start data input
- ✓ Returns 250 after successful email acceptance
- ✓ Rejects DATA without MAIL FROM
- ✓ Handles dot-stuffed content correctly
- ✓ Supports large messages (10KB+)
✅ CMD-13: QUIT Command (test.cmd-13.quit-command.test.ts)
Tests: 7 total (7 passing)
- Graceful connection termination
- QUIT after MAIL FROM
- QUIT after complete transaction
- Idempotent QUIT handling
- Immediate QUIT without EHLO
Key validations:
- ✓ Returns 221 Service closing
- ✓ Works at any point in SMTP session
- ✓ Properly closes connection
- ✓ Handles multiple QUIT commands gracefully
- ✓ Allows immediate QUIT after greeting
✅ CM-01: TLS Connection (test.cm-01.tls-connection.test.ts)
Tests: 8 total (8 passing)
- Server advertises STARTTLS capability
- STARTTLS command initiates upgrade
- Direct TLS connection support
- STARTTLS not available after already started
- STARTTLS requires EHLO first
- Connection accepts commands after TLS
- Server lifecycle management
Key validations:
- ✓ STARTTLS advertised in EHLO capabilities
- ✓ STARTTLS command responds with 220 Ready
- ✓ Direct TLS connections work (with self-signed certs)
- ✓ Second STARTTLS properly rejected
- ✓ STARTTLS before EHLO handled correctly
- ✓ TLS upgrade process validated
✅ EP-01: Basic Email Sending (test.ep-01.basic-email-sending.test.ts)
Tests: 7 total (7 passing)
- Complete SMTP transaction flow (CONNECT → EHLO → MAIL FROM → RCPT TO → DATA → CONTENT → QUIT)
- Email with MIME attachment (multipart/mixed)
- HTML email (multipart/alternative)
- Email with custom headers (X-Custom-Header, X-Priority, Reply-To, etc.)
- Minimal email (body only, no headers)
- Server lifecycle management
Key validations:
- ✓ Complete email lifecycle from greeting to QUIT
- ✓ MIME multipart messages with attachments
- ✓ HTML email with plain text fallback
- ✓ Custom header support (X-*, Reply-To, Organization)
- ✓ Minimal email content accepted
- ✓ Email queuing and processing confirmed
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
- 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
});
- Import assertions from @std/assert:
import { assert, assertEquals, assertMatch } from '@std/assert';
- Use test helpers:
import { startTestServer, stopTestServer } from '../../helpers/server.loader.ts';
import { connectToSmtp, sendSmtpCommand } from '../../helpers/utils.ts';
- Always cleanup:
- Close connections with
closeSmtpConnection()orconn.close() - Stop test servers with
stopTestServer() - Use try/finally blocks for guaranteed cleanup
- 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
netmodule - After: Deno
Deno.connect()/Deno.listen()
Imports
- Before:
.jsextensions, Node-style imports - After:
.tsextensions, Deno-style imports
Test Priorities
Phase 1: Core SMTP Functionality (High Priority) ✅ COMPLETE
- ✅ 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 (utils.ts, server.loader.ts, smtp.client.ts)
- Server lifecycle management
- SMTP protocol utilities with readSmtpResponse helper
- Test certificates (self-signed RSA)
Tests Ported: 7/100+ test files (47 total tests passing)
- ✅ CMD-01: EHLO Command (5 tests passing)
- ✅ CMD-02: MAIL FROM Command (6 tests passing)
- ✅ CMD-03: RCPT TO Command (7 tests passing)
- ✅ CMD-04: DATA Command (7 tests passing)
- ✅ CMD-13: QUIT Command (7 tests passing)
- ✅ CM-01: TLS Connection (8 tests passing)
- ✅ EP-01: Basic Email Sending (7 tests passing)
Coverage: Complete essential SMTP transaction flow
- EHLO → MAIL FROM → RCPT TO → DATA → QUIT ✅
- TLS/STARTTLS support ✅
- Complete email lifecycle (MIME, HTML, custom headers) ✅
Phase 1 Status: ✅ COMPLETE (7/7 tests, 100%)
Next Steps:
- Port CMD-06 (RSET) for transaction reset testing
- Port security tests (SEC-01 Authentication, SEC-06 IP Reputation, SEC-08 Rate Limiting)
- Port error handling tests (ERR-01 Syntax, ERR-02 Sequence)
- 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:
- Maintain test IDs and organization
- Convert to Deno.test() format
- Use @std/assert for assertions
- Update imports to .ts extensions
- Use Deno-native TCP connections
- Preserve test logic and validations
- Add
sanitizeResources: false, sanitizeOps: falsefor network tests - Update this README with ported tests