Files
fn_registry/functions/infra/get_gpu_info_test.go
T
egutierrez e3c8979e8d chore: auto-commit (95 archivos)
- cmd/fn/doctor.go
- cmd/fn/main.go
- cpp/apps/primitives_gallery/playground/tables/CMakeLists.txt
- cpp/apps/primitives_gallery/playground/tables/data_table.cpp
- cpp/apps/primitives_gallery/playground/tables/data_table_logic.cpp
- cpp/apps/primitives_gallery/playground/tables/data_table_logic.h
- cpp/apps/primitives_gallery/playground/tables/self_test.cpp
- cpp/apps/primitives_gallery/playground/tables/tql.cpp
- cpp/apps/primitives_gallery/playground/tables/viz.cpp
- cpp/apps/primitives_gallery/playground/tables/viz.h
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 00:50:34 +02:00

166 lines
4.6 KiB
Go

package infra
import (
"strconv"
"strings"
"testing"
)
// TestGetGpuInfoNoGpu verifica que la funcion retorna slice vacio sin error
// cuando nvidia-smi no esta instalado o no hay GPU NVIDIA presente.
// Este test pasa en cualquier maquina, con o sin GPU.
func TestGetGpuInfoNoGpu(t *testing.T) {
t.Run("retorna slice vacio y nil cuando no hay GPU NVIDIA", func(t *testing.T) {
gpus, err := GetGpuInfo()
if err != nil {
t.Errorf("GetGpuInfo() error inesperado: %v", err)
}
// En maquinas sin nvidia-smi el resultado debe ser un slice vacio (no nil)
if gpus == nil {
t.Error("GetGpuInfo() retorno nil, se esperaba slice vacio []GpuInfo{}")
}
})
}
// parseCsvNvidiaSmi replica la logica de parsing de GetGpuInfo para tests unitarios.
// Recibe el output de nvidia-smi --format=csv,noheader,nounits y retorna []GpuInfo.
func parseCsvNvidiaSmi(output string) ([]GpuInfo, error) {
trimmed := strings.TrimSpace(output)
if trimmed == "" {
return []GpuInfo{}, nil
}
lines := strings.Split(trimmed, "\n")
gpus := make([]GpuInfo, 0, len(lines))
for _, line := range lines {
parts := strings.Split(line, ",")
if len(parts) < 6 {
continue
}
idx, _ := strconv.Atoi(strings.TrimSpace(parts[0]))
totalMb, _ := strconv.Atoi(strings.TrimSpace(parts[2]))
freeMb, _ := strconv.Atoi(strings.TrimSpace(parts[3]))
gpus = append(gpus, GpuInfo{
Index: idx,
Name: strings.TrimSpace(parts[1]),
VramTotalMb: totalMb,
VramFreeMb: freeMb,
DriverVersion: strings.TrimSpace(parts[4]),
CudaVersion: strings.TrimSpace(parts[5]),
})
}
return gpus, nil
}
// TestParseCsvNvidiaSmi verifica el parsing de la salida CSV de nvidia-smi
// sin requerir GPU real ni nvidia-smi instalado.
func TestParseCsvNvidiaSmi(t *testing.T) {
tests := []struct {
name string
csvInput string
wantLen int
wantIndex int
wantName string
wantVramTotal int
wantVramFree int
wantDriver string
wantCuda string
}{
{
name: "linea GPU RTX 3080 tipica",
csvInput: "0, NVIDIA GeForce RTX 3080, 10240, 8192, 550.54.15, 12.4",
wantLen: 1,
wantIndex: 0,
wantName: "NVIDIA GeForce RTX 3080",
wantVramTotal: 10240,
wantVramFree: 8192,
wantDriver: "550.54.15",
wantCuda: "12.4",
},
{
name: "dos GPUs en el CSV",
csvInput: "0, GPU A, 8192, 4096, 525.0, 12.0\n1, GPU B, 24576, 20000, 525.0, 12.0",
wantLen: 2,
},
{
name: "CSV vacio retorna slice vacio",
csvInput: "",
wantLen: 0,
},
{
name: "linea con menos de 6 campos se ignora",
csvInput: "0, GPU, 8192",
wantLen: 0,
},
{
name: "espacios extra en los valores se eliminan",
csvInput: " 1 , NVIDIA RTX 4090 , 24576 , 20000 , 545.0 , 12.6 ",
wantLen: 1,
wantIndex: 1,
wantName: "NVIDIA RTX 4090",
wantVramTotal: 24576,
wantVramFree: 20000,
wantDriver: "545.0",
wantCuda: "12.6",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
gpus, err := parseCsvNvidiaSmi(tc.csvInput)
if err != nil {
t.Fatalf("error inesperado: %v", err)
}
if len(gpus) != tc.wantLen {
t.Fatalf("len(gpus) = %d, quería %d", len(gpus), tc.wantLen)
}
if tc.wantLen == 1 {
g := gpus[0]
if g.Index != tc.wantIndex {
t.Errorf("Index = %d, quería %d", g.Index, tc.wantIndex)
}
if g.Name != tc.wantName {
t.Errorf("Name = %q, quería %q", g.Name, tc.wantName)
}
if g.VramTotalMb != tc.wantVramTotal {
t.Errorf("VramTotalMb = %d, quería %d", g.VramTotalMb, tc.wantVramTotal)
}
if g.VramFreeMb != tc.wantVramFree {
t.Errorf("VramFreeMb = %d, quería %d", g.VramFreeMb, tc.wantVramFree)
}
if g.DriverVersion != tc.wantDriver {
t.Errorf("DriverVersion = %q, quería %q", g.DriverVersion, tc.wantDriver)
}
if g.CudaVersion != tc.wantCuda {
t.Errorf("CudaVersion = %q, quería %q", g.CudaVersion, tc.wantCuda)
}
}
})
}
}
// TestGpuInfoStruct verifica los campos del tipo GpuInfo.
func TestGpuInfoStruct(t *testing.T) {
t.Run("campos del struct GpuInfo correctos", func(t *testing.T) {
g := GpuInfo{
Index: 0,
Name: "NVIDIA GeForce GTX 1080",
VramTotalMb: 8192,
VramFreeMb: 6144,
DriverVersion: "470.0",
CudaVersion: "11.4",
}
if g.Index != 0 {
t.Errorf("Index = %d", g.Index)
}
if g.Name != "NVIDIA GeForce GTX 1080" {
t.Errorf("Name = %q", g.Name)
}
if g.VramTotalMb != 8192 {
t.Errorf("VramTotalMb = %d", g.VramTotalMb)
}
if g.VramFreeMb != 6144 {
t.Errorf("VramFreeMb = %d", g.VramFreeMb)
}
})
}