bandwidth: increase test coverage to 1.0.0 and older spec versions
Signed-off-by: Dan Williams <dcbw@redhat.com>
This commit is contained in:
parent
02cdaafe93
commit
da52be35bc
@ -18,7 +18,9 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/vishvananda/netlink"
|
||||
@ -26,8 +28,7 @@ import (
|
||||
"github.com/containernetworking/cni/pkg/invoke"
|
||||
"github.com/containernetworking/cni/pkg/skel"
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/cni/pkg/types/040"
|
||||
current "github.com/containernetworking/cni/pkg/types/100"
|
||||
"github.com/containernetworking/cni/pkg/types/100"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
|
||||
@ -45,7 +46,9 @@ func buildOneConfig(name, cniVersion string, orig *PluginConf, prevResult types.
|
||||
}
|
||||
// Add previous plugin result
|
||||
if prevResult != nil {
|
||||
inject["prevResult"] = prevResult
|
||||
r, err := prevResult.GetAsVersion(cniVersion)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
inject["prevResult"] = r
|
||||
}
|
||||
|
||||
// Ensure every config uses the same name and version
|
||||
@ -108,18 +111,27 @@ var _ = Describe("bandwidth test", func() {
|
||||
hostIfaceMTU = 1024
|
||||
ifbDeviceName = "bwpa8eda89404b7"
|
||||
|
||||
createVeth(hostNs.Path(), hostIfname, containerNs.Path(), containerIfname, hostIP, containerIP, hostIfaceMTU)
|
||||
createVeth(hostNs, hostIfname, containerNs, containerIfname, hostIP, containerIP, hostIfaceMTU)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
containerNs.Close()
|
||||
hostNs.Close()
|
||||
Expect(containerNs.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerNs)).To(Succeed())
|
||||
Expect(hostNs.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(hostNs)).To(Succeed())
|
||||
})
|
||||
|
||||
// Bandwidth requires host-side interface info, and thus only
|
||||
// supports 0.3.0 and later CNI versions
|
||||
for _, ver := range []string{"0.3.0", "0.3.1", "0.4.0", "1.0.0"} {
|
||||
// Redefine ver inside for scope so real value is picked up by each dynamically defined It()
|
||||
// See Gingkgo's "Patterns for dynamically generating tests" documentation.
|
||||
ver := ver
|
||||
|
||||
Describe("cmdADD", func() {
|
||||
It("Works with a Veth pair using 0.3.0 config", func() {
|
||||
conf := `{
|
||||
"cniVersion": "0.3.0",
|
||||
It(fmt.Sprintf("[%s] works with a Veth pair", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 8,
|
||||
@ -147,9 +159,8 @@ var _ = Describe("bandwidth test", func() {
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
conf = fmt.Sprintf(conf, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
@ -161,7 +172,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
defer GinkgoRecover()
|
||||
r, out, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
|
||||
Expect(err).NotTo(HaveOccurred(), string(out))
|
||||
result, err := types040.GetResult(r)
|
||||
result, err := types100.GetResult(r)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(result.Interfaces).To(HaveLen(3))
|
||||
@ -214,9 +225,9 @@ var _ = Describe("bandwidth test", func() {
|
||||
|
||||
})
|
||||
|
||||
It("Does not apply ingress when disabled", func() {
|
||||
conf := `{
|
||||
"cniVersion": "0.3.0",
|
||||
It(fmt.Sprintf("[%s] does not apply ingress when disabled", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 0,
|
||||
@ -244,9 +255,8 @@ var _ = Describe("bandwidth test", func() {
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
conf = fmt.Sprintf(conf, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
@ -283,9 +293,9 @@ var _ = Describe("bandwidth test", func() {
|
||||
|
||||
})
|
||||
|
||||
It("Does not apply egress when disabled", func() {
|
||||
conf := `{
|
||||
"cniVersion": "0.3.0",
|
||||
It(fmt.Sprintf("[%s] does not apply egress when disabled", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"egressRate": 0,
|
||||
@ -313,9 +323,8 @@ var _ = Describe("bandwidth test", func() {
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
conf = fmt.Sprintf(conf, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
@ -354,9 +363,9 @@ var _ = Describe("bandwidth test", func() {
|
||||
|
||||
})
|
||||
|
||||
It("fails an invalid ingress config", func() {
|
||||
conf := `{
|
||||
"cniVersion": "0.3.0",
|
||||
It(fmt.Sprintf("[%s] fails an invalid ingress config", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 0,
|
||||
@ -384,9 +393,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`
|
||||
|
||||
conf = fmt.Sprintf(conf, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
@ -404,9 +411,9 @@ var _ = Describe("bandwidth test", func() {
|
||||
})).To(Succeed())
|
||||
})
|
||||
|
||||
It("Works with a Veth pair using runtime config", func() {
|
||||
conf := `{
|
||||
"cniVersion": "0.3.0",
|
||||
It(fmt.Sprintf("[%s] works with a Veth pair using runtime config", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"runtimeConfig": {
|
||||
@ -438,9 +445,8 @@ var _ = Describe("bandwidth test", func() {
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
conf = fmt.Sprintf(conf, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
@ -452,7 +458,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
defer GinkgoRecover()
|
||||
r, out, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
|
||||
Expect(err).NotTo(HaveOccurred(), string(out))
|
||||
result, err := types040.GetResult(r)
|
||||
result, err := types100.GetResult(r)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(result.Interfaces).To(HaveLen(3))
|
||||
@ -505,9 +511,9 @@ var _ = Describe("bandwidth test", func() {
|
||||
|
||||
})
|
||||
|
||||
It("Should apply static config when both static config and runtime config exist", func() {
|
||||
conf := `{
|
||||
"cniVersion": "0.3.0",
|
||||
It(fmt.Sprintf("[%s] should apply static config when both static config and runtime config exist", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 0,
|
||||
@ -543,9 +549,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`
|
||||
|
||||
conf = fmt.Sprintf(conf, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
@ -565,9 +569,9 @@ var _ = Describe("bandwidth test", func() {
|
||||
})
|
||||
|
||||
Describe("cmdDEL", func() {
|
||||
It("Works with a Veth pair using 0.3.0 config", func() {
|
||||
conf := `{
|
||||
"cniVersion": "0.3.0",
|
||||
It(fmt.Sprintf("[%s] works with a Veth pair using 0.3.0 config", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 8,
|
||||
@ -595,9 +599,8 @@ var _ = Describe("bandwidth test", func() {
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
conf = fmt.Sprintf(conf, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
@ -622,25 +625,14 @@ var _ = Describe("bandwidth test", func() {
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Validating input", func() {
|
||||
It("Should allow only 4GB burst rate", func() {
|
||||
err := validateRateAndBurst(5000, 4*1024*1024*1024*8-16) // 2 bytes less than the max should pass
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
err = validateRateAndBurst(5000, 4*1024*1024*1024*8) // we're 1 bit above MaxUint32
|
||||
Expect(err).To(HaveOccurred())
|
||||
err = validateRateAndBurst(0, 1)
|
||||
Expect(err).To(HaveOccurred())
|
||||
err = validateRateAndBurst(1, 0)
|
||||
Expect(err).To(HaveOccurred())
|
||||
err = validateRateAndBurst(0, 0)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("Getting the host interface which plugin should work on from veth peer of container interface", func() {
|
||||
It("Should work with multiple host veth interfaces", func() {
|
||||
conf := `{
|
||||
"cniVersion": "0.4.0",
|
||||
It(fmt.Sprintf("[%s] should work with multiple host veth interfaces", ver), func() {
|
||||
// create veth peer in host ns
|
||||
vethName, peerName := "host-veth-peer1", "host-veth-peer2"
|
||||
createVethInOneNs(hostNs, vethName, peerName)
|
||||
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 8,
|
||||
@ -676,13 +668,8 @@ var _ = Describe("bandwidth test", func() {
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`
|
||||
}`, ver, vethName, peerName, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
// create veth peer in host ns
|
||||
vethName, peerName := "host-veth-peer1", "host-veth-peer2"
|
||||
createVethInOneNs(hostNs.Path(), vethName, peerName)
|
||||
|
||||
conf = fmt.Sprintf(conf, vethName, peerName, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
@ -694,7 +681,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
defer GinkgoRecover()
|
||||
r, out, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
|
||||
Expect(err).NotTo(HaveOccurred(), string(out))
|
||||
result, err := types040.GetResult(r)
|
||||
result, err := types100.GetResult(r)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(result.Interfaces).To(HaveLen(5))
|
||||
@ -747,9 +734,13 @@ var _ = Describe("bandwidth test", func() {
|
||||
|
||||
})
|
||||
|
||||
It("Should fail when container interface has no veth peer", func() {
|
||||
conf := `{
|
||||
"cniVersion": "0.4.0",
|
||||
It(fmt.Sprintf("[%s] should fail when container interface has no veth peer", ver), func() {
|
||||
// create a macvlan device to be container interface
|
||||
macvlanContainerIfname := "container-macv"
|
||||
createMacvlan(containerNs, containerIfname, macvlanContainerIfname)
|
||||
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 8,
|
||||
@ -777,13 +768,8 @@ var _ = Describe("bandwidth test", func() {
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`
|
||||
}`, ver, hostIfname, macvlanContainerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
// create a macvlan device to be container interface
|
||||
macvlanContainerIfname := "container-macv"
|
||||
createMacvlan(containerNs.Path(), containerIfname, macvlanContainerIfname)
|
||||
|
||||
conf = fmt.Sprintf(conf, hostIfname, macvlanContainerIfname, containerNs.Path(), containerIP.String())
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
@ -801,9 +787,9 @@ var _ = Describe("bandwidth test", func() {
|
||||
})).To(Succeed())
|
||||
})
|
||||
|
||||
It("Should fail when preResult has no interfaces", func() {
|
||||
conf := `{
|
||||
"cniVersion": "0.4.0",
|
||||
It(fmt.Sprintf("[%s] should fail when preResult has no interfaces", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 8,
|
||||
@ -815,7 +801,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
"ips": [],
|
||||
"routes": []
|
||||
}
|
||||
}`
|
||||
}`, ver)
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
@ -834,9 +820,12 @@ var _ = Describe("bandwidth test", func() {
|
||||
})).To(Succeed())
|
||||
})
|
||||
|
||||
It("Should fail when veth peer of container interface does not match any of host interfaces in preResult", func() {
|
||||
conf := `{
|
||||
"cniVersion": "0.4.0",
|
||||
It(fmt.Sprintf("[%s] should fail when veth peer of container interface does not match any of host interfaces in preResult", ver), func() {
|
||||
// fake a non-exist host interface name
|
||||
fakeHostIfname := fmt.Sprintf("%s-fake", hostIfname)
|
||||
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 8,
|
||||
@ -864,12 +853,8 @@ var _ = Describe("bandwidth test", func() {
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`
|
||||
}`, ver, fakeHostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
// fake a non-exist host interface name
|
||||
fakeHostIfname := fmt.Sprintf("%s-fake", hostIfname)
|
||||
|
||||
conf = fmt.Sprintf(conf, fakeHostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
@ -888,7 +873,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
})
|
||||
})
|
||||
|
||||
Context("when chaining bandwidth plugin with PTP using 0.3.0 config", func() {
|
||||
Context(fmt.Sprintf("[%s] when chaining bandwidth plugin with PTP", ver), func() {
|
||||
var ptpConf string
|
||||
var rateInBits uint64
|
||||
var burstInBits uint64
|
||||
@ -902,6 +887,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
var containerWithoutTbfRes types.Result
|
||||
var echoServerWithTbf *gexec.Session
|
||||
var echoServerWithoutTbf *gexec.Session
|
||||
var dataDir string
|
||||
|
||||
BeforeEach(func() {
|
||||
rateInBytes := 1000
|
||||
@ -909,169 +895,28 @@ var _ = Describe("bandwidth test", func() {
|
||||
burstInBits = rateInBits * 2
|
||||
packetInBytes = rateInBytes * 25
|
||||
|
||||
var err error
|
||||
dataDir, err = ioutil.TempDir("", "bandwidth_linux_test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
ptpConf = fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "mynet",
|
||||
"type": "ptp",
|
||||
"ipMasq": true,
|
||||
"mtu": 512,
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"subnet": "10.1.2.0/24"
|
||||
}
|
||||
}`, current.ImplementedSpecVersion)
|
||||
|
||||
containerWithTbfIFName := "ptp0"
|
||||
containerWithoutTbfIFName := "ptp1"
|
||||
|
||||
var err error
|
||||
containerWithTbfNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithoutTbfNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("create two containers, and use the bandwidth plugin on one of them")
|
||||
Expect(hostNs.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
containerWithTbfRes, _, err = testutils.CmdAdd(containerWithTbfNS.Path(), "dummy", containerWithTbfIFName, []byte(ptpConf), func() error {
|
||||
r, err := invoke.DelegateAdd(context.TODO(), "ptp", []byte(ptpConf), nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(r.Print()).To(Succeed())
|
||||
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithoutTbfRes, _, err = testutils.CmdAdd(containerWithoutTbfNS.Path(), "dummy2", containerWithoutTbfIFName, []byte(ptpConf), func() error {
|
||||
r, err := invoke.DelegateAdd(context.TODO(), "ptp", []byte(ptpConf), nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(r.Print()).To(Succeed())
|
||||
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithTbfResult, err := current.GetResult(containerWithTbfRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
tbfPluginConf := PluginConf{}
|
||||
tbfPluginConf.RuntimeConfig.Bandwidth = &BandwidthEntry{
|
||||
IngressBurst: burstInBits,
|
||||
IngressRate: rateInBits,
|
||||
EgressBurst: burstInBits,
|
||||
EgressRate: rateInBits,
|
||||
}
|
||||
tbfPluginConf.Name = "mynet"
|
||||
tbfPluginConf.CNIVersion = "0.3.0"
|
||||
tbfPluginConf.Type = "bandwidth"
|
||||
tbfPluginConf.RawPrevResult = map[string]interface{}{
|
||||
"ips": containerWithTbfResult.IPs,
|
||||
"interfaces": containerWithTbfResult.Interfaces,
|
||||
}
|
||||
|
||||
tbfPluginConf.PrevResult = ¤t.Result{
|
||||
IPs: containerWithTbfResult.IPs,
|
||||
Interfaces: containerWithTbfResult.Interfaces,
|
||||
}
|
||||
conf, err := json.Marshal(tbfPluginConf)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy3",
|
||||
Netns: containerWithTbfNS.Path(),
|
||||
IfName: containerWithTbfIFName,
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
|
||||
_, out, err := testutils.CmdAdd(containerWithTbfNS.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
|
||||
Expect(err).NotTo(HaveOccurred(), string(out))
|
||||
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
|
||||
By("starting a tcp server on both containers")
|
||||
portServerWithTbf, echoServerWithTbf, err = startEchoServerInNamespace(containerWithTbfNS)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
portServerWithoutTbf, echoServerWithoutTbf, err = startEchoServerInNamespace(containerWithoutTbfNS)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
containerWithTbfNS.Close()
|
||||
containerWithoutTbfNS.Close()
|
||||
if echoServerWithoutTbf != nil {
|
||||
echoServerWithoutTbf.Kill()
|
||||
}
|
||||
if echoServerWithTbf != nil {
|
||||
echoServerWithTbf.Kill()
|
||||
}
|
||||
})
|
||||
|
||||
Measure("limits ingress traffic on veth device", func(b Benchmarker) {
|
||||
var runtimeWithLimit time.Duration
|
||||
var runtimeWithoutLimit time.Duration
|
||||
|
||||
By("gather timing statistics about both containers")
|
||||
By("sending tcp traffic to the container that has traffic shaped", func() {
|
||||
runtimeWithLimit = b.Time("with tbf", func() {
|
||||
result, err := current.GetResult(containerWithTbfRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
makeTcpClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithTbf, packetInBytes)
|
||||
})
|
||||
})
|
||||
|
||||
By("sending tcp traffic to the container that does not have traffic shaped", func() {
|
||||
runtimeWithoutLimit = b.Time("without tbf", func() {
|
||||
result, err := current.GetResult(containerWithoutTbfRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
makeTcpClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithoutTbf, packetInBytes)
|
||||
})
|
||||
})
|
||||
|
||||
Expect(runtimeWithLimit).To(BeNumerically(">", runtimeWithoutLimit+1000*time.Millisecond))
|
||||
}, 1)
|
||||
})
|
||||
|
||||
Context("when chaining bandwidth plugin with PTP using 0.4.0 config", func() {
|
||||
var ptpConf string
|
||||
var rateInBits uint64
|
||||
var burstInBits uint64
|
||||
var packetInBytes int
|
||||
var containerWithoutTbfNS ns.NetNS
|
||||
var containerWithTbfNS ns.NetNS
|
||||
var portServerWithTbf int
|
||||
var portServerWithoutTbf int
|
||||
|
||||
var containerWithTbfRes types.Result
|
||||
var containerWithoutTbfRes types.Result
|
||||
var echoServerWithTbf *gexec.Session
|
||||
var echoServerWithoutTbf *gexec.Session
|
||||
|
||||
BeforeEach(func() {
|
||||
rateInBytes := 1000
|
||||
rateInBits = uint64(rateInBytes * 8)
|
||||
burstInBits = rateInBits * 2
|
||||
packetInBytes = rateInBytes * 25
|
||||
|
||||
ptpConf = `{
|
||||
"cniVersion": "0.4.0",
|
||||
"name": "myBWnet",
|
||||
"type": "ptp",
|
||||
"ipMasq": true,
|
||||
"mtu": 512,
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"subnet": "10.1.2.0/24"
|
||||
"subnet": "10.1.2.0/24",
|
||||
"dataDir": "%s"
|
||||
}
|
||||
}`
|
||||
}`, ver, dataDir)
|
||||
|
||||
containerWithTbfIFName := "ptp0"
|
||||
containerWithoutTbfIFName := "ptp1"
|
||||
const (
|
||||
containerWithTbfIFName = "ptp0"
|
||||
containerWithoutTbfIFName = "ptp1"
|
||||
)
|
||||
|
||||
var err error
|
||||
containerWithTbfNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
@ -1100,7 +945,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithTbfResult, err := types040.GetResult(containerWithTbfRes)
|
||||
containerWithTbfResult, err := types100.GetResult(containerWithTbfRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
tbfPluginConf := &PluginConf{}
|
||||
@ -1114,8 +959,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
EgressRate: rateInBits,
|
||||
}
|
||||
tbfPluginConf.Type = "bandwidth"
|
||||
cniVersion := "0.4.0"
|
||||
_, newConfBytes, err := buildOneConfig("myBWnet", cniVersion, tbfPluginConf, containerWithTbfResult)
|
||||
_, newConfBytes, err := buildOneConfig("myBWnet", ver, tbfPluginConf, containerWithTbfResult)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
@ -1128,6 +972,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
result, out, err := testutils.CmdAdd(containerWithTbfNS.Path(), args.ContainerID, "", newConfBytes, func() error { return cmdAdd(args) })
|
||||
Expect(err).NotTo(HaveOccurred(), string(out))
|
||||
|
||||
if testutils.SpecVersionHasCHECK(ver) {
|
||||
// Do CNI Check
|
||||
checkConf := &PluginConf{}
|
||||
err = json.Unmarshal([]byte(ptpConf), &checkConf)
|
||||
@ -1141,7 +986,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
}
|
||||
checkConf.Type = "bandwidth"
|
||||
|
||||
_, newCheckBytes, err := buildOneConfig("myBWnet", cniVersion, checkConf, result)
|
||||
_, newCheckBytes, err := buildOneConfig("myBWnet", ver, checkConf, result)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
args = &skel.CmdArgs{
|
||||
@ -1153,6 +998,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
|
||||
err = testutils.CmdCheck(containerWithTbfNS.Path(), args.ContainerID, "", newCheckBytes, func() error { return cmdCheck(args) })
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
@ -1165,8 +1011,13 @@ var _ = Describe("bandwidth test", func() {
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
containerWithTbfNS.Close()
|
||||
containerWithoutTbfNS.Close()
|
||||
Expect(os.RemoveAll(dataDir)).To(Succeed())
|
||||
|
||||
Expect(containerWithTbfNS.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerWithTbfNS)).To(Succeed())
|
||||
Expect(containerWithoutTbfNS.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerWithoutTbfNS)).To(Succeed())
|
||||
|
||||
if echoServerWithoutTbf != nil {
|
||||
echoServerWithoutTbf.Kill()
|
||||
}
|
||||
@ -1182,7 +1033,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
By("gather timing statistics about both containers")
|
||||
By("sending tcp traffic to the container that has traffic shaped", func() {
|
||||
runtimeWithLimit = b.Time("with tbf", func() {
|
||||
result, err := types040.GetResult(containerWithTbfRes)
|
||||
result, err := types100.GetResult(containerWithTbfRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
makeTcpClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithTbf, packetInBytes)
|
||||
@ -1191,7 +1042,7 @@ var _ = Describe("bandwidth test", func() {
|
||||
|
||||
By("sending tcp traffic to the container that does not have traffic shaped", func() {
|
||||
runtimeWithoutLimit = b.Time("without tbf", func() {
|
||||
result, err := types040.GetResult(containerWithoutTbfRes)
|
||||
result, err := types100.GetResult(containerWithoutTbfRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
makeTcpClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithoutTbf, packetInBytes)
|
||||
@ -1201,5 +1052,20 @@ var _ = Describe("bandwidth test", func() {
|
||||
Expect(runtimeWithLimit).To(BeNumerically(">", runtimeWithoutLimit+1000*time.Millisecond))
|
||||
}, 1)
|
||||
})
|
||||
}
|
||||
|
||||
Describe("Validating input", func() {
|
||||
It("Should allow only 4GB burst rate", func() {
|
||||
err := validateRateAndBurst(5000, 4*1024*1024*1024*8-16) // 2 bytes less than the max should pass
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
err = validateRateAndBurst(5000, 4*1024*1024*1024*8) // we're 1 bit above MaxUint32
|
||||
Expect(err).To(HaveOccurred())
|
||||
err = validateRateAndBurst(0, 1)
|
||||
Expect(err).To(HaveOccurred())
|
||||
err = validateRateAndBurst(1, 0)
|
||||
Expect(err).To(HaveOccurred())
|
||||
err = validateRateAndBurst(0, 0)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -106,7 +106,7 @@ func makeTcpClientInNS(netns string, address string, port int, numBytes int) {
|
||||
Expect(string(out)).To(Equal(message))
|
||||
}
|
||||
|
||||
func createVeth(hostNamespace string, hostVethIfName string, containerNamespace string, containerVethIfName string, hostIP []byte, containerIP []byte, hostIfaceMTU int) {
|
||||
func createVeth(hostNs ns.NetNS, hostVethIfName string, containerNs ns.NetNS, containerVethIfName string, hostIP []byte, containerIP []byte, hostIfaceMTU int) {
|
||||
vethDeviceRequest := &netlink.Veth{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: hostVethIfName,
|
||||
@ -116,10 +116,7 @@ func createVeth(hostNamespace string, hostVethIfName string, containerNamespace
|
||||
PeerName: containerVethIfName,
|
||||
}
|
||||
|
||||
hostNs, err := ns.GetNS(hostNamespace)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = hostNs.Do(func(_ ns.NetNS) error {
|
||||
err := hostNs.Do(func(_ ns.NetNS) error {
|
||||
if err := netlink.LinkAdd(vethDeviceRequest); err != nil {
|
||||
return fmt.Errorf("creating veth pair: %s", err)
|
||||
}
|
||||
@ -129,11 +126,6 @@ func createVeth(hostNamespace string, hostVethIfName string, containerNamespace
|
||||
return fmt.Errorf("failed to find newly-created veth device %q: %v", containerVethIfName, err)
|
||||
}
|
||||
|
||||
containerNs, err := ns.GetNS(containerNamespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = netlink.LinkSetNsFd(containerVeth, int(containerNs.Fd()))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to move veth to container namespace: %s", err)
|
||||
@ -169,8 +161,6 @@ func createVeth(hostNamespace string, hostVethIfName string, containerNamespace
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerNs, err := ns.GetNS(containerNamespace)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
err = containerNs.Do(func(_ ns.NetNS) error {
|
||||
peerAddr := &net.IPNet{
|
||||
IP: hostIP,
|
||||
@ -203,7 +193,7 @@ func createVeth(hostNamespace string, hostVethIfName string, containerNamespace
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
func createVethInOneNs(namespace, vethName, peerName string) {
|
||||
func createVethInOneNs(netNS ns.NetNS, vethName, peerName string) {
|
||||
vethDeviceRequest := &netlink.Veth{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: vethName,
|
||||
@ -212,10 +202,7 @@ func createVethInOneNs(namespace, vethName, peerName string) {
|
||||
PeerName: peerName,
|
||||
}
|
||||
|
||||
netNS, err := ns.GetNS(namespace)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = netNS.Do(func(_ ns.NetNS) error {
|
||||
err := netNS.Do(func(_ ns.NetNS) error {
|
||||
if err := netlink.LinkAdd(vethDeviceRequest); err != nil {
|
||||
return fmt.Errorf("failed to create veth pair: %v", err)
|
||||
}
|
||||
@ -229,11 +216,8 @@ func createVethInOneNs(namespace, vethName, peerName string) {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
func createMacvlan(namespace, master, macvlanName string) {
|
||||
netNS, err := ns.GetNS(namespace)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = netNS.Do(func(_ ns.NetNS) error {
|
||||
func createMacvlan(netNS ns.NetNS, master, macvlanName string) {
|
||||
err := netNS.Do(func(_ ns.NetNS) error {
|
||||
m, err := netlink.LinkByName(master)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to lookup master %q: %v", master, err)
|
||||
|
Loading…
x
Reference in New Issue
Block a user