Skip to content

Commit 50a943e

Browse files
committed
systemtests: initial draft of system tests
Signed-off-by: Erik Hollensbe <[email protected]>
1 parent ca04402 commit 50a943e

10 files changed

+2151
-2
lines changed

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ unit-test: stop clean build
9494
centos-tests:
9595
CONTIV_NODE_OS=centos make clean build unit-test sanity-test stop
9696

97-
sanity-test: start
98-
vagrant ssh netplugin-node1 -c 'bash -lc "cd /opt/gopath/src/github.com/contiv/netplugin/scripts/python && PYTHONIOENCODING=utf-8 ./sanity.py -nodes 192.168.2.10,192.168.2.11"'
97+
system-test: start
98+
godep go test -v -timeout 60m ./systemtests -check.v
9999

100100
host-build:
101101
@echo "dev: making binaries..."

systemtests/aci_test.go

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package systemtests
2+
3+
import (
4+
"github.com/contiv/contivmodel/client"
5+
. "gopkg.in/check.v1"
6+
)
7+
8+
func (s *systemtestSuite) TestACIMode(c *C) {
9+
c.Assert(s.cli.GlobalPost(&client.Global{
10+
Name: "global",
11+
NetworkInfraType: "aci",
12+
Vlans: "1-4094",
13+
Vxlans: "1-10000",
14+
}), IsNil)
15+
c.Assert(s.cli.NetworkPost(&client.Network{
16+
TenantName: "default",
17+
NetworkName: "aciNet",
18+
Subnet: "22.2.2.0/24",
19+
Gateway: "22.2.2.254",
20+
Encap: "vlan",
21+
}), IsNil)
22+
23+
c.Assert(s.cli.EndpointGroupPost(&client.EndpointGroup{
24+
TenantName: "default",
25+
NetworkName: "aciNet",
26+
GroupName: "epgA",
27+
}), IsNil)
28+
29+
c.Assert(s.cli.EndpointGroupPost(&client.EndpointGroup{
30+
TenantName: "default",
31+
NetworkName: "aciNet",
32+
GroupName: "epgB",
33+
}), IsNil)
34+
35+
cA1, err := s.nodes[0].runContainer(containerSpec{networkName: "epgA.aciNet"})
36+
c.Assert(err, IsNil)
37+
38+
cA2, err := s.nodes[0].runContainer(containerSpec{networkName: "epgA.aciNet"})
39+
c.Assert(err, IsNil)
40+
41+
cB1, err := s.nodes[0].runContainer(containerSpec{networkName: "epgB.aciNet"})
42+
c.Assert(err, IsNil)
43+
44+
cB2, err := s.nodes[0].runContainer(containerSpec{networkName: "epgB.aciNet"})
45+
c.Assert(err, IsNil)
46+
47+
// Verify cA1 can ping cA2
48+
c.Assert(cA1.checkPing(cA2.eth0), IsNil)
49+
// Verify cB1 can ping cB2
50+
c.Assert(cB1.checkPing(cB2.eth0), IsNil)
51+
// Verify cA1 cannot ping cB1
52+
c.Assert(cA1.checkPingFailure(cB1.eth0), IsNil)
53+
54+
c.Assert(s.removeContainers([]*container{cA1, cA2, cB1, cB2}), IsNil)
55+
c.Assert(s.cli.EndpointGroupDelete("default", "aciNet", "epgA"), IsNil)
56+
c.Assert(s.cli.EndpointGroupDelete("default", "aciNet", "epgB"), IsNil)
57+
c.Assert(s.cli.NetworkDelete("default", "aciNet"), IsNil)
58+
}

