mirror of
https://github.com/luxfi/ai.git
synced 2026-10-30 17:02:43 +00:00
Format capability.go, capability_test.go, rewards.go, scoring_test.go, tier.go, and tier_test.go to pass pre-flight checks.
1889 lines
51 KiB
Go
1889 lines
51 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package cc
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
// =============================================================================
|
|
// Mock Implementations for Testing
|
|
// =============================================================================
|
|
|
|
// MockCommandRunner returns predefined outputs for specific commands
|
|
type MockCommandRunner struct {
|
|
outputs map[string][]byte
|
|
errors map[string]error
|
|
}
|
|
|
|
func NewMockCommandRunner() *MockCommandRunner {
|
|
return &MockCommandRunner{
|
|
outputs: make(map[string][]byte),
|
|
errors: make(map[string]error),
|
|
}
|
|
}
|
|
|
|
func (m *MockCommandRunner) SetOutput(cmd string, output []byte) {
|
|
m.outputs[cmd] = output
|
|
}
|
|
|
|
func (m *MockCommandRunner) SetError(cmd string, err error) {
|
|
m.errors[cmd] = err
|
|
}
|
|
|
|
func (m *MockCommandRunner) Run(cmd string, args ...string) ([]byte, error) {
|
|
if err, ok := m.errors[cmd]; ok {
|
|
return nil, err
|
|
}
|
|
if output, ok := m.outputs[cmd]; ok {
|
|
return output, nil
|
|
}
|
|
return nil, errors.New("command not found: " + cmd)
|
|
}
|
|
|
|
// MockFileReader returns predefined content for specific paths
|
|
type MockFileReader struct {
|
|
files map[string][]byte
|
|
stats map[string]bool // true = exists, false = not exists
|
|
}
|
|
|
|
func NewMockFileReader() *MockFileReader {
|
|
return &MockFileReader{
|
|
files: make(map[string][]byte),
|
|
stats: make(map[string]bool),
|
|
}
|
|
}
|
|
|
|
func (m *MockFileReader) SetFile(path string, content []byte) {
|
|
m.files[path] = content
|
|
m.stats[path] = true
|
|
}
|
|
|
|
func (m *MockFileReader) SetExists(path string, exists bool) {
|
|
m.stats[path] = exists
|
|
}
|
|
|
|
func (m *MockFileReader) ReadFile(path string) ([]byte, error) {
|
|
if content, ok := m.files[path]; ok {
|
|
return content, nil
|
|
}
|
|
return nil, os.ErrNotExist
|
|
}
|
|
|
|
func (m *MockFileReader) Stat(path string) (os.FileInfo, error) {
|
|
if exists, ok := m.stats[path]; ok && exists {
|
|
return nil, nil // FileInfo not needed, just no error means exists
|
|
}
|
|
return nil, os.ErrNotExist
|
|
}
|
|
|
|
// =============================================================================
|
|
// NVIDIA Detection Tests
|
|
// =============================================================================
|
|
|
|
func TestDetectNVIDIACapabilities_H100(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
fileReader := NewMockFileReader()
|
|
|
|
// Simulate nvidia-smi output for H100
|
|
cmdRunner.SetOutput("nvidia-smi", []byte("NVIDIA H100 80GB HBM3, 81920, 535.154.05, GPU-12345678-1234-1234-1234-123456789012\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectNVIDIACapabilitiesWithDeps(cap, cmdRunner, fileReader)
|
|
|
|
if !result {
|
|
t.Fatal("Expected detection to succeed")
|
|
}
|
|
if cap.GPUVendor != VendorNVIDIA {
|
|
t.Errorf("Expected vendor NVIDIA, got %v", cap.GPUVendor)
|
|
}
|
|
if cap.GPUModel != "NVIDIA H100 80GB HBM3" {
|
|
t.Errorf("Expected model 'NVIDIA H100 80GB HBM3', got %s", cap.GPUModel)
|
|
}
|
|
if cap.GPUMemoryMB != 81920 {
|
|
t.Errorf("Expected memory 81920 MB, got %d", cap.GPUMemoryMB)
|
|
}
|
|
if cap.GPUDriverVer != "535.154.05" {
|
|
t.Errorf("Expected driver 535.154.05, got %s", cap.GPUDriverVer)
|
|
}
|
|
if cap.ComputeCap != "9.0" {
|
|
t.Errorf("Expected compute cap 9.0, got %s", cap.ComputeCap)
|
|
}
|
|
if !cap.GPUCCSupported {
|
|
t.Error("H100 should support CC")
|
|
}
|
|
if cap.TEEIOSupported {
|
|
t.Error("H100 should not support TEE-IO (Blackwell only)")
|
|
}
|
|
if !cap.MIGSupported {
|
|
t.Error("H100 should support MIG")
|
|
}
|
|
}
|
|
|
|
func TestDetectNVIDIACapabilities_B200(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
fileReader := NewMockFileReader()
|
|
|
|
// Simulate nvidia-smi output for B200
|
|
cmdRunner.SetOutput("nvidia-smi", []byte("NVIDIA B200, 141312, 560.28.03, GPU-BLACKWELL-SERIAL\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectNVIDIACapabilitiesWithDeps(cap, cmdRunner, fileReader)
|
|
|
|
if !result {
|
|
t.Fatal("Expected detection to succeed")
|
|
}
|
|
if cap.GPUModel != "NVIDIA B200" {
|
|
t.Errorf("Expected model 'NVIDIA B200', got %s", cap.GPUModel)
|
|
}
|
|
if cap.ComputeCap != "9.0" {
|
|
t.Errorf("Expected compute cap 9.0, got %s", cap.ComputeCap)
|
|
}
|
|
if !cap.GPUCCSupported {
|
|
t.Error("B200 should support CC")
|
|
}
|
|
if !cap.TEEIOSupported {
|
|
t.Error("B200 should support TEE-IO")
|
|
}
|
|
if !cap.MIGSupported {
|
|
t.Error("B200 should support MIG")
|
|
}
|
|
}
|
|
|
|
func TestDetectNVIDIACapabilities_GB200(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
fileReader := NewMockFileReader()
|
|
|
|
cmdRunner.SetOutput("nvidia-smi", []byte("NVIDIA GB200 NVL72, 288000, 560.28.03, GPU-GB200-SERIAL\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectNVIDIACapabilitiesWithDeps(cap, cmdRunner, fileReader)
|
|
|
|
if !result {
|
|
t.Fatal("Expected detection to succeed")
|
|
}
|
|
if !cap.GPUCCSupported {
|
|
t.Error("GB200 should support CC")
|
|
}
|
|
if !cap.TEEIOSupported {
|
|
t.Error("GB200 should support TEE-IO")
|
|
}
|
|
}
|
|
|
|
func TestDetectNVIDIACapabilities_RTX6000Ada(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
fileReader := NewMockFileReader()
|
|
|
|
cmdRunner.SetOutput("nvidia-smi", []byte("NVIDIA RTX 6000 Ada Generation, 49152, 535.154.05, GPU-RTX6000-SERIAL\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectNVIDIACapabilitiesWithDeps(cap, cmdRunner, fileReader)
|
|
|
|
if !result {
|
|
t.Fatal("Expected detection to succeed")
|
|
}
|
|
if cap.ComputeCap != "8.9" {
|
|
t.Errorf("Expected compute cap 8.9 for Ada, got %s", cap.ComputeCap)
|
|
}
|
|
if !cap.GPUCCSupported {
|
|
t.Error("RTX 6000 Ada should support CC")
|
|
}
|
|
if cap.TEEIOSupported {
|
|
t.Error("Ada should not support TEE-IO")
|
|
}
|
|
if cap.MIGSupported {
|
|
t.Error("RTX 6000 Ada should not support MIG")
|
|
}
|
|
}
|
|
|
|
func TestDetectNVIDIACapabilities_RTXPRO6000(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
fileReader := NewMockFileReader()
|
|
|
|
cmdRunner.SetOutput("nvidia-smi", []byte("NVIDIA RTX PRO 6000, 96000, 560.28.03, GPU-RTXPRO-SERIAL\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectNVIDIACapabilitiesWithDeps(cap, cmdRunner, fileReader)
|
|
|
|
if !result {
|
|
t.Fatal("Expected detection to succeed")
|
|
}
|
|
if cap.ComputeCap != "9.0" {
|
|
t.Errorf("Expected compute cap 9.0, got %s", cap.ComputeCap)
|
|
}
|
|
if !cap.GPUCCSupported {
|
|
t.Error("RTX PRO 6000 should support CC")
|
|
}
|
|
if !cap.TEEIOSupported {
|
|
t.Error("RTX PRO 6000 Blackwell should support TEE-IO")
|
|
}
|
|
}
|
|
|
|
func TestDetectNVIDIACapabilities_GraceHopper(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
fileReader := NewMockFileReader()
|
|
|
|
cmdRunner.SetOutput("nvidia-smi", []byte("NVIDIA GH200 Grace Hopper Superchip, 96000, 535.154.05, GPU-GRACE-SERIAL\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectNVIDIACapabilitiesWithDeps(cap, cmdRunner, fileReader)
|
|
|
|
if !result {
|
|
t.Fatal("Expected detection to succeed")
|
|
}
|
|
if !cap.GPUCCSupported {
|
|
t.Error("Grace Hopper should support CC")
|
|
}
|
|
if cap.TEEIOSupported {
|
|
t.Error("Grace Hopper should not support TEE-IO")
|
|
}
|
|
if !cap.MIGSupported {
|
|
t.Error("Grace Hopper should support MIG")
|
|
}
|
|
}
|
|
|
|
func TestDetectNVIDIACapabilities_RTX5090_NoCC(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
fileReader := NewMockFileReader()
|
|
|
|
cmdRunner.SetOutput("nvidia-smi", []byte("NVIDIA GeForce RTX 5090, 32768, 560.28.03, GPU-5090-SERIAL\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectNVIDIACapabilitiesWithDeps(cap, cmdRunner, fileReader)
|
|
|
|
if !result {
|
|
t.Fatal("Expected detection to succeed")
|
|
}
|
|
if cap.ComputeCap != "9.0" {
|
|
t.Errorf("Expected compute cap 9.0, got %s", cap.ComputeCap)
|
|
}
|
|
if cap.GPUCCSupported {
|
|
t.Error("RTX 5090 consumer should NOT support CC")
|
|
}
|
|
}
|
|
|
|
func TestDetectNVIDIACapabilities_GB10_NoCC(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
fileReader := NewMockFileReader()
|
|
|
|
cmdRunner.SetOutput("nvidia-smi", []byte("NVIDIA GB10, 128000, 560.28.03, GPU-GB10-SERIAL\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectNVIDIACapabilitiesWithDeps(cap, cmdRunner, fileReader)
|
|
|
|
if !result {
|
|
t.Fatal("Expected detection to succeed")
|
|
}
|
|
if cap.GPUCCSupported {
|
|
t.Error("DGX Spark GB10 should NOT support CC")
|
|
}
|
|
}
|
|
|
|
func TestDetectNVIDIACapabilities_RTX4090_NoCC(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
fileReader := NewMockFileReader()
|
|
|
|
cmdRunner.SetOutput("nvidia-smi", []byte("NVIDIA GeForce RTX 4090, 24576, 535.154.05, GPU-4090-SERIAL\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectNVIDIACapabilitiesWithDeps(cap, cmdRunner, fileReader)
|
|
|
|
if !result {
|
|
t.Fatal("Expected detection to succeed")
|
|
}
|
|
if cap.ComputeCap != "8.9" {
|
|
t.Errorf("Expected compute cap 8.9, got %s", cap.ComputeCap)
|
|
}
|
|
if cap.GPUCCSupported {
|
|
t.Error("RTX 4090 should NOT support CC")
|
|
}
|
|
}
|
|
|
|
func TestDetectNVIDIACapabilities_NoGPU(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
fileReader := NewMockFileReader()
|
|
|
|
cmdRunner.SetError("nvidia-smi", errors.New("nvidia-smi not found"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectNVIDIACapabilitiesWithDeps(cap, cmdRunner, fileReader)
|
|
|
|
if result {
|
|
t.Error("Expected detection to fail when nvidia-smi not available")
|
|
}
|
|
}
|
|
|
|
func TestDetectNVIDIACapabilities_WithNVTrust(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
fileReader.SetExists("/usr/local/bin/nv-attestation-tool", true)
|
|
|
|
// Test checkNVTrustAvailableWithDeps directly since mock returns same for command
|
|
result := checkNVTrustAvailableWithDeps(fileReader)
|
|
if !result {
|
|
t.Error("NVTrust should be available")
|
|
}
|
|
}
|
|
|
|
func TestDetectNVIDIACapabilities_WithCCEnabled(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
|
|
// Test the checkNVIDIACCEnabled directly
|
|
cmdRunner.SetOutput("nvidia-smi", []byte("enabled\n"))
|
|
|
|
result := checkNVIDIACCEnabledWithDeps(cmdRunner)
|
|
if !result {
|
|
t.Error("CC mode should be detected as enabled")
|
|
}
|
|
}
|
|
|
|
func TestCheckNVIDIACCEnabled_Variants(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
output string
|
|
expected bool
|
|
}{
|
|
{"on", "on\n", true},
|
|
{"enabled", "enabled\n", true},
|
|
{"1", "1\n", true},
|
|
{"ON uppercase", "ON\n", true},
|
|
{"Enabled mixed", "Enabled\n", true},
|
|
{"off", "off\n", false},
|
|
{"disabled", "disabled\n", false},
|
|
{"0", "0\n", false},
|
|
{"empty", "\n", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
cmdRunner.SetOutput("nvidia-smi", []byte(tt.output))
|
|
|
|
result := checkNVIDIACCEnabledWithDeps(cmdRunner)
|
|
if result != tt.expected {
|
|
t.Errorf("Expected %v for output %q, got %v", tt.expected, tt.output, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCheckNVTrustAvailable(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
paths []string
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "nvtrust in /usr/local/bin",
|
|
paths: []string{"/usr/local/bin/nv-attestation-tool"},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "nvtrust in /opt/nvidia",
|
|
paths: []string{"/opt/nvidia/nvtrust/bin/nv-attestation-tool"},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "nvtrust in /usr/bin",
|
|
paths: []string{"/usr/bin/nv-attestation-tool"},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "nvtrust not installed",
|
|
paths: []string{},
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
for _, path := range tt.paths {
|
|
fileReader.SetExists(path, true)
|
|
}
|
|
|
|
result := checkNVTrustAvailableWithDeps(fileReader)
|
|
if result != tt.expected {
|
|
t.Errorf("Expected %v, got %v", tt.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// AMD Detection Tests
|
|
// =============================================================================
|
|
|
|
func TestDetectAMDCapabilities_MI300X(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
|
|
cmdRunner.SetOutput("rocm-smi", []byte("Device,GPU_ID,Product Name\n0,0x74a1,AMD Instinct MI300X\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectAMDCapabilitiesWithDeps(cap, cmdRunner)
|
|
|
|
if !result {
|
|
t.Fatal("Expected detection to succeed")
|
|
}
|
|
if cap.GPUVendor != VendorAMD {
|
|
t.Errorf("Expected vendor AMD, got %v", cap.GPUVendor)
|
|
}
|
|
// AMD GPUs don't have native GPU CC
|
|
if cap.GPUCCSupported {
|
|
t.Error("AMD GPU should not report native GPU CC support")
|
|
}
|
|
}
|
|
|
|
func TestDetectAMDCapabilities_MI250(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
|
|
cmdRunner.SetOutput("rocm-smi", []byte("Device,Product Name\n0,AMD Instinct MI250X\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectAMDCapabilitiesWithDeps(cap, cmdRunner)
|
|
|
|
if !result {
|
|
t.Fatal("Expected detection to succeed")
|
|
}
|
|
if cap.GPUVendor != VendorAMD {
|
|
t.Errorf("Expected vendor AMD, got %v", cap.GPUVendor)
|
|
}
|
|
}
|
|
|
|
func TestDetectAMDCapabilities_NoGPU(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
|
|
cmdRunner.SetError("rocm-smi", errors.New("rocm-smi not found"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectAMDCapabilitiesWithDeps(cap, cmdRunner)
|
|
|
|
if result {
|
|
t.Error("Expected detection to fail when rocm-smi not available")
|
|
}
|
|
}
|
|
|
|
func TestDetectAMDCapabilities_OtherGPU(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
|
|
// Some other AMD GPU not in the MI series
|
|
cmdRunner.SetOutput("rocm-smi", []byte("Device,Product Name\n0,AMD Radeon RX 7900 XTX\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectAMDCapabilitiesWithDeps(cap, cmdRunner)
|
|
|
|
// Should return false because model is empty (not MI300/MI250)
|
|
if result {
|
|
t.Error("Expected detection to return false for non-datacenter AMD GPU")
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Apple Silicon Detection Tests
|
|
// =============================================================================
|
|
|
|
func TestDetectAppleSiliconCapabilities_M4(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
|
|
cmdRunner.SetOutput("sysctl", []byte("Apple M4 Max\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
detectAppleSiliconCapabilitiesWithDeps(cap, cmdRunner)
|
|
|
|
if cap.GPUVendor != VendorApple {
|
|
t.Errorf("Expected vendor Apple, got %v", cap.GPUVendor)
|
|
}
|
|
if cap.GPUModel != "Apple M4 Max" {
|
|
t.Errorf("Expected model 'Apple M4 Max', got %s", cap.GPUModel)
|
|
}
|
|
if cap.NPUModel != "Neural Engine 18-core" {
|
|
t.Errorf("Expected 18-core Neural Engine for M4, got %s", cap.NPUModel)
|
|
}
|
|
if cap.ComputeCap != "apple-m4" {
|
|
t.Errorf("Expected compute cap 'apple-m4', got %s", cap.ComputeCap)
|
|
}
|
|
if cap.DeviceTEEType != "SecureEnclave" {
|
|
t.Errorf("Expected SecureEnclave, got %s", cap.DeviceTEEType)
|
|
}
|
|
if !cap.DeviceTEEEnabled {
|
|
t.Error("Device TEE should be enabled for Apple Silicon")
|
|
}
|
|
}
|
|
|
|
func TestDetectAppleSiliconCapabilities_M3(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
|
|
cmdRunner.SetOutput("sysctl", []byte("Apple M3 Pro\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
detectAppleSiliconCapabilitiesWithDeps(cap, cmdRunner)
|
|
|
|
if cap.NPUModel != "Neural Engine 16-core" {
|
|
t.Errorf("Expected 16-core Neural Engine for M3, got %s", cap.NPUModel)
|
|
}
|
|
if cap.ComputeCap != "apple-m3" {
|
|
t.Errorf("Expected compute cap 'apple-m3', got %s", cap.ComputeCap)
|
|
}
|
|
}
|
|
|
|
func TestDetectAppleSiliconCapabilities_M2(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
|
|
cmdRunner.SetOutput("sysctl", []byte("Apple M2 Ultra\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
detectAppleSiliconCapabilitiesWithDeps(cap, cmdRunner)
|
|
|
|
if cap.ComputeCap != "apple-m2" {
|
|
t.Errorf("Expected compute cap 'apple-m2', got %s", cap.ComputeCap)
|
|
}
|
|
}
|
|
|
|
func TestDetectAppleSiliconCapabilities_M1(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
|
|
cmdRunner.SetOutput("sysctl", []byte("Apple M1\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
detectAppleSiliconCapabilitiesWithDeps(cap, cmdRunner)
|
|
|
|
if cap.ComputeCap != "apple-m1" {
|
|
t.Errorf("Expected compute cap 'apple-m1', got %s", cap.ComputeCap)
|
|
}
|
|
}
|
|
|
|
func TestDetectAppleSiliconCapabilities_Intel(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
|
|
cmdRunner.SetOutput("sysctl", []byte("Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
detectAppleSiliconCapabilitiesWithDeps(cap, cmdRunner)
|
|
|
|
// Should not set Apple vendor for Intel CPU
|
|
if cap.GPUVendor == VendorApple {
|
|
t.Error("Intel CPU should not be detected as Apple")
|
|
}
|
|
}
|
|
|
|
func TestDetectAppleSiliconCapabilities_Error(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
|
|
cmdRunner.SetError("sysctl", errors.New("sysctl failed"))
|
|
|
|
cap := &HardwareCapability{}
|
|
detectAppleSiliconCapabilitiesWithDeps(cap, cmdRunner)
|
|
|
|
// Should not crash, just not detect anything
|
|
if cap.GPUVendor == VendorApple {
|
|
t.Error("Should not detect Apple vendor on error")
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// CPU TEE Detection Tests (Linux)
|
|
// =============================================================================
|
|
|
|
func TestDetectLinuxCPUTEE_SEVSNP(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
|
|
cpuinfo := `processor : 0
|
|
vendor_id : AuthenticAMD
|
|
model name : AMD EPYC 9654 96-Core Processor
|
|
`
|
|
fileReader.SetFile("/proc/cpuinfo", []byte(cpuinfo))
|
|
fileReader.SetExists("/dev/sev-guest", true)
|
|
|
|
cap := &HardwareCapability{}
|
|
detectLinuxCPUTEEWithDeps(cap, fileReader)
|
|
|
|
if cap.CPUVendor != "AuthenticAMD" {
|
|
t.Errorf("Expected vendor AuthenticAMD, got %s", cap.CPUVendor)
|
|
}
|
|
if cap.CPUModel != "AMD EPYC 9654 96-Core Processor" {
|
|
t.Errorf("Expected EPYC model, got %s", cap.CPUModel)
|
|
}
|
|
if cap.CPUTEEType != TEESEVSNP {
|
|
t.Errorf("Expected SEV-SNP TEE type, got %v", cap.CPUTEEType)
|
|
}
|
|
if !cap.CPUTEEActive {
|
|
t.Error("SEV-SNP should be active when /dev/sev-guest exists")
|
|
}
|
|
}
|
|
|
|
func TestDetectLinuxCPUTEE_TDX(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
|
|
cpuinfo := `processor : 0
|
|
vendor_id : GenuineIntel
|
|
model name : Intel(R) Xeon(R) w9-3595X
|
|
`
|
|
fileReader.SetFile("/proc/cpuinfo", []byte(cpuinfo))
|
|
fileReader.SetExists("/dev/tdx-guest", true)
|
|
|
|
cap := &HardwareCapability{}
|
|
detectLinuxCPUTEEWithDeps(cap, fileReader)
|
|
|
|
if cap.CPUVendor != "GenuineIntel" {
|
|
t.Errorf("Expected vendor GenuineIntel, got %s", cap.CPUVendor)
|
|
}
|
|
if cap.CPUTEEType != TEETDX {
|
|
t.Errorf("Expected TDX TEE type, got %v", cap.CPUTEEType)
|
|
}
|
|
}
|
|
|
|
func TestDetectLinuxCPUTEE_SGX(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
|
|
cpuinfo := `processor : 0
|
|
vendor_id : GenuineIntel
|
|
model name : Intel(R) Xeon(R) E-2388G
|
|
`
|
|
fileReader.SetFile("/proc/cpuinfo", []byte(cpuinfo))
|
|
fileReader.SetExists("/dev/sgx_enclave", true)
|
|
// No TDX device
|
|
|
|
cap := &HardwareCapability{}
|
|
detectLinuxCPUTEEWithDeps(cap, fileReader)
|
|
|
|
if cap.CPUTEEType != TEESGX {
|
|
t.Errorf("Expected SGX TEE type, got %v", cap.CPUTEEType)
|
|
}
|
|
if !cap.CPUTEEActive {
|
|
t.Error("SGX should be active")
|
|
}
|
|
}
|
|
|
|
func TestDetectLinuxCPUTEE_ARMCCA(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
|
|
cpuinfo := `processor : 0
|
|
model name : ARMv9 Processor (aarch64)
|
|
`
|
|
fileReader.SetFile("/proc/cpuinfo", []byte(cpuinfo))
|
|
fileReader.SetExists("/sys/devices/platform/arm-cca", true)
|
|
|
|
cap := &HardwareCapability{}
|
|
detectLinuxCPUTEEWithDeps(cap, fileReader)
|
|
|
|
if cap.CPUTEEType != TEECCA {
|
|
t.Errorf("Expected CCA TEE type, got %v", cap.CPUTEEType)
|
|
}
|
|
if !cap.CPUTEEActive {
|
|
t.Error("CCA should be active")
|
|
}
|
|
}
|
|
|
|
func TestDetectLinuxCPUTEE_NoTEE(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
|
|
cpuinfo := `processor : 0
|
|
vendor_id : GenuineIntel
|
|
model name : Intel(R) Core(TM) i7-10700K
|
|
`
|
|
fileReader.SetFile("/proc/cpuinfo", []byte(cpuinfo))
|
|
// No TEE devices
|
|
|
|
cap := &HardwareCapability{CPUTEEType: TEENone} // Pre-initialize with TEENone
|
|
detectLinuxCPUTEEWithDeps(cap, fileReader)
|
|
|
|
// Should remain TEENone since no TEE devices found
|
|
if cap.CPUTEEType != TEENone {
|
|
t.Errorf("Expected TEENone, got %v", cap.CPUTEEType)
|
|
}
|
|
}
|
|
|
|
func TestDetectLinuxCPUTEE_NoCPUInfo(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
// No /proc/cpuinfo file
|
|
|
|
cap := &HardwareCapability{}
|
|
detectLinuxCPUTEEWithDeps(cap, fileReader)
|
|
|
|
// Should not crash, just not detect anything
|
|
if cap.CPUVendor != "" {
|
|
t.Error("Should not detect CPU vendor without cpuinfo")
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// SEV-SNP Active Tests
|
|
// =============================================================================
|
|
|
|
func TestCheckSEVSNPActive_ViaSysfs(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
fileReader.SetFile("/sys/kernel/security/coco/sev-snp/", []byte("active"))
|
|
|
|
result := checkSEVSNPActiveWithDeps(fileReader)
|
|
if !result {
|
|
t.Error("Should detect SEV-SNP as active via sysfs")
|
|
}
|
|
}
|
|
|
|
func TestCheckSEVSNPActive_ViaDevice(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
fileReader.SetExists("/dev/sev-guest", true)
|
|
|
|
result := checkSEVSNPActiveWithDeps(fileReader)
|
|
if !result {
|
|
t.Error("Should detect SEV-SNP as active via device")
|
|
}
|
|
}
|
|
|
|
func TestCheckSEVSNPActive_NotActive(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
// No sysfs or device
|
|
|
|
result := checkSEVSNPActiveWithDeps(fileReader)
|
|
if result {
|
|
t.Error("Should not detect SEV-SNP as active")
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// TDX Active Tests
|
|
// =============================================================================
|
|
|
|
func TestCheckTDXActive_ViaDevice(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
fileReader.SetExists("/dev/tdx-guest", true)
|
|
|
|
result := checkTDXActiveWithDeps(fileReader)
|
|
if !result {
|
|
t.Error("Should detect TDX as active via device")
|
|
}
|
|
}
|
|
|
|
func TestCheckTDXActive_ViaSysfs(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
fileReader.SetFile("/sys/kernel/security/coco/tdx/", []byte("active"))
|
|
|
|
result := checkTDXActiveWithDeps(fileReader)
|
|
if !result {
|
|
t.Error("Should detect TDX as active via sysfs")
|
|
}
|
|
}
|
|
|
|
func TestCheckTDXActive_NotActive(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
// No device or sysfs
|
|
|
|
result := checkTDXActiveWithDeps(fileReader)
|
|
if result {
|
|
t.Error("Should not detect TDX as active")
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// GPU Model Detection Tests
|
|
// =============================================================================
|
|
|
|
func TestDetectNVIDIACCCapabilitiesByModel(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
model string
|
|
expectCC bool
|
|
expectTEEIO bool
|
|
expectMIG bool
|
|
expectCompute string
|
|
}{
|
|
{"B100", "NVIDIA B100", true, true, true, "9.0"},
|
|
{"B200", "NVIDIA B200", true, true, true, "9.0"},
|
|
{"GB200", "NVIDIA GB200 NVL72", true, true, true, "9.0"},
|
|
{"H100", "NVIDIA H100 80GB", true, false, true, "9.0"},
|
|
{"H200", "NVIDIA H200", true, false, true, "9.0"},
|
|
{"RTX 6000 Ada", "NVIDIA RTX 6000 Ada Generation", true, false, false, "8.9"},
|
|
{"RTX PRO 6000", "NVIDIA RTX PRO 6000", true, true, false, "9.0"},
|
|
{"Grace", "NVIDIA GH200 Grace Hopper", true, false, true, "9.0"},
|
|
{"RTX 5090", "NVIDIA GeForce RTX 5090", false, false, false, "9.0"},
|
|
{"RTX 5080", "NVIDIA GeForce RTX 5080", false, false, false, "9.0"},
|
|
{"GB10", "NVIDIA GB10", false, false, false, "9.0"},
|
|
{"RTX 4090", "NVIDIA GeForce RTX 4090", false, false, false, "8.9"},
|
|
{"RTX 4080", "NVIDIA GeForce RTX 4080", false, false, false, "8.9"},
|
|
{"Unknown", "NVIDIA Quadro P4000", false, false, false, ""},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cap := &HardwareCapability{GPUModel: tt.model}
|
|
detectNVIDIACCCapabilitiesByModel(cap)
|
|
|
|
if cap.GPUCCSupported != tt.expectCC {
|
|
t.Errorf("GPUCCSupported: expected %v, got %v", tt.expectCC, cap.GPUCCSupported)
|
|
}
|
|
if cap.TEEIOSupported != tt.expectTEEIO {
|
|
t.Errorf("TEEIOSupported: expected %v, got %v", tt.expectTEEIO, cap.TEEIOSupported)
|
|
}
|
|
if cap.MIGSupported != tt.expectMIG {
|
|
t.Errorf("MIGSupported: expected %v, got %v", tt.expectMIG, cap.MIGSupported)
|
|
}
|
|
if cap.ComputeCap != tt.expectCompute {
|
|
t.Errorf("ComputeCap: expected %s, got %s", tt.expectCompute, cap.ComputeCap)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Mock Hardware Capability Tests - LP-5610 Section 3
|
|
// =============================================================================
|
|
|
|
// TestMockNoHardware tests CC tier calculation when no CC hardware is present
|
|
func TestMockNoHardware(t *testing.T) {
|
|
// Simulates a standard machine with no CC capabilities
|
|
cap := &HardwareCapability{
|
|
GPUVendor: VendorUnknown,
|
|
GPUModel: "",
|
|
GPUMemoryMB: 0,
|
|
GPUCCSupported: false,
|
|
GPUCCEnabled: false,
|
|
NVTrustAvail: false,
|
|
CPUTEEType: TEENone,
|
|
CPUTEEActive: false,
|
|
DeviceTEEEnabled: false,
|
|
}
|
|
|
|
// Should default to Tier 4 (stake-only)
|
|
cap.MaxTier = calculateMaxTier(cap)
|
|
if cap.MaxTier != Tier4Standard {
|
|
t.Errorf("No hardware should result in Tier4Standard, got %v", cap.MaxTier)
|
|
}
|
|
|
|
// Verify tier-related methods
|
|
if cap.IsGPUCCCapable() {
|
|
t.Error("No hardware should not be GPU CC capable")
|
|
}
|
|
if cap.IsCPUTEECapable() {
|
|
t.Error("No hardware should not be CPU TEE capable")
|
|
}
|
|
if cap.IsDeviceTEECapable() {
|
|
t.Error("No hardware should not be Device TEE capable")
|
|
}
|
|
|
|
// Should be able to achieve only Tier4
|
|
tiers := cap.GetSupportedTiers()
|
|
if len(tiers) != 1 {
|
|
t.Errorf("Expected 1 supported tier, got %d", len(tiers))
|
|
}
|
|
if tiers[0] != Tier4Standard {
|
|
t.Errorf("Only supported tier should be Tier4Standard, got %v", tiers[0])
|
|
}
|
|
|
|
// Should not require setup (no hardware to set up)
|
|
needsSetup, msg := cap.RequiresSetup()
|
|
if needsSetup {
|
|
t.Errorf("No hardware should not require setup, msg: %s", msg)
|
|
}
|
|
}
|
|
|
|
// TestMockConsumerGPUNoCC tests consumer GPUs without CC support
|
|
func TestMockConsumerGPUNoCC(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
model string
|
|
memory uint64
|
|
expected CCTier
|
|
}{
|
|
{
|
|
name: "RTX 4090 Consumer",
|
|
model: "NVIDIA GeForce RTX 4090",
|
|
memory: 24576,
|
|
expected: Tier4Standard,
|
|
},
|
|
{
|
|
name: "RTX 5090 Blackwell Consumer",
|
|
model: "NVIDIA GeForce RTX 5090",
|
|
memory: 32768,
|
|
expected: Tier4Standard,
|
|
},
|
|
{
|
|
name: "DGX Spark GB10",
|
|
model: "NVIDIA GB10",
|
|
memory: 128000,
|
|
expected: Tier4Standard, // Explicitly no CC per NVIDIA forums
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cap := &HardwareCapability{
|
|
GPUVendor: VendorNVIDIA,
|
|
GPUModel: tt.model,
|
|
GPUMemoryMB: tt.memory,
|
|
GPUCCSupported: false, // Consumer GPUs don't support CC
|
|
GPUCCEnabled: false,
|
|
NVTrustAvail: false,
|
|
CPUTEEType: TEENone,
|
|
}
|
|
|
|
cap.MaxTier = calculateMaxTier(cap)
|
|
if cap.MaxTier != tt.expected {
|
|
t.Errorf("%s: expected tier %v, got %v", tt.name, tt.expected, cap.MaxTier)
|
|
}
|
|
|
|
// Should support Tier4 only
|
|
if !cap.CanAchieveTier(Tier4Standard) {
|
|
t.Error("Should be able to achieve Tier4")
|
|
}
|
|
// Consumer GPUs should NOT achieve Tier1-3
|
|
if cap.CanAchieveTier(Tier1GPUNativeCC) {
|
|
t.Error("Consumer GPU should not achieve Tier1")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestMockDatacenterGPUWithCC tests datacenter GPUs with CC support
|
|
func TestMockDatacenterGPUWithCC(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
model string
|
|
memory uint64
|
|
ccSupported bool
|
|
ccEnabled bool
|
|
nvtrustAvail bool
|
|
expected CCTier
|
|
}{
|
|
{
|
|
name: "H100 with full CC",
|
|
model: "NVIDIA H100 80GB HBM3",
|
|
memory: 81920,
|
|
ccSupported: true,
|
|
ccEnabled: true,
|
|
nvtrustAvail: true,
|
|
expected: Tier1GPUNativeCC,
|
|
},
|
|
{
|
|
name: "H100 CC supported but not enabled",
|
|
model: "NVIDIA H100 80GB HBM3",
|
|
memory: 81920,
|
|
ccSupported: true,
|
|
ccEnabled: false, // Not enabled
|
|
nvtrustAvail: true,
|
|
expected: Tier4Standard, // Falls back to Tier4
|
|
},
|
|
{
|
|
name: "H100 CC enabled but no nvtrust",
|
|
model: "NVIDIA H100 80GB HBM3",
|
|
memory: 81920,
|
|
ccSupported: true,
|
|
ccEnabled: true,
|
|
nvtrustAvail: false, // nvtrust not installed
|
|
expected: Tier4Standard, // Can't verify locally
|
|
},
|
|
{
|
|
name: "B200 Blackwell with TEE-IO",
|
|
model: "NVIDIA B200",
|
|
memory: 141312,
|
|
ccSupported: true,
|
|
ccEnabled: true,
|
|
nvtrustAvail: true,
|
|
expected: Tier1GPUNativeCC,
|
|
},
|
|
{
|
|
name: "RTX 6000 Ada Pro",
|
|
model: "NVIDIA RTX 6000 Ada Generation",
|
|
memory: 49152,
|
|
ccSupported: true,
|
|
ccEnabled: true,
|
|
nvtrustAvail: true,
|
|
expected: Tier1GPUNativeCC,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cap := &HardwareCapability{
|
|
GPUVendor: VendorNVIDIA,
|
|
GPUModel: tt.model,
|
|
GPUMemoryMB: tt.memory,
|
|
GPUCCSupported: tt.ccSupported,
|
|
GPUCCEnabled: tt.ccEnabled,
|
|
NVTrustAvail: tt.nvtrustAvail,
|
|
CPUTEEType: TEENone,
|
|
}
|
|
|
|
cap.MaxTier = calculateMaxTier(cap)
|
|
if cap.MaxTier != tt.expected {
|
|
t.Errorf("%s: expected tier %v, got %v", tt.name, tt.expected, cap.MaxTier)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestMockConfidentialVMNoGPU tests Confidential VMs without GPU CC
|
|
func TestMockConfidentialVMNoGPU(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cpuTEE CPUTEEType
|
|
teeActive bool
|
|
gpuVendor GPUVendor
|
|
expected CCTier
|
|
}{
|
|
{
|
|
name: "SEV-SNP active with AMD Instinct",
|
|
cpuTEE: TEESEVSNP,
|
|
teeActive: true,
|
|
gpuVendor: VendorAMD,
|
|
expected: Tier2ConfidentialVM,
|
|
},
|
|
{
|
|
name: "TDX active with Intel GPU",
|
|
cpuTEE: TEETDX,
|
|
teeActive: true,
|
|
gpuVendor: VendorIntel,
|
|
expected: Tier2ConfidentialVM,
|
|
},
|
|
{
|
|
name: "ARM CCA active",
|
|
cpuTEE: TEECCA,
|
|
teeActive: true,
|
|
gpuVendor: VendorUnknown,
|
|
expected: Tier2ConfidentialVM,
|
|
},
|
|
{
|
|
name: "SEV-SNP available but not active",
|
|
cpuTEE: TEESEVSNP,
|
|
teeActive: false,
|
|
gpuVendor: VendorAMD,
|
|
expected: Tier4Standard,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cap := &HardwareCapability{
|
|
GPUVendor: tt.gpuVendor,
|
|
GPUCCSupported: false, // AMD/Intel GPUs don't have native CC
|
|
GPUCCEnabled: false,
|
|
NVTrustAvail: false,
|
|
CPUTEEType: tt.cpuTEE,
|
|
CPUTEEActive: tt.teeActive,
|
|
}
|
|
|
|
cap.MaxTier = calculateMaxTier(cap)
|
|
if cap.MaxTier != tt.expected {
|
|
t.Errorf("%s: expected tier %v, got %v", tt.name, tt.expected, cap.MaxTier)
|
|
}
|
|
|
|
// Verify CPU TEE capability
|
|
if tt.cpuTEE != TEENone && !cap.IsCPUTEECapable() {
|
|
t.Error("Should be CPU TEE capable")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestMockDeviceTEE tests Device TEE configurations (mobile/edge)
|
|
func TestMockDeviceTEE(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
deviceTEE string
|
|
deviceEnabled bool
|
|
npuModel string
|
|
expected CCTier
|
|
}{
|
|
{
|
|
name: "Apple M4 Secure Enclave",
|
|
deviceTEE: "SecureEnclave",
|
|
deviceEnabled: true,
|
|
npuModel: "Neural Engine 18-core",
|
|
expected: Tier3DeviceTEE,
|
|
},
|
|
{
|
|
name: "Apple M3 Secure Enclave",
|
|
deviceTEE: "SecureEnclave",
|
|
deviceEnabled: true,
|
|
npuModel: "Neural Engine 16-core",
|
|
expected: Tier3DeviceTEE,
|
|
},
|
|
{
|
|
name: "Qualcomm TrustZone",
|
|
deviceTEE: "TrustZone",
|
|
deviceEnabled: true,
|
|
npuModel: "Hexagon NPU",
|
|
expected: Tier3DeviceTEE,
|
|
},
|
|
{
|
|
name: "Device TEE disabled",
|
|
deviceTEE: "SecureEnclave",
|
|
deviceEnabled: false,
|
|
npuModel: "Neural Engine",
|
|
expected: Tier4Standard,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cap := &HardwareCapability{
|
|
GPUVendor: VendorApple,
|
|
GPUCCSupported: false,
|
|
CPUTEEType: TEENone,
|
|
DeviceTEEType: tt.deviceTEE,
|
|
DeviceTEEEnabled: tt.deviceEnabled,
|
|
NPUModel: tt.npuModel,
|
|
}
|
|
|
|
cap.MaxTier = calculateMaxTier(cap)
|
|
if cap.MaxTier != tt.expected {
|
|
t.Errorf("%s: expected tier %v, got %v", tt.name, tt.expected, cap.MaxTier)
|
|
}
|
|
|
|
// Verify device TEE capability
|
|
if tt.deviceEnabled && !cap.IsDeviceTEECapable() {
|
|
t.Error("Should be Device TEE capable")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestMockRequiresSetup tests setup requirements for various configurations
|
|
func TestMockRequiresSetup(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
ccSupported bool
|
|
ccEnabled bool
|
|
nvtrustAvail bool
|
|
needsSetup bool
|
|
containsMsg string
|
|
}{
|
|
{
|
|
name: "No CC support",
|
|
ccSupported: false,
|
|
ccEnabled: false,
|
|
nvtrustAvail: false,
|
|
needsSetup: false,
|
|
containsMsg: "",
|
|
},
|
|
{
|
|
name: "CC supported but not enabled",
|
|
ccSupported: true,
|
|
ccEnabled: false,
|
|
nvtrustAvail: true,
|
|
needsSetup: true,
|
|
containsMsg: "nvidia-smi",
|
|
},
|
|
{
|
|
name: "CC enabled but no nvtrust",
|
|
ccSupported: true,
|
|
ccEnabled: true,
|
|
nvtrustAvail: false,
|
|
needsSetup: true,
|
|
containsMsg: "nvtrust",
|
|
},
|
|
{
|
|
name: "Fully configured",
|
|
ccSupported: true,
|
|
ccEnabled: true,
|
|
nvtrustAvail: true,
|
|
needsSetup: false,
|
|
containsMsg: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cap := &HardwareCapability{
|
|
GPUCCSupported: tt.ccSupported,
|
|
GPUCCEnabled: tt.ccEnabled,
|
|
NVTrustAvail: tt.nvtrustAvail,
|
|
}
|
|
|
|
needsSetup, msg := cap.RequiresSetup()
|
|
if needsSetup != tt.needsSetup {
|
|
t.Errorf("RequiresSetup() = %v, want %v", needsSetup, tt.needsSetup)
|
|
}
|
|
if tt.containsMsg != "" && !containsStr(msg, tt.containsMsg) {
|
|
t.Errorf("Setup message should contain '%s', got: %s", tt.containsMsg, msg)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// GPU Vendor and Model Tests
|
|
// =============================================================================
|
|
|
|
func TestGPUVendorConstants(t *testing.T) {
|
|
vendors := []GPUVendor{
|
|
VendorNVIDIA,
|
|
VendorAMD,
|
|
VendorIntel,
|
|
VendorApple,
|
|
VendorQualcomm,
|
|
VendorUnknown,
|
|
}
|
|
|
|
seen := make(map[GPUVendor]bool)
|
|
for _, v := range vendors {
|
|
if seen[v] {
|
|
t.Errorf("Duplicate vendor: %v", v)
|
|
}
|
|
seen[v] = true
|
|
if string(v) == "" {
|
|
t.Errorf("Empty vendor string for %v", v)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCPUTEETypeConstants(t *testing.T) {
|
|
types := []CPUTEEType{
|
|
TEESEVSNP,
|
|
TEETDX,
|
|
TEESGX,
|
|
TEECCA,
|
|
TEETrustZone,
|
|
TEESecureEnclave,
|
|
TEENone,
|
|
}
|
|
|
|
seen := make(map[CPUTEEType]bool)
|
|
for _, t2 := range types {
|
|
if seen[t2] {
|
|
t.Errorf("Duplicate TEE type: %v", t2)
|
|
}
|
|
seen[t2] = true
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Supported Tiers Tests
|
|
// =============================================================================
|
|
|
|
func TestGetSupportedTiers(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
maxTier CCTier
|
|
expected []CCTier
|
|
}{
|
|
{
|
|
name: "Tier1 supports all",
|
|
maxTier: Tier1GPUNativeCC,
|
|
expected: []CCTier{Tier1GPUNativeCC, Tier2ConfidentialVM, Tier3DeviceTEE, Tier4Standard},
|
|
},
|
|
{
|
|
name: "Tier2 supports 2-4",
|
|
maxTier: Tier2ConfidentialVM,
|
|
expected: []CCTier{Tier2ConfidentialVM, Tier3DeviceTEE, Tier4Standard},
|
|
},
|
|
{
|
|
name: "Tier3 supports 3-4",
|
|
maxTier: Tier3DeviceTEE,
|
|
expected: []CCTier{Tier3DeviceTEE, Tier4Standard},
|
|
},
|
|
{
|
|
name: "Tier4 supports only 4",
|
|
maxTier: Tier4Standard,
|
|
expected: []CCTier{Tier4Standard},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cap := &HardwareCapability{MaxTier: tt.maxTier}
|
|
tiers := cap.GetSupportedTiers()
|
|
|
|
if len(tiers) != len(tt.expected) {
|
|
t.Errorf("Expected %d tiers, got %d", len(tt.expected), len(tiers))
|
|
}
|
|
|
|
for i, tier := range tiers {
|
|
if tier != tt.expected[i] {
|
|
t.Errorf("Tier[%d] = %v, want %v", i, tier, tt.expected[i])
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Edge Cases and Boundary Tests
|
|
// =============================================================================
|
|
|
|
func TestCalculateMaxTierPriority(t *testing.T) {
|
|
// Test that Tier1 takes priority over Tier2 when both available
|
|
cap := &HardwareCapability{
|
|
GPUCCSupported: true,
|
|
GPUCCEnabled: true,
|
|
NVTrustAvail: true,
|
|
CPUTEEType: TEESEVSNP,
|
|
CPUTEEActive: true,
|
|
}
|
|
|
|
tier := calculateMaxTier(cap)
|
|
if tier != Tier1GPUNativeCC {
|
|
t.Errorf("GPU CC should take priority over CVM, got %v", tier)
|
|
}
|
|
}
|
|
|
|
func TestCalculateMaxTierTier2OverTier3(t *testing.T) {
|
|
// Test that Tier2 takes priority over Tier3 when both available
|
|
cap := &HardwareCapability{
|
|
GPUCCSupported: false,
|
|
CPUTEEType: TEESEVSNP,
|
|
CPUTEEActive: true,
|
|
DeviceTEEEnabled: true,
|
|
DeviceTEEType: "SecureEnclave",
|
|
}
|
|
|
|
tier := calculateMaxTier(cap)
|
|
if tier != Tier2ConfidentialVM {
|
|
t.Errorf("CVM should take priority over Device TEE, got %v", tier)
|
|
}
|
|
}
|
|
|
|
func TestCanAchieveTierBoundary(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
maxTier CCTier
|
|
testTier CCTier
|
|
canAchieve bool
|
|
}{
|
|
{"Tier1 can achieve Tier1", Tier1GPUNativeCC, Tier1GPUNativeCC, true},
|
|
{"Tier1 can achieve Tier4", Tier1GPUNativeCC, Tier4Standard, true},
|
|
{"Tier4 can achieve Tier4", Tier4Standard, Tier4Standard, true},
|
|
{"Tier4 cannot achieve Tier1", Tier4Standard, Tier1GPUNativeCC, false},
|
|
{"Tier2 cannot achieve Tier1", Tier2ConfidentialVM, Tier1GPUNativeCC, false},
|
|
{"Tier2 can achieve Tier2", Tier2ConfidentialVM, Tier2ConfidentialVM, true},
|
|
{"Tier2 can achieve Tier3", Tier2ConfidentialVM, Tier3DeviceTEE, true},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cap := &HardwareCapability{MaxTier: tt.maxTier}
|
|
result := cap.CanAchieveTier(tt.testTier)
|
|
if result != tt.canAchieve {
|
|
t.Errorf("CanAchieveTier(%v) = %v, want %v", tt.testTier, result, tt.canAchieve)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Future Hardware Support Tests (Blueprint for expansion)
|
|
// =============================================================================
|
|
|
|
// TestFutureAMDGPUCC tests potential future AMD GPU CC support
|
|
// AMD is working on confidential compute for MI300X series
|
|
func TestFutureAMDGPUCC(t *testing.T) {
|
|
// When AMD adds GPU CC support, this test will validate it
|
|
cap := &HardwareCapability{
|
|
GPUVendor: VendorAMD,
|
|
GPUModel: "AMD Instinct MI300X",
|
|
GPUMemoryMB: 196608, // 192GB
|
|
GPUCCSupported: false, // Currently false, future: true
|
|
GPUCCEnabled: false,
|
|
// When AMD implements CC:
|
|
// GPUCCSupported: true,
|
|
// GPUCCEnabled: true,
|
|
// NVTrustAvail: true, // Would be AMD equivalent
|
|
CPUTEEType: TEESEVSNP,
|
|
CPUTEEActive: true, // Best with SEV-SNP host
|
|
}
|
|
|
|
tier := calculateMaxTier(cap)
|
|
// Currently should be Tier2 (CVM) since AMD GPU CC not supported yet
|
|
if tier != Tier2ConfidentialVM {
|
|
t.Logf("AMD with SEV-SNP should be Tier2, got %v", tier)
|
|
}
|
|
|
|
// Future test when AMD CC is supported:
|
|
// if tier != Tier1GPUNativeCC {
|
|
// t.Errorf("AMD MI300X with CC should be Tier1, got %v", tier)
|
|
// }
|
|
}
|
|
|
|
// TestFutureIntelGPUCC tests potential future Intel GPU CC support
|
|
func TestFutureIntelGPUCC(t *testing.T) {
|
|
cap := &HardwareCapability{
|
|
GPUVendor: VendorIntel,
|
|
GPUModel: "Intel Data Center GPU Max 1550",
|
|
GPUMemoryMB: 131072, // 128GB HBM
|
|
GPUCCSupported: false, // Intel GPUs currently don't have CC
|
|
CPUTEEType: TEETDX,
|
|
CPUTEEActive: true,
|
|
}
|
|
|
|
tier := calculateMaxTier(cap)
|
|
// Currently Tier2 with TDX
|
|
if tier != Tier2ConfidentialVM {
|
|
t.Logf("Intel GPU with TDX should be Tier2, got %v", tier)
|
|
}
|
|
}
|
|
|
|
// TestFutureQualcommCC tests potential future Qualcomm AI accelerator CC
|
|
func TestFutureQualcommCC(t *testing.T) {
|
|
cap := &HardwareCapability{
|
|
GPUVendor: VendorQualcomm,
|
|
GPUModel: "Qualcomm Cloud AI 100",
|
|
GPUCCSupported: false,
|
|
DeviceTEEType: "TrustZone",
|
|
DeviceTEEEnabled: true,
|
|
NPUModel: "Hexagon NPU",
|
|
}
|
|
|
|
tier := calculateMaxTier(cap)
|
|
// Currently Tier3 with TrustZone
|
|
if tier != Tier3DeviceTEE {
|
|
t.Logf("Qualcomm with TrustZone should be Tier3, got %v", tier)
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Helper Functions
|
|
// =============================================================================
|
|
|
|
func containsStr(s, substr string) bool {
|
|
return len(s) >= len(substr) && (s == substr || len(s) > 0 && containsSubstring(s, substr))
|
|
}
|
|
|
|
func containsSubstring(s, substr string) bool {
|
|
for i := 0; i+len(substr) <= len(s); i++ {
|
|
if s[i:i+len(substr)] == substr {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// =============================================================================
|
|
// Benchmarks
|
|
// =============================================================================
|
|
|
|
func BenchmarkCalculateMaxTier(b *testing.B) {
|
|
cap := &HardwareCapability{
|
|
GPUCCSupported: true,
|
|
GPUCCEnabled: true,
|
|
NVTrustAvail: true,
|
|
CPUTEEType: TEESEVSNP,
|
|
CPUTEEActive: true,
|
|
DeviceTEEEnabled: true,
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
calculateMaxTier(cap)
|
|
}
|
|
}
|
|
|
|
func BenchmarkGetSupportedTiers(b *testing.B) {
|
|
cap := &HardwareCapability{MaxTier: Tier1GPUNativeCC}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
cap.GetSupportedTiers()
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// System Detection Tests (runs against actual system)
|
|
// =============================================================================
|
|
|
|
// TestDetectCapabilities_System tests the real detection on the current system
|
|
func TestDetectCapabilities_System(t *testing.T) {
|
|
// This test runs on the actual system and should at minimum return a valid capability struct
|
|
cap, err := DetectCapabilities()
|
|
if err != nil {
|
|
t.Logf("DetectCapabilities returned error (may be expected): %v", err)
|
|
}
|
|
|
|
// Should always return a non-nil capability
|
|
if cap == nil {
|
|
t.Fatal("DetectCapabilities should never return nil")
|
|
}
|
|
|
|
// MaxTier should be set to something valid
|
|
validTiers := map[CCTier]bool{
|
|
Tier1GPUNativeCC: true,
|
|
Tier2ConfidentialVM: true,
|
|
Tier3DeviceTEE: true,
|
|
Tier4Standard: true,
|
|
}
|
|
if !validTiers[cap.MaxTier] {
|
|
t.Errorf("MaxTier %v is not a valid tier", cap.MaxTier)
|
|
}
|
|
}
|
|
|
|
// TestDefaultCommandRunner_Run tests the real command runner
|
|
func TestDefaultCommandRunner_Run(t *testing.T) {
|
|
runner := &DefaultCommandRunner{}
|
|
|
|
// Test a command that should exist on all systems
|
|
output, err := runner.Run("echo", "test")
|
|
if err != nil {
|
|
t.Logf("echo command failed (may be expected on some systems): %v", err)
|
|
} else {
|
|
if len(output) == 0 {
|
|
t.Error("Expected non-empty output from echo")
|
|
}
|
|
}
|
|
|
|
// Test a command that doesn't exist
|
|
_, err = runner.Run("nonexistent_command_12345")
|
|
if err == nil {
|
|
t.Error("Expected error for nonexistent command")
|
|
}
|
|
}
|
|
|
|
// TestDefaultFileReader_ReadFile tests the real file reader
|
|
func TestDefaultFileReader_ReadFile(t *testing.T) {
|
|
reader := &DefaultFileReader{}
|
|
|
|
// Test reading a file that should exist on all Unix systems
|
|
_, err := reader.ReadFile("/dev/null")
|
|
if err != nil {
|
|
t.Logf("Reading /dev/null failed (may be expected): %v", err)
|
|
}
|
|
|
|
// Test reading a file that doesn't exist
|
|
_, err = reader.ReadFile("/nonexistent/path/12345")
|
|
if err == nil {
|
|
t.Error("Expected error for nonexistent file")
|
|
}
|
|
}
|
|
|
|
// TestDefaultFileReader_Stat tests the real file stat
|
|
func TestDefaultFileReader_Stat(t *testing.T) {
|
|
reader := &DefaultFileReader{}
|
|
|
|
// Test stat on a file that should exist
|
|
info, err := reader.Stat("/dev/null")
|
|
if err != nil {
|
|
t.Logf("Stat /dev/null failed (may be expected): %v", err)
|
|
} else if info == nil {
|
|
t.Error("Expected non-nil FileInfo")
|
|
}
|
|
|
|
// Test stat on a file that doesn't exist
|
|
_, err = reader.Stat("/nonexistent/path/12345")
|
|
if err == nil {
|
|
t.Error("Expected error for nonexistent file")
|
|
}
|
|
}
|
|
|
|
// TestDetectGPUCapabilities_System tests GPU detection on the actual system
|
|
func TestDetectGPUCapabilities_System(t *testing.T) {
|
|
cap := &HardwareCapability{}
|
|
detectGPUCapabilities(cap)
|
|
|
|
// This may or may not detect a GPU depending on the system
|
|
t.Logf("GPU detection complete, Vendor: %v, Model: %s", cap.GPUVendor, cap.GPUModel)
|
|
}
|
|
|
|
// TestDetectCPUTEECapabilities_System tests CPU TEE detection on the actual system
|
|
func TestDetectCPUTEECapabilities_System(t *testing.T) {
|
|
cap := &HardwareCapability{}
|
|
detectCPUTEECapabilities(cap)
|
|
|
|
t.Logf("CPU TEE detection complete, Type: %v, Active: %v", cap.CPUTEEType, cap.CPUTEEActive)
|
|
}
|
|
|
|
// TestDetectDeviceTEECapabilities_System tests device TEE detection
|
|
func TestDetectDeviceTEECapabilities_System(t *testing.T) {
|
|
cap := &HardwareCapability{}
|
|
detectDeviceTEECapabilities(cap)
|
|
|
|
t.Logf("Device TEE detection complete, Type: %s, Enabled: %v", cap.DeviceTEEType, cap.DeviceTEEEnabled)
|
|
}
|
|
|
|
// =============================================================================
|
|
// Additional Mock Tests for Full Coverage
|
|
// =============================================================================
|
|
|
|
// TestCheckNVTrustAvailable_Additional tests more nvtrust availability cases
|
|
func TestCheckNVTrustAvailable_Additional(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
paths []string
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "nv-attestation-tool in /opt/nvidia/nvtrust/bin",
|
|
paths: []string{"/opt/nvidia/nvtrust/bin/nv-attestation-tool"},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "nv-attestation-tool in /usr/bin",
|
|
paths: []string{"/usr/bin/nv-attestation-tool"},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "multiple locations",
|
|
paths: []string{"/usr/bin/nv-attestation-tool", "/usr/local/bin/nv-attestation-tool"},
|
|
expected: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
for _, p := range tt.paths {
|
|
fileReader.SetExists(p, true)
|
|
}
|
|
|
|
result := checkNVTrustAvailableWithDeps(fileReader)
|
|
if result != tt.expected {
|
|
t.Errorf("Expected %v, got %v", tt.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestDetectAMDCapabilities_Mock tests AMD detection with mocks
|
|
func TestDetectAMDCapabilities_Mock(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
|
|
// Simulate rocm-smi output for MI300X
|
|
cmdRunner.SetOutput("rocm-smi", []byte("MI300X\n192GB\n"))
|
|
|
|
cap := &HardwareCapability{}
|
|
result := detectAMDCapabilitiesWithDeps(cap, cmdRunner)
|
|
|
|
// AMD detection may or may not succeed depending on mock setup
|
|
t.Logf("AMD detection result: %v, Model: %s", result, cap.GPUModel)
|
|
}
|
|
|
|
// TestDetectLinuxCPUTEE_Mock tests Linux CPU TEE detection
|
|
func TestDetectLinuxCPUTEE_Mock(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cpuInfo string
|
|
expected CPUTEEType
|
|
}{
|
|
{
|
|
name: "AMD with SEV",
|
|
cpuInfo: "AuthenticAMD\nsev\n",
|
|
expected: TEESEVSNP,
|
|
},
|
|
{
|
|
name: "Intel with SGX",
|
|
cpuInfo: "GenuineIntel\nsgx\n",
|
|
expected: TEESGX,
|
|
},
|
|
{
|
|
name: "No TEE support",
|
|
cpuInfo: "GenuineIntel\n",
|
|
expected: TEENone,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
fileReader.SetFile("/proc/cpuinfo", []byte(tt.cpuInfo))
|
|
|
|
cap := &HardwareCapability{}
|
|
detectLinuxCPUTEEWithDeps(cap, fileReader)
|
|
|
|
// The mock may not fully trigger all branches, log result
|
|
t.Logf("CPU TEE type detected: %v", cap.CPUTEEType)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestCheckSEVSNPActive_Mock tests SEV-SNP active checking
|
|
func TestCheckSEVSNPActive_Mock(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
sysPath string
|
|
devExists bool
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "SEV active via sysfs",
|
|
sysPath: "active",
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "SEV active via device",
|
|
devExists: true,
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "SEV not active",
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
if tt.sysPath != "" {
|
|
fileReader.SetFile("/sys/kernel/security/coco/sev-snp/", []byte(tt.sysPath))
|
|
}
|
|
if tt.devExists {
|
|
fileReader.SetExists("/dev/sev-guest", true)
|
|
}
|
|
|
|
result := checkSEVSNPActiveWithDeps(fileReader)
|
|
if result != tt.expected {
|
|
t.Errorf("Expected %v, got %v", tt.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestCheckTDXActive_Mock tests TDX active checking
|
|
func TestCheckTDXActive_Mock(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
sysPath string
|
|
devExists bool
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "TDX active via device",
|
|
devExists: true,
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "TDX active via sysfs",
|
|
sysPath: "active",
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "TDX not active",
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
fileReader := NewMockFileReader()
|
|
if tt.devExists {
|
|
fileReader.SetExists("/dev/tdx-guest", true)
|
|
}
|
|
if tt.sysPath != "" {
|
|
fileReader.SetFile("/sys/kernel/security/coco/tdx/", []byte(tt.sysPath))
|
|
}
|
|
|
|
result := checkTDXActiveWithDeps(fileReader)
|
|
if result != tt.expected {
|
|
t.Errorf("Expected %v, got %v", tt.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// System Wrapper Function Tests
|
|
// =============================================================================
|
|
|
|
// TestCheckNVTrustAvailable_System tests the real nvtrust check
|
|
func TestCheckNVTrustAvailable_System(t *testing.T) {
|
|
result := checkNVTrustAvailable()
|
|
t.Logf("nvtrust available on system: %v", result)
|
|
}
|
|
|
|
// TestCheckNVIDIACCEnabled_System tests the real NVIDIA CC check
|
|
func TestCheckNVIDIACCEnabled_System(t *testing.T) {
|
|
result := checkNVIDIACCEnabled()
|
|
t.Logf("NVIDIA CC enabled on system: %v", result)
|
|
}
|
|
|
|
// TestDetectLinuxCPUTEE_System tests Linux CPU TEE detection
|
|
func TestDetectLinuxCPUTEE_System(t *testing.T) {
|
|
cap := &HardwareCapability{}
|
|
detectLinuxCPUTEE(cap)
|
|
t.Logf("Linux CPU TEE type: %v, active: %v", cap.CPUTEEType, cap.CPUTEEActive)
|
|
}
|
|
|
|
// TestCheckSEVSNPActive_System tests SEV-SNP active check
|
|
func TestCheckSEVSNPActive_System(t *testing.T) {
|
|
result := checkSEVSNPActive()
|
|
t.Logf("SEV-SNP active on system: %v", result)
|
|
}
|
|
|
|
// TestCheckTDXActive_System tests TDX active check
|
|
func TestCheckTDXActive_System(t *testing.T) {
|
|
result := checkTDXActive()
|
|
t.Logf("TDX active on system: %v", result)
|
|
}
|
|
|
|
// =============================================================================
|
|
// Additional Coverage Tests - detectNVIDIACCCapabilitiesByModel
|
|
// =============================================================================
|
|
|
|
func TestDetectNVIDIACCCapabilitiesByModel_AllModels(t *testing.T) {
|
|
tests := []struct {
|
|
model string
|
|
ccSupport bool
|
|
teeIO bool
|
|
computeCap string
|
|
mig bool
|
|
}{
|
|
// Blackwell datacenter - highest CC tier
|
|
{"NVIDIA B200", true, true, "9.0", true},
|
|
{"NVIDIA B100", true, true, "9.0", true},
|
|
{"NVIDIA GB200", true, true, "9.0", true},
|
|
// Hopper datacenter - full CC support
|
|
{"NVIDIA H100", true, false, "9.0", true},
|
|
{"NVIDIA H200", true, false, "9.0", true},
|
|
// Grace Hopper
|
|
{"NVIDIA Grace Hopper", true, false, "9.0", true},
|
|
// Ada professional - CC support
|
|
{"NVIDIA RTX 6000 Ada", true, false, "8.9", false},
|
|
// RTX PRO Blackwell
|
|
{"NVIDIA RTX PRO 6000", true, true, "9.0", false},
|
|
// Consumer cards - NO CC
|
|
{"NVIDIA RTX 4090", false, false, "8.9", false},
|
|
{"NVIDIA RTX 5090", false, false, "9.0", false},
|
|
{"NVIDIA GTX 1080", false, false, "6.1", false},
|
|
// DGX Spark - NO CC
|
|
{"NVIDIA GB10", false, false, "9.0", false},
|
|
// Unknown
|
|
{"Unknown GPU", false, false, "", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.model, func(t *testing.T) {
|
|
cap := &HardwareCapability{GPUModel: tt.model}
|
|
detectNVIDIACCCapabilitiesByModel(cap)
|
|
|
|
if cap.GPUCCSupported != tt.ccSupport {
|
|
t.Errorf("CC support: expected %v, got %v", tt.ccSupport, cap.GPUCCSupported)
|
|
}
|
|
if cap.TEEIOSupported != tt.teeIO {
|
|
t.Errorf("TEE-IO: expected %v, got %v", tt.teeIO, cap.TEEIOSupported)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestCheckNVIDIACCEnabled_Outputs tests various nvidia-smi outputs
|
|
func TestCheckNVIDIACCEnabled_Outputs(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
output string
|
|
expected bool
|
|
}{
|
|
{"on lowercase", "on\n", true},
|
|
{"ON uppercase", "ON\n", true},
|
|
{"On mixed", "On\n", true},
|
|
{"enabled", "enabled\n", true},
|
|
{"Enabled", "Enabled\n", true},
|
|
{"ENABLED", "ENABLED\n", true},
|
|
{"1", "1\n", true},
|
|
{"off", "off\n", false},
|
|
{"OFF", "OFF\n", false},
|
|
{"disabled", "disabled\n", false},
|
|
{"0", "0\n", false},
|
|
{"empty", "", false},
|
|
{"whitespace only", " \n", false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cmdRunner := NewMockCommandRunner()
|
|
cmdRunner.SetOutput("nvidia-smi", []byte(tt.output))
|
|
|
|
result := checkNVIDIACCEnabledWithDeps(cmdRunner)
|
|
if result != tt.expected {
|
|
t.Errorf("Expected %v, got %v for output %q", tt.expected, result, tt.output)
|
|
}
|
|
})
|
|
}
|
|
}
|