diff --git a/tests/common/devices/multi_asic.py b/tests/common/devices/multi_asic.py index 28774017ad..6fc32137f7 100644 --- a/tests/common/devices/multi_asic.py +++ b/tests/common/devices/multi_asic.py @@ -678,6 +678,28 @@ def get_voq_inband_interfaces(self): ) return voq_inband_interfaces.keys() + def get_portchannel_member(self): + """ + This Function is applicable on packet Chassis, or + any dut that has PORTCHANNEL_MEMBER in config dbs. + Get PORTCHANNEL_MEMBER from config db of all asics. + Returns: + List of [portchannel]. e.g. ["PortChannel101|Ethernet104", "PortChannel01|EthernetBPxx", ...] + {} if VOQ chassis or other dut that doesn't have PORTCHANNEL_MEMBER + """ + if not self.sonichost.is_multi_asic: + return {} + pcs = {} + for asic in self.frontend_asics: + config_facts = self.config_facts( + host=self.hostname, source="running", + namespace=asic.namespace + )['ansible_facts'] + pcs.update( + config_facts.get("PORTCHANNEL_MEMBER", {}) + ) + return pcs.keys() + def run_redis_cmd(self, argv=[], asic_index=DEFAULT_ASIC_ID): """ Wrapper function to call run_redis_cmd on sonic_asic.py diff --git a/tests/route/test_route_flap.py b/tests/route/test_route_flap.py index d1b538aab3..270bba0cf1 100644 --- a/tests/route/test_route_flap.py +++ b/tests/route/test_route_flap.py @@ -197,13 +197,35 @@ def is_dualtor(tbinfo): return "dualtor" in tbinfo["topo"]["name"] -def get_dev_port_and_route(duthost, asichost, dst_prefix_set): - # Get internal bgp ips for later filtering - internal_bgp_ips = duthost.get_internal_bgp_peers().keys() - # Get voq inband interface for later filtering +def get_internal_interfaces(duthost): + """ + This function returns internal interfaces for any + multi-asic dut, including voq/packet chassis + """ + internal_intfs = [] + + # First check for packet chassis, or any dut that has PORTCHANNEL_MEMBER in config db + pcs = duthost.get_portchannel_member() + for pc in pcs: + """ + For packet chassis, 'pcs' looks like: + ["PortChannel101|Ethernet104", "PortChannel01|Ethernet-BPxx",...] + """ + if 'IB' in pc or 'BP' in pc: + internal_intfs.append(pc) + + # Then check for voq chassis: get voq inband interface for later filtering voq_inband_interfaces = duthost.get_voq_inband_interfaces() + internal_intfs.append([voq_inband_interfaces]) + + return internal_intfs + + +def get_dev_port_and_route(duthost, asichost, dst_prefix_set): dev_port = None route_to_ping = None + # Get internal interfaces for later filtering + internal_intfs = get_internal_interfaces(duthost) for dst_prefix in dst_prefix_set: if dev_port: break @@ -219,20 +241,22 @@ def get_dev_port_and_route(duthost, asichost, dst_prefix_set): continue if 'ip' not in per_hop.keys(): continue - if per_hop['ip'] in internal_bgp_ips: - continue - if per_hop['interfaceName'] in voq_inband_interfaces: - continue - if 'IB' in per_hop['interfaceName'] or 'BP' in per_hop['interfaceName']: + if per_hop['interfaceName'] in internal_intfs: continue - dev_port = per_hop['interfaceName'] + port = per_hop['interfaceName'] + neigh = duthost.shell("show ip int | grep -w {}".format(port))['stdout'] + if neigh == '': + logger.info("{} is still internal interface, skipping".format(port)) + else: + dev_port = port break else: dev = json.loads(asichost.run_vtysh(cmd)['stdout']) for per_hop in dev[route_to_ping][0]['nexthops']: if 'interfaceName' not in per_hop.keys(): continue - if per_hop['interfaceName'] in voq_inband_interfaces: + # For chassis, even single-asic linecard could have internal interface + if per_hop['interfaceName'] in internal_intfs: continue if 'IB' in per_hop['interfaceName'] or 'BP' in per_hop['interfaceName']: continue