Repository: hashicorp/nomad
File: client/lib/numalib/detect_linux_test.go (Go)

Code before:
		"/sys/devices/system/cpu/cpu2/topology/physical_package_id":  []byte("0"),
		"/sys/devices/system/cpu/cpu2/topology/thread_siblings_list": []byte("0,2"),
		"/sys/devices/system/cpu/cpu3/acpi_cppc/nominal_freq":        []byte("2450"),
		"/sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_max_freq":      []byte("3500000"),
		"/sys/devices/system/cpu/cpu3/cpufreq/scaling_driver":        []byte("acpi-cpufreq"),
		"/sys/devices/system/cpu/cpu3/topology/physical_package_id":  []byte("0"),
		"/sys/devices/system/cpu/cpu3/topology/thread_siblings_list": []byte("1,3"),
	}[path], nil
}

func TestSysfs_discoverOnline(t *testing.T) {
	st := MockTopology(&idset.Set[hw.NodeID]{}, SLIT{}, []Core{})
	goodIDSet := idset.From[hw.NodeID]([]uint8{0, 1})
	oneNode := idset.From[hw.NodeID]([]uint8{0})

	tests := []struct {
		name          string
		readerFunc    pathReaderFn
		expectedIDSet *idset.Set[hw.NodeID]
	}{
		{"lxc values", badSysData, oneNode},
		{"good values", goodSysData, goodIDSet},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			sy := &Sysfs{}
			sy.discoverOnline(st, tt.readerFunc)
			must.Eq(t, tt.expectedIDSet, st.GetNodes())
		})
	}
}

func TestSysfs_discoverCosts(t *testing.T) {
	st := MockTopology(idset.Empty[hw.NodeID](), SLIT{}, []Core{})
	twoNodes := idset.From[hw.NodeID]([]uint8{1, 3})

	tests := []struct {
		name              string
		nodeIDs           *idset.Set[hw.NodeID]
		readerFunc        pathReaderFn
		expectedDistances SLIT
	}{
		{"empty node IDs", idset.Empty[hw.NodeID](), os.ReadFile, SLIT{}},
		{"two nodes and bad sys data", twoNodes, badSysData, SLIT{
			[]Cost{0, 0},
			[]Cost{0, 0},
		}},
		{"two nodes and good sys data", twoNodes, goodSysData, SLIT{
			[]Cost{0, 0},
			[]Cost{10, 0},
		}},

Review comment (suggestion):
are these nodes' `cpulist`s empty just because they're irrelevant to the test? I haven't looked at a lot of these device files in reality, but intuitively we're leaving `1,5-15` out of this test data, and I'm not sure why.

Code after:
		"/sys/devices/system/cpu/cpu2/cpufreq/scaling_driver":        []byte("acpi-cpufreq"),
		"/sys/devices/system/cpu/cpu2/topology/physical_package_id":  []byte("0"),
		"/sys/devices/system/cpu/cpu2/topology/thread_siblings_list": []byte("0,2"),
		"/sys/devices/system/cpu/cpu3/acpi_cppc/nominal_freq":        []byte("2450"),
		"/sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_max_freq":      []byte("3500000"),
		"/sys/devices/system/cpu/cpu3/cpufreq/scaling_driver":        []byte("acpi-cpufreq"),
		"/sys/devices/system/cpu/cpu3/topology/physical_package_id":  []byte("0"),
		"/sys/devices/system/cpu/cpu3/topology/thread_siblings_list": []byte("1,3"),
	}[path], nil
}

// discontinuousSysData represents a host with nodes that are online but don't
// have any cpus associated with them ref
// https://github.com/hashicorp/nomad/issues/27266
func discontinuousSysData(path string) ([]byte, error) {
	out := map[string][]byte{
		"/sys/devices/system/node/online":         []byte("0,2-4"),
		"/sys/devices/system/cpu/online":          []byte("0-15"),
		"/sys/devices/system/node/node0/distance": []byte("10 80 80 80"),
		"/sys/devices/system/node/node0/cpulist":  []byte("0-15"),
		"/sys/devices/system/node/node2/distance": []byte("80 10 80 80"),
		"/sys/devices/system/node/node2/cpulist":  []byte(""),
		"/sys/devices/system/node/node3/distance": []byte("80 80 10 80"),
		"/sys/devices/system/node/node3/cpulist":  []byte(""),
		"/sys/devices/system/node/node4/distance": []byte("80 80 80 10"),
		"/sys/devices/system/node/node4/cpulist":  []byte(""),
	}
	for i := range 15 {
		cpuPath := fmt.Sprintf("/sys/devices/system/cpu/cpu%d", i)
		out[cpuPath+"/cpufreq/cpuinfo_max_freq"] = []byte("3500000")
		out[cpuPath+"/cpufreq/base_frequency"] = []byte("2100000")
		out[cpuPath+"/topology/physical_package_id"] = []byte("0")
		out[cpuPath+"/topology/thread_siblings_list"] = []byte("0,2")

	}
	return out[path], nil
}

func TestSysfs_discoverOnline(t *testing.T) {
	st := MockTopology(&idset.Set[hw.NodeID]{}, SLIT{}, []Core{})
	goodIDSet := idset.From[hw.NodeID]([]uint8{1, 3})
	oneNode := idset.From[hw.NodeID]([]uint8{0})

	tests := []struct {
		name          string
		readerFunc    pathReaderFn
		expectedIDSet *idset.Set[hw.NodeID]
	}{
		{"lxc values", badSysData, oneNode},
		{"good values", goodSysData, goodIDSet},
	}