Skip to content

Commit 7438c33

Browse files
committed
pcie: hw: add tool to create test data
add a support tool which we can run to extract the machine data from sysfs and create fstest.MapFS data to use in unit test. The usage is straightforward: ``` $ go run tools/gen-pcie-testdata/main.go -h Usage of /tmp/go-build4024417054/b001/exe/main: -build-tag string inject a //go:build constraint for the current architecture, set "" to disable (default "amd64") -func string function name for the generated MapFS fixture (default "makeSysfsFixture") -pkg string package name for the generated MapFS fixture (default "device") -sysfs-root string sysfs root path (default "/sys") ``` We intentionally don't wire the tool in the Makefile (e.g. no target) because this is meant to be a developer tool, not something users consume. Signed-off-by: Francesco Romani <fromani@redhat.com>
1 parent 4dc7f26 commit 7438c33

5 files changed

Lines changed: 396 additions & 1 deletion

File tree

pkg/device/pciescan_amd64_test.go

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,16 @@ limitations under the License.
1616

1717
package device
1818

19-
import "testing"
19+
import (
20+
"io/fs"
21+
"sort"
22+
"testing"
23+
"testing/fstest"
24+
25+
"github.com/go-logr/logr/testr"
26+
"github.com/google/go-cmp/cmp"
27+
"k8s.io/utils/cpuset"
28+
)
2029