systemtests/basic_test.go

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package systemtests
2+
3+
import (
4+
"github.com/contiv/contivmodel/client"
5+
. "gopkg.in/check.v1"
6+
)
7+
8+
var privateNetwork = &client.Network{
9+
PktTag: 1001,
10+
NetworkName: "private",
11+
Subnet: "10.1.0.0/16",
12+
Gateway: "10.1.1.254",
13+
Encap: "vxlan",
14+
TenantName: "default",
15+
}
16+
17+
func (s *systemtestSuite) TestBasicStartRemoveContainerVXLAN(c *C) {
18+
s.testBasicStartRemoveContainer(c, "vxlan")
19+
}
20+
21+
func (s *systemtestSuite) TestBasicStartRemoveContainerVLAN(c *C) {
22+
s.testBasicStartRemoveContainer(c, "vlan")
23+
}
24+
25+
func (s *systemtestSuite) testBasicStartRemoveContainer(c *C, encap string) {
26+
c.Assert(s.cli.NetworkPost(&client.Network{
27+
PktTag: 1001,
28+
NetworkName: "private",
29+
Subnet: "10.1.0.0/16",
30+
Gateway: "10.1.1.254",
31+
Encap: encap,
32+
TenantName: "default",
33+
}), IsNil)
34+
35+
for i := 0; i < s.iterations; i++ {
36+
containers, err := s.runContainers(s.containers, false, "private", nil)
37+
c.Assert(err, IsNil)
38+
c.Assert(s.pingTest(containers), IsNil)
39+
c.Assert(s.removeContainers(containers), IsNil)
40+
}
41+
42+
c.Assert(s.cli.NetworkDelete("default", "private"), IsNil)
43+
}
44+
45+
func (s *systemtestSuite) TestBasicStartStopContainerVXLAN(c *C) {
46+
s.testBasicStartStopContainer(c, "vxlan")
47+
}
48+
49+
func (s *systemtestSuite) TestBasicStartStopContainerVLAN(c *C) {
50+
s.testBasicStartStopContainer(c, "vlan")
51+
}
52+
53+
func (s *systemtestSuite) testBasicStartStopContainer(c *C, encap string) {
54+
c.Assert(s.cli.NetworkPost(&client.Network{
55+
PktTag: 1001,
56+
NetworkName: "private",
57+
Subnet: "10.1.0.0/16",
58+
Gateway: "10.1.1.254",
59+
Encap: encap,
60+
TenantName: "default",
61+
}), IsNil)
62+
63+
for i := 0; i < s.iterations; i++ {
64+
containers, err := s.runContainers(s.containers, false, "private", nil)
65+
c.Assert(err, IsNil)
66+
67+
errChan := make(chan error)
68+
for _, cont := range containers {
69+
go func(cont *container) { errChan <- cont.stop() }(cont)
70+
}
71+
72+
for range containers {
73+
c.Assert(<-errChan, IsNil)
74+
}
75+
76+
for _, cont := range containers {
77+
go func(cont *container) { errChan <- cont.start() }(cont)
78+
}
79+
80+
for range containers {
81+
c.Assert(<-errChan, IsNil)
82+
}
83+
84+
c.Assert(s.pingTest(containers), IsNil)
85+
c.Assert(s.removeContainers(containers), IsNil)
86+
}
87+
88+
c.Assert(s.cli.NetworkDelete("default", "private"), IsNil)
89+
}

