Skip to content

Commit

Permalink
Add unit test to check the correct behavior of the CNI plugin
Browse files Browse the repository at this point in the history
Signed-off-by: Miguel Duarte Barroso <[email protected]>
  • Loading branch information
maiqueb committed Feb 14, 2020
1 parent f18d034 commit 732b635
Show file tree
Hide file tree
Showing 2 changed files with 208 additions and 0 deletions.
13 changes: 13 additions & 0 deletions pkg/cni/cni_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package cni_test

import (
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

func TestCni(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Cni Suite")
}
195 changes: 195 additions & 0 deletions pkg/cni/plugin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
package cni_test

import (
"fmt"

"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
"github.com/kubevirt/macvtap-cni/pkg/cni"
"github.com/kubevirt/macvtap-cni/pkg/util"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/vishvananda/netlink"
)

const LOWER_DEVICE = "eth0"

var _ = Describe("Macvtap device plugin", func() {
var originalNS ns.NetNS
var targetNs ns.NetNS
var lowerDevice netlink.Link
var macvtapInterface netlink.Link
var deviceID string
var stdInArgs string

BeforeEach(func() {
var err error
originalNS, err = testutils.NewNS()
Expect(err).NotTo(HaveOccurred())
targetNs, err = testutils.NewNS()
Expect(err).NotTo(HaveOccurred())

err = originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()

// create lower device
err = netlink.LinkAdd(&netlink.Dummy{
LinkAttrs: netlink.LinkAttrs{
Name: LOWER_DEVICE,
},
})
Expect(err).NotTo(HaveOccurred())
lowerDevice, err = netlink.LinkByName(LOWER_DEVICE)
Expect(err).NotTo(HaveOccurred())

// create macvtap on top of lower device
macvtapIfaceName := "macvtap0"
_, err = util.CreateMacvtap(macvtapIfaceName, LOWER_DEVICE, "bridge")
Expect(err).NotTo(HaveOccurred())
macvtapInterface, err = netlink.LinkByName(macvtapIfaceName)
Expect(err).NotTo(HaveOccurred())
deviceID = macvtapIfaceName

stdInArgs = fmt.Sprintf(`{
"cniVersion": "0.3.1",
"name": "mynet",
"type": "macvtap",
"deviceID": "%s"
}`, macvtapIfaceName)
return nil
})

Expect(err).NotTo(HaveOccurred())
})

AfterEach(func() {
// cleanup the original namespace
originalNS.Do(func(ns.NetNS) error {
return netlink.LinkDel(lowerDevice)
})
Expect(originalNS.Close()).To(Succeed())
Expect(testutils.UnmountNS(originalNS)).To(Succeed())

// cleanup the target namespace
targetNs.Do(func(ns.NetNS) error {
return netlink.LinkDel(macvtapInterface)
})
Expect(targetNs.Close()).To(Succeed())
Expect(testutils.UnmountNS(targetNs)).To(Succeed())
})

It("imports a macvtap interface into the target netns", func() {
args := &skel.CmdArgs{
ContainerID: "dummy",
Netns: targetNs.Path(),
IfName: deviceID,
StdinData: []byte(stdInArgs),
}

// import existing interface to target namespace
originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()

_, _, err := testutils.CmdAdd(args.Netns, args.ContainerID, args.IfName, args.StdinData, func() error { return cni.CmdAdd(args) })
Expect(err).NotTo(HaveOccurred())
return nil
})

// confirm macvtap is available on target namespace
targetNs.Do(func(ns.NetNS) error {
defer GinkgoRecover()
_, err := netlink.LinkByName(deviceID)
Expect(err).NotTo(HaveOccurred())
return nil
})
})

It("removes a macvtap interface", func() {
args := &skel.CmdArgs{
ContainerID: "dummy",
Netns: targetNs.Path(),
IfName: deviceID,
StdinData: []byte(stdInArgs),
}

// import existing interface to target namespace
originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()

_, _, err := testutils.CmdAdd(args.Netns, args.ContainerID, args.IfName, args.StdinData, func() error { return cni.CmdAdd(args) })
Expect(err).NotTo(HaveOccurred())

err = testutils.CmdDel(args.Netns, args.ContainerID, args.IfName, func() error { return cni.CmdDel(args) })
Expect(err).NotTo(HaveOccurred())
_, err = netlink.LinkByName(deviceID)
Expect(err).To(HaveOccurred())
return nil
})
})

It("imports a macvtap interface into the target netns, and configures the MAC address", func() {
const macAddress = "0a:59:00:dc:6a:e0"

args := &skel.CmdArgs{
ContainerID: "dummy",
Netns: targetNs.Path(),
IfName: deviceID,
StdinData: []byte(stdInArgs),
Args: fmt.Sprintf("MAC=%s", macAddress),
}

// import existing interface to target namespace
originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()

_, _, err := testutils.CmdAdd(args.Netns, args.ContainerID, args.IfName, args.StdinData, func() error { return cni.CmdAdd(args) })
Expect(err).NotTo(HaveOccurred())
return nil
})

// confirm macvtap is available on target namespace, and the correct configurations were applied
targetNs.Do(func(ns.NetNS) error {
defer GinkgoRecover()
link, err := netlink.LinkByName(deviceID)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr.String()).To(Equal(macAddress))
return nil
})
})

It("imports a macvtap interface into the target netns, and configures the MTU", func() {
const mtu = 1000
updatedMtuArgs := fmt.Sprintf(`{
"cniVersion": "0.3.1",
"name": "mynet",
"type": "macvtap",
"deviceID": "%s",
"mtu": %d
}`, deviceID, mtu)
args := &skel.CmdArgs{
ContainerID: "dummy",
Netns: targetNs.Path(),
IfName: deviceID,
StdinData: []byte(updatedMtuArgs),
}

// import existing interface to target namespace
originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()

_, _, err := testutils.CmdAdd(args.Netns, args.ContainerID, args.IfName, args.StdinData, func() error { return cni.CmdAdd(args) })
Expect(err).NotTo(HaveOccurred())
return nil
})

// confirm macvtap is available on target namespace, and the correct configurations were applied
targetNs.Do(func(ns.NetNS) error {
defer GinkgoRecover()
link, err := netlink.LinkByName(deviceID)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().MTU).To(Equal(mtu))
return nil
})
})
})

0 comments on commit 732b635

Please sign in to comment.