From eef4c427eb7038d8e9cb15ab30e3d8aabe7d863b Mon Sep 17 00:00:00 2001 From: Cong Hou Date: Tue, 22 Nov 2022 11:00:15 +0800 Subject: [PATCH] Use ptf_runner in qos sai test and fdb mac expire test --- tests/fdb/test_fdb_mac_expire.py | 29 ++-- tests/ptf_runner.py | 15 +- tests/qos/qos_sai_base.py | 277 +++++++++++++++---------------- 3 files changed, 154 insertions(+), 167 deletions(-) diff --git a/tests/fdb/test_fdb_mac_expire.py b/tests/fdb/test_fdb_mac_expire.py index 7b6371db3e3..4f340f46c1f 100644 --- a/tests/fdb/test_fdb_mac_expire.py +++ b/tests/fdb/test_fdb_mac_expire.py @@ -3,7 +3,8 @@ import time from tests.common.helpers.assertions import pytest_assert -from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # lgtm [py/unused-import] +from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # noqa F401 # lgtm [py/unused-import] +from tests.ptf_runner import ptf_runner pytestmark = [ pytest.mark.topology('t0', 'm0', 'mx') @@ -13,6 +14,8 @@ DISABLE_REFRESH = "disable_refresh" REFRESH_DEST_MAC = "refresh_with_dest_mac" + + class TestFdbMacExpire: """ TestFdbMacExpire Verifies FDb aging timer is respected @@ -90,24 +93,14 @@ def __runPtfTest(self, ptfhost, testCase='', testParams={}): RunAnsibleModuleFail if ptf test fails """ logger.info("Running PTF test case '{0}' on '{1}'".format(testCase, ptfhost.hostname)) - ptfhost.shell(argv=[ - "/root/env-python3/bin/ptf", - "--test-dir", - "ptftests/py3", - testCase, - "--platform-dir", + ptf_runner( + ptfhost, "ptftests", - "--platform", - "remote", - "-t", - ";".join(["{0}={1}".format(k, repr(v)) for k, v in testParams.items()]), - "--relax", - "--debug", - "info", - "--log-file", - "/tmp/{0}".format(testCase) - ], - chdir = "/root", + testCase, + platform_dir="ptftests", + params=testParams, + log_file="/tmp/{0}".format(testCase), + is_python3=True ) @pytest.fixture(scope="class", autouse=True) diff --git a/tests/ptf_runner.py b/tests/ptf_runner.py index a37bbacc942..9c5621f259a 100644 --- a/tests/ptf_runner.py +++ b/tests/ptf_runner.py @@ -25,9 +25,10 @@ def ptf_collect(host, log_file): host.fetch(src=pcap_file, dest=filename_pcap, flat=True, fail_on_missing=False) allure.attach.file(filename_pcap, 'ptf_pcap: ' + filename_pcap, allure.attachment_type.PCAP) + def ptf_runner(host, testdir, testname, platform_dir=None, params={}, platform="remote", qlen=0, relax=True, debug_level="info", - socket_recv_size=None, log_file=None, device_sockets=[], timeout=0, + socket_recv_size=None, log_file=None, device_sockets=[], timeout=0, custom_options="", module_ignore_errors=False, is_python3=False): # Call virtual env ptf for migrated py3 scripts. # ptf will load all scripts under ptftests, it will throw error for py2 scripts. @@ -37,9 +38,9 @@ def ptf_runner(host, testdir, testname, platform_dir=None, params={}, if path_exists["stat"]["exists"]: cmd = "/root/env-python3/bin/ptf --test-dir {} {}".format(testdir+'/py3', testname) else: - error_msg = "Virtual environment for Python3 /root/env-python3/bin/ptf doesn't exist.\nPlease check and update docker-ptf image, make sure to use the correct one." - logger.error("Exception caught while executing case: {}. Error message: {}"\ - .format(testname, error_msg)) + error_msg = "Virtual environment for Python3 /root/env-python3/bin/ptf doesn't exist.\n" \ + "Please check and update docker-ptf image, make sure to use the correct one." + logger.error("Exception caught while executing case: {}. Error message: {}".format(testname, error_msg)) raise Exception(error_msg) else: cmd = "ptf --test-dir {} {}".format(testdir, testname) @@ -75,6 +76,9 @@ def ptf_runner(host, testdir, testname, platform_dir=None, params={}, if timeout: cmd += " --test-case-timeout {}".format(int(timeout)) + if custom_options: + cmd += " " + custom_options + if hasattr(host, "macsec_enabled") and host.macsec_enabled: if not is_python3: logger.error("MACsec is only available in Python3") @@ -95,7 +99,6 @@ def ptf_runner(host, testdir, testname, platform_dir=None, params={}, ptf_collect(host, log_file) traceback_msg = traceback.format_exc() allure.attach(traceback_msg, 'ptf_runner_exception_traceback', allure.attachment_type.TEXT) - logger.error("Exception caught while executing case: {}. Error message: {}"\ - .format(testname, traceback_msg)) + logger.error("Exception caught while executing case: {}. Error message: {}".format(testname, traceback_msg)) raise Exception return True diff --git a/tests/qos/qos_sai_base.py b/tests/qos/qos_sai_base.py index 59feb956b6a..6272fdfebb9 100644 --- a/tests/qos/qos_sai_base.py +++ b/tests/qos/qos_sai_base.py @@ -3,19 +3,25 @@ import pytest import re import yaml +import random +import os +import sys -from tests.common.fixtures.ptfhost_utils import ptf_portmap_file # lgtm[py/unused-import] +from tests.common.fixtures.ptfhost_utils import ptf_portmap_file # noqa F401 from tests.common.helpers.assertions import pytest_assert, pytest_require from tests.common.mellanox_data import is_mellanox_device as isMellanoxDevice -from tests.common.dualtor.dual_tor_utils import upper_tor_host,lower_tor_host,dualtor_ports -from tests.common.dualtor.mux_simulator_control import toggle_all_simulator_ports, get_mux_status, check_mux_status, validate_check_result -from tests.common.dualtor.constants import UPPER_TOR, LOWER_TOR +#from tests.common.dualtor.dual_tor_utils import upper_tor_host, lower_tor_host, dualtor_ports # noqa F401 +from tests.common.dualtor.mux_simulator_control \ + import toggle_all_simulator_ports, get_mux_status, check_mux_status, validate_check_result # noqa F401 +from tests.common.dualtor.constants import UPPER_TOR, LOWER_TOR # noqa F401 from tests.common.utilities import check_qos_db_fv_reference_with_table -from tests.common.fixtures.duthost_utils import dut_qos_maps, separated_dscp_to_tc_map_on_uplink +from tests.common.fixtures.duthost_utils import dut_qos_maps, separated_dscp_to_tc_map_on_uplink # noqa F401 from tests.common.utilities import wait_until +from tests.ptf_runner import ptf_runner logger = logging.getLogger(__name__) + class QosBase: """ Common APIs @@ -35,7 +41,7 @@ class QosBase: def isBufferInApplDb(self, dut_asic): if not self.buffer_model_initialized: self.buffer_model = dut_asic.run_redis_cmd( - argv = [ + argv=[ "redis-cli", "-n", "4", "hget", "DEVICE_METADATA|localhost", "buffer_model" ] @@ -43,8 +49,7 @@ def isBufferInApplDb(self, dut_asic): self.buffer_model_initialized = True logger.info( - "Buffer model is {}, buffer tables will be fetched from {}". - format( + "Buffer model is {}, buffer tables will be fetched from {}".format( self.buffer_model or "not defined", "APPL_DB" if self.buffer_model else "CONFIG_DB" ) @@ -79,35 +84,22 @@ def runPtfTest(self, ptfhost, testCase='', testParams={}): Raises: RunAnsibleModuleFail if ptf test fails """ - params = [ - "/root/env-python3/bin/ptf", - "--test-dir", - "saitests/py3", - testCase, - "--platform-dir", - "ptftests", - "--platform", - "remote", - "-t", - ";".join(["{}={}".format(k, repr(v)) for k, v in testParams.items()]), - "--qlen", - "10000", - "--disable-ipv6", - "--disable-vxlan", - "--disable-geneve", - "--disable-erspan", - "--disable-mpls", - "--disable-nvgre", - "--log-file", - "/tmp/{0}.log".format(testCase), - "--test-case-timeout", - "600" - ] - result = ptfhost.shell( - argv=params, - chdir="/root", - ) - pytest_assert(result["rc"] == 0, "Failed when running test '{0}'".format(testCase)) + custom_options = " --disable-ipv6 --disable-vxlan --disable-geneve" \ + " --disable-erspan --disable-mpls --disable-nvgre" + ptf_runner( + ptfhost, + "saitests", + testCase, + platform_dir="ptftests", + params=testParams, + log_file="/tmp/{0}.log".format(testCase), + qlen=10000, + is_python3=True, + relax=False, + timeout=600, + custom_options=custom_options + ) + class QosSaiBase(QosBase): """ @@ -132,16 +124,16 @@ def __computeBufferThreshold(self, dut_asic, bufferProfile): else: db = "4" keystr = "BUFFER_POOL|" - if check_qos_db_fv_reference_with_table(dut_asic) == True: + if check_qos_db_fv_reference_with_table(dut_asic): pool = bufferProfile["pool"].encode("utf-8").translate(None, "[]") else: pool = keystr + bufferProfile["pool"].encode("utf-8") bufferSize = int( dut_asic.run_redis_cmd( - argv = ["redis-cli", "-n", db, "HGET", pool, "size"] + argv=["redis-cli", "-n", db, "HGET", pool, "size"] )[0] ) - bufferScale = 2**float(bufferProfile["dynamic_th"]) + bufferScale = 2 ** float(bufferProfile["dynamic_th"]) bufferScale /= (bufferScale + 1) bufferProfile.update( {"static_th": int(bufferProfile["size"]) + int(bufferScale * bufferSize)} @@ -158,20 +150,20 @@ def __updateVoidRoidParams(self, dut_asic, bufferProfile): Returns: Updates bufferProfile with VOID/ROID obtained from Redis db """ - if check_qos_db_fv_reference_with_table(dut_asic) == True: + if check_qos_db_fv_reference_with_table(dut_asic): if self.isBufferInApplDb(dut_asic): bufferPoolName = bufferProfile["pool"].encode("utf-8").translate( - None, "[]").replace("BUFFER_POOL_TABLE:",'' - ) + None, "[]").replace("BUFFER_POOL_TABLE:", '' + ) else: bufferPoolName = bufferProfile["pool"].encode("utf-8").translate( - None, "[]").replace("BUFFER_POOL|",'' - ) + None, "[]").replace("BUFFER_POOL|", '' + ) else: bufferPoolName = bufferProfile["pool"].encode("utf-8") bufferPoolVoid = dut_asic.run_redis_cmd( - argv = [ + argv=[ "redis-cli", "-n", "2", "HGET", "COUNTERS_BUFFER_POOL_NAME_MAP", bufferPoolName ] @@ -179,8 +171,8 @@ def __updateVoidRoidParams(self, dut_asic, bufferProfile): bufferProfile.update({"bufferPoolVoid": bufferPoolVoid}) bufferPoolRoid = dut_asic.run_redis_cmd( - argv = ["redis-cli", "-n", "1", "HGET", "VIDTORID", bufferPoolVoid] - )[0].encode("utf-8").replace("oid:",'') + argv=["redis-cli", "-n", "1", "HGET", "VIDTORID", bufferPoolVoid] + )[0].encode("utf-8").replace("oid:", '') bufferProfile.update({"bufferPoolRoid": bufferPoolRoid}) def __getBufferProfile(self, request, dut_asic, os_version, table, port, priorityGroup): @@ -207,16 +199,16 @@ def __getBufferProfile(self, request, dut_asic, os_version, table, port, priorit keystr = "{0}|{1}|{2}".format(table, port, priorityGroup) bufkeystr = "BUFFER_PROFILE|" - if check_qos_db_fv_reference_with_table(dut_asic) == True: + if check_qos_db_fv_reference_with_table(dut_asic): bufferProfileName = dut_asic.run_redis_cmd( - argv = ["redis-cli", "-n", db, "HGET", keystr, "profile"] + argv=["redis-cli", "-n", db, "HGET", keystr, "profile"] )[0].encode("utf-8").translate(None, "[]") else: bufferProfileName = bufkeystr + dut_asic.run_redis_cmd( - argv = ["redis-cli", "-n", db, "HGET", keystr, "profile"])[0].encode("utf-8") + argv=["redis-cli", "-n", db, "HGET", keystr, "profile"])[0].encode("utf-8") result = dut_asic.run_redis_cmd( - argv = ["redis-cli", "-n", db, "HGETALL", bufferProfileName] + argv=["redis-cli", "-n", db, "HGETALL", bufferProfileName] ) it = iter(result) bufferProfile = dict(zip(it, it)) @@ -258,7 +250,7 @@ def __getSharedHeadroomPoolSize(self, request, dut_asic): db = "4" keystr = "BUFFER_POOL|ingress_lossless_pool" result = dut_asic.run_redis_cmd( - argv = ["redis-cli", "-n", db, "HGETALL", keystr] + argv=["redis-cli", "-n", db, "HGETALL", keystr] ) it = iter(result) ingressLosslessPool = dict(zip(it, it)) @@ -276,9 +268,9 @@ def __getEcnWredParam(self, dut_asic, table, port): Returns: wredProfile (dict): Map of ECN/WRED attributes """ - if check_qos_db_fv_reference_with_table(dut_asic) == True: + if check_qos_db_fv_reference_with_table(dut_asic): wredProfileName = dut_asic.run_redis_cmd( - argv = [ + argv=[ "redis-cli", "-n", "4", "HGET", "{0}|{1}|{2}".format(table, port, self.TARGET_QUEUE_WRED), "wred_profile" @@ -286,7 +278,7 @@ def __getEcnWredParam(self, dut_asic, table, port): )[0].encode("utf-8").translate(None, "[]") else: wredProfileName = "WRED_PROFILE|" + dut_asic.run_redis_cmd( - argv = [ + argv=[ "redis-cli", "-n", "4", "HGET", "{0}|{1}|{2}".format(table, port, self.TARGET_QUEUE_WRED), "wred_profile" @@ -294,7 +286,7 @@ def __getEcnWredParam(self, dut_asic, table, port): )[0].encode("utf-8") result = dut_asic.run_redis_cmd( - argv = ["redis-cli", "-n", "4", "HGETALL", wredProfileName] + argv=["redis-cli", "-n", "4", "HGETALL", wredProfileName] ) it = iter(result) wredProfile = dict(zip(it, it)) @@ -312,7 +304,7 @@ def __getWatermarkStatus(self, dut_asic): watermarkStatus (str): Watermark status """ watermarkStatus = dut_asic.run_redis_cmd( - argv = [ + argv=[ "redis-cli", "-n", "4", "HGET", "FLEX_COUNTER_TABLE|QUEUE_WATERMARK", "FLEX_COUNTER_STATUS" ] @@ -332,23 +324,23 @@ def __getSchedulerParam(self, dut_asic, port, queue): Returns: SchedulerParam (dict): Map of scheduler parameters """ - if check_qos_db_fv_reference_with_table(dut_asic) == True: + if check_qos_db_fv_reference_with_table(dut_asic): schedProfile = dut_asic.run_redis_cmd( - argv = [ + argv=[ "redis-cli", "-n", "4", "HGET", "QUEUE|{0}|{1}".format(port, queue), "scheduler" ] )[0].encode("utf-8").translate(None, "[]") else: schedProfile = "SCHEDULER|" + dut_asic.run_redis_cmd( - argv = [ + argv=[ "redis-cli", "-n", "4", "HGET", "QUEUE|{0}|{1}".format(port, queue), "scheduler" ] )[0].encode("utf-8") schedWeight = dut_asic.run_redis_cmd( - argv = ["redis-cli", "-n", "4", "HGET", schedProfile, "weight"] + argv=["redis-cli", "-n", "4", "HGET", schedProfile, "weight"] )[0].encode("utf-8") return {"schedProfile": schedProfile, "schedWeight": schedWeight} @@ -365,14 +357,14 @@ def __assignTestPortIps(self, mgFacts): """ dutPortIps = {} if len(mgFacts["minigraph_vlans"]) > 0: - #TODO: handle the case when there are multiple vlans + # TODO: handle the case when there are multiple vlans testVlan = next(iter(mgFacts["minigraph_vlans"])) testVlanMembers = mgFacts["minigraph_vlans"][testVlan]["members"] testVlanIp = None for vlan in mgFacts["minigraph_vlan_interfaces"]: if mgFacts["minigraph_vlans"][testVlan]["name"] in vlan["attachto"]: - testVlanIp = ipaddress.ip_address(unicode(vlan["addr"])) + testVlanIp = ipaddress.ip_address(unicode(vlan["addr"])) # noqa F821 break pytest_assert(testVlanIp, "Failed to obtain vlan IP") @@ -380,7 +372,7 @@ def __assignTestPortIps(self, mgFacts): if 'type' in mgFacts["minigraph_vlans"][testVlan]: vlan_type = mgFacts["minigraph_vlans"][testVlan]['type'] if vlan_type is not None and "Tagged" in vlan_type: - vlan_id = mgFacts["minigraph_vlans"][testVlan]['vlanid'] + vlan_id = mgFacts["minigraph_vlans"][testVlan]['vlanid'] for i in range(len(testVlanMembers)): portIndex = mgFacts["minigraph_ptf_indices"][testVlanMembers[i]] @@ -411,7 +403,7 @@ def __buildTestPorts(self, request, testPortIds, testPortIps, src_port_ids, dst_ pytest_assert( len(set(testPortIds).intersection(set(dst_port_ids))) == len(set(dst_port_ids)), "Dest port id passed in qos.yml not valid" - ) + ) dstPorts = dst_port_ids elif len(testPortIds) >= 4: dstPorts = [0, 2, 3] @@ -425,7 +417,7 @@ def __buildTestPorts(self, request, testPortIds, testPortIps, src_port_ids, dst_ pytest_assert( len(set(testPortIds).intersection(set(src_port_ids))) == len(set(src_port_ids)), "Source port id passed in qos.yml not valid" - ) + ) # To verify ingress lossless speed/cable-length randomize the source port. srcPorts = [random.choice(src_port_ids)] else: @@ -444,8 +436,7 @@ def __buildTestPorts(self, request, testPortIds, testPortIps, src_port_ids, dst_ ) ) - - #TODO: Randomize port selection + # TODO: Randomize port selection dstPort = dstPorts[0] if dst_port_ids else testPortIds[dstPorts[0]] dstVlan = testPortIps[dstPort]['vlan_id'] if 'vlan_id' in testPortIps[dstPort] else None dstPort2 = dstPorts[1] if dst_port_ids else testPortIds[dstPorts[1]] @@ -471,9 +462,8 @@ def __buildTestPorts(self, request, testPortIds, testPortIps, src_port_ids, dst_ @pytest.fixture(scope='class', autouse=True) def dutConfig( - self, request, duthosts, enum_rand_one_per_hwsku_frontend_hostname, - enum_frontend_asic_index, lower_tor_host, tbinfo, dualtor_ports, dut_qos_maps - ): + self, request, duthosts, enum_rand_one_per_hwsku_frontend_hostname, + enum_frontend_asic_index, lower_tor_host, tbinfo, dualtor_ports, dut_qos_maps): # noqa F811 """ Build DUT host config pertaining to QoS SAI tests @@ -517,7 +507,7 @@ def dutConfig( dutLagInterfaces.append(mgFacts["minigraph_ptf_indices"][intf]) testPortIds = set(mgFacts["minigraph_ptf_indices"][port] - for port in mgFacts["minigraph_ports"].keys()) + for port in mgFacts["minigraph_ports"].keys()) testPortIds -= set(dutLagInterfaces) if isMellanoxDevice(duthost): # The last port is used for up link from DUT switch @@ -548,7 +538,7 @@ def dutConfig( elif topo in self.SUPPORTED_T1_TOPOS: use_separated_upkink_dscp_tc_map = separated_dscp_to_tc_map_on_uplink(duthost, dut_qos_maps) - for iface,addr in dut_asic.get_active_ip_interfaces(tbinfo).items(): + for iface, addr in dut_asic.get_active_ip_interfaces(tbinfo).items(): vlan_id = None if iface.startswith("Ethernet"): if "." in iface: @@ -581,7 +571,7 @@ def dutConfig( testPortIds = sorted(dutPortIps.keys()) elif tbinfo["topo"]["type"] == "t2": - for iface,addr in dut_asic.get_active_ip_interfaces(tbinfo).items(): + for iface, addr in dut_asic.get_active_ip_interfaces(tbinfo).items(): vlan_id = None if iface.startswith("Ethernet") and ("Ethernet-Rec" not in iface): if "." in iface: @@ -598,7 +588,7 @@ def dutConfig( portIndex = mgFacts["minigraph_ptf_indices"][portName] portIpMap = {'peer_addr': addr["peer_ipv4"]} dutPortIps.update({portIndex: portIpMap}) - + testPortIds = sorted(dutPortIps.keys()) # restore currently assigned IPs @@ -633,10 +623,10 @@ def dutConfig( src_port_ids = None dst_port_ids = None try: - if "src_port_ids" in qosConfigs['qos_params'][dutAsic][dutTopo]: + if "src_port_ids" in qosConfigs['qos_params'][dutAsic][dutTopo]: src_port_ids = qosConfigs['qos_params'][dutAsic][dutTopo]["src_port_ids"] - if "dst_port_ids" in qosConfigs['qos_params'][dutAsic][dutTopo]: + if "dst_port_ids" in qosConfigs['qos_params'][dutAsic][dutTopo]: dst_port_ids = qosConfigs['qos_params'][dutAsic][dutTopo]["dst_port_ids"] except KeyError: pass @@ -654,7 +644,7 @@ def dutConfig( "downlink_port_ids": downlinkPortIds, "downlink_port_ips": downlinkPortIps, "downlink_port_names": downlinkPortNames - }) + }) dutinterfaces = {} for port, index in mgFacts["minigraph_ptf_indices"].items(): if 'Ethernet-Rec' not in port and 'Ethernet-IB' not in port: @@ -665,17 +655,17 @@ def dutConfig( "testPortIps": testPortIps, "testPorts": testPorts, "qosConfigs": qosConfigs, - "dutAsic" : dutAsic, - "dutTopo" : dutTopo, - "dutInstance" : duthost, - "dualTor" : request.config.getoption("--qos_dual_tor"), - "dualTorScenario" : len(dualtor_ports) != 0 + "dutAsic": dutAsic, + "dutTopo": dutTopo, + "dutInstance": duthost, + "dualTor": request.config.getoption("--qos_dual_tor"), + "dualTorScenario": len(dualtor_ports) != 0 } @pytest.fixture(scope='class') def ssh_tunnel_to_syncd_rpc( - self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_frontend_asic_index, - swapSyncd, tbinfo, lower_tor_host + self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_frontend_asic_index, + swapSyncd, tbinfo, lower_tor_host ): if 'dualtor' in tbinfo['topo']['name']: duthost = lower_tor_host @@ -690,7 +680,8 @@ def ssh_tunnel_to_syncd_rpc( @pytest.fixture(scope='class') def updateIptables( - self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_frontend_asic_index, swapSyncd, tbinfo, lower_tor_host + self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_frontend_asic_index, swapSyncd, tbinfo, + lower_tor_host ): """ Update iptables on DUT host with drop rule for BGP SYNC packets @@ -708,7 +699,7 @@ def updateIptables( duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] dut_asic = duthost.asic_instance(enum_frontend_asic_index) - ipVersions = [{"ip_version": "ipv4"}, {"ip_version": "ipv6"}] + ipVersions = [{"ip_version": "ipv4"}, {"ip_version": "ipv6"}] logger.info("Add ip[6]tables rule to drop BGP SYN Packet from peer so that we do not ACK back") for ipVersion in ipVersions: @@ -722,10 +713,9 @@ def updateIptables( @pytest.fixture(scope='class') def stopServices( - self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_frontend_asic_index, - swapSyncd, enable_container_autorestart, disable_container_autorestart, - tbinfo, upper_tor_host, lower_tor_host, toggle_all_simulator_ports - ): + self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_frontend_asic_index, + swapSyncd, enable_container_autorestart, disable_container_autorestart, + tbinfo, upper_tor_host, lower_tor_host, toggle_all_simulator_ports): # noqa F811 """ Stop services (lldp-syncs, lldpd, bgpd) on DUT host prior to test start @@ -743,6 +733,7 @@ def stopServices( duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname] dut_asic = duthost.asic_instance(enum_frontend_asic_index) + def updateDockerService(host, docker="", action="", service=""): """ Helper function to update docker services @@ -775,10 +766,10 @@ def updateDockerService(host, docker="", action="", service=""): try: duthost.shell("ls %s" % file) - duthost.shell("sudo cp {} {}".format(file,backup_file)) + duthost.shell("sudo cp {} {}".format(file, backup_file)) duthost.shell("sudo rm {}".format(file)) duthost.shell("sudo touch {}".format(file)) - except: + except Exception: pytest.skip('file {} not found'.format(file)) duthost_upper.shell('sudo config feature state mux disabled') @@ -787,8 +778,8 @@ def updateDockerService(host, docker="", action="", service=""): services = [ {"docker": dut_asic.get_docker_name("lldp"), "service": "lldp-syncd"}, {"docker": dut_asic.get_docker_name("lldp"), "service": "lldpd"}, - {"docker": dut_asic.get_docker_name("bgp"), "service": "bgpd"}, - {"docker": dut_asic.get_docker_name("bgp"), "service": "bgpmon"}, + {"docker": dut_asic.get_docker_name("bgp"), "service": "bgpd"}, + {"docker": dut_asic.get_docker_name("bgp"), "service": "bgpmon"}, ] feature_list = ['lldp', 'bgp', 'syncd', 'swss'] @@ -806,23 +797,22 @@ def updateDockerService(host, docker="", action="", service=""): """ Start mux conatiner for dual ToR """ if 'dualtor' in tbinfo['topo']['name']: - try: - duthost.shell("ls %s" % backup_file) - duthost.shell("sudo cp {} {}".format(backup_file,file)) - duthost.shell("sudo chmod +x {}".format(file)) - duthost.shell("sudo rm {}".format(backup_file)) - except: - pytest.skip('file {} not found'.format(backup_file)) - - duthost.shell('sudo config feature state mux enabled') - duthost_upper.shell('sudo config feature state mux enabled') - logger.info("Start mux container for dual ToR testbed") + try: + duthost.shell("ls %s" % backup_file) + duthost.shell("sudo cp {} {}".format(backup_file, file)) + duthost.shell("sudo chmod +x {}".format(file)) + duthost.shell("sudo rm {}".format(backup_file)) + except Exception: + pytest.skip('file {} not found'.format(backup_file)) + + duthost.shell('sudo config feature state mux enabled') + duthost_upper.shell('sudo config feature state mux enabled') + logger.info("Start mux container for dual ToR testbed") enable_container_autorestart(duthost, testcase="test_qos_sai", feature_list=feature_list) if 'dualtor' in tbinfo['topo']['name']: enable_container_autorestart(duthost_upper, testcase="test_qos_sai", feature_list=feature_list) - @pytest.fixture(autouse=True) def updateLoganalyzerExceptions(self, enum_rand_one_per_hwsku_frontend_hostname, loganalyzer): """ @@ -838,21 +828,22 @@ def updateLoganalyzerExceptions(self, enum_rand_one_per_hwsku_frontend_hostname, if loganalyzer: ignoreRegex = [ ".*ERR monit.*'lldpd_monitor' process is not running.*", - ".*ERR monit.* 'lldp\|lldpd_monitor' status failed.*-- 'lldpd:' is not running.*", + ".*ERR monit.* 'lldp\\|lldpd_monitor' status failed.*-- 'lldpd:' is not running.*", ".*ERR monit.*'lldp_syncd' process is not running.*", - ".*ERR monit.*'lldp\|lldp_syncd' status failed.*-- 'python.* -m lldp_syncd' is not running.*", + ".*ERR monit.*'lldp\\|lldp_syncd' status failed.*-- 'python.* -m lldp_syncd' is not running.*", ".*ERR monit.*'bgpd' process is not running.*", - ".*ERR monit.*'bgp\|bgpd' status failed.*-- '/usr/lib/frr/bgpd' is not running.*", + ".*ERR monit.*'bgp\\|bgpd' status failed.*-- '/usr/lib/frr/bgpd' is not running.*", ".*ERR monit.*'bgpcfgd' process is not running.*", - ".*ERR monit.*'bgp\|bgpcfgd' status failed.*-- '/usr/bin/python.* /usr/local/bin/bgpcfgd' is not running.*", + ".*ERR monit.*'bgp\\|bgpcfgd' status failed.*-- " + "'/usr/bin/python.* /usr/local/bin/bgpcfgd' is not running.*", ".*ERR syncd#syncd:.*brcm_sai_set_switch_attribute:.*updating switch mac addr failed.*", - ".*ERR monit.*'bgp\|bgpmon' status failed.*'/usr/bin/python.* /usr/local/bin/bgpmon' is not running.*", - ".*ERR monit.*bgp\|fpmsyncd.*status failed.*NoSuchProcess process no longer exists.*", + ".*ERR monit.*'bgp\\|bgpmon' status failed.*'/usr/bin/python.* /usr/local/bin/bgpmon' is not running.*", + ".*ERR monit.*bgp\\|fpmsyncd.*status failed.*NoSuchProcess process no longer exists.*", ".*WARNING syncd#SDK:.*check_attribs_metadata: Not implemented attribute.*", ".*WARNING syncd#SDK:.*sai_set_attribute: Failed attribs check, key:Switch ID.*", ".*WARNING syncd#SDK:.*check_rate: Set max rate to 0.*" @@ -863,7 +854,7 @@ def updateLoganalyzerExceptions(self, enum_rand_one_per_hwsku_frontend_hostname, @pytest.fixture(scope='class', autouse=True) def disablePacketAging( - self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, stopServices + self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, stopServices ): """ disable packet aging on DUT host @@ -892,10 +883,10 @@ def disablePacketAging( @pytest.fixture(scope='class', autouse=True) def dutQosConfig( - self, duthosts, enum_frontend_asic_index, enum_rand_one_per_hwsku_frontend_hostname, - dutConfig, ingressLosslessProfile, ingressLossyProfile, - egressLosslessProfile, egressLossyProfile, sharedHeadroomPoolSize, - tbinfo, lower_tor_host + self, duthosts, enum_frontend_asic_index, enum_rand_one_per_hwsku_frontend_hostname, + dutConfig, ingressLosslessProfile, ingressLossyProfile, + egressLosslessProfile, egressLossyProfile, sharedHeadroomPoolSize, + tbinfo, lower_tor_host ): """ Prepares DUT host QoS configuration @@ -921,9 +912,9 @@ def dutQosConfig( logger.info("Lossless Buffer profile selected is {}".format(profileName)) if self.isBufferInApplDb(dut_asic): - profile_pattern = "^BUFFER_PROFILE_TABLE\:pg_lossless_(.*)_profile$" + profile_pattern = "^BUFFER_PROFILE_TABLE\\:pg_lossless_(.*)_profile$" else: - profile_pattern = "^BUFFER_PROFILE\|pg_lossless_(.*)_profile" + profile_pattern = "^BUFFER_PROFILE\\|pg_lossless_(.*)_profile" m = re.search(profile_pattern, profileName) pytest_assert(m.group(1), "Cannot find port speed/cable length") @@ -948,7 +939,7 @@ def dutQosConfig( egressLossyProfile, sharedHeadroomPoolSize, dutConfig["dualTor"] - ) + ) qosParams = qpm.run() else: qosParams = qosConfigs['qos_params'][dutAsic][dutTopo] @@ -959,8 +950,8 @@ def dutQosConfig( @pytest.fixture(scope='class') def releaseAllPorts( - self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, dutTestParams, - updateIptables, ssh_tunnel_to_syncd_rpc + self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, ptfhost, dutTestParams, + updateIptables, ssh_tunnel_to_syncd_rpc ): """ Release all paused ports prior to running QoS SAI test cases @@ -1049,8 +1040,8 @@ def handleFdbAging(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname): @pytest.fixture(scope='class', autouse=True) def populateArpEntries( - self, duthosts, enum_frontend_asic_index, enum_rand_one_per_hwsku_frontend_hostname, - ptfhost, dutTestParams, dutConfig, releaseAllPorts, handleFdbAging, tbinfo, lower_tor_host + self, duthosts, enum_frontend_asic_index, enum_rand_one_per_hwsku_frontend_hostname, + ptfhost, dutTestParams, dutConfig, releaseAllPorts, handleFdbAging, tbinfo, lower_tor_host ): """ Update ARP entries of QoS SAI test ports @@ -1107,8 +1098,8 @@ def dut_disable_ipv6(self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, @pytest.fixture(scope='class', autouse=True) def sharedHeadroomPoolSize( - self, request, duthosts, enum_frontend_asic_index, - enum_rand_one_per_hwsku_frontend_hostname, tbinfo, lower_tor_host + self, request, duthosts, enum_frontend_asic_index, + enum_rand_one_per_hwsku_frontend_hostname, tbinfo, lower_tor_host ): """ Retreives shared headroom pool size @@ -1133,8 +1124,8 @@ def sharedHeadroomPoolSize( @pytest.fixture(scope='class', autouse=True) def ingressLosslessProfile( - self, request, duthosts, enum_frontend_asic_index, - enum_rand_one_per_hwsku_frontend_hostname, dutConfig, tbinfo, lower_tor_host, dualtor_ports + self, request, duthosts, enum_frontend_asic_index, + enum_rand_one_per_hwsku_frontend_hostname, dutConfig, tbinfo, lower_tor_host, dualtor_ports ): """ Retreives ingress lossless profile @@ -1172,8 +1163,8 @@ def ingressLosslessProfile( @pytest.fixture(scope='class', autouse=True) def ingressLossyProfile( - self, request, duthosts, enum_frontend_asic_index, - enum_rand_one_per_hwsku_frontend_hostname, dutConfig, tbinfo, lower_tor_host + self, request, duthosts, enum_frontend_asic_index, + enum_rand_one_per_hwsku_frontend_hostname, dutConfig, tbinfo, lower_tor_host ): """ Retreives ingress lossy profile @@ -1204,8 +1195,8 @@ def ingressLossyProfile( @pytest.fixture(scope='class', autouse=True) def egressLosslessProfile( - self, request, duthosts, enum_frontend_asic_index, - enum_rand_one_per_hwsku_frontend_hostname, dutConfig, tbinfo, lower_tor_host, dualtor_ports + self, request, duthosts, enum_frontend_asic_index, + enum_rand_one_per_hwsku_frontend_hostname, dutConfig, tbinfo, lower_tor_host, dualtor_ports ): """ Retreives egress lossless profile @@ -1243,8 +1234,8 @@ def egressLosslessProfile( @pytest.fixture(scope='class', autouse=True) def egressLossyProfile( - self, request, duthosts, enum_frontend_asic_index, - enum_rand_one_per_hwsku_frontend_hostname, dutConfig, tbinfo, lower_tor_host, dualtor_ports + self, request, duthosts, enum_frontend_asic_index, + enum_rand_one_per_hwsku_frontend_hostname, dutConfig, tbinfo, lower_tor_host, dualtor_ports ): """ Retreives egress lossy profile @@ -1284,7 +1275,7 @@ def egressLossyProfile( def losslessSchedProfile( self, duthosts, enum_frontend_asic_index, enum_rand_one_per_hwsku_frontend_hostname, dutConfig, tbinfo, lower_tor_host - ): + ): """ Retreives lossless scheduler profile @@ -1309,8 +1300,8 @@ def losslessSchedProfile( @pytest.fixture(scope='class') def lossySchedProfile( - self, duthosts, enum_frontend_asic_index, enum_rand_one_per_hwsku_frontend_hostname, - dutConfig, tbinfo, lower_tor_host + self, duthosts, enum_frontend_asic_index, enum_rand_one_per_hwsku_frontend_hostname, + dutConfig, tbinfo, lower_tor_host ): """ Retreives lossy scheduler profile @@ -1336,8 +1327,8 @@ def lossySchedProfile( @pytest.fixture def updateSchedProfile( - self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_frontend_asic_index, - dutQosConfig, losslessSchedProfile, lossySchedProfile, tbinfo, lower_tor_host + self, duthosts, enum_rand_one_per_hwsku_frontend_hostname, enum_frontend_asic_index, + dutQosConfig, losslessSchedProfile, lossySchedProfile, tbinfo, lower_tor_host ): """ Updates lossless/lossy scheduler profiles @@ -1367,7 +1358,7 @@ def updateRedisSchedParam(schedParam): None """ duthost.asic_instance(enum_frontend_asic_index).run_redis_cmd( - argv = [ + argv=[ "redis-cli", "-n", "4", @@ -1410,7 +1401,7 @@ def updateRedisSchedParam(schedParam): @pytest.fixture def resetWatermark( - self, duthosts, enum_frontend_asic_index, enum_rand_one_per_hwsku_frontend_hostname, tbinfo, lower_tor_host + self, duthosts, enum_frontend_asic_index, enum_rand_one_per_hwsku_frontend_hostname, tbinfo, lower_tor_host ): """ Reset queue watermark