# 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/)