-
Notifications
You must be signed in to change notification settings - Fork 6
Description
Background
MCV currently has minimal test coverage with only 8 test files. There are no integration tests, E2E tests, or benchmarks.
Current State
$ find . -name "*_test.go" -type f | grep -v vendor | wc -l
8
Existing tests: Primarily unit tests, limited coverage of edge cases.
Missing:
- Integration tests with real GPU detection
- E2E tests for create/extract workflows
- Benchmark tests
- Test fixtures and mocks
- Multi-GPU architecture testing
Proposed Solution
Establish comprehensive test coverage across all major packages with unit, integration, and E2E tests.
Test Coverage Goals
Target: 80%+ code coverage for critical paths
Priority packages:
- pkg/cache/ - Cache detection and manifest generation
- pkg/accelerator/devices/ - GPU detection
- pkg/fetcher/ - Image fetching
- pkg/imgbuild/ - Image building
- pkg/preflightcheck/ - Compatibility validation
- pkg/client/ - Public API
Test Structure
tests/
├── unit/ # Unit tests (already colocated with code)
├── integration/ # Integration tests
│ ├── gpu_detection_test.go
│ ├── cache_extraction_test.go
│ ├── image_build_test.go
│ └── preflight_test.go
├── e2e/ # End-to-end tests
│ ├── create_extract_test.go
│ ├── multi_gpu_test.go
│ └── registry_ops_test.go
├── benchmarks/ # Performance benchmarks
│ ├── cache_bench_test.go
│ └── gpu_detection_bench_test.go
└── fixtures/ # Test data
├── triton-cache/
├── vllm-cache/
└── manifests/
Integration Tests
GPU Detection Tests:
// tests/integration/gpu_detection_test.go
func TestGPUDetection_NVIDIA(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test")
}
devices := detectNVIDIAGPUs()
assert.NotEmpty(t, devices)
for _, dev := range devices {
assert.NotEmpty(t, dev.Name)
assert.NotEmpty(t, dev.UUID)
assert.Greater(t, dev.MemoryTotalMB, uint64(0))
}
}
func TestGPUDetection_AMD(t *testing.T) {
// Similar test for AMD GPUs
}
Cache Creation/Extraction Tests:
// tests/integration/cache_extraction_test.go
func TestCreateExtractRoundtrip_Triton(t *testing.T) {
tmpDir := t.TempDir()
// Create image from test fixture
imageName := "localhost/test-cache:latest"
err := createImage(imageName, "fixtures/triton-cache")
require.NoError(t, err)
// Extract to temp directory
extractDir := filepath.Join(tmpDir, "extracted")
err = extractCache(imageName, extractDir)
require.NoError(t, err)
// Verify extracted cache matches original
assertCachesEqual(t, "fixtures/triton-cache", extractDir)
}
E2E Tests
Full workflow tests:
// tests/e2e/create_extract_test.go
func TestE2E_CompleteWorkflow(t *testing.T) {
// 1. Detect GPUs
gpus := detectSystemGPUs()
// 2. Create cache image
imageName := "localhost/e2e-test:latest"
createImageFromCache(imageName, testCacheDir)
// 3. Run preflight check
matched, unmatched := preflightCheck(imageName)
assert.NotEmpty(t, matched)
// 4. Extract cache
extractDir := t.TempDir()
extractCache(imageName, extractDir)
// 5. Verify cache works
verifyCacheFunctional(extractDir, gpus[0])
}
Test Utilities
Create test helpers:
// tests/testutil/helpers.go
package testutil
// AssertCachesEqual verifies two cache directories are identical
func AssertCachesEqual(t *testing.T, expected, actual string) {
// Compare file trees
// Verify manifests
// Check cache entries
}
// CreateTestCache generates a test cache directory
func CreateTestCache(t *testing.T, cacheType string) string {
// Generate minimal valid cache
}
// RunWithTimeout runs a test with timeout
func RunWithTimeout(t *testing.T, timeout time.Duration, fn func()) {
// Test timeout wrapper
}
Makefile Targets
Update Makefile
test: ## Run unit tests
go test -v -short ./...
test-integration: ## Run integration tests (requires GPU)
go test -v -run Integration ./tests/integration/...
test-e2e: ## Run E2E tests
go test -v ./tests/e2e/...
test-all: test test-integration test-e2e ## Run all tests
coverage: ## Generate coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
test-gpu-nvidia: ## Test with NVIDIA GPU
GPU_TYPE=nvidia go test -v ./tests/integration/...
test-gpu-amd: ## Test with AMD GPU
GPU_TYPE=amd go test -v ./tests/integration/...
CI Integration
# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- name: Run unit tests
run: make test
- name: Upload coverage
uses: codecov/codecov-action@v4
integration-tests-nvidia:
runs-on: [self-hosted, nvidia-gpu]
steps:
- uses: actions/checkout@v4
- name: Run NVIDIA tests
run: make test-gpu-nvidia
integration-tests-amd:
runs-on: [self-hosted, amd-gpu]
steps:
- uses: actions/checkout@v4
- name: Run AMD tests
run: make test-gpu-amdFiles to Create/Modify
- tests/integration/ - Integration test directory
- tests/e2e/ - E2E test directory
- tests/fixtures/ - Test fixtures
- tests/testutil/ - Test utilities
- pkg/accelerator/devices/mock.go - Enhanced mocks
- Makefile - Add test targets
- .github/workflows/test.yml - Test workflow
- Add tests for existing packages (fill gaps)
Acceptance Criteria
- Unit test coverage >80% for critical packages
- Integration tests for GPU detection (NVIDIA, AMD, stub)
- E2E tests for create/extract workflows
- Test fixtures for Triton and vLLM caches
- Mock/stub support for CI testing
- Makefile targets for different test types
- CI runs tests automatically on PRs
- Coverage reports uploaded to codecov
- Documentation on running tests
Benefits
- Catch bugs early in development
- Confidence in refactoring
- Better code quality
- Easier onboarding for contributors
- Validated multi-GPU support