Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3161,7 +3161,7 @@ qos/test_qos_dscp_mapping.py:
- "asic_type in ['cisco-8000'] and platform.startswith('x86_64-8122_')"
- "asic_type in ['vs']"

qos/test_qos_dscp_mapping.py::TestQoSSaiDSCPQueueMapping_IPIP_Base::test_dscp_to_queue_mapping_pipe_mode:
qos/test_qos_dscp_mapping.py::TestQoSSaiDSCPQueueMapping_IPIP_Base::test_dscp_to_queue_mapping[pipe]:
skip:
reason: "Pipe decap mode not supported due to either SAI or platform limitation / M* topo does not support qos"
conditions_logical_operator: or
Expand All @@ -3170,7 +3170,7 @@ qos/test_qos_dscp_mapping.py::TestQoSSaiDSCPQueueMapping_IPIP_Base::test_dscp_to
- https://github.com/sonic-net/sonic-mgmt/issues/12906
- "topo_type in ['m0', 'mx', 'm1']"

qos/test_qos_dscp_mapping.py::TestQoSSaiDSCPQueueMapping_IPIP_Base::test_dscp_to_queue_mapping_uniform_mode:
qos/test_qos_dscp_mapping.py::TestQoSSaiDSCPQueueMapping_IPIP_Base::test_dscp_to_queue_mapping[uniform]:
skip:
reason: "Uniform decap mode is not supported on Mellanox dualtor testbed due to the mode is pipe to support dscp remapping"
conditions:
Expand Down
41 changes: 32 additions & 9 deletions tests/common/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,19 @@ def find_egress_queue(all_queue_pkts, exp_queue_pkts, tolerance=0.05):
return -1


def handle_queue_stats_output(intf_queue_stats):
queue_stats = []
for prio in range(8):
total_pkts_prio_str = intf_queue_stats.get("UC{}".format(prio)) if intf_queue_stats.get("UC{}".format(prio)) \
is not None else {"totalpacket": "0"}
total_pkts_str = total_pkts_prio_str.get("totalpacket")
if total_pkts_str == "N/A" or total_pkts_str is None:
total_pkts_str = "0"
queue_stats.append(int(total_pkts_str.replace(',', '')))

return queue_stats


def get_egress_queue_pkt_count_all_prio(duthost, port):
"""
Get the egress queue count in packets for a given port and all priorities from SONiC CLI.
Expand All @@ -1224,17 +1237,27 @@ def get_egress_queue_pkt_count_all_prio(duthost, port):
raw_out = duthost.shell("queuestat -jp {}".format(port))['stdout']
raw_json = json.loads(raw_out)
intf_queue_stats = raw_json.get(port)
queue_stats = []

for prio in range(8):
total_pkts_prio_str = intf_queue_stats.get("UC{}".format(prio)) if intf_queue_stats.get("UC{}".format(prio)) \
is not None else {"totalpacket": "0"}
total_pkts_str = total_pkts_prio_str.get("totalpacket")
if total_pkts_str == "N/A" or total_pkts_str is None:
total_pkts_str = "0"
queue_stats.append(int(total_pkts_str.replace(',', '')))
return handle_queue_stats_output(intf_queue_stats)

return queue_stats

def get_egress_queue_pkt_count_all_port_prio(duthost):
"""
Get the egress queue count in packets for all ports and all priorities from SONiC CLI.
This is the equivalent of the "queuestat -j" command.
Args:
duthost (Ansible host instance): device under test
Returns:
array [int]: total count of packets in the queue for all priorities and ports
"""
raw_out = duthost.shell("queuestat -j")['stdout']
raw_json = json.loads(raw_out)
all_stats = {}
for port in raw_json.keys():
intf_queue_stats = raw_json.get(port)
all_stats[port] = handle_queue_stats_output(intf_queue_stats)

return all_stats


@contextlib.contextmanager
Expand Down
52 changes: 51 additions & 1 deletion tests/qos/qos_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
import os
import json
import logging
import requests

logger = logging.getLogger(__name__)


PFC_GEN_FILE = 'pfc_gen.py'
PFC_GEN_LOCAL_PATH = '../../ansible/roles/test/files/helpers/pfc_gen.py'
PFC_GEN_REMOTE_PATH = '~/pfc_gen.py'
WITHDRAW = 'withdraw'
ANNOUNCE = 'announce'


def atoi(text):
Expand Down Expand Up @@ -316,3 +318,51 @@ def disable_voq_watchdog(duthosts, get_src_dst_asic_and_duts):
yield
# Enable voq watchdog.
modify_voq_watchdog(duthosts, get_src_dst_asic_and_duts, enable=True)


def get_upstream_vm_offset(nbrhosts, tbinfo):
"""
Get ports offset of exabgp port
"""
port_offset_list = []
if 't0' in tbinfo['topo']['type']:
vm_filter = 'T1'
elif 't1' in tbinfo['topo']['type']:
vm_filter = 'T2'
vm_name_list = [vm_name for vm_name in nbrhosts.keys() if vm_name.endswith(vm_filter)]
for vm_name in vm_name_list:
port_offset = tbinfo['topo']['properties']['topology']['VMs'][vm_name]['vm_offset']
port_offset_list.append((port_offset))
return port_offset_list


def get_upstream_exabgp_port(nbrhosts, tbinfo, exabgp_base_port):
"""
Get exabgp port and ptf receive port
"""
port_offset_list = get_upstream_vm_offset(nbrhosts, tbinfo)
return [_ + exabgp_base_port for _ in port_offset_list]


def install_route_from_exabgp(operation, ptfip, route, port):
"""
Install or withdraw ip route by exabgp
"""
route_data = [route]
url = "http://{}:{}".format(ptfip, port)
command = "{} attribute next-hop self nlri {}".format(operation, ' '.join(route_data))
data = {"command": command}
logger.info("url: {}".format(url))
logger.info("command: {}".format(data))
r = requests.post(url, data=data, timeout=90)
assert r.status_code == 200


def announce_route(ptfip, route, port, action=ANNOUNCE):
"""
Announce or withdraw ipv4 or ipv6 route
"""
logger.info("\n========================== announce_route -- {} ==========================".format(action))
logger.info(" action:{}\n ptfip:{}\n route:{}\n port:{}".format(action, ptfip, route, port))
install_route_from_exabgp(action, ptfip, route, port)
logger.info("\n--------------------------------------------------------------------------------")
Loading