Backend tests: - CPU, memory, disk, network collector tests (existing) - Added temperature, processes, system, AMD GPU collector tests - All tests use mock filesystem data Frontend tests: - Added Vitest with jsdom environment - Tests for formatters (formatBytes, formatUptime, etc.) - Tests for theme store 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
167 lines
4.3 KiB
Go
167 lines
4.3 KiB
Go
package collectors
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestAMDGPUCollector(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
sysPath := filepath.Join(tmpDir, "sys")
|
|
|
|
// Create mock AMD GPU sysfs structure
|
|
gpuPath := filepath.Join(sysPath, "class/drm/card0/device")
|
|
if err := os.MkdirAll(gpuPath, 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create driver symlink (required for AMD GPU detection)
|
|
driverTarget := filepath.Join(tmpDir, "drivers/amdgpu")
|
|
if err := os.MkdirAll(driverTarget, 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Symlink(driverTarget, filepath.Join(gpuPath, "driver")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// GPU utilization
|
|
if err := os.WriteFile(filepath.Join(gpuPath, "gpu_busy_percent"), []byte("75\n"), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// VRAM
|
|
if err := os.WriteFile(filepath.Join(gpuPath, "mem_info_vram_used"), []byte("4294967296\n"), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(gpuPath, "mem_info_vram_total"), []byte("17179869184\n"), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Clock frequencies (format: "0: 500Mhz\n1: 800Mhz *\n2: 1200Mhz")
|
|
sclk := "0: 500Mhz\n1: 800Mhz\n2: 1200Mhz *\n"
|
|
if err := os.WriteFile(filepath.Join(gpuPath, "pp_dpm_sclk"), []byte(sclk), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
mclk := "0: 400Mhz\n1: 875Mhz *\n"
|
|
if err := os.WriteFile(filepath.Join(gpuPath, "pp_dpm_mclk"), []byte(mclk), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create hwmon for temperature, power, fan
|
|
hwmonPath := filepath.Join(gpuPath, "hwmon/hwmon5")
|
|
if err := os.MkdirAll(hwmonPath, 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Temperature (65°C in millidegrees)
|
|
if err := os.WriteFile(filepath.Join(hwmonPath, "temp1_input"), []byte("65000\n"), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Power (150W in microwatts)
|
|
if err := os.WriteFile(filepath.Join(hwmonPath, "power1_average"), []byte("150000000\n"), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Fan RPM
|
|
if err := os.WriteFile(filepath.Join(hwmonPath, "fan1_input"), []byte("1500\n"), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
collector := NewAMDGPUCollector(sysPath)
|
|
stats, err := collector.Collect()
|
|
if err != nil {
|
|
t.Fatalf("Collect failed: %v", err)
|
|
}
|
|
|
|
if !stats.Available {
|
|
t.Error("Expected GPU to be available")
|
|
}
|
|
|
|
if stats.Utilization != 75 {
|
|
t.Errorf("Expected utilization 75, got %d", stats.Utilization)
|
|
}
|
|
|
|
if stats.VRAMUsed != 4294967296 {
|
|
t.Errorf("Expected VRAM used 4294967296, got %d", stats.VRAMUsed)
|
|
}
|
|
|
|
if stats.VRAMTotal != 17179869184 {
|
|
t.Errorf("Expected VRAM total 17179869184, got %d", stats.VRAMTotal)
|
|
}
|
|
|
|
if stats.ClockGPU != 1200 {
|
|
t.Errorf("Expected GPU clock 1200, got %d", stats.ClockGPU)
|
|
}
|
|
|
|
if stats.ClockMemory != 875 {
|
|
t.Errorf("Expected memory clock 875, got %d", stats.ClockMemory)
|
|
}
|
|
|
|
if stats.Temperature != 65.0 {
|
|
t.Errorf("Expected temperature 65.0, got %f", stats.Temperature)
|
|
}
|
|
|
|
if stats.PowerWatts != 150.0 {
|
|
t.Errorf("Expected power 150.0W, got %f", stats.PowerWatts)
|
|
}
|
|
|
|
if stats.FanRPM != 1500 {
|
|
t.Errorf("Expected fan 1500 RPM, got %d", stats.FanRPM)
|
|
}
|
|
}
|
|
|
|
func TestAMDGPUCollector_NoGPU(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
collector := NewAMDGPUCollector(tmpDir)
|
|
|
|
stats, err := collector.Collect()
|
|
if err != nil {
|
|
t.Fatalf("Collect failed: %v", err)
|
|
}
|
|
|
|
if stats.Available {
|
|
t.Error("Expected GPU to be unavailable")
|
|
}
|
|
}
|
|
|
|
func TestAMDGPUCollector_PartialData(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
sysPath := filepath.Join(tmpDir, "sys")
|
|
|
|
// Create minimal GPU structure (only utilization)
|
|
gpuPath := filepath.Join(sysPath, "class/drm/card0/device")
|
|
if err := os.MkdirAll(gpuPath, 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create driver symlink (required for AMD GPU detection)
|
|
driverTarget := filepath.Join(tmpDir, "drivers/amdgpu")
|
|
if err := os.MkdirAll(driverTarget, 0755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Symlink(driverTarget, filepath.Join(gpuPath, "driver")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := os.WriteFile(filepath.Join(gpuPath, "gpu_busy_percent"), []byte("50\n"), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
collector := NewAMDGPUCollector(sysPath)
|
|
stats, err := collector.Collect()
|
|
if err != nil {
|
|
t.Fatalf("Collect failed: %v", err)
|
|
}
|
|
|
|
if !stats.Available {
|
|
t.Error("Expected GPU to be available with partial data")
|
|
}
|
|
|
|
if stats.Utilization != 50 {
|
|
t.Errorf("Expected utilization 50, got %d", stats.Utilization)
|
|
}
|
|
}
|