Skip to content

Commit

Permalink
Merge pull request sonic-net#649 from lguohan/vstest
Browse files Browse the repository at this point in the history
[vstest]: various vstest fixes and enhancements
  • Loading branch information
lguohan authored Oct 22, 2018
2 parents e8e3ddc + 8620a51 commit 4bf28ed
Show file tree
Hide file tree
Showing 24 changed files with 277 additions and 197 deletions.
3 changes: 3 additions & 0 deletions orchagent/dtelorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ DTelOrch::DTelOrch(DBConnector *db, vector<string> tableNames, PortsOrch *portOr

attr.id = SAI_DTEL_ATTR_INT_L4_DSCP;

attr.value.aclfield.enable = true;
attr.value.aclfield.data.u8 = 0x11;
attr.value.aclfield.mask.u8 = 0x3f;

Expand Down Expand Up @@ -661,6 +662,8 @@ void DTelOrch::doDtelTableTask(Consumer &consumer)
goto dtel_table_continue;
}

attr.value.aclfield.enable = true;

status = sai_dtel_api->set_dtel_attribute(dtelId, &attr);
if (status != SAI_STATUS_SUCCESS)
{
Expand Down
146 changes: 113 additions & 33 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import tarfile
import StringIO
import subprocess
from datetime import datetime
from swsscommon import swsscommon

def ensure_system(cmd):
Expand All @@ -20,6 +21,8 @@ def ensure_system(cmd):
def pytest_addoption(parser):
parser.addoption("--dvsname", action="store", default=None,
help="dvs name")
parser.addoption("--keeptb", action="store_true", default=False,
help="keep testbed after test")

class AsicDbValidator(object):
def __init__(self, dvs):
Expand Down Expand Up @@ -110,14 +113,14 @@ def __init__(self, ctn_name, pid, i):
ensure_system("nsenter -t %d -n ip link set arp off dev %s" % (pid, self.vifname))
ensure_system("nsenter -t %d -n sysctl -w net.ipv6.conf.%s.disable_ipv6=1" % (pid, self.vifname))

def __del__(self):
def destroy(self):
if self.cleanup:
pids = subprocess.check_output("ip netns pids %s" % (self.nsname), shell=True)
if pids:
for pid in pids.split('\n'):
if len(pid) > 0:
os.system("kill %s" % int(pid))
os.system("ip netns delete %s" % self.nsname)
ensure_system("ip netns delete %s" % self.nsname)

def runcmd(self, cmd):
return os.system("ip netns exec %s %s" % (self.nsname, cmd))
Expand All @@ -126,25 +129,28 @@ def runcmd_async(self, cmd):
return subprocess.Popen("ip netns exec %s %s" % (self.nsname, cmd), shell=True)

class DockerVirtualSwitch(object):
def __init__(self, name=None):
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"
def __init__(self, name=None, keeptb=False):
self.basicd = ['redis-server',
'rsyslogd']
self.swssd = ['orchagent',
'intfmgrd',
'intfsyncd',
'neighsyncd',
'portsyncd',
'vlanmgrd',
'vrfmgrd',
'portmgrd']
self.syncd = ['syncd']
self.rtd = ['fpmsyncd', 'zebra']
self.teamd = ['teamsyncd', 'teammgrd']
self.alld = self.basicd + self.swssd + self.syncd + self.rtd + self.teamd
self.client = docker.from_env()

self.ctn = None
self.cleanup = True
if keeptb:
self.cleanup = False
else:
self.cleanup = True
if name != None:
# get virtual switch container
for ctn in self.client.containers.list():
Expand Down Expand Up @@ -183,6 +189,11 @@ def __init__(self, name=None):
server = VirtualServer(self.ctn_sw.name, self.ctn_sw_pid, i)
self.servers.append(server)

# mount redis to base to unique directory
self.mount = "/var/run/redis-vs/{}".format(self.ctn_sw.name)
os.system("mkdir -p {}".format(self.mount))
self.redis_sock = self.mount + '/' + "redis.sock"

# create virtual switch container
self.ctn = self.client.containers.run('docker-sonic-vs', privileged=True, detach=True,
network_mode="container:%s" % self.ctn_sw.name,
Expand All @@ -207,8 +218,9 @@ def destroy(self):
if self.cleanup:
self.ctn.remove(force=True)
self.ctn_sw.remove(force=True)
os.system("rm -rf {}".format(self.mount))
for s in self.servers:
del(s)
s.destroy()

def check_ready(self, timeout=30):
'''check if all processes in the dvs is ready'''
Expand All @@ -232,13 +244,17 @@ def check_ready(self, timeout=30):

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

# check if start.sh exited
if process_status["start.sh"] != "EXITED":
ready = False

if ready == True:
break

Expand All @@ -251,6 +267,20 @@ def check_ready(self, timeout=30):
def restart(self):
self.ctn.restart()

# start processes in SWSS
def start_swss(self):
cmd = ""
for pname in self.swssd:
cmd += "supervisorctl start {}; ".format(pname)
self.runcmd(['sh', '-c', cmd])

# stop processes in SWSS
def stop_swss(self):
cmd = ""
for pname in self.swssd:
cmd += "supervisorctl stop {}; ".format(pname)
self.runcmd(['sh', '-c', cmd])

def init_asicdb_validator(self):
self.asicdb = AsicDbValidator(self)

Expand All @@ -273,6 +303,57 @@ def copy_file(self, path, filename):
self.ctn.put_archive(path, tarstr.getvalue())
tarstr.close()

def get_logs(self, modname=None):
stream, stat = self.ctn.get_archive("/var/log/")
if modname == None:
log_dir = "log"
else:
log_dir = "log/{}".format(modname)
os.system("rm -rf {}".format(log_dir))
os.system("mkdir -p {}".format(log_dir))
p = subprocess.Popen(["tar", "--no-same-owner", "-C", "./{}".format(log_dir), "-x"], stdin=subprocess.PIPE)
for x in stream:
p.stdin.write(x)
p.stdin.close()
p.wait()
if p.returncode:
raise RuntimeError("Failed to unpack the archive.")
os.system("chmod a+r -R log")

def add_log_marker(self):
marker = "=== start marker {} ===".format(datetime.now().isoformat())
self.ctn.exec_run("logger {}".format(marker))
return marker

def SubscribeAsicDbObject(self, objpfx):
r = redis.Redis(unix_socket_path=self.redis_sock, db=swsscommon.ASIC_DB)
pubsub = r.pubsub()
pubsub.psubscribe("__keyspace@1__:ASIC_STATE:%s*" % objpfx)
return pubsub

def CountSubscribedObjects(self, pubsub, ignore=None, timeout=10):
nadd = 0
ndel = 0
idle = 0
while True and idle < timeout:
message = pubsub.get_message()
if message:
print message
if ignore:
fds = message['channel'].split(':')
if fds[2] in ignore:
continue
if message['data'] == 'hset':
nadd += 1
elif message['data'] == 'del':
ndel += 1
idle = 0
else:
time.sleep(1)
idle += 1

return (nadd, ndel)

def get_map_iface_bridge_port_id(self, asic_db):
port_id_2_iface = self.asicdb.portoidmap
tbl = swsscommon.Table(asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT")
Expand Down Expand Up @@ -481,21 +562,20 @@ def setReadOnlyAttr(self, obj, attr, val):

ntf.send("set_ro", key, fvp)

# start processes in SWSS
def start_swss(self):
self.runcmd(['sh', '-c', 'supervisorctl start orchagent; supervisorctl start portsyncd; supervisorctl start intfsyncd; \
supervisorctl start neighsyncd; supervisorctl start intfmgrd; supervisorctl start vlanmgrd; \
supervisorctl start buffermgrd; supervisorctl start arp_update'])

# stop processes in SWSS
def stop_swss(self):
self.runcmd(['sh', '-c', 'supervisorctl stop orchagent; supervisorctl stop portsyncd; supervisorctl stop intfsyncd; \
supervisorctl stop neighsyncd; supervisorctl stop intfmgrd; supervisorctl stop vlanmgrd; \
supervisorctl stop buffermgrd; supervisorctl stop arp_update'])

@pytest.yield_fixture(scope="module")
def dvs(request):
name = request.config.getoption("--dvsname")
dvs = DockerVirtualSwitch(name)
keeptb = request.config.getoption("--keeptb")
dvs = DockerVirtualSwitch(name, keeptb)
yield dvs
if name == None:
dvs.get_logs(request.module.__name__)
else:
dvs.get_logs()
dvs.destroy()

@pytest.yield_fixture
def testlog(request, dvs):
dvs.runcmd("logger === start test %s ===" % request.node.name)
yield testlog
dvs.runcmd("logger === finish test %s ===" % request.node.name)
Loading

0 comments on commit 4bf28ed

Please sign in to comment.