github.com/k8snetworkplumbingwg/sriov-network-operator@v1.2.1-0.20240408194816-2d2e5a45d453/cmd/sriov-network-config-daemon/service_test.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/golang/mock/gomock"
     7  	"github.com/spf13/cobra"
     8  	"gopkg.in/yaml.v3"
     9  
    10  	. "github.com/onsi/ginkgo/v2"
    11  	. "github.com/onsi/gomega"
    12  
    13  	sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1"
    14  	"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/helper"
    15  	helperMock "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/helper/mock"
    16  	"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/platforms"
    17  	platformsMock "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/platforms/mock"
    18  	plugin "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/plugins"
    19  	"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/plugins/generic"
    20  	pluginsMock "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/plugins/mock"
    21  	"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/systemd"
    22  	"github.com/k8snetworkplumbingwg/sriov-network-operator/test/util/fakefilesystem"
    23  	testHelpers "github.com/k8snetworkplumbingwg/sriov-network-operator/test/util/helpers"
    24  )
    25  
    26  func restoreOrigFuncs() {
    27  	origNewGenericPluginFunc := newGenericPluginFunc
    28  	origNewVirtualPluginFunc := newVirtualPluginFunc
    29  	origNewHostHelpersFunc := newHostHelpersFunc
    30  	origNewPlatformHelperFunc := newPlatformHelperFunc
    31  	DeferCleanup(func() {
    32  		newGenericPluginFunc = origNewGenericPluginFunc
    33  		newVirtualPluginFunc = origNewVirtualPluginFunc
    34  		newHostHelpersFunc = origNewHostHelpersFunc
    35  		newPlatformHelperFunc = origNewPlatformHelperFunc
    36  	})
    37  }
    38  
    39  func getTestSriovInterfaceConfig(platform int) []byte {
    40  	return []byte(fmt.Sprintf(`spec:
    41      dpconfigversion: ""
    42      interfaces:
    43          - pciaddress: 0000:d8:00.0
    44            numvfs: 4
    45            mtu: 1500
    46            name: enp216s0f0np0
    47            linktype: ""
    48            eswitchmode: legacy
    49            vfgroups:
    50              - resourcename: legacy
    51                devicetype: ""
    52                vfrange: 0-3
    53                policyname: test-legacy
    54                mtu: 1500
    55                isrdma: false
    56                vdpatype: ""
    57            externallymanaged: false
    58  unsupportedNics: false
    59  platformType: %d
    60  `, platform))
    61  }
    62  
    63  var testSriovSupportedNicIDs = `8086 1583 154c
    64  8086 0d58 154c
    65  8086 10c9 10ca
    66  `
    67  
    68  func getTestResultFileContent(syncStatus, errMsg string) []byte {
    69  	data, err := yaml.Marshal(systemd.SriovResult{SyncStatus: syncStatus, LastSyncError: errMsg})
    70  	ExpectWithOffset(1, err).NotTo(HaveOccurred())
    71  	return data
    72  }
    73  
    74  // checks if NodeState contains deviceName in spec and status fields
    75  func newNodeStateContainsDeviceMatcher(deviceName string) gomock.Matcher {
    76  	return &nodeStateContainsDeviceMatcher{deviceName: deviceName}
    77  }
    78  
    79  type nodeStateContainsDeviceMatcher struct {
    80  	deviceName string
    81  }
    82  
    83  func (ns *nodeStateContainsDeviceMatcher) Matches(x interface{}) bool {
    84  	s, ok := x.(*sriovnetworkv1.SriovNetworkNodeState)
    85  	if !ok {
    86  		return false
    87  	}
    88  	specFound := false
    89  	for _, i := range s.Spec.Interfaces {
    90  		if i.Name == ns.deviceName {
    91  			specFound = true
    92  			break
    93  		}
    94  	}
    95  	if !specFound {
    96  		return false
    97  	}
    98  	statusFound := false
    99  	for _, i := range s.Status.Interfaces {
   100  		if i.Name == ns.deviceName {
   101  			statusFound = true
   102  			break
   103  		}
   104  	}
   105  	return statusFound
   106  }
   107  
   108  func (ns *nodeStateContainsDeviceMatcher) String() string {
   109  	return "node state contains match: " + ns.deviceName
   110  }
   111  
   112  var _ = Describe("Service", func() {
   113  	var (
   114  		hostHelpers    *helperMock.MockHostHelpersInterface
   115  		platformHelper *platformsMock.MockInterface
   116  		genericPlugin  *pluginsMock.MockVendorPlugin
   117  		virtualPlugin  *pluginsMock.MockVendorPlugin
   118  
   119  		testCtrl  *gomock.Controller
   120  		testError = fmt.Errorf("test")
   121  	)
   122  
   123  	BeforeEach(func() {
   124  		restoreOrigFuncs()
   125  
   126  		testCtrl = gomock.NewController(GinkgoT())
   127  		hostHelpers = helperMock.NewMockHostHelpersInterface(testCtrl)
   128  		platformHelper = platformsMock.NewMockInterface(testCtrl)
   129  		genericPlugin = pluginsMock.NewMockVendorPlugin(testCtrl)
   130  		virtualPlugin = pluginsMock.NewMockVendorPlugin(testCtrl)
   131  
   132  		newGenericPluginFunc = func(_ helper.HostHelpersInterface, _ ...generic.Option) (plugin.VendorPlugin, error) {
   133  			return genericPlugin, nil
   134  		}
   135  		newVirtualPluginFunc = func(_ helper.HostHelpersInterface) (plugin.VendorPlugin, error) {
   136  			return virtualPlugin, nil
   137  		}
   138  		newHostHelpersFunc = func() (helper.HostHelpersInterface, error) {
   139  			return hostHelpers, nil
   140  		}
   141  		newPlatformHelperFunc = func() (platforms.Interface, error) {
   142  			return platformHelper, nil
   143  		}
   144  
   145  	})
   146  	AfterEach(func() {
   147  		phaseArg = ""
   148  		testCtrl.Finish()
   149  	})
   150  
   151  	It("Pre phase - baremetal cluster", func() {
   152  		phaseArg = PhasePre
   153  		testHelpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   154  			Dirs: []string{"/etc/sriov-operator"},
   155  			Files: map[string][]byte{
   156  				"/etc/sriov-operator/sriov-supported-nics-ids.yaml": []byte(testSriovSupportedNicIDs),
   157  				"/etc/sriov-operator/sriov-interface-config.yaml":   getTestSriovInterfaceConfig(0),
   158  				"/etc/sriov-operator/sriov-interface-result.yaml":   []byte("something"),
   159  			},
   160  		})
   161  		hostHelpers.EXPECT().TryEnableRdma().Return(true, nil)
   162  		hostHelpers.EXPECT().TryEnableTun().Return()
   163  		hostHelpers.EXPECT().TryEnableVhostNet().Return()
   164  		hostHelpers.EXPECT().DiscoverSriovDevices(hostHelpers).Return([]sriovnetworkv1.InterfaceExt{{
   165  			Name: "enp216s0f0np0",
   166  		}}, nil)
   167  		genericPlugin.EXPECT().OnNodeStateChange(newNodeStateContainsDeviceMatcher("enp216s0f0np0")).Return(true, false, nil)
   168  		genericPlugin.EXPECT().Apply().Return(nil)
   169  
   170  		Expect(runServiceCmd(&cobra.Command{}, []string{})).NotTo(HaveOccurred())
   171  
   172  		testHelpers.GinkgoAssertFileContentsEquals("/etc/sriov-operator/sriov-interface-result.yaml",
   173  			string(getTestResultFileContent("InProgress", "")))
   174  	})
   175  
   176  	It("Pre phase - virtual cluster", func() {
   177  		phaseArg = PhasePre
   178  		testHelpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   179  			Dirs: []string{"/etc/sriov-operator"},
   180  			Files: map[string][]byte{
   181  				"/etc/sriov-operator/sriov-supported-nics-ids.yaml": []byte(testSriovSupportedNicIDs),
   182  				"/etc/sriov-operator/sriov-interface-config.yaml":   getTestSriovInterfaceConfig(1),
   183  				"/etc/sriov-operator/sriov-interface-result.yaml":   []byte("something"),
   184  			},
   185  		})
   186  		hostHelpers.EXPECT().TryEnableRdma().Return(true, nil)
   187  		hostHelpers.EXPECT().TryEnableTun().Return()
   188  		hostHelpers.EXPECT().TryEnableVhostNet().Return()
   189  
   190  		platformHelper.EXPECT().CreateOpenstackDevicesInfo().Return(nil)
   191  		platformHelper.EXPECT().DiscoverSriovDevicesVirtual().Return([]sriovnetworkv1.InterfaceExt{{
   192  			Name: "enp216s0f0np0",
   193  		}}, nil)
   194  
   195  		virtualPlugin.EXPECT().OnNodeStateChange(newNodeStateContainsDeviceMatcher("enp216s0f0np0")).Return(true, false, nil)
   196  		virtualPlugin.EXPECT().Apply().Return(nil)
   197  
   198  		Expect(runServiceCmd(&cobra.Command{}, []string{})).NotTo(HaveOccurred())
   199  
   200  		testHelpers.GinkgoAssertFileContentsEquals("/etc/sriov-operator/sriov-interface-result.yaml",
   201  			string(getTestResultFileContent("InProgress", "")))
   202  	})
   203  
   204  	It("Pre phase - apply failed", func() {
   205  		phaseArg = PhasePre
   206  		testHelpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   207  			Dirs: []string{"/etc/sriov-operator"},
   208  			Files: map[string][]byte{
   209  				"/etc/sriov-operator/sriov-supported-nics-ids.yaml": []byte(testSriovSupportedNicIDs),
   210  				"/etc/sriov-operator/sriov-interface-config.yaml":   getTestSriovInterfaceConfig(0),
   211  				"/etc/sriov-operator/sriov-interface-result.yaml":   []byte("something"),
   212  			},
   213  		})
   214  		hostHelpers.EXPECT().TryEnableRdma().Return(true, nil)
   215  		hostHelpers.EXPECT().TryEnableTun().Return()
   216  		hostHelpers.EXPECT().TryEnableVhostNet().Return()
   217  		hostHelpers.EXPECT().DiscoverSriovDevices(hostHelpers).Return([]sriovnetworkv1.InterfaceExt{{
   218  			Name: "enp216s0f0np0",
   219  		}}, nil)
   220  		genericPlugin.EXPECT().OnNodeStateChange(newNodeStateContainsDeviceMatcher("enp216s0f0np0")).Return(true, false, nil)
   221  		genericPlugin.EXPECT().Apply().Return(testError)
   222  
   223  		Expect(runServiceCmd(&cobra.Command{}, []string{})).To(MatchError(ContainSubstring("test")))
   224  
   225  		testHelpers.GinkgoAssertFileContentsEquals("/etc/sriov-operator/sriov-interface-result.yaml",
   226  			string(getTestResultFileContent("Failed", "pre: failed to apply configuration: test")))
   227  	})
   228  
   229  	It("Post phase - baremetal cluster", func() {
   230  		phaseArg = PhasePost
   231  		testHelpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   232  			Dirs: []string{"/etc/sriov-operator"},
   233  			Files: map[string][]byte{
   234  				"/etc/sriov-operator/sriov-supported-nics-ids.yaml": []byte(testSriovSupportedNicIDs),
   235  				"/etc/sriov-operator/sriov-interface-config.yaml":   getTestSriovInterfaceConfig(0),
   236  				"/etc/sriov-operator/sriov-interface-result.yaml":   getTestResultFileContent("InProgress", ""),
   237  			},
   238  		})
   239  		hostHelpers.EXPECT().DiscoverSriovDevices(hostHelpers).Return([]sriovnetworkv1.InterfaceExt{{
   240  			Name: "enp216s0f0np0",
   241  		}}, nil)
   242  		genericPlugin.EXPECT().OnNodeStateChange(newNodeStateContainsDeviceMatcher("enp216s0f0np0")).Return(true, false, nil)
   243  		genericPlugin.EXPECT().Apply().Return(nil)
   244  		Expect(runServiceCmd(&cobra.Command{}, []string{})).NotTo(HaveOccurred())
   245  		testHelpers.GinkgoAssertFileContentsEquals("/etc/sriov-operator/sriov-interface-result.yaml",
   246  			string(getTestResultFileContent("Succeeded", "")))
   247  	})
   248  
   249  	It("Post phase - virtual cluster", func() {
   250  		phaseArg = PhasePost
   251  		testHelpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   252  			Dirs: []string{"/etc/sriov-operator"},
   253  			Files: map[string][]byte{
   254  				"/etc/sriov-operator/sriov-supported-nics-ids.yaml": []byte(testSriovSupportedNicIDs),
   255  				"/etc/sriov-operator/sriov-interface-config.yaml":   getTestSriovInterfaceConfig(1),
   256  				"/etc/sriov-operator/sriov-interface-result.yaml":   getTestResultFileContent("InProgress", ""),
   257  			},
   258  		})
   259  		Expect(runServiceCmd(&cobra.Command{}, []string{})).NotTo(HaveOccurred())
   260  		testHelpers.GinkgoAssertFileContentsEquals("/etc/sriov-operator/sriov-interface-result.yaml",
   261  			string(getTestResultFileContent("Succeeded", "")))
   262  	})
   263  
   264  	It("Post phase - wrong result of the pre phase", func() {
   265  		phaseArg = PhasePost
   266  		testHelpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   267  			Dirs: []string{"/etc/sriov-operator"},
   268  			Files: map[string][]byte{
   269  				"/etc/sriov-operator/sriov-supported-nics-ids.yaml": []byte(testSriovSupportedNicIDs),
   270  				"/etc/sriov-operator/sriov-interface-config.yaml":   getTestSriovInterfaceConfig(1),
   271  				"/etc/sriov-operator/sriov-interface-result.yaml":   getTestResultFileContent("Failed", "pretest"),
   272  			},
   273  		})
   274  		Expect(runServiceCmd(&cobra.Command{}, []string{})).To(HaveOccurred())
   275  		testHelpers.GinkgoAssertFileContentsEquals("/etc/sriov-operator/sriov-interface-result.yaml",
   276  			string(getTestResultFileContent("Failed", "post: unexpected result of the pre phase: Failed, syncError: pretest")))
   277  	})
   278  })