forked from sonic-net/sonic-buildimage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor swss integration test (sonic-net#404)
- Loading branch information
Showing
5 changed files
with
278 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file was deleted.
Oops, something went wrong.