github.com/vishvananda/netlink@v1.3.0/vdpa_linux_test.go (about) 1 package netlink 2 3 import ( 4 "errors" 5 "syscall" 6 "testing" 7 8 "github.com/vishvananda/netlink/nl" 9 ) 10 11 // tests in this package require following modules: vdpa, vdpa_sim, vdpa_sim_net 12 // The vpda_sim_net module creates virtual VDPA mgmt device with name vdpasim_net. 13 14 const ( 15 vdpaSimMGMTDev = "vdpasim_net" 16 vdpaTestDeviceName = "__nl_test_dev" 17 ) 18 19 var ( 20 vdapTestReqModules = []string{"vdpa", "vdpa_sim", "vdpa_sim_net"} 21 ) 22 23 func setupVDPATest(t *testing.T, reqCommands ...int) func() { 24 t.Helper() 25 skipUnlessRoot(t) 26 skipUnlessKModuleLoaded(t, vdapTestReqModules...) 27 gFam, err := GenlFamilyGet(nl.VDPA_GENL_NAME) 28 if err != nil { 29 t.Skip("can't check for supported VDPA commands") 30 } 31 for _, c := range reqCommands { 32 found := false 33 for _, supportedOpt := range gFam.Ops { 34 if supportedOpt.ID == uint32(c) { 35 found = true 36 } 37 } 38 if !found { 39 t.Skip("host doesn't support required VDPA command for the test") 40 } 41 } 42 return func() { 43 _ = VDPADelDev(vdpaTestDeviceName) 44 } 45 } 46 47 func TestVDPAGetMGMTDevList(t *testing.T) { 48 defer setupVDPATest(t, nl.VDPA_CMD_MGMTDEV_GET)() 49 mgmtDevs, err := VDPAGetMGMTDevList() 50 if err != nil { 51 t.Fatalf("Failed to list VDPA mgmt devs: %v", err) 52 } 53 simMGMTFound := false 54 for _, d := range mgmtDevs { 55 if d.DevName != vdpaSimMGMTDev || d.BusName != "" { 56 continue 57 } 58 simMGMTFound = true 59 checkVDPAMGMTDev(t, d) 60 } 61 if !simMGMTFound { 62 t.Fatal("VDPA vdpasim_net MGMT device not found") 63 } 64 } 65 66 func TestVDPAGetMGMTDevByBusAndName(t *testing.T) { 67 defer setupVDPATest(t, nl.VDPA_CMD_MGMTDEV_GET)() 68 mgmtDev, err := VDPAGetMGMTDevByBusAndName("", vdpaSimMGMTDev) 69 if err != nil { 70 t.Fatalf("Failed to get VDPA sim mgmt dev: %v", err) 71 } 72 checkVDPAMGMTDev(t, mgmtDev) 73 if mgmtDev.DevName != vdpaSimMGMTDev || mgmtDev.BusName != "" { 74 t.Fatalf("Invalid device received for Get call, expected: %s, actual: %s", vdpaSimMGMTDev, mgmtDev.DevName) 75 } 76 } 77 78 func TestVDPAGetMGMTDevByBusAndName_Unknown_Device(t *testing.T) { 79 defer setupVDPATest(t, nl.VDPA_CMD_MGMTDEV_GET)() 80 _, err := VDPAGetMGMTDevByBusAndName("pci", "__should_not_exist") 81 if !errors.Is(err, syscall.ENODEV) { 82 t.Fatal("VDPAGetMGMTDevByBusAndName returns unexpected error for unknown device") 83 } 84 } 85 86 func TestVDPANewDev(t *testing.T) { 87 defer setupVDPATest(t, nl.VDPA_CMD_DEV_GET, nl.VDPA_CMD_DEV_NEW)() 88 if err := createVDPATestDev(); err != nil { 89 t.Fatalf("failed to create VDPA device: %v", err) 90 } 91 _, err := VDPAGetDevByName(vdpaTestDeviceName) 92 if err != nil { 93 t.Fatalf("failed to get created VDPA devvice: %v", err) 94 } 95 } 96 97 func TestVDPANewDev_Already_Exist(t *testing.T) { 98 defer setupVDPATest(t, nl.VDPA_CMD_DEV_GET, nl.VDPA_CMD_DEV_NEW)() 99 if err := createVDPATestDev(); err != nil { 100 t.Fatalf("failed to create VDPA device: %v", err) 101 } 102 err := createVDPATestDev() 103 if !errors.Is(err, syscall.EEXIST) { 104 t.Fatal("VDPANewDev returns unexpected error for device which is already exist") 105 } 106 } 107 108 func TestVDPANewDev_Unknown_MGMT_DEV(t *testing.T) { 109 defer setupVDPATest(t, nl.VDPA_CMD_DEV_GET, nl.VDPA_CMD_DEV_NEW)() 110 err := VDPANewDev(vdpaTestDeviceName, "", "__should_not_exist", VDPANewDevParams{}) 111 if !errors.Is(err, syscall.ENODEV) { 112 t.Fatal("VDPANewDev returns unexpected error for unknown mgmt device") 113 } 114 } 115 116 func TestVDPADelDev(t *testing.T) { 117 defer setupVDPATest(t, nl.VDPA_CMD_DEV_DEL, nl.VDPA_CMD_DEV_NEW)() 118 defer setupVDPATest(t)() 119 if err := createVDPATestDev(); err != nil { 120 t.Fatalf("failed to create VDPA device: %v", err) 121 } 122 if err := VDPADelDev(vdpaTestDeviceName); err != nil { 123 t.Fatalf("VDPADelDev failed: %v", err) 124 } 125 } 126 127 func TestVDPADelDev_Unknown_Device(t *testing.T) { 128 defer setupVDPATest(t, nl.VDPA_CMD_DEV_DEL)() 129 err := VDPADelDev("__should_not_exist") 130 if !errors.Is(err, syscall.ENODEV) { 131 t.Fatal("VDPADelDev returns unexpected error for unknown device") 132 } 133 } 134 135 func TestVDPAGetDevList(t *testing.T) { 136 defer setupVDPATest(t, nl.VDPA_CMD_DEV_GET, nl.VDPA_CMD_DEV_NEW)() 137 if err := createVDPATestDev(); err != nil { 138 t.Fatalf("failed to create VDPA device: %v", err) 139 } 140 devs, err := VDPAGetDevList() 141 if err != nil { 142 t.Fatalf("VDPAGetDevList failed: %v", err) 143 } 144 testDevFound := false 145 for _, d := range devs { 146 if d.Name != vdpaTestDeviceName { 147 continue 148 } 149 testDevFound = true 150 checkVDPADev(t, d) 151 } 152 if !testDevFound { 153 t.Fatal("VDPA test device not found") 154 } 155 } 156 157 func TestVDPAGetDevByName(t *testing.T) { 158 defer setupVDPATest(t, nl.VDPA_CMD_DEV_GET, nl.VDPA_CMD_DEV_NEW)() 159 if err := createVDPATestDev(); err != nil { 160 t.Fatalf("failed to create VDPA device: %v", err) 161 } 162 dev, err := VDPAGetDevByName(vdpaTestDeviceName) 163 if err != nil { 164 t.Fatalf("VDPAGetDevByName failed: %v", err) 165 } 166 checkVDPADev(t, dev) 167 if dev.Name != vdpaTestDeviceName { 168 t.Fatalf("Invalid device received for Get call, expected: %s, actual: %s", vdpaTestDeviceName, dev.Name) 169 } 170 } 171 172 func TestVDPAGetDevByName_Unknown(t *testing.T) { 173 defer setupVDPATest(t, nl.VDPA_CMD_DEV_GET)() 174 _, err := VDPAGetDevByName("__should_not_exist") 175 if !errors.Is(err, syscall.ENODEV) { 176 t.Fatal("VDPAGetDevByName returns unexpected error for unknown device") 177 } 178 } 179 180 func TestVDPAGetDevConfigList(t *testing.T) { 181 defer setupVDPATest(t, nl.VDPA_CMD_DEV_GET, nl.VDPA_CMD_DEV_CONFIG_GET)() 182 if err := createVDPATestDev(); err != nil { 183 t.Fatalf("failed to create VDPA device: %v", err) 184 } 185 devConfs, err := VDPAGetDevConfigList() 186 if err != nil { 187 t.Fatalf("VDPAGetDevConfigList failed: %v", err) 188 } 189 testDevConfFound := false 190 for _, d := range devConfs { 191 if d.Name != vdpaTestDeviceName { 192 continue 193 } 194 testDevConfFound = true 195 checkVDPADevConf(t, d) 196 } 197 if !testDevConfFound { 198 t.Fatal("VDPA test device config not found") 199 } 200 } 201 202 func TestVDPAGetDevConfigByName(t *testing.T) { 203 defer setupVDPATest(t, nl.VDPA_CMD_DEV_GET, nl.VDPA_CMD_DEV_CONFIG_GET)() 204 if err := createVDPATestDev(); err != nil { 205 t.Fatalf("failed to create VDPA device: %v", err) 206 } 207 dev, err := VDPAGetDevConfigByName(vdpaTestDeviceName) 208 if err != nil { 209 t.Fatalf("VDPAGetDevConfigByName failed: %v", err) 210 } 211 checkVDPADevConf(t, dev) 212 if dev.Name != vdpaTestDeviceName { 213 t.Fatalf("Invalid device received for Get call, expected: %s, actual: %s", vdpaTestDeviceName, dev.Name) 214 } 215 } 216 217 func TestVDPAGetDevConfigByName_Unknowm(t *testing.T) { 218 defer setupVDPATest(t, nl.VDPA_CMD_DEV_GET, nl.VDPA_CMD_DEV_CONFIG_GET)() 219 _, err := VDPAGetDevConfigByName("__should_not_exist") 220 if !errors.Is(err, syscall.ENODEV) { 221 t.Fatal("VDPAGetDevConfigByName returns unexpected error for unknown device") 222 } 223 } 224 225 func TestSetGetBits(t *testing.T) { 226 features := SetBits(0, VIRTIO_NET_F_CSUM, VIRTIO_NET_F_MQ) 227 if !IsBitSet(features, VIRTIO_NET_F_CSUM) || !IsBitSet(features, VIRTIO_NET_F_MQ) { 228 t.Fatal("BitSet test failed") 229 } 230 if IsBitSet(features, VIRTIO_NET_F_STATUS) { 231 t.Fatal("unexpected bit is set") 232 } 233 } 234 235 func createVDPATestDev() error { 236 return VDPANewDev(vdpaTestDeviceName, "", vdpaSimMGMTDev, VDPANewDevParams{}) 237 } 238 239 func checkVDPAMGMTDev(t *testing.T, d *VDPAMGMTDev) { 240 if d == nil { 241 t.Fatal("VDPA MGMT dev is nil") 242 } 243 if d.DevName == "" { 244 t.Fatal("VDPA MGMT dev name is not set") 245 } 246 } 247 248 func checkVDPADev(t *testing.T, d *VDPADev) { 249 if d == nil { 250 t.Fatal("VDPA dev is nil") 251 } 252 if d.Name == "" { 253 t.Fatal("VDPA dev name is not set") 254 } 255 if d.ID == 0 { 256 t.Fatal("VDPA dev ID is not set") 257 } 258 } 259 260 func checkVDPADevConf(t *testing.T, d *VDPADevConfig) { 261 if d == nil { 262 t.Fatal("VDPA dev config is nil") 263 } 264 if d.Name == "" { 265 t.Fatal("VDPA dev name is not set") 266 } 267 if d.ID == 0 { 268 t.Fatal("VDPA dev ID is not set") 269 } 270 }