@@ -170,6 +170,54 @@ def filter_ports(all_port_indices, tbinfo):
170170 return host_ptf_ports_all
171171
172172
173+ def get_port_and_portchannel_members (port_name , all_port_indices , duts_minigraph_facts ,
174+ upstream_lc , tbinfo ):
175+ """
176+ Get PTF port indices for a port and all its port channel members (if applicable).
177+
178+ Args:
179+ port_name: The DUT port name to check
180+ all_port_indices: Dictionary mapping PTF port indices to (asic_id, port_name)
181+ duts_minigraph_facts: Minigraph facts containing port channel information
182+ upstream_lc: The upstream line card hostname
183+
184+ Returns:
185+ List of PTF port indices for the port and all its port channel members
186+ """
187+
188+ # for T2(except UT2) topologies, no need to append, as we are already filtering out the whole upstream lc ports
189+ if tbinfo ['topo' ]['type' ] == 't2' and 't2_single_node' not in tbinfo ['topo' ]['name' ]:
190+ return []
191+
192+ # Search all ASICs for port channel information
193+ portchannel_members = [port_name ] # Default is just the single port
194+ found_portchannel = False
195+
196+ for asic_id , asic_data in duts_minigraph_facts [upstream_lc ]:
197+ mg_facts = asic_data
198+ if mg_facts and 'minigraph_portchannels' in mg_facts :
199+ for pc_name , pc_info in mg_facts ['minigraph_portchannels' ].items ():
200+ if port_name in pc_info .get ('members' , []):
201+ portchannel_members = pc_info ['members' ]
202+ logging .info ("Port {} is a member of port channel {} with {} member(s): {}" .format (
203+ port_name , pc_name , len (portchannel_members ), portchannel_members ))
204+ found_portchannel = True
205+ break
206+ if found_portchannel :
207+ break
208+
209+ # Find PTF port indices for all port channel members
210+ ptf_ports_to_filter = []
211+ for member_port in portchannel_members :
212+ for ptf_port , (asic_id , dut_port ) in all_port_indices .items ():
213+ if dut_port == member_port :
214+ ptf_ports_to_filter .append (ptf_port )
215+ logging .info ("Found PTF port {} for port channel member {}" .format (ptf_port , member_port ))
216+ break
217+
218+ return ptf_ports_to_filter
219+
220+
173221def fib_info_files_per_function (duthosts , ptfhost , duts_running_config_facts , duts_minigraph_facts , tbinfo , request ):
174222 """Get FIB info from database and store to text files on PTF host.
175223
@@ -840,8 +888,14 @@ def test_ecmp_group_member_flap(
840888 logging .info ("Shutting down port {}" .format (nh_dut_ports [port_index_to_shut ][1 ]))
841889 duthosts [0 ].shell ("sudo config interface {} shutdown {}" .format (asic_ns , nh_dut_ports [port_index_to_shut ][1 ]))
842890
843- time .sleep (10 ) # Allow time for the state to stabilize
844- filtered_ports .append (nh_ptf_ports [port_index_to_shut ])
891+ time .sleep (60 ) # Allow time for the state to stabilize
892+
893+ # Get all PTF ports for the port and its port channel members (if applicable)
894+ ptf_ports_to_filter = get_port_and_portchannel_members (
895+ nh_dut_ports [port_index_to_shut ][1 ], all_port_indices , duts_minigraph_facts , upstream_lc , tbinfo )
896+
897+ # Add them to filtered_ports
898+ filtered_ports .extend (ptf_ports_to_filter )
845899
846900 # --- Re-run the PTF test after member down ---
847901 logging .info ("Verifying ECMP behavior after member down." )
@@ -885,7 +939,11 @@ def test_ecmp_group_member_flap(
885939
886940 logging .info ("Enabling port {}" .format (nh_dut_ports [port_index_to_shut ][1 ]))
887941 duthosts [0 ].shell ("sudo config interface {} startup {}" .format (asic_ns , nh_dut_ports [port_index_to_shut ][1 ]))
888- filtered_ports .pop ()
942+
943+ # Remove the PTF ports that were added earlier
944+ for ptf_port in ptf_ports_to_filter :
945+ if ptf_port in filtered_ports :
946+ filtered_ports .remove (ptf_port )
889947
890948 time .sleep (60 ) # Allow time for the state to stabilize
891949
0 commit comments