Skip to content

MCV: Improve test coverage and add comprehensive integration tests #150

Description

@maryamtahhan

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:

  1. pkg/cache/ - Cache detection and manifest generation
  2. pkg/accelerator/devices/ - GPU detection
  3. pkg/fetcher/ - Image fetching
  4. pkg/imgbuild/ - Image building
  5. pkg/preflightcheck/ - Compatibility validation
  6. 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-amd

Files 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions