This document provides comprehensive information about testing the AMTP Gateway implementation.
The testing strategy follows Go best practices with a mix of unit tests, integration tests, and benchmarks.
agentry/
├── internal/
│ ├── types/
│ │ └── message_test.go # Message type validation tests
│ ├── validation/
│ │ └── validator_test.go # Request validation tests
│ ├── processing/
│ │ ├── processor_test.go # Message processing unit tests
│ │ ├── delivery_test.go # Delivery engine unit tests
│ │ └── test_utils.go # Shared test utilities
│ ├── server/
│ │ └── handlers_test.go # HTTP handler unit tests
│ └── errors/
│ └── errors_test.go # Error handling tests
├── pkg/
│ └── uuid/
│ └── uuidv7_test.go # UUID generation tests
├── tests/
│ ├── integration_test.go # End-to-end integration tests
│ └── helpers.go # Test helpers and builders
└── scripts/
└── run-tests.sh # Test runner script
# Run all tests
go test ./...
# Run tests with verbose output
go test -v ./...
# Run tests with coverage
go test -cover ./...# Run comprehensive test suite
./scripts/run-tests.shThe test script provides:
- ✅ Colored output for better readability
- 📊 Test coverage reporting
- 🏃 Benchmark execution
- 📈 Summary statistics
# Test specific packages
go test ./internal/processing -v
go test ./internal/server -v
go test ./tests -v
# Run benchmarks
go test ./internal/processing -bench=.
go test ./tests -bench=.Location: Alongside source code in *_test.go files
Purpose: Test individual components in isolation
Examples:
- Message validation logic
- UUID generation
- Error handling
- Processing algorithms
- Delivery mechanisms
Key Features:
- Mock dependencies for isolation
- Fast execution
- High code coverage
- Edge case testing
Location: tests/integration_test.go
Purpose: Test complete request/response flows
Coverage:
- HTTP API endpoints
- Message lifecycle (send → process → deliver → status)
- Error handling across components
- Coordination types (parallel, sequential, conditional)
- Idempotency verification
Key Features:
- Real HTTP server testing
- End-to-end message flows
- Error scenario validation
- Performance benchmarking
Location: tests/helpers.go and internal/processing/test_utils.go
Purpose: Provide reusable test infrastructure
Components:
- TestMessageBuilder: Fluent interface for creating test messages
- TestSendRequestBuilder: Builder for API requests
- TestDataGenerator: Random test data generation
- MockDiscovery: Mock DNS discovery service
- MockDeliveryEngine: Mock message delivery
- TestAssertions: Common validation helpers
// Using the builder pattern
message := NewTestMessage().
WithSender("test@example.com").
WithRecipients("recipient1@test.com", "recipient2@test.com").
WithSubject("Test Message").
WithParallelCoordination(30).
Build()// Setup mocks
discovery := NewMockDiscovery()
discovery.SetCapabilities("test.com", &dns.AMTPCapabilities{
Version: "1.0",
Gateway: "https://test.com",
MaxSize: 10485760,
})
deliveryEngine := NewMockDeliveryEngine()
deliveryEngine.SetDeliveryResult("recipient@test.com", &DeliveryResult{
Status: types.StatusDelivered,
})// Create test server
server := createTestServer(t)
defer server.Close()
// Make request
resp, err := http.Post(server.URL+"/v1/messages", "application/json", body)// Test error scenarios
tests := []struct {
name string
request interface{}
expectedStatus int
expectedCode string
}{
{"Invalid JSON", "invalid json", 400, "INVALID_REQUEST_FORMAT"},
{"Missing Sender", request, 400, "VALIDATION_FAILED"},
}✅ Message Types and Validation
- Message structure validation
- Coordination configuration validation
- Schema format validation
- Size calculations
✅ Processing Engine
- Immediate path processing
- Coordination types (parallel, sequential, conditional)
- Idempotency checking
- Status tracking
- Error handling
✅ Delivery Engine
- HTTPS delivery
- Retry logic with exponential backoff
- Connection pooling
- Error classification
- Batch delivery
✅ HTTP Handlers
- Message sending endpoint
- Message retrieval
- Status queries
- Health checks
- Error responses
✅ Error Handling
- Error code standardization
- HTTP status mapping
- Error response formatting
- Retryable error classification
✅ Integration Flows
- Complete message lifecycle
- Multi-recipient scenarios
- Coordination patterns
- Error propagation
- Idempotency verification
- Unit Tests: >90% code coverage
- Integration Tests: All major user flows
- Error Scenarios: All error codes and edge cases
- Performance: Benchmark critical paths
const (
ValidMessageID = "01234567-89ab-7def-8123-456789abcdef"
ValidIdempotencyKey = "01234567-89ab-4def-8123-456789abcdef"
ValidEmail = "test@example.com"
ValidSchema = "agntcy:commerce.order.v1"
)
var (
SimplePayload = json.RawMessage(`{"message": "Hello, World!"}`)
ComplexPayload = json.RawMessage(`{
"order_id": "order-123",
"customer": {"id": "cust-456", "name": "John Doe"},
"items": [{"id": "item-1", "quantity": 2, "price": 19.99}],
"total": 69.97
}`)
)generator := NewTestDataGenerator()
email := generator.RandomEmail() // user123@example.com
emails := generator.RandomEmails(5) // []string{...}
subject := generator.RandomSubject() // "Important Update"
payload := generator.RandomPayload() // Random JSON
schema := generator.RandomSchema() // "agntcy:commerce.order.v1"
headers := generator.RandomHeaders() // map[string]interface{}# Run all benchmarks
go test -bench=. ./...
# Run specific benchmarks
go test -bench=BenchmarkProcessMessage ./internal/processing
go test -bench=BenchmarkDeliverMessage ./internal/processing
go test -bench=BenchmarkIntegration ./testsTypical performance characteristics:
- Message Processing: ~1ms per message (immediate path)
- HTTP Request Handling: ~2ms per request
- UUID Generation: ~100ns per UUID
- Message Validation: ~10μs per message
- Lint Check:
golangci-lint run - Unit Tests:
go test ./... -short - Integration Tests:
go test ./tests - Coverage Report:
go test -coverprofile=coverage.out ./... - Benchmark Regression:
go test -bench=. -benchmem
- ✅ All tests must pass
- ✅ Code coverage >85%
- ✅ No linting errors
- ✅ Benchmark performance within 10% of baseline
go test -v ./internal/processinggo test -run TestProcessMessage_ImmediatePath ./internal/processingdlv test ./internal/processing -- -test.run TestProcessMessage_ImmediatePathTests use structured logging that can be enabled:
// In test setup
logger := logging.NewLogger(config.LoggingConfig{Level: "debug"})func TestMessageLifecycle(t *testing.T) {
// 1. Send message
// 2. Verify processing
// 3. Check delivery status
// 4. Validate final state
}func TestErrorScenarios(t *testing.T) {
// 1. Invalid input
// 2. Processing failures
// 3. Delivery failures
// 4. Network errors
}func TestCoordinationTypes(t *testing.T) {
// 1. Parallel coordination
// 2. Sequential coordination
// 3. Conditional coordination
// 4. Mixed scenarios
}func BenchmarkHighLoad(b *testing.B) {
// 1. Setup test environment
// 2. Generate load
// 3. Measure performance
// 4. Validate results
}- Identify test category (unit/integration)
- Choose appropriate location (alongside code or tests/)
- Use existing patterns (builders, mocks, helpers)
- Follow naming conventions (TestFunctionName_Scenario)
- Add to test script if needed
- Keep tests in sync with code changes
- Update mocks when interfaces change
- Maintain test data validity
- Review coverage after changes
- Document complex test scenarios
- Explain mock configurations
- Provide examples for new patterns
- Update this guide when adding new test types
- Import cycles: Use interfaces and dependency injection
- Flaky tests: Avoid time dependencies, use mocks
- Slow tests: Optimize setup, use parallel execution
- Coverage gaps: Add tests for uncovered branches
- Check error messages for specific failures
- Verify test data is still valid
- Review recent changes that might affect tests
- Run tests in isolation to identify conflicts
- Load Testing: High-concurrency scenarios
- Chaos Testing: Network failures, service disruptions
- Contract Testing: API compatibility verification
- Security Testing: Authentication, authorization, input validation
- Performance Regression: Automated benchmark comparison
- Test Containers: Database and external service testing
- Test Fixtures: Standardized test data sets
- Test Reporting: Enhanced metrics and dashboards
- Parallel Execution: Faster test runs
This testing guide ensures comprehensive coverage of the AMTP Gateway functionality while maintaining high code quality and performance standards.