Game detection: foreign GPU holders take an external lock hold (GAME_PROCS, GPU_FOREIGN_VRAM_MB)
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"slices"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNormName(t *testing.T) {
|
||||
for in, want := range map[string]string{
|
||||
"Cyberpunk2077.exe": "cyberpunk2077",
|
||||
"ollama": "ollama",
|
||||
"OLLAMA APP.EXE": "ollama app",
|
||||
" python.exe ": "python",
|
||||
"hl2": "hl2",
|
||||
} {
|
||||
if got := normName(in); got != want {
|
||||
t.Errorf("normName(%q) = %q, want %q", in, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseComputeApps(t *testing.T) {
|
||||
apps, err := parseComputeApps("1234, 512\n 42 , 8192 \n\n")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := []computeApp{{PID: 1234, UsedMB: 512}, {PID: 42, UsedMB: 8192}}
|
||||
if !slices.Equal(apps, want) {
|
||||
t.Errorf("got %+v, want %+v", apps, want)
|
||||
}
|
||||
|
||||
// WDDM reports "N/A" for memory; those rows are skipped, not fatal.
|
||||
apps, err = parseComputeApps("1234, N/A\n42, 1024\n")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !slices.Equal(apps, []computeApp{{PID: 42, UsedMB: 1024}}) {
|
||||
t.Errorf("got %+v", apps)
|
||||
}
|
||||
|
||||
if _, err := parseComputeApps("garbage\n"); err == nil {
|
||||
t.Error("expected an error for a malformed line")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetect(t *testing.T) {
|
||||
d := New([]string{"Cyberpunk2077.exe", "hl2"}, 1024,
|
||||
[]string{"ollama", "python", "pythonw"}, nil)
|
||||
ps := []Process{
|
||||
{PID: 10, Name: "ollama.exe"},
|
||||
{PID: 20, Name: "python.exe"},
|
||||
{PID: 30, Name: "cyberpunk2077.exe"},
|
||||
}
|
||||
apps := []computeApp{
|
||||
{PID: 10, UsedMB: 8192}, // ignored: ollama
|
||||
{PID: 20, UsedMB: 4096}, // ignored: python (ComfyUI)
|
||||
{PID: 40, UsedMB: 2048}, // foreign, above threshold
|
||||
{PID: 50, UsedMB: 100}, // foreign but below threshold
|
||||
}
|
||||
holders := d.detect(ps, apps)
|
||||
if len(holders) != 2 {
|
||||
t.Fatalf("got %v, want 2 holders", holders)
|
||||
}
|
||||
if holders[0] != "cyberpunk2077.exe (pid 30)" {
|
||||
t.Errorf("holders[0] = %q", holders[0])
|
||||
}
|
||||
if holders[1] != "unknown process (pid 40) using 2048 MiB VRAM" {
|
||||
t.Errorf("holders[1] = %q", holders[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectNothingConfigured(t *testing.T) {
|
||||
d := New(nil, 0, nil, nil)
|
||||
if got := d.detect([]Process{{PID: 1, Name: "game.exe"}}, nil); len(got) != 0 {
|
||||
t.Errorf("got %v, want none", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessesLive(t *testing.T) {
|
||||
if runtime.GOOS != "windows" && runtime.GOOS != "linux" {
|
||||
t.Skip("no process listing on this platform")
|
||||
}
|
||||
ps, err := processes()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(ps) == 0 {
|
||||
t.Fatal("no processes listed")
|
||||
}
|
||||
for _, p := range ps {
|
||||
if p.Name == "" {
|
||||
t.Errorf("pid %d has an empty name", p.PID)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user