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
111 changes: 91 additions & 20 deletions tests/qos/qos_sai_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,8 +676,8 @@ def get_src_dst_asic_and_duts(self, duthosts, tbinfo, select_src_dst_dut_and_asi
rtn_dict.update(select_src_dst_dut_and_asic)
yield rtn_dict

def __buildTestPorts(self, request, testPortIds, testPortIps, src_port_ids,
dst_port_ids, get_src_dst_asic_and_duts, uplinkPortIds):
def __buildTestPorts(self, request, testPortIds, testPortIps, src_port_ids, dst_port_ids,
get_src_dst_asic_and_duts, uplinkPortIds, sysPortMap=None):
"""
Build map of test ports index and IPs

Expand All @@ -688,6 +688,7 @@ def __buildTestPorts(self, request, testPortIds, testPortIps, src_port_ids,

Returns:
testPorts (dict): Map of test ports index and IPs
sysPortMap (dict): Map of system port IDs and Qos SAI test port IDs
"""
dstPorts = request.config.getoption("--qos_dst_ports")
srcPorts = request.config.getoption("--qos_src_ports")
Expand Down Expand Up @@ -757,23 +758,40 @@ def __buildTestPorts(self, request, testPortIds, testPortIps, src_port_ids,
srcVlan = src_test_port_ips[srcPort]['vlan_id'] if 'vlan_id' in src_test_port_ips[srcPort] else None

src_port_ip = src_test_port_ips[srcPorts[0] if src_port_ids else src_test_port_ids[srcPorts[0]]]
# collecting the system ports associated with dst ports
# In case of PortChannel as dst port, all lag ports will be added to the list
# ex. {dstPort: system_port, dstPort1:system_port1 ...}
dst_all_sys_port = {}
if 'platform_asic' in get_src_dst_asic_and_duts["src_dut"].facts and \
get_src_dst_asic_and_duts["src_dut"].facts['platform_asic'] == 'broadcom-dnx':
sysPorts = sysPortMap[get_src_dst_asic_and_duts['dst_dut_index']][
get_src_dst_asic_and_duts['dst_asic_index']]
for port_id in [dstPort, dstPort2, dstPort3]:
if port_id in sysPorts and port_id not in dst_all_sys_port:
dst_all_sys_port.update({port_id: sysPorts[port_id]['system_port']})
if 'PortChannel' in sysPorts[port_id]['port_type']:
for sport, sysMap in sysPorts.items():
if sysMap['port_type'] == sysPorts[port_id]['port_type'] and sport != port_id:
dst_all_sys_port.update({sport: sysMap['system_port']})

return {
"dst_port_id": dstPort,
"dst_port_ip": dst_test_port_ips[dstPort]['peer_addr'],
"dst_port_ipv6": dst_test_port_ips[dstPort]['peer_addr_ipv6'],
"dst_port_vlan": dstVlan,
"dst_port_2_id": dstPort2,
"dst_port_2_ip": dst_test_port_ips[dstPort2]['peer_addr'],
"dst_port_2_ipv6": dst_test_port_ips[dstPort2]['peer_addr_ipv6'],
"dst_port_2_vlan": dstVlan2,
'dst_port_3_id': dstPort3,
"dst_port_3_ip": dst_test_port_ips[dstPort3]['peer_addr'],
"dst_port_3_ipv6": dst_test_port_ips[dstPort3]['peer_addr_ipv6'],
"dst_port_3_vlan": dstVlan3,
"src_port_id": srcPort,
"src_port_ip": src_port_ip["peer_addr"],
"src_port_ipv6": src_port_ip["peer_addr_ipv6"],
"src_port_vlan": srcVlan
"dst_port_id": dstPort,
"dst_port_ip": dst_test_port_ips[dstPort]['peer_addr'],
"dst_port_ipv6": dst_test_port_ips[dstPort]['peer_addr_ipv6'],
"dst_port_vlan": dstVlan,
"dst_port_2_id": dstPort2,
"dst_port_2_ip": dst_test_port_ips[dstPort2]['peer_addr'],
"dst_port_2_ipv6": dst_test_port_ips[dstPort2]['peer_addr_ipv6'],
"dst_port_2_vlan": dstVlan2,
'dst_port_3_id': dstPort3,
"dst_port_3_ip": dst_test_port_ips[dstPort3]['peer_addr'],
"dst_port_3_ipv6": dst_test_port_ips[dstPort3]['peer_addr_ipv6'],
"dst_port_3_vlan": dstVlan3,
"src_port_id": srcPort,
"src_port_ip": src_port_ip["peer_addr"],
"src_port_ipv6": src_port_ip["peer_addr_ipv6"],
"src_port_vlan": srcVlan,
"dst_sys_ports": dst_all_sys_port
}

@pytest.fixture(scope='class', autouse=True)
Expand Down Expand Up @@ -807,6 +825,7 @@ def dutConfig(
downlinkPortIds = []
downlinkPortIps = []
downlinkPortNames = []
sysPortMap = {}

src_dut_index = get_src_dst_asic_and_duts['src_dut_index']
src_asic_index = get_src_dst_asic_and_duts['src_asic_index']
Expand Down Expand Up @@ -950,18 +969,34 @@ def dutConfig(
src_asic = get_src_dst_asic_and_duts['src_asic']
dst_dut_index = get_src_dst_asic_and_duts['dst_dut_index']
dst_asic = get_src_dst_asic_and_duts['dst_asic']
src_system_port = {}
if 'platform_asic' in get_src_dst_asic_and_duts["src_dut"].facts and \
get_src_dst_asic_and_duts["src_dut"].facts['platform_asic'] == 'broadcom-dnx':
src_system_port = src_dut.config_facts(host=src_dut.hostname, source='running')['ansible_facts'][
'SYSTEM_PORT'][src_dut.hostname]

# Lets get data for the src dut and src asic
dutPortIps[src_dut_index] = {}
sysPortMap[src_dut_index] = {}
testPortIds[src_dut_index] = {}
dutPortIps[src_dut_index][src_asic_index] = {}
sysPortMap[src_dut_index][src_asic_index] = {}
active_ips = src_asic.get_active_ip_interfaces(tbinfo, include_ipv6=True)
for iface, addr in active_ips.items():
if iface.startswith("Ethernet") and ("Ethernet-Rec" not in iface):
portIndex = src_mgFacts["minigraph_ptf_indices"][iface]
portIpMap = {'peer_addr': addr["peer_ipv4"], 'peer_addr_ipv6': addr['peer_ipv6'],
'port': iface}
dutPortIps[src_dut_index][src_asic_index].update({portIndex: portIpMap})
# Map port IDs to system port for dnx chassis
if 'platform_asic' in get_src_dst_asic_and_duts["src_dut"].facts and \
get_src_dst_asic_and_duts["src_dut"].facts['platform_asic'] == 'broadcom-dnx':
sys_key = src_asic.namespace + '|' + iface
if sys_key in src_system_port:
system_port = src_system_port[sys_key]['system_port_id']
sysPort = {'port': iface, 'system_port': system_port, 'port_type': iface}
sysPortMap[src_dut_index][src_asic_index].update({portIndex: sysPort})

elif iface.startswith("PortChannel"):
portName = next(
iter(src_mgFacts["minigraph_portchannels"][iface]["members"])
Expand All @@ -970,6 +1005,16 @@ def dutConfig(
portIpMap = {'peer_addr': addr["peer_ipv4"], 'peer_addr_ipv6': addr['peer_ipv6'],
'port': portName}
dutPortIps[src_dut_index][src_asic_index].update({portIndex: portIpMap})
# Map lag port IDs to system port IDs for dnx chassis
if 'platform_asic' in get_src_dst_asic_and_duts["src_dut"].facts and \
get_src_dst_asic_and_duts["src_dut"].facts['platform_asic'] == 'broadcom-dnx':
for portName in src_mgFacts["minigraph_portchannels"][iface]["members"]:
sys_key = src_asic.namespace + '|' + portName
port_Index = src_mgFacts["minigraph_ptf_indices"][portName]
if sys_key in src_system_port:
system_port = src_system_port[sys_key]['system_port_id']
sysPort = {'port': portName, 'system_port': system_port, 'port_type': iface}
sysPortMap[src_dut_index][src_asic_index].update({port_Index: sysPort})

testPortIds[src_dut_index][src_asic_index] = sorted(dutPortIps[src_dut_index][src_asic_index].keys())

Expand All @@ -981,16 +1026,32 @@ def dutConfig(
dst_mgFacts = dst_dut.get_extended_minigraph_facts(tbinfo)
dutPortIps[dst_dut_index] = {}
testPortIds[dst_dut_index] = {}
sysPortMap[dst_dut_index] = {}
if 'platform_asic' in get_src_dst_asic_and_duts["src_dut"].facts and \
get_src_dst_asic_and_duts["src_dut"].facts['platform_asic'] == 'broadcom-dnx':
dst_system_port = dst_dut.config_facts(host=dst_dut.hostname, source='running')[
'ansible_facts']['SYSTEM_PORT'][dst_dut.hostname]
else:
dst_mgFacts = src_mgFacts
dst_system_port = src_system_port
dutPortIps[dst_dut_index][dst_asic_index] = {}
sysPortMap[dst_dut_index][dst_asic_index] = {}
active_ips = dst_asic.get_active_ip_interfaces(tbinfo, include_ipv6=True)
for iface, addr in active_ips.items():
if iface.startswith("Ethernet") and ("Ethernet-Rec" not in iface):
portIndex = dst_mgFacts["minigraph_ptf_indices"][iface]
portIpMap = {'peer_addr': addr["peer_ipv4"], 'peer_addr_ipv6': addr['peer_ipv6'],
'port': iface}
dutPortIps[dst_dut_index][dst_asic_index].update({portIndex: portIpMap})
# Map port IDs to system port IDs
if 'platform_asic' in get_src_dst_asic_and_duts["src_dut"].facts and \
get_src_dst_asic_and_duts["src_dut"].facts['platform_asic'] == 'broadcom-dnx':
sys_key = dst_asic.namespace + '|' + iface
if sys_key in dst_system_port:
system_port = dst_system_port[sys_key]['system_port_id']
sysPort = {'port': iface, 'system_port': system_port, 'port_type': iface}
sysPortMap[dst_dut_index][dst_asic_index].update({portIndex: sysPort})

elif iface.startswith("PortChannel"):
portName = next(
iter(dst_mgFacts["minigraph_portchannels"][iface]["members"])
Expand All @@ -999,6 +1060,16 @@ def dutConfig(
portIpMap = {'peer_addr': addr["peer_ipv4"], 'peer_addr_ipv6': addr['peer_ipv6'],
'port': portName}
dutPortIps[dst_dut_index][dst_asic_index].update({portIndex: portIpMap})
# Map lag port IDs to system port IDs
if 'platform_asic' in get_src_dst_asic_and_duts["src_dut"].facts and \
get_src_dst_asic_and_duts["src_dut"].facts['platform_asic'] == 'broadcom-dnx':
for portName in dst_mgFacts["minigraph_portchannels"][iface]["members"]:
sys_key = dst_asic.namespace + '|' + portName
port_Index = dst_mgFacts["minigraph_ptf_indices"][portName]
if sys_key in dst_system_port:
system_port = dst_system_port[sys_key]['system_port_id']
sysPort = {'port': portName, 'system_port': system_port, 'port_type': iface}
sysPortMap[dst_dut_index][dst_asic_index].update({port_Index: sysPort})

testPortIds[dst_dut_index][dst_asic_index] = sorted(dutPortIps[dst_dut_index][dst_asic_index].keys())

Expand Down Expand Up @@ -1067,8 +1138,8 @@ def dutConfig(
if dualTor:
testPortIds = dualTorPortIndexes

testPorts = self.__buildTestPorts(request, testPortIds, testPortIps,
src_port_ids, dst_port_ids, get_src_dst_asic_and_duts, uplinkPortIds)
testPorts = self.__buildTestPorts(request, testPortIds, testPortIps, src_port_ids, dst_port_ids,
get_src_dst_asic_and_duts, uplinkPortIds, sysPortMap)
# Update the uplink/downlink ports to testPorts
testPorts.update({
"uplink_port_ids": uplinkPortIds,
Expand Down
1 change: 1 addition & 0 deletions tests/qos/test_qos_sai.py
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,7 @@ def testQosSaiLossyQueue(
"buffer_max_size": ingressLossyProfile["static_th"],
"headroom_size": ingressLossyProfile["size"],
"dst_port_id": dutConfig["testPorts"]["dst_port_id"],
"dst_sys_ports": dutConfig["testPorts"]["dst_sys_ports"],
"dst_port_ip": dutConfig["testPorts"]["dst_port_ip"],
"dst_port_2_id": dutConfig["testPorts"]["dst_port_2_id"],
"dst_port_2_ip": dutConfig["testPorts"]["dst_port_2_ip"],
Expand Down
25 changes: 24 additions & 1 deletion tests/saitests/py3/sai_qos_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@
sai_thrift_read_buffer_pool_watermark,
sai_thrift_read_headroom_pool_watermark,
sai_thrift_read_queue_occupancy,
sai_thrift_read_pg_occupancy)
sai_thrift_read_pg_occupancy,
sai_thrift_read_port_voq_counters,
sai_thrift_get_voq_port_id
)
from switch_sai_thrift.ttypes import (sai_thrift_attribute_value_t,
sai_thrift_attribute_t)
from switch_sai_thrift.sai_headers import SAI_PORT_ATTR_QOS_SCHEDULER_PROFILE_ID
Expand Down Expand Up @@ -3653,6 +3656,7 @@ def runTest(self):
sonic_version = self.test_params['sonic_version']
router_mac = self.test_params['router_mac']
dst_port_id = int(self.test_params['dst_port_id'])
dst_sys_port_ids = self.test_params.get('dst_sys_ports', None)
dst_port_ip = self.test_params['dst_port_ip']
dst_port_mac = self.dataplane.get_mac(0, dst_port_id)
src_port_id = int(self.test_params['src_port_id'])
Expand Down Expand Up @@ -3709,6 +3713,15 @@ def runTest(self):
self.src_client, asic_type, port_list['src'][src_port_id])
xmit_counters_base, queue_counters = sai_thrift_read_port_counters(
self.dst_client, asic_type, port_list['dst'][dst_port_id])
# for t2 chassis
if platform_asic and platform_asic == "broadcom-dnx":
if dst_port_id in dst_sys_port_ids:
for port_id, sysport in dst_sys_port_ids.items():
if dst_port_id == port_id:
dst_sys_port_id = int(sysport)
print("actual dst_sys_port_id: %d" % (dst_sys_port_id), file=sys.stderr)
voq_list = sai_thrift_get_voq_port_id(self.src_client, dst_sys_port_id)
voq_queue_counters_base = sai_thrift_read_port_voq_counters(self.src_client, voq_list)
# add slight tolerance in threshold characterization to consider
# the case that cpu puts packets in the egress queue after we pause the egress
# or the leak out is simply less than expected as we have occasionally observed
Expand Down Expand Up @@ -3776,6 +3789,9 @@ def runTest(self):
self.src_client, asic_type, port_list['src'][src_port_id])
xmit_counters, queue_counters = sai_thrift_read_port_counters(
self.dst_client, asic_type, port_list['dst'][dst_port_id])
# for t2 chassis
if platform_asic and platform_asic == "broadcom-dnx":
voq_queue_counters = sai_thrift_read_port_voq_counters(self.src_client, voq_list)
# recv port no pfc
assert (recv_counters[pg] == recv_counters_base[pg])
# recv port no ingress drop
Expand Down Expand Up @@ -3822,6 +3838,13 @@ def runTest(self):
for cntr in egress_counters:
assert (xmit_counters[cntr] > xmit_counters_base[cntr])

# voq ingress drop
if platform_asic and platform_asic == "broadcom-dnx":
voq_index = pg - 2
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please share more info on this logic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed, the pg value is set by adding 2 (pg = int(self.test_params['pg']) + 2) in the initialization. Hence reducing 2 here to get the correct voq_index

print("voq_counters_base: %d, voq_counters: %d " % (voq_queue_counters_base[voq_index],
voq_queue_counters[voq_index]), file=sys.stderr)
assert (voq_queue_counters[voq_index] > (
voq_queue_counters_base[voq_index] + pkts_num_trig_egr_drp - margin))
finally:
self.sai_thrift_port_tx_enable(self.dst_client, asic_type, [dst_port_id])

Expand Down
29 changes: 28 additions & 1 deletion tests/saitests/py3/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
SAI_INGRESS_PRIORITY_GROUP_STAT_CURR_OCCUPANCY_BYTES


from switch_sai_thrift.sai_headers import SAI_SWITCH_ATTR_SRC_MAC_ADDRESS
from switch_sai_thrift.sai_headers import SAI_SWITCH_ATTR_SRC_MAC_ADDRESS, SAI_SYSTEM_PORT_ATTR_QOS_VOQ_LIST

this_dir = os.path.dirname(os.path.abspath(__file__))

Expand Down Expand Up @@ -822,6 +822,33 @@ def sai_thrift_read_port_counters(client, asic_type, port):
return (counters_results, queue_counters_results)


def sai_thrift_get_voq_port_id(client, system_port_id):
object_id = client.sai_thrift_get_sys_port_obj_id_by_port_id(system_port_id)
voq_list = []
port_attr_list = client.sai_thrift_get_system_port_attribute(object_id)
attr_list = port_attr_list.attr_list
for attribute in attr_list:
if attribute.id == SAI_SYSTEM_PORT_ATTR_QOS_VOQ_LIST:
for voq_id in attribute.value.objlist.object_id_list:
voq_list.append(voq_id)
return (voq_list)


def sai_thrift_read_port_voq_counters(client, voq_list):
cnt_ids = []
thrift_results = []
voq_counters_results = []
cnt_ids.append(SAI_QUEUE_STAT_PACKETS)
counter = 0
for voq in voq_list:
if counter <= 7:
thrift_results = client.sai_thrift_get_queue_stats(
voq, cnt_ids, len(cnt_ids))
voq_counters_results.append(thrift_results[0])
counter += 1
return (voq_counters_results)


def sai_thrift_read_port_watermarks(client, port):
q_wm_ids = []
q_wm_ids.append(SAI_QUEUE_STAT_SHARED_WATERMARK_BYTES)
Expand Down