• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

k8snetworkplumbingwg / ib-sriov-cni / 19924469928

04 Dec 2025 09:42AM UTC coverage: 23.678% (+0.7%) from 23.009%
19924469928

push

github

web-flow
Merge pull request #146 from winsopc/vfio-support-upstream

VF VFIO device support

51 of 105 new or added lines in 5 files covered. (48.57%)

282 of 1191 relevant lines covered (23.68%)

0.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.63
/pkg/utils/testing.go
1
/*
2
        This file contains test helper functions to mock linux sysfs directory.
3
        If a package need to access system sysfs it should call CreateTmpSysFs() before test
4
        then call RemoveTmpSysFs() once test is done for clean up.
5
*/
6

7
package utils
8

9
import (
10
        "os"
11
        "path/filepath"
12
)
13

14
const (
15
        OwnerReadWriteExecuteOthersReadExecuteAttrs = 0755
16
        OwnerReadWriteOthersReadAttrs               = 0644
17
)
18

19
func check(e error) {
2✔
20
        if e != nil {
2✔
21
                panic(e)
×
22
        }
23
}
24

25
type tmpSysFs struct {
26
        dirRoot        string
27
        dirList        []string
28
        fileList       map[string][]byte
29
        netSymlinks    map[string]string
30
        devSymlinks    map[string]string
31
        vfSymlinks     map[string]string
32
        driverSymlinks map[string]string
33
        originalRoot   *os.File
34
}
35

36
var ts = tmpSysFs{
37
        dirList: []string{
38
                "sys/class/net",
39
                "sys/bus/pci/devices",
40
                "sys/bus/pci/drivers/mlx5_core",
41
                "sys/bus/pci/drivers/vfio-pci",
42
                "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.1/net/ib0",
43
                "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.0/net/ib1",
44
                "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.1/net/ib2",
45
                "sys/devices/pci0000:00/0000:00:02.0/0000:05:00.0/net/ib3",
46
                "sys/devices/pci0000:00/0000:00:02.0/0000:05:00.0/net/ib4",
47
        },
48
        fileList: map[string][]byte{
49
                "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.1/sriov_numvfs": []byte("2"),
50
                "sys/devices/pci0000:00/0000:00:02.0/0000:05:00.0/sriov_numvfs": []byte("0"),
51
        },
52
        netSymlinks: map[string]string{
53
                "sys/class/net/ib0": "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.1/net/ib0",
54
                "sys/class/net/ib1": "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.0/net/ib1",
55
                "sys/class/net/ib2": "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.1/net/ib2",
56
                "sys/class/net/ib3": "sys/devices/pci0000:00/0000:00:02.0/0000:05:00.0/net/ib3",
57
                "sys/class/net/ib4": "sys/devices/pci0000:00/0000:00:02.0/0000:05:00.0/net/ib4",
58
        },
59
        devSymlinks: map[string]string{
60
                "sys/class/net/ib0/device": "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.1",
61
                "sys/class/net/ib1/device": "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.0",
62
                "sys/class/net/ib2/device": "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.1",
63
                "sys/class/net/ib3/device": "sys/devices/pci0000:00/0000:00:02.0/0000:05:00.0",
64
                "sys/class/net/ib4/device": "sys/devices/pci0000:00/0000:00:02.0/0000:05:00.0",
65

66
                "sys/bus/pci/devices/0000:af:00.1": "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.1",
67
                "sys/bus/pci/devices/0000:af:06.0": "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.0",
68
                "sys/bus/pci/devices/0000:af:06.1": "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.1",
69
                "sys/bus/pci/devices/0000:05:00.0": "sys/devices/pci0000:00/0000:00:02.0/0000:05:00.0",
70
        },
71
        vfSymlinks: map[string]string{
72
                "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.1/virtfn0": "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.0",
73
                "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.0/physfn":  "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.1",
74

75
                "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.1/virtfn1": "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.1",
76
                "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.1/physfn":  "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.1",
77
        },
78
        driverSymlinks: map[string]string{
79
                // PF device (ib0 / 0000:af:00.1) bound to mlx5_core driver
80
                "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:00.1/driver": "sys/bus/pci/drivers/mlx5_core",
81
                // Normal VF (ib1 / 0000:af:06.0) bound to mlx5_core driver
82
                "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.0/driver": "sys/bus/pci/drivers/mlx5_core",
83
                // VFIO VF (ib2 / 0000:af:06.1) bound to vfio-pci driver (for testing VFIO devices)
84
                "sys/devices/pci0000:ae/0000:ae:00.0/0000:af:06.1/driver": "sys/bus/pci/drivers/" + VfioPciDriverName,
85
        },
86
}
87

