provisioning-catalog/providers/hetzner/tests/README.md

341 lines
10 KiB
Markdown
Raw Permalink Normal View History

# Hetzner Provider Test Suite
Complete test infrastructure for the Hetzner provider with unit and integration tests (mock mode).
## Overview
The test suite includes:
- **Unit Tests** - Test individual utility functions (15 tests)
- **Integration Tests** - Test API client, server lifecycle, and pricing with mock responses (36 tests)
- **Mock API Responses** - Pre-defined JSON responses for all Hetzner Cloud API endpoints
## Test Structure
```bash
tests/
├── unit/
│ └── test_utils.nu # Utility functions (15 tests)
├── integration/
│ ├── test_api_client.nu # API client operations (13 tests)
│ ├── test_server_lifecycle.nu # Server CRUD operations (11 tests)
│ └── test_pricing_cache.nu # Pricing & caching (12 tests)
├── mocks/
│ └── mock_api_responses.json # Mock Hetzner API responses
└── run_hetzner_tests.nu # Main test runner
```
**Total Coverage**: ~51 tests across 4 test modules
## Running Tests
### Run All Tests
```bash
cd provisioning/extensions/providers/hetzner/tests
nu run_hetzner_tests.nu
```
### Run Specific Test Module
```bash
# Unit tests only
nu unit/test_utils.nu
# API client tests
nu integration/test_api_client.nu
# Server lifecycle tests
nu integration/test_server_lifecycle.nu
# Pricing & cache tests
nu integration/test_pricing_cache.nu
```
### Expected Output
```bash
╔═════════════════════════════════════════════════
═══════════╗
║ Hetzner Provider Test Suite - Mock Mode ║
╚═════════════════════════════════════════════════
═══════════╝
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━
Running UNIT TESTS...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━
✓ parse_server_identifier: string input
✓ parse_server_identifier: hostname field
✓ parse_server_identifier: name field
✓ parse_server_identifier: id field
✓ is_valid_ipv4: valid address
✓ is_valid_ipv4: invalid address
✓ is_valid_ipv4: malformed
✓ is_valid_ipv6: valid address
✓ is_valid_ipv6: invalid address
✓ extract_api_error: from error.message
✓ extract_api_error: from message
✓ extract_api_error: fallback to string
✓ validate_server_config: valid config
✓ validate_server_config: missing fields
✓ validate_server_config: empty hostname
Test Summary:
Passed: 15/15
Failed: 0/15
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━
Running INTEGRATION TESTS (Mock Mode)...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━
📋 API Client Tests...
✓ GET /servers: response structure
✓ GET /servers: returns list
✓ GET /servers/{id}: single server response
✓ GET /volumes: returns list
✓ GET /networks: returns list
✓ GET /floating_ips: returns list
✓ GET /server_types: returns list
✓ server_types: pricing structure
✓ error_response: 401 Unauthorized format
✓ error_response: 404 Not Found format
✓ response: contains servers
✓ error_handling: unknown endpoint fails
✓ response: server ID is integer
Test Summary:
Passed: 13/13
Failed: 0/13
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━
🖥️ Server Lifecycle Tests...
✓ list_servers: returns list
✓ server_info: has required fields
✓ server_info: name matches request
✓ server_info: status is running
✓ server_info: public IPs present
✓ server_info: server type details available
✓ create_server: response has required fields
✓ server_info: error on nonexistent server
✓ list_servers: contains servers
✓ server_status: valid status value
✓ server_location: location data complete
Test Summary:
Passed: 11/11
Failed: 0/11
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━
💰 Pricing & Cache Tests...
✓ get_pricing: returns pricing data
✓ pricing: server type structure
✓ pricing: hourly rate field
✓ pricing: monthly rate field
✓ cache: create entry structure
✓ cache: read entry
✓ cache: timestamp is integer
✓ pricing: net and gross prices
✓ pricing: multiple server types
✓ cache: preserves server name
✓ pricing: volume per GB calculation
✓ pricing: standard server types available
Test Summary:
Passed: 12/12
Failed: 0/12
╔═════════════════════════════════════════════════
═══════════╗
║ TEST RESULTS SUMMARY ║
╚═════════════════════════════════════════════════
═══════════╝
Test Suites:
✓ Passed: 4
✗ Failed: 0
Total: 4
Individual Tests:
✓ Passed: 51
Total: 51
✨ All tests passed! ✨
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━
Test Duration: < 5 seconds (mock mode)
Mode: Mock API (no real Hetzner Cloud calls)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━━━━
```
## Test Coverage
### Unit Tests (test_utils.nu)
Tests utility functions from `nulib/hetzner/utils.nu`:
- `parse_server_identifier` - Parse server from different formats (string, hostname, id)
- `is_valid_ipv4` - Validate IPv4 addresses
- `is_valid_ipv6` - Validate IPv6 addresses
- `extract_api_error` - Extract error messages from API responses
- `validate_server_config` - Validate server configuration before creation
### Integration Tests (API Client)
Tests API client operations with mock responses:
- GET requests to various endpoints (/servers, /volumes, /networks, /floating_ips)
- Response structure validation
- Error handling (401, 404, 429 status codes)
- Data type validation
### Integration Tests (Server Lifecycle)
Tests server CRUD operations with mocks:
- List servers
- Get server info
- Server creation
- Server state transitions
- Server configuration structure
### Integration Tests (Pricing & Cache)
Tests pricing calculations and caching:
- Get pricing data
- Server type pricing structure
- Hourly/monthly rate calculation
- Cache entry creation and retrieval
- Volume pricing per GB
## Mock API Responses
Mock responses are stored in `mocks/mock_api_responses.json` and include:
- `servers_list` - List of servers
- `server_info` - Single server details
- `server_create_success` - Response from server creation
- `volumes_list` - List of volumes
- `networks_list` - List of networks
- `floating_ips_list` - List of floating IPs
- `server_types_list` - Available server types with pricing
- `error_401` - Unauthorized error response
- `error_404` - Not found error response
- `error_429` - Rate limit error response
## Performance
All tests use mock API responses (no real Hetzner Cloud calls):
- **Total test duration**: < 5 seconds
- **Test count**: ~51 individual tests
- **Test suites**: 4 modules
- **Reliability**: 100% (deterministic, no API dependencies)
## Running Tests in CI/CD
The test suite is designed for CI/CD integration:
```bash
#!/bin/bash
# In GitHub Actions or similar CI system
cd provisioning/extensions/providers/hetzner/tests
nu run_hetzner_tests.nu
# Exit with appropriate code
if [ $? -eq 0 ]; then
echo "All tests passed"
exit 0
else
echo "Tests failed"
exit 1
fi
```
## Adding New Tests
To add a new test:
1. Create test function following the pattern
2. Add to main runner in `run_hetzner_tests.nu`
3. Update mock responses if needed in `mocks/mock_api_responses.json`
Example test function:
```python
def test_my_feature []: nothing -> record {
let result = (do {
let response = (mock-http-response "/endpoint")
($response | has field)
} | complete)
let passed = ($result.exit_code == 0 and $result.stdout)
test-result "feature: description" $passed
}
```
## Features
- **Mock API Responses** - Pre-defined responses for all endpoints
- **Nushell 0.109.0+** - Uses `do { } | complete` pattern (no try-catch)
- **Deterministic** - Same input always produces same output
- **Offline** - No internet connection required
- **Fast** - All tests complete in < 5 seconds
- **CI/CD Ready** - Exit codes and structured output
## Notes
- Tests use only **mock API responses** - no real Hetzner Cloud API calls
- Tests follow **Nushell 0.109.0+** guidelines (no try-catch, use do/complete)
- All tests are **deterministic** - reliable for CI/CD pipelines
- Tests can run **offline** - no internet connection required
- All test output is **human-readable** with emojis and formatting
## Real API Testing (Optional Future)
To add real API integration tests:
1. Set `HCLOUD_TOKEN` environment variable
2. Create test account/project in Hetzner Cloud
3. Add `tests/real/test_real_api.nu` with real API calls
4. Document cleanup procedures to avoid orphaned resources
## Troubleshooting
### Tests fail with file not found
Make sure you're running tests from the `tests/` directory:
```bash
cd provisioning/extensions/providers/hetzner/tests
nu run_hetzner_tests.nu
```
### Mock responses not loading
Verify mock file exists:
```bash
ls -la mocks/mock_api_responses.json
```
### Nushell version issues
Ensure Nushell 0.109.0+:
```nushell
nu --version
```
## Related Documentation
- [Provider README](../README.md)
- [Nushell Guidelines](../../../../.claude/guidelines/nushell.md)
- [Hetzner API Docs](https://docs.hetzner.cloud/)