2130
func TestIsPCIeRootName(t *testing.T) {
2231
tests := []struct {
@@ -105,3 +114,88 @@ func TestIsPCIeRootName(t *testing.T) {
105114
})
106115
}
107116
}
117+
118+
func TestPCIeDomainsFromFS(t *testing.T) {
119+
logger := testr.New(t)
120+
tests := []struct {
121+
name string
122+
fs fstest.MapFS
123+
want []PCIeDomain
124+
}{
125+
{
126+
name: "empty FS",
127+
fs: fstest.MapFS{
128+
"devices": &fstest.MapFile{
129+
Mode: fs.ModeDir,
130+
},
131+
},
132+
want: []PCIeDomain{},
133+
},
134+
{
135+
name: "ryzen 9 5950X - single PCIe root",
136+
fs: makeRyzen95950XFixture(),
137+
want: []PCIeDomain{
138+
{
139+
// created manually inspecting the machine hardware.
140+
RootName: "pci0000:00",
141+
LocalCPUs: mustParseCPUSet(t, "0-31"),
142+
},
143+
},
144+
},
145+
{
146+
name: "xeon gold 6230R - multiple symmetric PCIe roots",
147+
fs: makeXeonGold6230RFixture(),
148+
want: []PCIeDomain{
149+
{
150+
RootName: "pci0000:00",
151+
LocalCPUs: mustParseCPUSet(t, "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102"),
152+
},
153+
{
154+
RootName: "pci0000:17",
155+
LocalCPUs: mustParseCPUSet(t, "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102"),
156+
},
157+
{
158+
RootName: "pci0000:3a",
159+
LocalCPUs: mustParseCPUSet(t, "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102"),
160+
},
161+
{
162+
RootName: "pci0000:5d",
163+
LocalCPUs: mustParseCPUSet(t, "0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102"),
164+
},
165+
{
166+
RootName: "pci0000:80",
167+
LocalCPUs: mustParseCPUSet(t, "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99,101,103"),
168+
},
169+
{
170+
RootName: "pci0000:85",
171+
LocalCPUs: mustParseCPUSet(t, "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99,101,103"),
172+
},
173+
{
174+
RootName: "pci0000:ae",
175+
LocalCPUs: mustParseCPUSet(t, "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99,101,103"),
176+
},
177+
{
178+
RootName: "pci0000:d7",
179+
LocalCPUs: mustParseCPUSet(t, "1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99,101,103"),
180+
},
181+
},
182+
},
183+
}
184+
185+
for _, tt := range tests {
186+
t.Run(tt.name, func(t *testing.T) {
187+
got, err := PCIeDomainsFromFS(logger, tt.fs)
188+
if err != nil {
189+
t.Fatalf("unexpected error: %v", err)
190+
}
191+
sort.Slice(got, func(i, j int) bool {
192+
return got[i].RootName < got[j].RootName
193+
})
194+
if diff := cmp.Diff(tt.want, got, cmp.Comparer(func(a, b cpuset.CPUSet) bool {
195+
return a.Equals(b)
196+
})); diff != "" {
197+
t.Errorf("PCIeDomain mismatch:\n%s", diff)
198+
}
199+
})
200+
}
201+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//go:build amd64
2+
3+
// autogenerated - DO NOT EDIT!
4+
// regenerate from the project root with:
5+
// go run tools/gen-pcie-testdata/main.go --func makeRyzen95950XFixture --pkg device --build-tag amd64
6+
7+
package device
8+
9+
import (
10+
"testing/fstest"
11+
)
12+
13+
func makeRyzen95950XFixture() fstest.MapFS {
14+
return fstest.MapFS{
15+
"devices/pci0000:00/pci_bus/0000:00/cpulistaffinity": &fstest.MapFile{
16+
Data: []byte("0-31\n"),
17+
},
18+
"devices/system/cpu/online": &fstest.MapFile{
19+
Data: []byte("0-31\n"),
20+
},
21+
}
22+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//go:build amd64
2+
3+
// autogenerated - DO NOT EDIT!
4+
// regenerate from the project root with:
5+
// go run tools/gen-pcie-testdata/main.go --func makeXeonGold6230RFixture --pkg device --build-tag amd64
6+
7+
package device
8+
9+
import (
10+
"testing/fstest"
11+
)
12+
13+
func makeXeonGold6230RFixture() fstest.MapFS {
14+
return fstest.MapFS{
15+
"devices/pci0000:00/pci_bus/0000:00/cpulistaffinity": &fstest.MapFile{
16+
Data: []byte("0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102\n"),
17+
},
18+
"devices/pci0000:17/pci_bus/0000:17/cpulistaffinity": &fstest.MapFile{
19+
Data: []byte("0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102\n"),
20+
},
21+
"devices/pci0000:3a/pci_bus/0000:3a/cpulistaffinity": &fstest.MapFile{
22+
Data: []byte("0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102\n"),
23+
},
24+
"devices/pci0000:5d/pci_bus/0000:5d/cpulistaffinity": &fstest.MapFile{
25+
Data: []byte("0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102\n"),
26+
},
27+
"devices/pci0000:80/pci_bus/0000:80/cpulistaffinity": &fstest.MapFile{
28+
Data: []byte("1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99,101,103\n"),
29+
},
30+
"devices/pci0000:85/pci_bus/0000:85/cpulistaffinity": &fstest.MapFile{
31+
Data: []byte("1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99,101,103\n"),
32+
},
33+
"devices/pci0000:ae/pci_bus/0000:ae/cpulistaffinity": &fstest.MapFile{
34+
Data: []byte("1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99,101,103\n"),
35+
},
36+
"devices/pci0000:d7/pci_bus/0000:d7/cpulistaffinity": &fstest.MapFile{
37+
Data: []byte("1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79,81,83,85,87,89,91,93,95,97,99,101,103\n"),
38+
},
39+
"devices/system/cpu/online": &fstest.MapFile{
40+
Data: []byte("0-103\n"),
41+
},
42+
}
43+
}

tools/gen-pcie-testdata/Dockerfile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# use this Dockerfile if you want an image to run
2+
# in your cluster to extract test data for this driver
3+
4+
# setup cross-compile env
5+
FROM --platform=$BUILDPLATFORM golang:1.26 AS builder
6+
ARG TARGETARCH
7+
ARG GOARCH=${TARGETARCH} CGO_ENABLED=0
8+
ARG LDFLAGS=-s -w
9+
10+
# cache go modules
11+
WORKDIR /go/src/app
12+
COPY go.mod go.sum .
13+
RUN go mod download
14+
15+
# build
16+
COPY . .
17+
RUN go build -ldflags "${LDFLAGS}" -o /go/bin/gen ./tools/gen-pcie-testdata/
18+
19+
# copy binary onto base image
20+
FROM gcr.io/distroless/base-debian12
21+
COPY --from=builder --chown=root:root /go/bin/gen /gen
22+
CMD ["/gen"]

0 commit comments

Comments
 (0)