88
// CreateTmpSysFs create mock sysfs for testing
89
func CreateTmpSysFs() error {
1✔
90
        originalRoot, _ := os.Open("/")
1✔
91
        ts.originalRoot = originalRoot
1✔
92

1✔
93
        tmpdir, ioErr := os.MkdirTemp("/tmp", "ib-sriov-cni-plugin-testfiles-")
1✔
94
        if ioErr != nil {
1✔
95
                return ioErr
×
96
        }
×
97

98
        ts.dirRoot = tmpdir
1✔
99

1✔
100
        for _, dir := range ts.dirList {
10✔
101
                if err := os.MkdirAll(filepath.Join(ts.dirRoot, dir), OwnerReadWriteExecuteOthersReadExecuteAttrs); err != nil {
9✔
102
                        return err
×
103
                }
×
104
        }
105
        for filename, body := range ts.fileList {
3✔
106
                if err := os.WriteFile(filepath.Join(ts.dirRoot, filename), body, OwnerReadWriteOthersReadAttrs); err != nil {
2✔
107
                        return err
×
108
                }
×
109
        }
110

111
        for link, target := range ts.netSymlinks {
6✔
112
                if err := createSymlinks(filepath.Join(ts.dirRoot, link), filepath.Join(ts.dirRoot, target)); err != nil {
5✔
113
                        return err
×
114
                }
×
115
        }
116

117
        for link, target := range ts.devSymlinks {
10✔
118
                if err := createSymlinks(filepath.Join(ts.dirRoot, link), filepath.Join(ts.dirRoot, target)); err != nil {
9✔
119
                        return err
×
120
                }
×
121
        }
122

123
        for link, target := range ts.vfSymlinks {
5✔
124
                if err := createSymlinks(filepath.Join(ts.dirRoot, link), filepath.Join(ts.dirRoot, target)); err != nil {
4✔
125
                        return err
×
126
                }
×
127
        }
128

129
        for link, target := range ts.driverSymlinks {
4✔
130
                if err := createSymlinks(filepath.Join(ts.dirRoot, link), filepath.Join(ts.dirRoot, target)); err != nil {
3✔
NEW
131
                        return err
×
NEW
132
                }
×
133
        }
134

135
        SysBusPci = filepath.Join(ts.dirRoot, SysBusPci)
1✔
136
        NetDirectory = filepath.Join(ts.dirRoot, NetDirectory)
1✔
137
        return nil
1✔
138
}
139

140
func createSymlinks(link, target string) error {
21✔
141
        if err := os.MkdirAll(target, OwnerReadWriteExecuteOthersReadExecuteAttrs); err != nil {
21✔
142
                return err
×
143
        }
×
144
        if err := os.Symlink(target, link); err != nil {
21✔
145
                return err
×
146
        }
×
147
        return nil
21✔
148
}
149

150
// RemoveTmpSysFs removes mocked sysfs
151
func RemoveTmpSysFs() error {
1✔
152
        if err := ts.originalRoot.Chdir(); err != nil {
1✔
153
                return err
×
154
        }
×
155
        if err := ts.originalRoot.Close(); err != nil {
1✔
156
                return err
×
157
        }
×
158
        if err := os.RemoveAll(ts.dirRoot); err != nil {
1✔
159
                return err
×
160
        }
×
161
        return nil
1✔
162
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc