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:
Dan Williams 2021-02-11 20:15:56 -06:00
parent 02cdaafe93
commit da52be35bc
2 changed files with 904 additions and 1054 deletions

View File

@ -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 = &current.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())
})
})
})

View File

@ -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)