Skip to content

Commit c115fd1

Browse files
committed
Add unit tests for CDI spec generation for passthrough devices
Signed-off-by: Christopher Desiniotis <[email protected]>
1 parent 808d390 commit c115fd1

File tree

4 files changed

+625
-2
lines changed

4 files changed

+625
-2
lines changed

internal/cdi/lib-vfio_test.go

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/**
2+
# Copyright (c) NVIDIA CORPORATION. All rights reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
**/
16+
17+
package cdi
18+
19+
import (
20+
"testing"
21+
22+
"github.com/container-orchestrated-devices/container-device-interface/specs-go"
23+
"github.com/stretchr/testify/require"
24+
"gitlab.com/nvidia/cloud-native/go-nvlib/pkg/nvpci"
25+
)
26+
27+
func TestGetAllDeviceSpecs(t *testing.T) {
28+
testCases := []struct {
29+
description string
30+
lib *vfiolib
31+
expectedDeviceSpecs []specs.Device
32+
}{
33+
{
34+
description: "no NVIDIA devices",
35+
lib: &vfiolib{
36+
nvpcilib: &nvpciInterfaceMock{
37+
GetGPUsFunc: func() ([]*nvpci.NvidiaPCIDevice, error) {
38+
devices := []*nvpci.NvidiaPCIDevice{}
39+
return devices, nil
40+
},
41+
},
42+
},
43+
expectedDeviceSpecs: nil,
44+
},
45+
{
46+
description: "one NVIDIA device, not bound to vfio-pci",
47+
lib: &vfiolib{
48+
nvpcilib: &nvpciInterfaceMock{
49+
GetGPUsFunc: func() ([]*nvpci.NvidiaPCIDevice, error) {
50+
devices := []*nvpci.NvidiaPCIDevice{
51+
{
52+
Address: "000:3B:00.0",
53+
Device: 0x2331,
54+
IommuGroup: -1,
55+
Driver: "nvidia",
56+
},
57+
}
58+
return devices, nil
59+
},
60+
},
61+
},
62+
expectedDeviceSpecs: nil,
63+
},
64+
{
65+
description: "one NVIDIA device, bound to vfio-pci",
66+
lib: &vfiolib{
67+
nvpcilib: &nvpciInterfaceMock{
68+
GetGPUsFunc: func() ([]*nvpci.NvidiaPCIDevice, error) {
69+
devices := []*nvpci.NvidiaPCIDevice{
70+
{
71+
Address: "000:3B:00.0",
72+
Device: 0x2331,
73+
IommuGroup: 60,
74+
Driver: "vfio-pci",
75+
},
76+
}
77+
return devices, nil
78+
},
79+
},
80+
},
81+
expectedDeviceSpecs: []specs.Device{
82+
{
83+
Name: "0",
84+
ContainerEdits: specs.ContainerEdits{
85+
DeviceNodes: []*specs.DeviceNode{
86+
{
87+
Path: "/dev/vfio/60",
88+
},
89+
},
90+
},
91+
},
92+
},
93+
},
94+
{
95+
description: "multiple NVIDIA devices, one bound to vfio-pci",
96+
lib: &vfiolib{
97+
nvpcilib: &nvpciInterfaceMock{
98+
GetGPUsFunc: func() ([]*nvpci.NvidiaPCIDevice, error) {
99+
devices := []*nvpci.NvidiaPCIDevice{
100+
{
101+
Address: "000:3B:00.0",
102+
Device: 0x2331,
103+
IommuGroup: 60,
104+
Driver: "vfio-pci",
105+
},
106+
{
107+
Address: "000:86:00.0",
108+
Device: 0x2331,
109+
IommuGroup: -1,
110+
Driver: "",
111+
},
112+
}
113+
return devices, nil
114+
},
115+
},
116+
},
117+
expectedDeviceSpecs: []specs.Device{
118+
{
119+
Name: "0",
120+
ContainerEdits: specs.ContainerEdits{
121+
DeviceNodes: []*specs.DeviceNode{
122+
{
123+
Path: "/dev/vfio/60",
124+
},
125+
},
126+
},
127+
},
128+
},
129+
},
130+
{
131+
description: "multiple NVIDIA devices, all bound to vfio-pci",
132+
lib: &vfiolib{
133+
nvpcilib: &nvpciInterfaceMock{
134+
GetGPUsFunc: func() ([]*nvpci.NvidiaPCIDevice, error) {
135+
devices := []*nvpci.NvidiaPCIDevice{
136+
{
137+
Address: "000:3B:00.0",
138+
Device: 0x2331,
139+
IommuGroup: 60,
140+
Driver: "vfio-pci",
141+
},
142+
{
143+
Address: "000:86:00.0",
144+
Device: 0x2331,
145+
IommuGroup: 90,
146+
Driver: "vfio-pci",
147+
},
148+
}
149+
return devices, nil
150+
},
151+
},
152+
},
153+
expectedDeviceSpecs: []specs.Device{
154+
{
155+
Name: "0",
156+
ContainerEdits: specs.ContainerEdits{
157+
DeviceNodes: []*specs.DeviceNode{
158+
{
159+
Path: "/dev/vfio/60",
160+
},
161+
},
162+
},
163+
},
164+
{
165+
Name: "1",
166+
ContainerEdits: specs.ContainerEdits{
167+
DeviceNodes: []*specs.DeviceNode{
168+
{
169+
Path: "/dev/vfio/90",
170+
},
171+
},
172+
},
173+
},
174+
},
175+
},
176+
}
177+
178+
for _, tc := range testCases {
179+
t.Run(tc.description, func(t *testing.T) {
180+
deviceSpecs, err := tc.lib.GetAllDeviceSpecs()
181+
require.NoError(t, err)
182+
require.Equal(t, tc.expectedDeviceSpecs, deviceSpecs)
183+
})
184+
}
185+
}

internal/cdi/lib.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type nvcdilib struct {
2525
vendor string
2626
class string
2727

28-
nvpcilib nvpci.Interface
28+
nvpcilib nvpciInterface
2929
}
3030

3131
// New creates a new instance of this library
@@ -51,7 +51,7 @@ func New(opts ...Option) (nvcdi.Interface, error) {
5151
type Option func(*nvcdilib)
5252

5353
// WithNvpciLib sets the nvpci library for the library
54-
func WithNvpciLib(nvpcilib nvpci.Interface) Option {
54+
func WithNvpciLib(nvpcilib nvpciInterface) Option {
5555
return func(l *nvcdilib) {
5656
l.nvpcilib = nvpcilib
5757
}

0 commit comments

Comments
 (0)