package cli import ( "testing" "gitea.mynodes.xyz/ilker/llmgw/internal/control/adminapi" "gitea.mynodes.xyz/ilker/llmgw/internal/modelplan" ) func TestAPlanSeesANodesMIGInstancesAsAClassOfTheirOwn(t *testing.T) { // Card 0 cut into two 3g.40gb instances, both free, and card 1 whole and // busy: the instances are a pool of forty-gigabyte devices, and the busy // card no pool at all. hw := hardwareFrom([]adminapi.NodeView{{ID: "a100", State: "ready", GPUTotal: 3, GPUFree: 2, Classes: []string{"a100-80g-mig-3g.40gb", "a100-80g"}, ClassGPUs: []adminapi.ClassGPUs{ {Class: "a100-80g-mig-3g.40gb", Total: 2, Free: 2, MIG: true}, {Class: "a100-80g", Total: 1, Free: 0}, }}}) if len(hw) != 1 { t.Fatalf("pools: %+v", hw) } want := modelplan.Hardware{Class: "a100-80g-mig-3g.40gb", GPUMemGB: 40, GPUsPerNode: 2, Nodes: 1} if hw[0] != want { t.Errorf("pool %+v, want %+v", hw[0], want) } } func TestCtlNodesCountsANodesDevicesByClassWhenItHasMIG(t *testing.T) { mig := adminapi.NodeView{Classes: []string{"a100-80g-mig-3g.40gb", "a100-80g"}, ClassGPUs: []adminapi.ClassGPUs{ {Class: "a100-80g-mig-3g.40gb", Total: 2, MIG: true}, {Class: "a100-80g", Total: 1}}} if got := classesColumn(mig); got != "a100-80g-mig-3g.40gb×2,a100-80g×1" { t.Errorf("MIG node: %q", got) } // A node of one kind of whole card reads as it always did. plain := adminapi.NodeView{Classes: []string{"h100-80g"}, ClassGPUs: []adminapi.ClassGPUs{{Class: "h100-80g", Total: 8}}} if got := classesColumn(plain); got != "h100-80g" { t.Errorf("plain node: %q", got) } }