Skip to content

Commit

Permalink
refactor swss integration test (sonic-net#404)
Browse files Browse the repository at this point in the history
  • Loading branch information
lguohan authored Dec 2, 2017
1 parent bf4265c commit 226f96c
Show file tree
Hide file tree
Showing 5 changed files with 278 additions and 108 deletions.
115 changes: 115 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import os
import re
import time
import docker
import pytest
import commands

class VirtualServer(object):
def __init__(self, ctn_name, pid, i):
self.nsname = "%s_srv%d" % (ctn_name, i)
self.vifname = "vEthernet%d" % (i * 4)

# create netns
os.system("ip netns add %s" % self.nsname)

# create vpeer link
os.system("ip link add %s type veth peer name %s" % (self.nsname[0:12], self.vifname))
os.system("ip link set %s netns %s" % (self.nsname[0:12], self.nsname))
os.system("ip link set %s netns %d" % (self.vifname, pid))

# bring up link in the virtual server
os.system("ip netns exec %s ip link set dev %s name eth0" % (self.nsname, self.nsname[0:12]))
os.system("ip netns exec %s ip link set dev eth0 up" % (self.nsname))

# bring up link in the virtual switch
os.system("nsenter -t %d -n ip link set dev %s up" % (pid, self.vifname))

def __del__(self):
os.system("ip netns delete %s" % self.nsname)

def runcmd(self, cmd):
os.system("ip netns exec %s %s" % (self.nsname, cmd))

class DockerVirtualSwitch(object):
def __init__(self):
self.name = "vs"
self.pnames = ['fpmsyncd',
'intfmgrd',
'intfsyncd',
'neighsyncd',
'orchagent',
'portsyncd',
'redis-server',
'rsyslogd',
'syncd',
'teamsyncd',
'vlanmgrd',
'zebra']
self.mount = "/var/run/redis-vs"
self.redis_sock = self.mount + '/' + "redis.sock"
self.client = docker.from_env()
self.ctn_sw = self.client.containers.run('debian:jessie', privileged=True, detach=True,
command="bash", stdin_open=True)
(status, output) = commands.getstatusoutput("docker inspect --format '{{.State.Pid}}' %s" % self.ctn_sw.name)
self.cnt_sw_pid = int(output)
self.servers = []
for i in range(32):
server = VirtualServer(self.ctn_sw.name, self.cnt_sw_pid, i)
self.servers.append(server)
self.ctn = self.client.containers.run('docker-sonic-vs', privileged=True, detach=True,
network_mode="container:%s" % self.ctn_sw.name,
volumes={ self.mount: { 'bind': '/var/run/redis', 'mode': 'rw' } })

def destroy(self):
self.ctn.remove(force=True)
self.ctn_sw.remove(force=True)
for s in self.servers:
del(s)

def ready(self, timeout=30):
'''check if all processes in the dvs is ready'''

re_space = re.compile('\s+')
process_status = {}
ready = False
started = 0
while True:
# get process status
out = self.ctn.exec_run("supervisorctl status")
for l in out.split('\n'):
fds = re_space.split(l)
if len(fds) < 2:
continue
process_status[fds[0]] = fds[1]

# check if all processes are running
ready = True
for pname in self.pnames:
try:
if process_status[pname] != "RUNNING":
ready = False
except KeyError:
ready = False

if ready == True:
break

started += 1
if started > timeout:
print out
raise

time.sleep(1)

def restart(self):
self.ctn.restart()

def runcmd(self, cmd):
return self.ctn.exec_run(cmd)

@pytest.yield_fixture(scope="module")
def dvs():
dvs = DockerVirtualSwitch()
yield dvs
dvs.destroy()
60 changes: 60 additions & 0 deletions tests/test_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from swsscommon import swsscommon
import time
import re
import json

def parse_route_key(rt_key):
(otype, kstr) = rt_key.split(':', 1)
assert otype == "SAI_OBJECT_TYPE_ROUTE_ENTRY"
return json.loads(kstr)

def test_InterfaceIpChange(dvs):

dvs.restart()

dvs.ready()

dvs.runcmd("ifconfig Ethernet0 10.0.0.0/31 up")

time.sleep(1)

# check if route was propagated to ASIC DB

db = swsscommon.DBConnector(1, dvs.redis_sock, 0)

tbl = swsscommon.Table(db, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY")

keys = tbl.getKeys()

for k in keys:
rt_key = parse_route_key(k)

if rt_key['dest'] == "10.0.0.0/31":
subnet_found = True

if rt_key['dest'] == "10.0.0.0/32":
ip2me_found = True

assert subnet_found == True and ip2me_found == True

subnet_found = False
ip2me_found = False

dvs.runcmd("ifconfig Ethernet0 10.0.0.0/24 up")

time.sleep(1)

# check if route was propagated to ASIC DB

keys = tbl.getKeys()

for k in keys:
rt_key = parse_route_key(k)

if rt_key['dest'] == "10.0.0.0/24":
subnet_found = True

if rt_key['dest'] == "10.0.0.0/32":
ip2me_found = True

assert subnet_found == True and ip2me_found == True
50 changes: 50 additions & 0 deletions tests/test_port.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from swsscommon import swsscommon
import time
import os

def test_PortNotification(dvs):

dvs.restart()

dvs.ready()

dvs.runcmd("ifconfig Ethernet0 10.0.0.0/31 up") == 0
dvs.runcmd("ifconfig Ethernet4 10.0.0.2/31 up") == 0

dvs.servers[0].runcmd("ip link set down dev eth0") == 0

time.sleep(1)

db = swsscommon.DBConnector(0, dvs.redis_sock, 0)

tbl = swsscommon.Table(db, "PORT_TABLE")

(status, fvs) = tbl.get("Ethernet0")

assert status == True

oper_status = "unknown"

for v in fvs:
if v[0] == "oper_status":
oper_status = v[1]
break

assert oper_status == "down"

dvs.servers[0].runcmd("ip link set up dev eth0") == 0

time.sleep(1)

(status, fvs) = tbl.get("Ethernet0")

assert status == True

oper_status = "unknown"

for v in fvs:
if v[0] == "oper_status":
oper_status = v[1]
break

assert oper_status == "up"
53 changes: 53 additions & 0 deletions tests/test_route.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from swsscommon import swsscommon
import os
import re
import time
import json

def parse_route_key(rt_key):
(otype, kstr) = rt_key.split(':', 1)
assert otype == "SAI_OBJECT_TYPE_ROUTE_ENTRY"
return json.loads(kstr)

def test_RouteAdd(dvs):

dvs.restart()

dvs.ready()

dvs.runcmd("ifconfig Ethernet0 10.0.0.0/31 up")
dvs.runcmd("ifconfig Ethernet4 10.0.0.2/31 up")

dvs.servers[0].runcmd("ifconfig eth0 10.0.0.1/31")
dvs.servers[0].runcmd("ip route add default via 10.0.0.0")

dvs.servers[1].runcmd("ifconfig eth0 10.0.0.3/31")
dvs.servers[1].runcmd("ip route add default via 10.0.0.2")

# get neighbor and arp entry
dvs.servers[0].runcmd("ping -c 1 10.0.0.3")

db = swsscommon.DBConnector(0, dvs.redis_sock, 0)
ps = swsscommon.ProducerStateTable(db, "ROUTE_TABLE")
fvs = swsscommon.FieldValuePairs([("nexthop","10.0.0.1"), ("ifname", "Ethernet0")])

ps.set("2.2.2.0/24", fvs)

time.sleep(1)

# check if route was propagated to ASIC DB

db = swsscommon.DBConnector(1, dvs.redis_sock, 0)

tbl = swsscommon.Table(db, "ASIC_STATE:SAI_OBJECT_TYPE_ROUTE_ENTRY")

keys = tbl.getKeys()

found_route = False
for k in keys:
rt_key = parse_route_key(k)

if rt_key['dest'] == "2.2.2.0/24":
found_route = True

assert found_route
108 changes: 0 additions & 108 deletions tests/test_vs.py

This file was deleted.

0 comments on commit 226f96c

Please sign in to comment.