refactor: modularize audit and harden build validation
This commit is contained in:
@@ -33,10 +33,10 @@ func fakeNUMANodes(t *testing.T, byBDF map[string]string) {
|
||||
}
|
||||
|
||||
func TestGPUNUMANodesResolvesFromPCIBusID(t *testing.T) {
|
||||
fakeNvidiaSmiBusIDs(t, "0, 00000000:05:00.0\n1, 00000000:F4:00.0\n")
|
||||
fakeNvidiaSmiBusIDs(t, "0, 00000000:05:00.0\n1, 00000000:f4:00.0\n")
|
||||
fakeNUMANodes(t, map[string]string{
|
||||
"0000:05:00.0": "0\n",
|
||||
"0000:F4:00.0": "1\n",
|
||||
"0000:f4:00.0": "1\n",
|
||||
})
|
||||
|
||||
nodes, err := gpuNUMANodes([]int{0, 1})
|
||||
@@ -69,14 +69,14 @@ func TestGPUNUMANodesSkipsUnresolvableNode(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGPUBandwidthSocketGroupsSplitsBySocket(t *testing.T) {
|
||||
fakeNvidiaSmiBusIDs(t, "0, 00000000:05:00.0\n1, 00000000:06:00.0\n2, 00000000:76:00.0\n3, 00000000:77:00.0\n4, 00000000:F4:00.0\n5, 00000000:F5:00.0\n")
|
||||
fakeNvidiaSmiBusIDs(t, "0, 00000000:05:00.0\n1, 00000000:06:00.0\n2, 00000000:76:00.0\n3, 00000000:77:00.0\n4, 00000000:f4:00.0\n5, 00000000:f5:00.0\n")
|
||||
fakeNUMANodes(t, map[string]string{
|
||||
"0000:05:00.0": "0\n",
|
||||
"0000:06:00.0": "0\n",
|
||||
"0000:76:00.0": "0\n",
|
||||
"0000:77:00.0": "0\n",
|
||||
"0000:F4:00.0": "1\n",
|
||||
"0000:F5:00.0": "1\n",
|
||||
"0000:f4:00.0": "1\n",
|
||||
"0000:f5:00.0": "1\n",
|
||||
})
|
||||
|
||||
groups := gpuBandwidthSocketGroups([]int{0, 1, 2, 3, 4, 5}, nil)
|
||||
@@ -91,30 +91,20 @@ func TestGPUBandwidthSocketGroupsSplitsBySocket(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGPUBandwidthSocketGroupsFoldsUnresolvedIntoLastGroup(t *testing.T) {
|
||||
// GPU 4's NUMA node fails to resolve (e.g. a flaky sysfs read), but the
|
||||
// other 5 GPUs still clearly span two sockets — the split should survive
|
||||
// and GPU 4 should ride along with the last group rather than being
|
||||
// tested alone or collapsing the whole thing to one pass.
|
||||
fakeNvidiaSmiBusIDs(t, "0, 00000000:05:00.0\n1, 00000000:06:00.0\n2, 00000000:76:00.0\n3, 00000000:77:00.0\n4, 00000000:F4:00.0\n5, 00000000:F5:00.0\n")
|
||||
func TestGPUBandwidthSocketGroupsFallsBackWhenAnyNodeIsUnresolved(t *testing.T) {
|
||||
fakeNvidiaSmiBusIDs(t, "0, 00000000:05:00.0\n1, 00000000:06:00.0\n2, 00000000:76:00.0\n3, 00000000:77:00.0\n4, 00000000:f4:00.0\n5, 00000000:f5:00.0\n")
|
||||
fakeNUMANodes(t, map[string]string{
|
||||
"0000:05:00.0": "0\n",
|
||||
"0000:06:00.0": "0\n",
|
||||
"0000:76:00.0": "0\n",
|
||||
"0000:77:00.0": "0\n",
|
||||
// GPU 4 (F4:00.0) deliberately missing.
|
||||
"0000:F5:00.0": "1\n",
|
||||
"0000:f5:00.0": "1\n",
|
||||
})
|
||||
|
||||
groups := gpuBandwidthSocketGroups([]int{0, 1, 2, 3, 4, 5}, nil)
|
||||
if len(groups) != 2 {
|
||||
t.Fatalf("groups=%v want 2 groups", groups)
|
||||
}
|
||||
if joinIndexList(groups[0]) != "0,1,2,3" {
|
||||
t.Fatalf("groups[0]=%v want 0,1,2,3", groups[0])
|
||||
}
|
||||
if joinIndexList(groups[1]) != "4,5" {
|
||||
t.Fatalf("groups[1]=%v want 4,5 (unresolved GPU 4 folded into last group)", groups[1])
|
||||
if len(groups) != 1 || joinIndexList(groups[0]) != "0,1,2,3,4,5" {
|
||||
t.Fatalf("groups=%v want single fallback group", groups)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +151,8 @@ func TestNormalizeNvidiaBDF(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"00000000:05:00.0": "0000:05:00.0",
|
||||
"0000:05:00.0": "0000:05:00.0",
|
||||
"00000000:CB:00.0": "0000:cb:00.0",
|
||||
"0000:4F:00.0": "0000:4f:00.0",
|
||||
"garbage": "garbage",
|
||||
}
|
||||
for in, want := range cases {
|
||||
@@ -171,17 +163,17 @@ func TestNormalizeNvidiaBDF(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRunNvidiaBandwidthPackSplitsPerSocketThenAll(t *testing.T) {
|
||||
fakeNvidiaSmiBusIDs(t, "0, 00000000:05:00.0\n1, 00000000:06:00.0\n2, 00000000:F4:00.0\n3, 00000000:F5:00.0\n")
|
||||
fakeNvidiaSmiBusIDs(t, "0, 00000000:05:00.0\n1, 00000000:06:00.0\n2, 00000000:f4:00.0\n3, 00000000:f5:00.0\n")
|
||||
fakeNUMANodes(t, map[string]string{
|
||||
"0000:05:00.0": "0\n",
|
||||
"0000:06:00.0": "0\n",
|
||||
"0000:F4:00.0": "1\n",
|
||||
"0000:F5:00.0": "1\n",
|
||||
"0000:f4:00.0": "1\n",
|
||||
"0000:f5:00.0": "1\n",
|
||||
})
|
||||
|
||||
dir := t.TempDir()
|
||||
s := &System{}
|
||||
_, err := s.RunNvidiaBandwidthPack(nil, dir, []int{0, 1, 2, 3}, nil)
|
||||
_, err := s.RunNvidiaBandwidthPack(nil, dir, []int{0, 1, 2, 3}, true, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("RunNvidiaBandwidthPack error: %v", err)
|
||||
}
|
||||
@@ -211,6 +203,34 @@ func TestRunNvidiaBandwidthPackSplitsPerSocketThenAll(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunNvidiaBandwidthPackValidateNeverSplits(t *testing.T) {
|
||||
// Multi-socket system, but fullMatrix=false (Validate tier): still one
|
||||
// nvbandwidth pass across every GPU, no per-socket split.
|
||||
fakeNvidiaSmiBusIDs(t, "0, 00000000:05:00.0\n1, 00000000:06:00.0\n2, 00000000:f4:00.0\n3, 00000000:f5:00.0\n")
|
||||
fakeNUMANodes(t, map[string]string{
|
||||
"0000:05:00.0": "0\n",
|
||||
"0000:06:00.0": "0\n",
|
||||
"0000:f4:00.0": "1\n",
|
||||
"0000:f5:00.0": "1\n",
|
||||
})
|
||||
|
||||
dir := t.TempDir()
|
||||
if _, err := (&System{}).RunNvidiaBandwidthPack(nil, dir, []int{0, 1, 2, 3}, false, nil); err != nil {
|
||||
t.Fatalf("RunNvidiaBandwidthPack error: %v", err)
|
||||
}
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDir: %v", err)
|
||||
}
|
||||
runDir := filepath.Join(dir, entries[0].Name())
|
||||
if _, err := os.Stat(filepath.Join(runDir, "03-dcgmi-nvbandwidth.log")); err != nil {
|
||||
t.Fatalf("missing single-pass job output: %v", err)
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(runDir, "03-dcgmi-nvbandwidth-socket0.log")); err == nil {
|
||||
t.Fatalf("Validate tier must not split per socket")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunNvidiaBandwidthPackSinglePassWhenOneSocket(t *testing.T) {
|
||||
fakeNvidiaSmiBusIDs(t, "0, 00000000:05:00.0\n1, 00000000:06:00.0\n")
|
||||
fakeNUMANodes(t, map[string]string{
|
||||
@@ -220,7 +240,7 @@ func TestRunNvidiaBandwidthPackSinglePassWhenOneSocket(t *testing.T) {
|
||||
|
||||
dir := t.TempDir()
|
||||
s := &System{}
|
||||
_, err := s.RunNvidiaBandwidthPack(nil, dir, []int{0, 1}, nil)
|
||||
_, err := s.RunNvidiaBandwidthPack(nil, dir, []int{0, 1}, true, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("RunNvidiaBandwidthPack error: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user