This commit includes: ## Audit & Testing Infrastructure - scripts/audit.sh: 12-section comprehensive codebase audit - scripts/test.sh: 7 test types (unit, integration, race, bench, coverage, contracts, pkg) - scripts/check-compliance.sh: SPEC.md compliance validation - scripts/check-docs.sh: Documentation coverage checker - scripts/dev.sh: Unified development script with all commands ## Documentation - SPEC.md: Authoritative technical specification - docs/AUDIT_AND_TESTING.md: Complete testing guide (600+ lines) - docs/SCRIPTS_REFERENCE.md: All scripts documented (700+ lines) - docs/README.md: Documentation index and navigation - docs/DEVELOPMENT_SETUP.md: Environment setup guide - docs/REFACTORING_PLAN.md: Systematic refactoring plan ## Phase 1 Refactoring (Critical Fixes) - pkg/validation/helpers.go: Validation functions for addresses/amounts - pkg/sequencer/selector_registry.go: Thread-safe selector registry - pkg/sequencer/reader.go: Fixed race conditions with atomic metrics - pkg/sequencer/swap_filter.go: Fixed race conditions, added error logging - pkg/sequencer/decoder.go: Added address validation ## Changes Summary - Fixed race conditions on 13 metric counters (atomic operations) - Added validation at all ingress points - Eliminated silent error handling - Created selector registry for future ABI migration - Reduced SPEC.md violations from 7 to 5 Build Status: ✅ All packages compile Compliance: ✅ No race conditions, no silent failures Documentation: ✅ 1,700+ lines across 5 comprehensive guides 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
8.5 KiB
Audit and Testing Guide
Comprehensive guide for testing and auditing the MEV bot codebase.
Quick Reference
# Run everything
./scripts/dev.sh test all # All tests
./scripts/dev.sh audit # Code quality audit
./scripts/dev.sh check-compliance # SPEC.md compliance
./scripts/dev.sh check-docs # Documentation coverage
# Specific tests
./scripts/dev.sh test unit # Unit tests only
./scripts/dev.sh test coverage # Coverage report
./scripts/dev.sh test race # Race detection
./scripts/dev.sh test bench # Benchmarks
Testing Suite
1. Unit Tests
Fast tests that verify individual components in isolation.
# Run all unit tests
./scripts/dev.sh test unit
# Run tests for specific package
./scripts/dev.sh test pkg sequencer
# Verbose output
./scripts/test.sh unit true
What it tests:
- Individual function correctness
- Edge cases and error handling
- Component behavior in isolation
Files: All *_test.go files in pkg/
2. Integration Tests
Tests that verify components work together correctly.
# Run integration tests
./scripts/dev.sh test integration
What it tests:
- Sequencer → Swap Filter → Pool Cache pipeline
- Database operations
- External service interactions
Files: tests/*_integration_test.go
3. Race Detection
Detects data races in concurrent code.
# Run with race detector
./scripts/dev.sh test race
What it checks:
- Concurrent access to shared state
- Mutex usage correctness
- Channel safety
Important: Always run before committing concurrent code changes.
4. Benchmarks
Performance testing for critical paths.
# Run benchmarks
./scripts/dev.sh test bench
What it measures:
- Swap parsing throughput
- Pool cache lookup speed
- Channel message processing rate
Files: Functions named Benchmark* in *_test.go
5. Coverage Report
Measures test coverage percentage.
# Generate coverage report
./scripts/dev.sh test coverage
Output:
coverage/coverage.out- Coverage datacoverage/coverage.html- HTML report (open in browser)
Target: >70% coverage for production code
Audit Suite
1. Codebase Audit
Comprehensive code quality and security check.
./scripts/dev.sh audit
Checks:
Code Quality
go vetwarnings- TODO/FIXME comments
- panic() usage
- Error handling patterns
Security
- Hardcoded secrets
- SQL injection risks
- Command injection
- Unsafe pointer usage
Concurrency
- Race condition risks
- Mutex coverage
- Channel usage
SPEC.md Compliance
- Hardcoded function selectors (forbidden)
- HTTP RPC in sequencer (forbidden)
- Blocking operations in hot paths (forbidden)
- Manual ABI files (forbidden)
Exit codes:
- 0: No issues
- 1: Issues found (review required)
2. Documentation Coverage
Verifies all code is properly documented.
./scripts/dev.sh check-docs
Checks:
- Package
doc.gofiles - Exported function comments
- Exported type comments
- README files in key directories
- Project documentation (SPEC.md, CLAUDE.md, etc.)
- Inline comment density
Target: >80% documentation coverage
3. SPEC.md Compliance
Ensures code adheres to all SPEC.md requirements.
./scripts/dev.sh check-compliance
Validates:
MUST DO ✅
- ✓ Use Arbitrum sequencer feed
- ✓ Channel-based communication
- ✓ Official contract ABIs
- ✓ Generated bindings
- ✓ Data validation
- ✓ Thread-safe structures
- ✓ Comprehensive metrics
- ✓ Container-based development
MUST NOT DO ❌
- ✗ HTTP RPC in sequencer
- ✗ Manual ABI files
- ✗ Hardcoded selectors
- ✗ Zero addresses/amounts propagation
- ✗ Blocking operations
- ✗ Unprotected shared state
- ✗ Silent failures
Exit codes:
- 0: Fully compliant
- 1: Violations found
Continuous Integration
Pre-Commit Checks
Run before every commit:
# Quick validation
./scripts/dev.sh test unit
./scripts/dev.sh check-compliance
# Full pre-commit
./scripts/dev.sh test all
./scripts/dev.sh audit
Pre-Push Checks
Run before pushing to remote:
# Comprehensive check
./scripts/dev.sh test all
./scripts/dev.sh test race
./scripts/dev.sh audit
./scripts/dev.sh check-compliance
./scripts/dev.sh check-docs
Pre-Release Checks
Run before creating a release:
# Full audit
./scripts/dev.sh test coverage # Ensure >70%
./scripts/dev.sh test bench # Check performance
./scripts/dev.sh audit # Security & quality
./scripts/dev.sh check-compliance # SPEC.md adherence
./scripts/dev.sh check-docs # Documentation complete
Test Writing Guidelines
Unit Test Example
// pkg/sequencer/swap_filter_test.go
func TestSwapFilter_DetectUniswapV2Swap(t *testing.T) {
// Setup
filter := NewSwapFilter(logger, poolCache)
// Create test message with known swap
msg := map[string]interface{}{
"messages": []interface{}{
map[string]interface{}{
"message": map[string]interface{}{
"l2Msg": base64EncodedSwapTx,
},
},
},
}
// Execute
filter.ProcessMessage(msg)
// Verify
select {
case swap := <-filter.SwapCh():
assert.Equal(t, "UniswapV2", swap.Protocol.Name)
assert.NotEqual(t, common.Address{}, swap.Pool.Address)
case <-time.After(time.Second):
t.Fatal("timeout waiting for swap event")
}
}
Benchmark Example
// pkg/pools/cache_bench_test.go
func BenchmarkPoolCache_Lookup(b *testing.B) {
cache := NewPoolCache(...)
// Pre-populate cache
for i := 0; i < 1000; i++ {
cache.AddOrUpdate(generateTestPool())
}
addr := testPoolAddress
b.ResetTimer()
for i := 0; i < b.N; i++ {
cache.Get(addr)
}
}
Integration Test Example
// tests/sequencer_integration_test.go
func TestSequencerToPoolCache_Pipeline(t *testing.T) {
// Start real sequencer feed
reader := sequencer.NewReader(config)
swapFilter := sequencer.NewSwapFilter(logger, poolCache)
// Connect pipeline
go reader.Start(ctx)
go swapFilter.Start(ctx)
// Wait for real swaps from mainnet
timeout := time.After(30 * time.Second)
swapsFound := 0
for swapsFound < 5 {
select {
case swap := <-swapFilter.SwapCh():
// Verify swap is valid
assert.NotEqual(t, common.Address{}, swap.Pool.Address)
swapsFound++
case <-timeout:
t.Fatalf("only found %d swaps in 30s", swapsFound)
}
}
}
Common Issues
Issue: Tests timeout
Cause: Blocking operations in tests
Fix:
// Bad
time.Sleep(10 * time.Second)
// Good
select {
case result := <-resultCh:
// ...
case <-time.After(5 * time.Second):
t.Fatal("timeout")
}
Issue: Race detector reports races
Cause: Unprotected shared state
Fix:
// Bad
var counter int
func increment() { counter++ }
// Good
var mu sync.Mutex
var counter int
func increment() {
mu.Lock()
defer mu.Unlock()
counter++
}
Issue: Low coverage
Cause: Missing test cases
Fix:
- Identify uncovered code:
go tool cover -func=coverage/coverage.out - Add tests for edge cases
- Test error paths
- Add table-driven tests
Metrics and Monitoring
Coverage Trends
Track coverage over time:
# Generate report
./scripts/dev.sh test coverage
# View current coverage
grep "total:" coverage/coverage.out
Performance Baselines
Establish performance baselines:
# Run benchmarks
./scripts/dev.sh test bench > benchmarks/baseline-$(date +%Y%m%d).txt
# Compare with previous
benchstat benchmarks/baseline-old.txt benchmarks/baseline-new.txt
CI/CD Integration
GitHub Actions Example
name: Test Suite
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Start dev environment
run: ./scripts/dev.sh up
- name: Run tests
run: ./scripts/dev.sh test all
- name: Run audit
run: ./scripts/dev.sh audit
- name: Check compliance
run: ./scripts/dev.sh check-compliance
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
file: ./coverage/coverage.out
References
- Go Testing Package
- Table Driven Tests
- Go Race Detector
- SPEC.md - Technical requirements
- CLAUDE.md - Development guidelines