systemtests/container_test.go

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package systemtests
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"strings"
7+
8+
"github.com/Sirupsen/logrus"
9+
)
10+
11+
type container struct {
12+
node *node
13+
containerID string
14+
name string
15+
eth0 string
16+
}
17+
18+
func newContainer(node *node, containerID, name string) (*container, error) {
19+
cont := &container{node: node, containerID: containerID, name: name}
20+
21+
out, err := cont.getIPAddr("eth0")
22+
if err != nil {
23+
return nil, err
24+
}
25+
cont.eth0 = out
26+
27+
return cont, nil
28+
}
29+
30+
func (c *container) String() string {
31+
return fmt.Sprintf("(container: %s (name: %q ip: %s host: %s))", c.containerID, c.name, c.eth0, c.node.Name())
32+
}
33+
34+
func (c *container) checkPingFailure(ipaddr string) error {
35+
logrus.Infof("Expecting ping failure from %v to %s", c, ipaddr)
36+
if err := c.checkPing(ipaddr); err == nil {
37+
return fmt.Errorf("Ping succeeded when expected to fail from %v to %s", c, ipaddr)
38+
}
39+
40+
return nil
41+
}
42+
43+
func (c *container) checkPing(ipaddr string) error {
44+
logrus.Infof("Checking ping from %v to %s", c, ipaddr)
45+
out, err := c.exec("ping -c 1 " + ipaddr)
46+
if err != nil {
47+
return err
48+
}
49+
50+
if err != nil || strings.Contains(out, "0 received, 100% packet loss") {
51+
logrus.Errorf("Ping from %v to %s FAILED: %q - %v", c, ipaddr, out, err)
52+
return fmt.Errorf("Ping failed from %v to %s: %q - %v", c, ipaddr, out, err)
53+
}
54+
55+
logrus.Infof("Ping from %v to %s SUCCEEDED", c, ipaddr)
56+
return nil
57+
}
58+
59+
func (c *container) getIPAddr(dev string) (string, error) {
60+
out, err := c.exec(fmt.Sprintf("ip addr show dev %s | grep inet | head -1", dev))
61+
if err != nil {
62+
logrus.Errorf("Failed to get IP for container %q", c.containerID)
63+
logrus.Println(out)
64+
}
65+
66+
parts := regexp.MustCompile(`\s+`).Split(strings.TrimSpace(out), -1)
67+
if len(parts) < 2 {
68+
return "", fmt.Errorf("Invalid output from container %q: %s", c.containerID, out)
69+
}
70+
71+
parts = strings.Split(parts[1], "/")
72+
out = strings.TrimSpace(parts[0])
73+
return out, err
74+
}
75+
76+
func (c *container) exec(args string) (string, error) {
77+
return c.node.runCommand(fmt.Sprintf("docker exec %s %s", c.containerID, args))
78+
}
79+
80+
func (c *container) execBG(args string) (string, error) {
81+
return c.node.runCommand(fmt.Sprintf("docker exec -d %s %s", c.containerID, args))
82+
}
83+
84+
func (c *container) dockerCmd(arg string) error {
85+
out, err := c.node.runCommand(fmt.Sprintf("docker %s %s", arg, c.containerID))
86+
if err != nil {
87+
logrus.Println(out)
88+
return err
89+
}
90+
91+
return nil
92+
}
93+
94+
func (c *container) start() error {
95+
logrus.Infof("Starting container %s on %s", c.containerID, c.node.Name())
96+
return c.dockerCmd("start")
97+
}
98+
99+
func (c *container) stop() error {
100+
logrus.Infof("Stopping container %s on %s", c.containerID, c.node.Name())
101+
return c.dockerCmd("stop")
102+
}
103+
104+
func (c *container) rm() error {
105+
logrus.Infof("Removing container %s on %s", c.containerID, c.node.Name())
106+
c.dockerCmd("kill -s 9")
107+
return c.dockerCmd("rm -f")
108+
}
109+
110+
func (c *container) startListener(port int, protocol string) error {
111+
var protoStr string
112+
113+
if protocol == "udp" {
114+
protoStr = "-u"
115+
}
116+
117+
logrus.Infof("Starting a %s listener on %v port %d", protocol, c, port)
118+
_, err := c.execBG(fmt.Sprintf("nc -lk %s -p %v -e /bin/true", protoStr, port))
119+
return err
120+
}
121+
122+
func (c *container) checkConnection(ipaddr, protocol string, port int) error {
123+
var protoStr string
124+
125+
if protocol == "udp" {
126+
protoStr = "-u"
127+
}
128+
129+
logrus.Infof("Checking connection from %v to ip %s on port %d", c, ipaddr, port)
130+
131+
_, err := c.exec(fmt.Sprintf("nc -z -n -v -w 1 %s %s %v", protoStr, ipaddr, port))
132+
if err != nil {
133+
logrus.Errorf("Connection from %v to ip %s on port %d FAILED", c, ipaddr, port)
134+
} else {
135+
logrus.Infof("Connection from %v to ip %s on port %d SUCCEEDED", c, ipaddr, port)
136+
}
137+
138+
return err
139+
}
140+
141+
func (c *container) checkNoConnection(ipaddr, protocol string, port int) error {
142+
logrus.Infof("Expecting connection to fail from %v to %s on port %d", c, ipaddr, port)
143+
144+
if err := c.checkConnection(ipaddr, protocol, port); err != nil {
145+
return nil
146+
}
147+
148+
return fmt.Errorf("Connection SUCCEEDED on port %d from %s from %v when it should have FAILED.", port, ipaddr, c)
149+
}

0 commit comments

Comments
 (0)