github.com/k8snetworkplumbingwg/sriov-network-operator@v1.2.1-0.20240408194816-2d2e5a45d453/pkg/host/internal/udev/udev_test.go (about)

     1  package udev
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"github.com/golang/mock/gomock"
     9  
    10  	. "github.com/onsi/ginkgo/v2"
    11  	. "github.com/onsi/gomega"
    12  
    13  	"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/host/types"
    14  	utilsMockPkg "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils/mock"
    15  	"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/vars"
    16  	"github.com/k8snetworkplumbingwg/sriov-network-operator/test/util/fakefilesystem"
    17  	"github.com/k8snetworkplumbingwg/sriov-network-operator/test/util/helpers"
    18  )
    19  
    20  const (
    21  	testExpectedPFUdevRule = `SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", KERNELS=="0000:d8:00.0", NAME="enp129"`
    22  	testExpectedNMUdevRule = `SUBSYSTEM=="net", ACTION=="add|change|move", ` +
    23  		`ATTRS{device}=="0x1017|0x1018", ` +
    24  		`IMPORT{program}="/etc/udev/disable-nm-sriov.sh $env{INTERFACE} 0000:d8:00.0"`
    25  	testExpectedSwitchdevUdevRule = `SUBSYSTEM=="net", ACTION=="add|move", ` +
    26  		`ATTRS{phys_switch_id}=="7cfe90ff2cc0", ` +
    27  		`ATTR{phys_port_name}=="pf0vf*", IMPORT{program}="/etc/udev/switchdev-vf-link-name.sh $attr{phys_port_name}", ` +
    28  		`NAME="enp216s0f0np0_$env{NUMBER}"`
    29  )
    30  
    31  var _ = Describe("UDEV", func() {
    32  	var (
    33  		s         types.UdevInterface
    34  		testCtrl  *gomock.Controller
    35  		utilsMock *utilsMockPkg.MockCmdInterface
    36  		testError = fmt.Errorf("test")
    37  	)
    38  
    39  	BeforeEach(func() {
    40  		testCtrl = gomock.NewController(GinkgoT())
    41  		utilsMock = utilsMockPkg.NewMockCmdInterface(testCtrl)
    42  		s = New(utilsMock)
    43  	})
    44  
    45  	AfterEach(func() {
    46  		testCtrl.Finish()
    47  	})
    48  
    49  	Context("AddDisableNMUdevRule", func() {
    50  		It("Created", func() {
    51  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{})
    52  			Expect(s.AddDisableNMUdevRule("0000:d8:00.0")).To(BeNil())
    53  			helpers.GinkgoAssertFileContentsEquals(
    54  				"/etc/udev/rules.d/10-nm-disable-0000:d8:00.0.rules",
    55  				testExpectedNMUdevRule)
    56  		})
    57  		It("Overwrite", func() {
    58  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
    59  				Dirs: []string{"/etc/udev/rules.d"},
    60  				Files: map[string][]byte{
    61  					"/etc/udev/rules.d/10-nm-disable-0000:d8:00.0.rules": []byte("something"),
    62  				},
    63  			})
    64  			Expect(s.AddDisableNMUdevRule("0000:d8:00.0")).To(BeNil())
    65  			helpers.GinkgoAssertFileContentsEquals(
    66  				"/etc/udev/rules.d/10-nm-disable-0000:d8:00.0.rules",
    67  				testExpectedNMUdevRule)
    68  		})
    69  	})
    70  	Context("RemoveDisableNMUdevRule", func() {
    71  		It("Exist", func() {
    72  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
    73  				Dirs: []string{"/etc/udev/rules.d"},
    74  				Files: map[string][]byte{
    75  					"/etc/udev/rules.d/10-nm-disable-0000:d8:00.0.rules": []byte(testExpectedNMUdevRule),
    76  				},
    77  			})
    78  			Expect(s.RemoveDisableNMUdevRule("0000:d8:00.0")).To(BeNil())
    79  			_, err := os.Stat(filepath.Join(vars.FilesystemRoot,
    80  				"/etc/udev/rules.d/10-nm-disable-0000:d8:00.0.rules"))
    81  			Expect(os.IsNotExist(err)).To(BeTrue())
    82  		})
    83  		It("Not found", func() {
    84  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
    85  				Dirs: []string{"/etc/udev/rules.d"},
    86  			})
    87  			Expect(s.RemoveDisableNMUdevRule("0000:d8:00.0")).To(BeNil())
    88  		})
    89  	})
    90  	Context("AddPersistPFNameUdevRule", func() {
    91  		It("Created", func() {
    92  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{})
    93  			Expect(s.AddPersistPFNameUdevRule("0000:d8:00.0", "enp129")).To(BeNil())
    94  			helpers.GinkgoAssertFileContentsEquals(
    95  				"/etc/udev/rules.d/10-pf-name-0000:d8:00.0.rules",
    96  				testExpectedPFUdevRule)
    97  
    98  		})
    99  		It("Overwrite", func() {
   100  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   101  				Dirs: []string{"/etc/udev/rules.d"},
   102  				Files: map[string][]byte{
   103  					"etc/udev/rules.d/10-pf-name-0000:d8:00.0.rules": []byte("something"),
   104  				},
   105  			})
   106  			Expect(s.AddPersistPFNameUdevRule("0000:d8:00.0", "enp129")).To(BeNil())
   107  			helpers.GinkgoAssertFileContentsEquals(
   108  				"/etc/udev/rules.d/10-pf-name-0000:d8:00.0.rules",
   109  				testExpectedPFUdevRule)
   110  		})
   111  	})
   112  	Context("RemovePersistPFNameUdevRule", func() {
   113  		It("Exist", func() {
   114  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   115  				Dirs: []string{"/etc/udev/rules.d"},
   116  				Files: map[string][]byte{
   117  					"/etc/udev/rules.d/10-pf-name-0000:d8:00.0.rules": []byte(testExpectedPFUdevRule),
   118  				},
   119  			})
   120  			Expect(s.RemovePersistPFNameUdevRule("0000:d8:00.0")).To(BeNil())
   121  			_, err := os.Stat(filepath.Join(vars.FilesystemRoot,
   122  				"/etc/udev/rules.d/10-pf-name-0000:d8:00.0.rules"))
   123  			Expect(os.IsNotExist(err)).To(BeTrue())
   124  		})
   125  		It("Not found", func() {
   126  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   127  				Dirs: []string{"/etc/udev/rules.d"},
   128  			})
   129  			Expect(s.RemovePersistPFNameUdevRule("0000:d8:00.0")).To(BeNil())
   130  		})
   131  	})
   132  	Context("AddVfRepresentorUdevRule", func() {
   133  		It("Created", func() {
   134  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{})
   135  			Expect(s.AddVfRepresentorUdevRule("0000:d8:00.0",
   136  				"enp216s0f0np0", "7cfe90ff2cc0", "p0")).To(BeNil())
   137  			helpers.GinkgoAssertFileContentsEquals(
   138  				"/etc/udev/rules.d/20-switchdev-0000:d8:00.0.rules",
   139  				testExpectedSwitchdevUdevRule)
   140  		})
   141  		It("Overwrite", func() {
   142  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   143  				Dirs: []string{"/etc/udev/rules.d"},
   144  				Files: map[string][]byte{
   145  					"/etc/udev/rules.d/20-switchdev-0000:d8:00.0.rules": []byte("something"),
   146  				},
   147  			})
   148  			Expect(s.AddVfRepresentorUdevRule("0000:d8:00.0",
   149  				"enp216s0f0np0", "7cfe90ff2cc0", "p0")).To(BeNil())
   150  			helpers.GinkgoAssertFileContentsEquals(
   151  				"/etc/udev/rules.d/20-switchdev-0000:d8:00.0.rules",
   152  				testExpectedSwitchdevUdevRule)
   153  		})
   154  	})
   155  	Context("RemoveVfRepresentorUdevRule", func() {
   156  		It("Exist", func() {
   157  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   158  				Dirs: []string{"/etc/udev/rules.d"},
   159  				Files: map[string][]byte{
   160  					"/etc/udev/rules.d/20-switchdev-0000:d8:00.0.rules": []byte(testExpectedSwitchdevUdevRule),
   161  				},
   162  			})
   163  			Expect(s.RemoveVfRepresentorUdevRule("0000:d8:00.0")).To(BeNil())
   164  			_, err := os.Stat(filepath.Join(vars.FilesystemRoot,
   165  				"/etc/udev/rules.d/20-switchdev-0000:d8:00.0.rules"))
   166  			Expect(os.IsNotExist(err)).To(BeTrue())
   167  		})
   168  		It("Not found", func() {
   169  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   170  				Dirs: []string{"/etc/udev/rules.d"},
   171  			})
   172  			Expect(s.RemoveVfRepresentorUdevRule("0000:d8:00.0")).To(BeNil())
   173  		})
   174  	})
   175  	Context("PrepareVFRepUdevRule", func() {
   176  		It("Already Exist", func() {
   177  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   178  				Dirs: []string{"/host/etc/udev", "/bindata/scripts"},
   179  				Files: map[string][]byte{
   180  					"/host/etc/udev/switchdev-vf-link-name.sh":   []byte("before"),
   181  					"/bindata/scripts/switchdev-vf-link-name.sh": []byte("script"),
   182  				},
   183  			})
   184  			Expect(s.PrepareVFRepUdevRule()).To(BeNil())
   185  			helpers.GinkgoAssertFileContentsEquals("/host/etc/udev/switchdev-vf-link-name.sh", "script")
   186  		})
   187  		It("Fail - no folder", func() {
   188  			helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
   189  				Dirs: []string{"/bindata/scripts"},
   190  				Files: map[string][]byte{
   191  					"/bindata/scripts/switchdev-vf-link-name.sh": []byte("script"),
   192  				},
   193  			})
   194  			Expect(s.PrepareVFRepUdevRule()).NotTo(BeNil())
   195  		})
   196  	})
   197  	Context("LoadUdevRules", func() {
   198  		It("Succeed", func() {
   199  			utilsMock.EXPECT().RunCommand("udevadm", "control", "--reload-rules").Return("", "", nil)
   200  			utilsMock.EXPECT().RunCommand("udevadm", "trigger", "--action", "add", "--attr-match", "subsystem=net").Return("", "", nil)
   201  			Expect(s.LoadUdevRules()).NotTo(HaveOccurred())
   202  		})
   203  		It("Failed to reload rules", func() {
   204  			utilsMock.EXPECT().RunCommand("udevadm", "control", "--reload-rules").Return("", "", testError)
   205  			Expect(s.LoadUdevRules()).To(MatchError(testError))
   206  		})
   207  		It("Failed to trigger rules", func() {
   208  			utilsMock.EXPECT().RunCommand("udevadm", "control", "--reload-rules").Return("", "", nil)
   209  			utilsMock.EXPECT().RunCommand("udevadm", "trigger", "--action", "add", "--attr-match", "subsystem=net").Return("", "", testError)
   210  			Expect(s.LoadUdevRules()).To(MatchError(testError))
   211  		})
   212  	})
   213  })