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  }