VM Tracker Client - Unit Tests¶
Overview¶
This project contains comprehensive unit tests for the VM Tracker Client, written in Go.
Test Coverage¶
Current Coverage: 27.7% of statements (focused on testable business logic)
Detailed Coverage by Function:¶
| Function | Coverage | Description |
|---|---|---|
getHostname |
60.0% | Tests for hostname detection |
getIPAddress |
81.8% | Tests for IP address detection |
Post (DefaultHTTPClient) |
100.0% | HTTP client wrapper |
sendRegistrationWithClient |
83.3% | Registration logic with mock HTTP client |
Note: The main() function (0% coverage) is not tested as it contains orchestration logic that is better covered by integration tests.
Test Categories¶
1. JSON Marshaling/Unmarshaling Tests¶
TestVMInfoJSONMarshaling: Tests correct serialization and deserialization of VMInfo- Covers normal cases, empty fields, and special characters
- Ensures JSON tags work correctly
2. Hostname Tests¶
TestGetHostname: Validates hostname detection- Verifies that a valid hostname is returned
3. IP Address Tests¶
TestGetIPAddress: Comprehensive tests for network interface detection- Valid interface names
- Invalid interface names
- Empty interface names
- Validates IPv4 format
- Automatically detects available network interfaces
4. HTTP Registration Tests¶
TestSendRegistrationSuccess: Successful registrationTestSendRegistrationHTTPErrors: HTTP error scenarios- 400 Bad Request
- 401 Unauthorized
- 404 Not Found
- 500 Internal Server Error
- 503 Service Unavailable
- Network connection errors
TestSendRegistrationURLFormatting: URL formatting- URLs with/without trailing slash
- URLs with port
- HTTPS URLs
- Localhost
5. Edge Cases & Validation¶
TestVMInfoFieldValidation: Field validation- Very long hostnames (255 characters)
- IPv6-mapped IPv4 addresses
- Complex interface names
TestDefaultHTTPClient: HTTP client wrapper
Benchmarks¶
Performance tests for critical operations:
BenchmarkVMInfoMarshaling-8 11367013 110.8 ns/op 80 B/op 1 allocs/op
BenchmarkVMInfoUnmarshaling-8 1992078 606.0 ns/op 296 B/op 8 allocs/op
Interpretation: - Marshaling: ~111 ns per operation, very efficient - Unmarshaling: ~606 ns per operation, acceptable for JSON parsing - Low memory allocations
Running Tests¶
Run all tests:¶
Tests with coverage:¶
Detailed coverage report:¶
HTML coverage visualization:¶
go test -coverprofile=coverage.out
go tool cover -html=coverage.out -o coverage.html
# Open coverage.html in a browser
Run benchmarks:¶
Run specific tests:¶
# Only JSON tests
go test -v -run TestVMInfoJSON
# Only IP address tests
go test -v -run TestGetIPAddress
# Only HTTP tests
go test -v -run TestSendRegistration
Mock Architecture¶
The tests use a mock-based architecture for HTTP calls:
HTTPClient Interface¶
type HTTPClient interface {
Post(url, contentType string, body *bytes.Buffer) (*http.Response, error)
}
Benefits:¶
- ✅ No real network calls in tests
- ✅ Full control over HTTP responses
- ✅ Tests are fast and deterministic
- ✅ Easy testing of error scenarios
- ✅ No external dependencies
Code Changes for Testability¶
The main.go was minimally refactored:
- HTTPClient Interface: Enables mocking of HTTP calls
- DefaultHTTPClient: Production implementation
- sendRegistrationWithClient: Testable version with dependency injection
- sendRegistration: Wrapper for production code (unchanged API)
These changes: - ✅ Don't break existing functionality - ✅ Are backwards compatible - ✅ Enable comprehensive tests without real network calls
Best Practices¶
The tests follow Go best practices:
- Table-Driven Tests: Multiple test cases in one test function
- Subtests: Structured organization with
t.Run() - Clear Naming: Descriptive test and subtest names
- Mocking: Interface-based mocking for external dependencies
- Error Checking: Comprehensive error handling
- Benchmarking: Performance measurements for critical paths
Continuous Integration¶
These tests can easily be integrated into CI/CD pipelines:
# Example GitHub Actions
- name: Run tests
run: go test -v -coverprofile=coverage.out
- name: Upload coverage
run: go tool cover -html=coverage.out -o coverage.html
Future Enhancements¶
Possible test extensions:
- [ ] Integration tests for the entire main() function
- [ ] Tests for signal handling (SIGTERM, SIGINT)
- [ ] Tests for retry logic
- [ ] Tests for ticker-based updates
- [ ] Mock server for end-to-end tests
- [ ] Property-based tests with fuzzing
Troubleshooting¶
Tests fail with "no valid network interface"¶
- This is normal when no non-loopback IPv4 interfaces are available
- The test is automatically skipped (
t.Skip())
Coverage seems low¶
- The 27.7% coverage focuses on business logic
- main() and orchestration are intentionally not tested
- These are better covered by integration tests
Contact¶
For questions or problems with the tests, please create an issue.