Skip to content

Commit

Permalink
Enabling testQosSaiBufferPoolWatermark Testcase for cisco-8000 platfo…
Browse files Browse the repository at this point in the history
…rm (#5512)

* Changes for Bufferpool Watermark Testcase for cisco-8000 platform

* removing sleep from fill_leakout
  • Loading branch information
jsanghra authored May 12, 2022
1 parent bb10a8b commit c453cf4
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 17 deletions.
6 changes: 6 additions & 0 deletions tests/qos/test_qos_sai.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ def testQosSaiBufferPoolWatermark(
RunAnsibleModuleFail if ptf test fails
"""
disableTest = request.config.getoption("--disable_test")
if dutTestParams["basicParams"]["sonic_asic_type"] == 'cisco-8000':
disableTest = False
if disableTest:
pytest.skip("Buffer Pool watermark test is disabled")

Expand Down Expand Up @@ -398,6 +400,10 @@ def testQosSaiBufferPoolWatermark(
"cell_size": qosConfig[bufPool]["cell_size"],
"buf_pool_roid": buf_pool_roid
})

if "packet_size" in qosConfig[bufPool].keys():
testParams["packet_size"] = qosConfig[bufPool]["packet_size"]

self.runPtfTest(
ptfhost, testCase="sai_qos_tests.BufferPoolWatermarkTest",
testParams=testParams
Expand Down
80 changes: 63 additions & 17 deletions tests/saitests/sai_qos_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
sai_thrift_read_pg_shared_watermark,
sai_thrift_read_buffer_pool_watermark,
sai_thrift_read_headroom_pool_watermark,
sai_thrift_read_queue_occupancy,
sai_thrift_port_tx_disable,
sai_thrift_port_tx_enable)
from switch_sai_thrift.ttypes import (sai_thrift_attribute_value_t,
Expand Down Expand Up @@ -146,6 +147,21 @@ def get_counter_names(sonic_version):

return ingress_counters, egress_counters

def fill_leakout_plus_one(test_case, src_port_id, dst_port_id, pkt, queue, asic_type):
# Attempts to queue 1 packet while compensating for a varying packet leakout.
# Returns whether 1 packet was successfully enqueued.
if asic_type in ['cisco-8000']:
queue_counters_base = sai_thrift_read_queue_occupancy(test_case.client, dst_port_id)
max_packets = 100
for packet_i in range(max_packets):
send_packet(test_case, src_port_id, pkt, 1)
queue_counters = sai_thrift_read_queue_occupancy(test_case.client, dst_port_id)
if queue_counters[queue] > queue_counters_base[queue]:
print >> sys.stderr, "fill_leakout_plus_one: Success, sent %d packets, queue occupancy bytes rose from %d to %d" % (packet_i + 1, queue_counters_base[queue], queue_counters[queue])
return True
return False


class ARPpopulate(sai_base_test.ThriftInterfaceDataPlane):
def setUp(self):
sai_base_test.ThriftInterfaceDataPlane.setUp(self)
Expand Down Expand Up @@ -2222,12 +2238,24 @@ def runTest(self):
buf_pool_roid=int(self.test_params['buf_pool_roid'], 0)
print >> sys.stderr, "buf_pool_roid: 0x%lx" % (buf_pool_roid)

buffer_pool_wm_base = 0
if 'cisco-8000' in asic_type:
# Some small amount of memory is always occupied
buffer_pool_wm_base = sai_thrift_read_buffer_pool_watermark(self.client, buf_pool_roid)

# Prepare TCP packet data
tos = dscp << 2
tos |= ecn
ttl = 64
default_packet_length = 64
pkt = simple_tcp_packet(pktlen=default_packet_length,

if 'packet_size' in self.test_params.keys():
packet_length = int(self.test_params['packet_size'])
else:
packet_length = 64

cell_occupancy = (packet_length + cell_size - 1) / cell_size

pkt = simple_tcp_packet(pktlen=packet_length,
eth_dst=router_mac if router_mac != '' else dst_port_mac,
eth_src=src_port_mac,
ip_src=src_port_ip,
Expand All @@ -2237,15 +2265,19 @@ def runTest(self):
# 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
upper_bound_margin = 2
# On TD2, we found the watermark value is always short of the expected
# value by 1
lower_bound_margin = 1
upper_bound_margin = 2 * cell_occupancy
if 'cisco-8000' in asic_type:
lower_bound_margin = 2 * cell_occupancy
else:
# On TD2, we found the watermark value is always short of the expected
# value by 1
lower_bound_margin = 1

# On TH2 using scheduler-based TX enable, we find the Q min being inflated
# to have 0x10 = 16 cells. This effect is captured in lossy traffic ingress
# buffer pool test and lossy traffic egress buffer pool test to illusively
# have extra capacity in the buffer pool space
extra_cap_margin = 8
extra_cap_margin = 8 * cell_occupancy

# Adjust the methodology to enable TX for each incremental watermark value test
# To this end, send the total # of packets instead of the incremental amount
Expand All @@ -2266,7 +2298,7 @@ def runTest(self):
send_packet(self, src_port_id, pkt, pkts_num_to_send)
sai_thrift_port_tx_enable(self.client, asic_type, [dst_port_id])
time.sleep(8)
buffer_pool_wm = sai_thrift_read_buffer_pool_watermark(self.client, buf_pool_roid)
buffer_pool_wm = sai_thrift_read_buffer_pool_watermark(self.client, buf_pool_roid) - buffer_pool_wm_base
print >> sys.stderr, "Init pkts num sent: %d, min: %d, actual watermark value to start: %d" % ((pkts_num_leak_out + pkts_num_fill_min), pkts_num_fill_min, buffer_pool_wm)
if pkts_num_fill_min:
assert(buffer_pool_wm <= upper_bound_margin * cell_size)
Expand All @@ -2281,22 +2313,31 @@ def runTest(self):
# send packet batch of fixed packet numbers to fill shared
# first round sends only 1 packet
expected_wm = 0
total_shared = pkts_num_fill_shared - pkts_num_fill_min
pkts_inc = total_shared >> 2
pkts_num = 1 + upper_bound_margin
total_shared = (pkts_num_fill_shared - pkts_num_fill_min) * cell_occupancy
pkts_inc = (total_shared >> 2) // cell_occupancy
if 'cisco-8000' in asic_type:
# No additional packet margin needed while sending,
# but small margin still needed during boundary checks below
pkts_num = 1
else:
pkts_num = (1 + upper_bound_margin) // cell_occupancy
while (expected_wm < total_shared):
expected_wm += pkts_num
expected_wm += pkts_num * cell_occupancy
if (expected_wm > total_shared):
pkts_num -= (expected_wm - total_shared)
pkts_num -= (expected_wm - total_shared + cell_occupancy - 1) // cell_occupancy
expected_wm = total_shared
print >> sys.stderr, "pkts num to send: %d, total pkts: %d, shared: %d" % (pkts_num, expected_wm, total_shared)

sai_thrift_port_tx_disable(self.client, asic_type, [dst_port_id])
pkts_num_to_send += pkts_num
send_packet(self, src_port_id, pkt, pkts_num_to_send)
if 'cisco-8000' in asic_type:
assert(fill_leakout_plus_one(self, src_port_id, dst_port_id, pkt, queue, asic_type))
send_packet(self, src_port_id, pkt, pkts_num_to_send - 1)
else:
send_packet(self, src_port_id, pkt, pkts_num_to_send)
sai_thrift_port_tx_enable(self.client, asic_type, [dst_port_id])
time.sleep(8)
buffer_pool_wm = sai_thrift_read_buffer_pool_watermark(self.client, buf_pool_roid)
buffer_pool_wm = sai_thrift_read_buffer_pool_watermark(self.client, buf_pool_roid) - buffer_pool_wm_base
print >> sys.stderr, "lower bound (-%d): %d, actual value: %d, upper bound (+%d): %d" % (lower_bound_margin, (expected_wm - lower_bound_margin)* cell_size, buffer_pool_wm, upper_bound_margin, (expected_wm + upper_bound_margin) * cell_size)
assert(buffer_pool_wm <= (expected_wm + upper_bound_margin) * cell_size)
assert((expected_wm - lower_bound_margin)* cell_size <= buffer_pool_wm)
Expand All @@ -2306,10 +2347,15 @@ def runTest(self):
# overflow the shared pool
sai_thrift_port_tx_disable(self.client, asic_type, [dst_port_id])
pkts_num_to_send += pkts_num
send_packet(self, src_port_id, pkt, pkts_num_to_send)
if 'cisco-8000' in asic_type:
assert(fill_leakout_plus_one(self, src_port_id, dst_port_id, pkt, queue, asic_type))
send_packet(self, src_port_id, pkt, pkts_num_to_send - 1)
else:
send_packet(self, src_port_id, pkt, pkts_num_to_send)

sai_thrift_port_tx_enable(self.client, asic_type, [dst_port_id])
time.sleep(8)
buffer_pool_wm = sai_thrift_read_buffer_pool_watermark(self.client, buf_pool_roid)
buffer_pool_wm = sai_thrift_read_buffer_pool_watermark(self.client, buf_pool_roid) - buffer_pool_wm_base
print >> sys.stderr, "exceeded pkts num sent: %d, expected watermark: %d, actual value: %d" % (pkts_num, (expected_wm * cell_size), buffer_pool_wm)
assert(expected_wm == total_shared)
assert((expected_wm - lower_bound_margin)* cell_size <= buffer_pool_wm)
Expand Down
18 changes: 18 additions & 0 deletions tests/saitests/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,24 @@ def sai_thrift_read_headroom_pool_watermark(client, buffer_pool_id):
return None
return wm_vals[0]

def sai_thrift_read_queue_occupancy(client, port_id):
queue_list=[]
port_attr_list = client.sai_thrift_get_port_attribute(port_list[port_id])
attr_list = port_attr_list.attr_list
for attribute in attr_list:
if attribute.id == SAI_PORT_ATTR_QOS_QUEUE_LIST:
for queue_id in attribute.value.objlist.object_id_list:
queue_list.append(queue_id)
cnt_ids=[SAI_QUEUE_STAT_CURR_OCCUPANCY_BYTES]
queue_counters_results=[]
queue1=0
for queue in queue_list:
if queue1 <= 7:
thrift_results=client.sai_thrift_get_queue_stats(queue,cnt_ids,len(cnt_ids))
queue_counters_results.append(thrift_results[0])
queue1+=1
return queue_counters_results

def sai_thrift_create_vlan_member(client, vlan_id, port_id, tagging_mode):
vlan_member_attr_list = []
attribute_value = sai_thrift_attribute_value_t(s32=vlan_id)
Expand Down

0 comments on commit c453cf4

Please sign in to comment.