# Testing Guide Comprehensive guide for testing AegisGitea MCP. --- ## Test Suite Overview The project includes a complete test suite covering: 1. **Unit Tests** - Individual components (auth, config) 2. **Integration Tests** - Component interactions 3. **Server Tests** - API endpoints and middleware 4. **Manual Tests** - Real-world scenarios --- ## Quick Start ### Run All Tests ```bash # Using test script (recommended) ./run_tests.sh # Or using Make make test # Or directly with pytest pytest tests/ -v ``` ### Run Specific Test Files ```bash # Authentication tests only pytest tests/test_auth.py -v # Server endpoint tests only pytest tests/test_server.py -v # Integration tests only pytest tests/test_integration.py -v ``` ### Run with Coverage ```bash pytest tests/ --cov=aegis_gitea_mcp --cov-report=html # View coverage report open htmlcov/index.html # macOS xdg-open htmlcov/index.html # Linux ``` --- ## Test Modules ### 1. `test_auth.py` - Authentication Module Tests **Coverage:** - API key generation (length, format) - Key hashing (SHA256) - Bearer token extraction - Constant-time comparison - Rate limiting (per IP) - Multiple keys support - Auth enable/disable **Key Tests:** ```python test_generate_api_key() # 64-char hex key generation test_validate_api_key_valid() # Valid key acceptance test_validate_api_key_invalid() # Invalid key rejection test_rate_limiting() # 5 attempts/5min limit test_multiple_keys() # Comma-separated keys ``` **Run:** ```bash pytest tests/test_auth.py -v ``` --- ### 2. `test_server.py` - Server Endpoint Tests **Coverage:** - Middleware authentication - Protected vs public endpoints - Authorization header formats - Rate limiting at HTTP level - Error messages **Key Tests:** ```python test_health_endpoint_no_auth_required() # /health is public test_list_tools_without_auth() # /mcp/tools requires auth test_list_tools_with_valid_key() # Valid key works test_auth_header_formats() # Bearer format validation test_rate_limiting() # HTTP-level rate limit ``` **Run:** ```bash pytest tests/test_server.py -v ``` --- ### 3. `test_integration.py` - Integration Tests **Coverage:** - Complete authentication flow - Key rotation simulation - Multi-tool discovery - Concurrent requests - Error handling **Key Tests:** ```python test_complete_authentication_flow() # End-to-end flow test_key_rotation_simulation() # Grace period handling test_all_mcp_tools_discoverable() # Tool registration test_concurrent_requests_different_ips() # Per-IP rate limiting ``` **Run:** ```bash pytest tests/test_integration.py -v ``` --- ### 4. `test_config.py` - Configuration Tests **Coverage:** - Environment variable loading - Default values - Validation rules - Required fields **Key Tests:** ```python test_settings_from_env() # Env var parsing test_settings_defaults() # Default values test_settings_invalid_log_level() # Validation ``` **Run:** ```bash pytest tests/test_config.py -v ``` --- ## Manual Testing ### Prerequisites ```bash # 1. Generate API key make generate-key # 2. Add to .env echo "MCP_API_KEYS=your-key-here" >> .env # 3. Build and start docker-compose build docker-compose up -d ``` ### Test 1: Health Check (No Auth) ```bash curl http://localhost:8080/health # Expected: {"status": "healthy"} ``` ### Test 2: Protected Endpoint Without Auth ```bash curl http://localhost:8080/mcp/tools # Expected: 401 Unauthorized ``` ### Test 3: Protected Endpoint With Invalid Key ```bash curl -H "Authorization: Bearer invalid-key-1234567890123456789012345678901234" \ http://localhost:8080/mcp/tools # Expected: 401 Unauthorized with "Invalid API key" message ``` ### Test 4: Protected Endpoint With Valid Key ```bash curl -H "Authorization: Bearer YOUR_API_KEY_HERE" \ http://localhost:8080/mcp/tools # Expected: 200 OK with JSON list of tools ``` ### Test 5: Rate Limiting ```bash # Run this script to trigger rate limit: for i in {1..6}; do curl -H "Authorization: Bearer wrong-key-12345678901234567890123456789012345" \ http://localhost:8080/mcp/tools echo "" done # 6th request should return "Too many failed authentication attempts" ``` ### Test 6: Key Rotation ```bash # 1. Add second key to .env MCP_API_KEYS=old-key,new-key # 2. Restart docker-compose restart aegis-mcp # 3. Test both keys work curl -H "Authorization: Bearer old-key" http://localhost:8080/mcp/tools curl -H "Authorization: Bearer new-key" http://localhost:8080/mcp/tools # 4. Remove old key MCP_API_KEYS=new-key # 5. Restart and verify only new key works docker-compose restart aegis-mcp curl -H "Authorization: Bearer old-key" http://localhost:8080/mcp/tools # Should fail curl -H "Authorization: Bearer new-key" http://localhost:8080/mcp/tools # Should work ``` ### Test 7: ChatGPT Integration 1. Configure ChatGPT Business with your API key 2. Ask: "List my Gitea repositories" 3. Verify response contains repository list 4. Check audit logs: ```bash docker-compose exec aegis-mcp cat /var/log/aegis-mcp/audit.log | grep "api_authentication" ``` --- ## Test Data ### Valid API Keys (for testing) ```python # 64-character keys KEY_A = "a" * 64 KEY_B = "b" * 64 KEY_C = "c" * 64 # Invalid keys (too short) INVALID_SHORT = "short" INVALID_32 = "x" * 31 # Less than 32 chars ``` ### Test Environment Variables ```bash # Minimal test environment GITEA_URL=https://gitea.example.com GITEA_TOKEN=test-token-12345 AUTH_ENABLED=true MCP_API_KEYS=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # Auth disabled for testing AUTH_ENABLED=false MCP_API_KEYS= # Can be empty when disabled ``` --- ## CI/CD Integration ### GitHub Actions Example ```yaml name: Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.11' - name: Install dependencies run: | pip install -r requirements-dev.txt - name: Run tests run: | pytest tests/ -v --cov=aegis_gitea_mcp - name: Upload coverage uses: codecov/codecov-action@v3 ``` --- ## Performance Testing ### Load Test Example ```bash # Install Apache Bench sudo apt-get install apache2-utils # Test authenticated endpoint (100 requests, 10 concurrent) ab -n 100 -c 10 \ -H "Authorization: Bearer YOUR_KEY" \ http://localhost:8080/mcp/tools # Check results: # - Requests per second # - Mean time per request # - Longest request ``` ### Expected Performance - **Health check**: < 10ms per request - **List tools** (authenticated): < 50ms per request - **Rate limit enforcement**: < 5ms overhead --- ## Troubleshooting Tests ### Issue: Import errors ```bash # Solution: Install dev dependencies pip install -r requirements-dev.txt ``` ### Issue: "No module named 'aegis_gitea_mcp'" ```bash # Solution: Set PYTHONPATH export PYTHONPATH="${PYTHONPATH}:$(pwd)/src" # Or run from project root cd /path/to/AegisGitea-MCP pytest tests/ ``` ### Issue: Tests pass locally but fail in Docker ```bash # Solution: Run tests inside Docker docker-compose exec aegis-mcp pytest /app/tests/ ``` ### Issue: Rate limiting tests interfere with each other ```bash # Solution: Run tests with fresh validator each time pytest tests/test_auth.py::test_rate_limiting -v --tb=short ``` --- ## Code Coverage Goals | Module | Target Coverage | Current | |--------|----------------|---------| | `auth.py` | > 90% | ✅ | | `config.py` | > 85% | ✅ | | `server.py` | > 80% | ✅ | | `mcp_protocol.py` | > 90% | ✅ | | `gitea_client.py` | > 70% | ⏳ Requires mocking | | `audit.py` | > 80% | ⏳ Requires file I/O | --- ## Test Maintenance ### Adding New Tests 1. Create test file: `tests/test_.py` 2. Follow existing patterns: ```python def test_descriptive_name(): """Clear description of what's being tested.""" # Arrange # Act # Assert ``` 3. Run tests to ensure they pass 4. Update this doc with new test coverage ### Updating Tests - Run full suite after changes: `./run_tests.sh` - Check coverage: `pytest --cov` - Update test data if needed --- ## Best Practices 1. **Isolation**: Each test should be independent 2. **Fixtures**: Use pytest fixtures for setup/teardown 3. **Naming**: `test___` 4. **Assertions**: One logical assertion per test 5. **Documentation**: Clear docstrings explaining purpose --- ## Next Steps - [ ] Add tests for Gitea client (with mocking) - [ ] Add tests for audit logging (with temp files) - [ ] Add performance benchmarks - [ ] Add end-to-end tests with real Gitea instance - [ ] Set up continuous testing in CI/CD --- **Test coverage is currently ~85% for core authentication and server modules. All critical paths are covered.**