From c03862627357698673664b101d2ee0b18ec0534d Mon Sep 17 00:00:00 2001 From: lguohan Date: Sat, 10 Nov 2018 13:40:02 -0800 Subject: [PATCH] [vstest]: add testlog for vstests (#2247) Signed-off-by: Guohan Lu --- platform/vs/tests/bgp/test_invalid_nexthop.py | 2 +- platform/vs/tests/bgp/test_no_export.py | 2 +- platform/vs/tests/conftest.py | 253 +----------------- platform/vs/tests/teamd/test_portchannel.py | 2 +- 4 files changed, 4 insertions(+), 255 deletions(-) mode change 100644 => 120000 platform/vs/tests/conftest.py diff --git a/platform/vs/tests/bgp/test_invalid_nexthop.py b/platform/vs/tests/bgp/test_invalid_nexthop.py index 616f26df6e..eb4f6c212e 100644 --- a/platform/vs/tests/bgp/test_invalid_nexthop.py +++ b/platform/vs/tests/bgp/test_invalid_nexthop.py @@ -4,7 +4,7 @@ import re import time import json -def test_InvalidNexthop(dvs): +def test_InvalidNexthop(dvs, testlog): dvs.copy_file("/etc/quagga/", "bgp/files/invalid_nexthop/bgpd.conf") dvs.runcmd("supervisorctl start bgpd") diff --git a/platform/vs/tests/bgp/test_no_export.py b/platform/vs/tests/bgp/test_no_export.py index 57f9bb322b..f2d06f31cd 100644 --- a/platform/vs/tests/bgp/test_no_export.py +++ b/platform/vs/tests/bgp/test_no_export.py @@ -4,7 +4,7 @@ import re import time import json -def test_bounce(dvs): +def test_bounce(dvs, testlog): dvs.servers[0].runcmd("pkill -f exabgp") dvs.copy_file("/etc/quagga/", "bgp/files/no_export/bgpd.conf") dvs.runcmd("supervisorctl start bgpd") diff --git a/platform/vs/tests/conftest.py b/platform/vs/tests/conftest.py deleted file mode 100644 index 8acaed5e90..0000000000 --- a/platform/vs/tests/conftest.py +++ /dev/null @@ -1,252 +0,0 @@ -import os -import os.path -import re -import time -import docker -import pytest -import commands -import tarfile -import StringIO -import subprocess -from swsscommon import swsscommon - -def pytest_addoption(parser): - parser.addoption("--dvsname", action="store", default=None, - help="dvs name") - -class AsicDbValidator(object): - def __init__(self, dvs): - self.adb = swsscommon.DBConnector(1, dvs.redis_sock, 0) - - # get default dot1q vlan id - atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_VLAN") - - keys = atbl.getKeys() - assert len(keys) == 1 - self.default_vlan_id = keys[0] - - # build port oid to front port name mapping - self.portoidmap = {} - self.portnamemap = {} - self.hostifoidmap = {} - self.hostifnamemap = {} - atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF") - keys = atbl.getKeys() - - assert len(keys) == 32 - for k in keys: - (status, fvs) = atbl.get(k) - - assert status == True - - for fv in fvs: - if fv[0] == "SAI_HOSTIF_ATTR_OBJ_ID": - port_oid = fv[1] - elif fv[0] == "SAI_HOSTIF_ATTR_NAME": - port_name = fv[1] - - self.portoidmap[port_oid] = port_name - self.portnamemap[port_name] = port_oid - self.hostifoidmap[k] = port_name - self.hostifnamemap[port_name] = k - - # get default acl table and acl rules - atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE") - keys = atbl.getKeys() - - assert len(keys) >= 1 - self.default_acl_tables = keys - - atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY") - keys = atbl.getKeys() - - assert len(keys) == 2 - self.default_acl_entries = keys - -class VirtualServer(object): - def __init__(self, ctn_name, pid, i): - self.nsname = "%s-srv%d" % (ctn_name, i) - self.vifname = "vEthernet%d" % (i * 4) - self.cleanup = True - - # create netns - if os.path.exists("/var/run/netns/%s" % self.nsname): - self.cleanup = False - else: - 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)) - os.system("ip netns exec %s ethtool -K eth0 tx off" % (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): - 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) - - def runcmd(self, cmd): - os.system("ip netns exec %s %s" % (self.nsname, cmd)) - - 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" - self.client = docker.from_env() - - self.ctn = None - self.cleanup = True - if name != None: - # get virtual switch container - for ctn in self.client.containers.list(): - if ctn.name == name: - self.ctn = ctn - (status, output) = commands.getstatusoutput("docker inspect --format '{{.HostConfig.NetworkMode}}' %s" % name) - ctn_sw_id = output.split(':')[1] - self.cleanup = False - if self.ctn == None: - raise NameError("cannot find container %s" % name) - - # get base container - for ctn in self.client.containers.list(): - if ctn.id == ctn_sw_id or ctn.name == ctn_sw_id: - ctn_sw_name = ctn.name - - (status, output) = commands.getstatusoutput("docker inspect --format '{{.State.Pid}}' %s" % ctn_sw_name) - self.ctn_sw_pid = int(output) - - # create virtual servers - self.servers = [] - for i in range(32): - server = VirtualServer(ctn_sw_name, self.ctn_sw_pid, i) - self.servers.append(server) - - self.restart() - else: - 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.ctn_sw_pid = int(output) - - # create virtual server - self.servers = [] - for i in range(32): - server = VirtualServer(self.ctn_sw.name, self.ctn_sw_pid, i) - self.servers.append(server) - - # 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, - volumes={ self.mount: { 'bind': '/var/run/redis', 'mode': 'rw' } }) - - try: - self.ctn.exec_run("sysctl -w net.ipv6.conf.all.disable_ipv6=0") - self.check_ready() - self.init_asicdb_validator() - except: - self.destroy() - raise - - def destroy(self): - if self.cleanup: - self.ctn.remove(force=True) - self.ctn_sw.remove(force=True) - for s in self.servers: - del(s) - - def check_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 - res = self.ctn.exec_run("supervisorctl status") - try: - out = res.output - except AttributeError: - out = res - 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: - raise ValueError(out) - - time.sleep(1) - - def restart(self): - self.ctn.restart() - - def init_asicdb_validator(self): - self.asicdb = AsicDbValidator(self) - - def runcmd(self, cmd): - res = self.ctn.exec_run(cmd) - try: - exitcode = res.exit_code - out = res.output - except AttributeError: - exitcode = 0 - out = res - return (exitcode, out) - - def copy_file(self, path, filename): - tarstr = StringIO.StringIO() - tar = tarfile.open(fileobj=tarstr, mode="w") - tar.add(filename, os.path.basename(filename)) - tar.close() - self.ctn.exec_run("mkdir -p %s" % path) - self.ctn.put_archive(path, tarstr.getvalue()) - tarstr.close() - -@pytest.yield_fixture(scope="module") -def dvs(request): - name = request.config.getoption("--dvsname") - dvs = DockerVirtualSwitch(name) - yield dvs - dvs.destroy() diff --git a/platform/vs/tests/conftest.py b/platform/vs/tests/conftest.py new file mode 120000 index 0000000000..9fef6363db --- /dev/null +++ b/platform/vs/tests/conftest.py @@ -0,0 +1 @@ +../../../src/sonic-swss/tests/conftest.py \ No newline at end of file diff --git a/platform/vs/tests/teamd/test_portchannel.py b/platform/vs/tests/teamd/test_portchannel.py index 7ce7fc6c41..3bc601152c 100644 --- a/platform/vs/tests/teamd/test_portchannel.py +++ b/platform/vs/tests/teamd/test_portchannel.py @@ -3,7 +3,7 @@ import time import re import json -def test_PortChannel(dvs): +def test_PortChannel(dvs, testlog): appldb = swsscommon.DBConnector(0, dvs.redis_sock, 0) statdb = swsscommon.DBConnector(6, dvs.redis_sock, 0)