131 lines
3.3 KiB
Go
131 lines
3.3 KiB
Go
package resource
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestParseNvidiaSMI(t *testing.T) {
|
|
output := `0, NVIDIA GeForce RTX 4090, 45, 30, 4096, 24576, 16.67, 150.5, 450.0
|
|
1, NVIDIA GeForce RTX 4090, 52, 75, 8192, 24576, 33.33, 320.0, 450.0`
|
|
|
|
metrics := parseNvidiaSMI(output)
|
|
if len(metrics) != 2 {
|
|
t.Fatalf("expected 2 GPUs, got %d", len(metrics))
|
|
}
|
|
|
|
if metrics[0].Index != 0 {
|
|
t.Errorf("expected index 0, got %d", metrics[0].Index)
|
|
}
|
|
if metrics[0].Name != "NVIDIA GeForce RTX 4090" {
|
|
t.Errorf("unexpected name: %s", metrics[0].Name)
|
|
}
|
|
if metrics[0].TemperatureC != 45 {
|
|
t.Errorf("expected temp 45, got %d", metrics[0].TemperatureC)
|
|
}
|
|
if metrics[0].UtilizationGPU != 30 {
|
|
t.Errorf("expected util 30, got %d", metrics[0].UtilizationGPU)
|
|
}
|
|
if metrics[0].MemoryUsedMB != 4096 {
|
|
t.Errorf("expected mem used 4096, got %d", metrics[0].MemoryUsedMB)
|
|
}
|
|
if metrics[0].MemoryTotalMB != 24576 {
|
|
t.Errorf("expected mem total 24576, got %d", metrics[0].MemoryTotalMB)
|
|
}
|
|
if metrics[0].PowerDrawW != 150.5 {
|
|
t.Errorf("expected power 150.5, got %f", metrics[0].PowerDrawW)
|
|
}
|
|
|
|
if metrics[1].Index != 1 {
|
|
t.Errorf("expected index 1, got %d", metrics[1].Index)
|
|
}
|
|
if metrics[1].UtilizationGPU != 75 {
|
|
t.Errorf("expected util 75, got %d", metrics[1].UtilizationGPU)
|
|
}
|
|
}
|
|
|
|
func TestParseNvidiaSMIEmpty(t *testing.T) {
|
|
metrics := parseNvidiaSMI("")
|
|
if len(metrics) != 0 {
|
|
t.Errorf("expected 0 metrics for empty input, got %d", len(metrics))
|
|
}
|
|
}
|
|
|
|
func TestParseNvidiaSMIInvalidLines(t *testing.T) {
|
|
output := `invalid line
|
|
0, GPU0, 40, 50, 1024, 8192, 12.5, 100.0, 300.0
|
|
, , , , , , , , `
|
|
|
|
metrics := parseNvidiaSMI(output)
|
|
// Both lines with 9 fields parse; the empty-name one has Name=""
|
|
validCount := 0
|
|
for _, m := range metrics {
|
|
if m.Name != "" {
|
|
validCount++
|
|
}
|
|
}
|
|
if validCount != 1 {
|
|
t.Errorf("expected 1 valid metric with name, got %d", validCount)
|
|
}
|
|
}
|
|
|
|
func TestGPUCollectorTotals(t *testing.T) {
|
|
c := &GPUCollector{
|
|
metrics: []GPUMetrics{
|
|
{MemoryUsedMB: 4096, MemoryTotalMB: 24576, UtilizationGPU: 30},
|
|
{MemoryUsedMB: 8192, MemoryTotalMB: 24576, UtilizationGPU: 75},
|
|
},
|
|
}
|
|
|
|
if c.TotalMemoryUsedMB() != 12288 {
|
|
t.Errorf("expected 12288, got %d", c.TotalMemoryUsedMB())
|
|
}
|
|
if c.TotalMemoryTotalMB() != 49152 {
|
|
t.Errorf("expected 49152, got %d", c.TotalMemoryTotalMB())
|
|
}
|
|
|
|
avg := c.AverageUtilization()
|
|
if avg != 52.5 {
|
|
t.Errorf("expected 52.5, got %f", avg)
|
|
}
|
|
|
|
ratio := c.MemoryUtilizationRatio()
|
|
expectedRatio := 12288.0 / 49152.0
|
|
if ratio != expectedRatio {
|
|
t.Errorf("expected %f, got %f", expectedRatio, ratio)
|
|
}
|
|
}
|
|
|
|
func TestGPUCollectorEmpty(t *testing.T) {
|
|
c := &GPUCollector{}
|
|
if c.TotalMemoryUsedMB() != 0 {
|
|
t.Error("expected 0 for empty collector")
|
|
}
|
|
if c.AverageUtilization() != 0 {
|
|
t.Error("expected 0 for empty collector")
|
|
}
|
|
if c.MemoryUtilizationRatio() != 0 {
|
|
t.Error("expected 0 for empty collector")
|
|
}
|
|
}
|
|
|
|
func TestParseIntSafe(t *testing.T) {
|
|
if parseIntSafe("42") != 42 {
|
|
t.Error("expected 42")
|
|
}
|
|
if parseIntSafe("invalid") != 0 {
|
|
t.Error("expected 0 for invalid")
|
|
}
|
|
if parseIntSafe(" 100 ") != 100 {
|
|
t.Error("expected 100 with whitespace")
|
|
}
|
|
}
|
|
|
|
func TestParseFloatSafe(t *testing.T) {
|
|
if parseFloatSafe("3.14") != 3.14 {
|
|
t.Error("expected 3.14")
|
|
}
|
|
if parseFloatSafe("invalid") != 0 {
|
|
t.Error("expected 0 for invalid")
|
|
}
|
|
}
|