Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Snappi]: PFC - Mixed Speed testcases #14122

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion tests/common/snappi_tests/common_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,7 @@ def get_interface_stats(duthost, port):

def get_queue_count_all_prio(duthost, port):
"""
Get the egress queue count in packets and bytes for a given port and priority from SONiC CLI.
Get the egress queue count in packets and bytes for a given port and all priorities.
This is the equivalent of the "show queue counters" command.
Args:
duthost (Ansible host instance): device under test
Expand Down
1 change: 0 additions & 1 deletion tests/common/snappi_tests/snappi_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,6 @@ def _get_multidut_snappi_ports(line_card_choice, line_card_info):
if port["peer_port"] in asic_port_map[asic] and hostname in port['peer_device']:
port['asic_value'] = asic
port['asic_type'] = host.facts["asic_type"]
port['duthost'] = host
ports.append(port)
return ports
return _get_multidut_snappi_ports
Expand Down
2 changes: 2 additions & 0 deletions tests/common/snappi_tests/snappi_test_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def __init__(self):
is_snappi_ingress_port_cap (bool): whether or not the packet capture is on the tgen ingress port, if False,
then pcap is on the tgen egress port
base_flow_config (dict): base flow configuration
base_flow_config_list (list): list for base flow config.
test_tx_frames (list): number of test frames transmitted for priorities to test ex. [2000, 3000]
for priorities 3 and 4
multi_dut_params (MultiDUTParams obj): contains det=120ails of duthost objects,
Expand All @@ -49,6 +50,7 @@ def __init__(self):
self.packet_capture_ports = None
self.is_snappi_ingress_port_cap = True
self.base_flow_config = None
self.base_flow_config_list = []
self.test_tx_frames = 0
self.multi_dut_params = MultiDUTParams()
self.test_iterations = 1
Expand Down
567 changes: 555 additions & 12 deletions tests/common/snappi_tests/traffic_generation.py

Large diffs are not rendered by default.

383 changes: 383 additions & 0 deletions tests/snappi_tests/pfc/files/mixed_speed_multidut_helper.py

Large diffs are not rendered by default.

424 changes: 424 additions & 0 deletions tests/snappi_tests/pfc/test_pfc_mixed_speed.py

Large diffs are not rendered by default.

291 changes: 291 additions & 0 deletions tests/snappi_tests/pfcwd/test_pfcwd_mixed_speed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
import pytest
import random
from tests.common.helpers.assertions import pytest_require, pytest_assert # noqa: F401
from tests.common.fixtures.conn_graph_facts import conn_graph_facts, fanout_graph_facts_multidut # noqa: F401
from tests.common.snappi_tests.snappi_fixtures import snappi_api_serv_ip, snappi_api_serv_port, \
snappi_api, cleanup_config, get_snappi_ports_for_rdma, snappi_multi_base_config, \
get_snappi_ports, get_snappi_ports_multi_dut, clear_fabric_counters, check_fabric_counters # noqa: F401
from tests.common.snappi_tests.qos_fixtures import prio_dscp_map, lossless_prio_list, \
lossy_prio_list, all_prio_list # noqa: F401
from tests.snappi_tests.variables import MIXED_SPEED_PORT_INFO, MULTIDUT_TESTBED
from tests.snappi_tests.pfc.files.mixed_speed_multidut_helper import run_pfc_test
from tests.common.snappi_tests.snappi_test_params import SnappiTestParams

import logging
logger = logging.getLogger(__name__)

pytestmark = [pytest.mark.topology('multidut-tgen')]

port_map = [[1, 100, 1, 400]]
# Testplan: docs/testplan/PFC_Snappi_Additional_Testcases.md
# This test-script covers testcase#03: DETECT CONGESTION WITH MISMATCHED INGRESS AND EGRESS


@pytest.mark.parametrize('port_map', port_map)
@pytest.mark.parametrize("multidut_port_info", MIXED_SPEED_PORT_INFO[MULTIDUT_TESTBED])
def test_mixed_speed_pfcwd_enable(snappi_api, # noqa: F811
conn_graph_facts, # noqa: F811
fanout_graph_facts_multidut, # noqa: F811
duthosts,
prio_dscp_map, # noqa: F811
lossless_prio_list, # noqa: F811
lossy_prio_list, # noqa: F811
tbinfo,
get_snappi_ports, # noqa: F811
port_map,
multidut_port_info): # noqa: F811

"""
Test to oversubscribe the 100Gbps egress link and have PFCWD enabled.
Sending PAUSE frames to egress link for the lossless traffic.
In response to congestion due to PFC storm, DUT drops lossless traffic on egress side.
On ingress side, DUT sends PFCs to slow down IXIA transmitter.
Lossy traffic should be dropped.
DUT allows equal amount of traffic (lossless and lossy priorities) to the egress.
Egress traffic is around 60Gbps of lossy traffic only.

Args:
snappi_api (pytest fixture): SNAPPI session
conn_graph_facts (pytest fixture): connection graph
fanout_graph_facts_multidut (pytest fixture): fanout graph
duthosts (pytest fixture): list of DUTs
prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority).
lossless_prio_list(list): list of lossless priorities
lossy_prio_list(list): list of lossy priorities.
tbinfo(key): element to identify testbed info name.
get_snappi_ports(pytest fixture): returns list of ports based on linecards selected.
port_map(list): list for port-speed combination.
multidut_port_info : Line card classification along with ports selected as Rx and Tx port.

Returns:
N/A
"""

# port_map is defined as port-speed combination.
# first two parameters are count of egress links and its speed.
# last two parameters are count of ingress links and its speed.

# pkt_size of 1024B will be used unless imix flag is set.
# With imix flag set, the traffic_generation.py uses IMIX profile.
pkt_size = 1024

for testbed_subtype, rdma_ports in MIXED_SPEED_PORT_INFO[MULTIDUT_TESTBED].items():
tx_port_count = port_map[0]
rx_port_count = port_map[2]
snappi_port_list = get_snappi_ports
pytest_assert(MULTIDUT_TESTBED == tbinfo['conf-name'],
"The testbed name from testbed file doesn't match with MULTIDUT_TESTBED in variables.py ")
pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count,
"Need Minimum of 2 ports defined in ansible/files/*links.csv file")

pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count,
'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \
testbed {}, subtype {} in variables.py'.
format(MULTIDUT_TESTBED, testbed_subtype))

pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count,
'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \
testbed {}, subtype {} in variables.py'.
format(MULTIDUT_TESTBED, testbed_subtype))
logger.info('Running test for testbed subtype: {}'.format(testbed_subtype))

snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports,
tx_port_count, rx_port_count, MULTIDUT_TESTBED)

testbed_config, port_config_list, snappi_ports = snappi_multi_base_config(duthosts,
snappi_ports,
snappi_api)

# Percentage drop expected for lossless and lossy traffic.
# speed_tol is speed tolerance between egress link speed and actual speed.
# loss_expected to check losses on DUT and TGEN.
test_check = {'lossless': 100, 'lossy': 75, 'speed_tol': 40, 'loss_expected': True, 'pfc': True}
test_def = {'TEST_FLOW_AGGR_RATE_PERCENT': 40,
'BG_FLOW_AGGR_RATE_PERCENT': 60,
'data_flow_pkt_size': pkt_size,
'DATA_FLOW_DURATION_SEC': 300,
'data_flow_delay_sec': 0,
'SNAPPI_POLL_DELAY_SEC': 60,
'test_type': '/tmp/Single_400Gbps_Ingress_Single_100Gbps_Egress_pause_pfcwd_enable_',
'line_card_choice': testbed_subtype,
'port_map': port_map,
'enable_pfcwd': True,
'enable_credit_wd': True,
'stats_interval': 60,
'background_traffic': True,
'imix': False,
'test_check': test_check,
'verify_flows': False}

test_prio_list = lossless_prio_list
pause_prio_list = test_prio_list
bg_prio_list = random.sample(lossy_prio_list, 3)
logger.info('Selected lossless :{} and lossy priorities:{} for the test'.format(test_prio_list, bg_prio_list))

snappi_extra_params = SnappiTestParams()
snappi_extra_params.multi_dut_params.duthost1 = snappi_ports[0]['duthost']
snappi_extra_params.multi_dut_params.duthost2 = snappi_ports[-1]['duthost']

snappi_extra_params.multi_dut_params.multi_dut_ports = snappi_ports
if (snappi_ports[0]['peer_device'] == snappi_ports[-1]['peer_device']):
dut_list = [snappi_ports[0]['duthost']]
else:
dut_list = [snappi_ports[0]['duthost'], snappi_ports[-1]['duthost']]

for dut in duthosts:
clear_fabric_counters(dut)

try:
run_pfc_test(api=snappi_api,
testbed_config=testbed_config,
port_config_list=port_config_list,
conn_data=conn_graph_facts,
fanout_data=fanout_graph_facts_multidut,
global_pause=False,
pause_prio_list=pause_prio_list,
test_prio_list=test_prio_list,
bg_prio_list=bg_prio_list,
prio_dscp_map=prio_dscp_map,
test_traffic_pause=True,
test_def=test_def,
snappi_extra_params=snappi_extra_params)

for dut in duthosts:
check_fabric_counters(dut)

finally:
cleanup_config(dut_list, snappi_ports)


@pytest.mark.parametrize('port_map', port_map)
@pytest.mark.parametrize("multidut_port_info", MIXED_SPEED_PORT_INFO[MULTIDUT_TESTBED])
def test_mixed_speed_pfcwd_disable(snappi_api, # noqa: F811
conn_graph_facts, # noqa: F811
fanout_graph_facts_multidut, # noqa: F811
duthosts,
prio_dscp_map, # noqa: F811
lossless_prio_list, # noqa: F811
lossy_prio_list, # noqa: F811
tbinfo,
get_snappi_ports, # noqa: F811
port_map,
multidut_port_info): # noqa: F811

"""
Test to oversubscribe the 100Gbps egress link and have PFCWD disabled.
Sending PAUSE frames to egress link for the lossless traffic.
DUT should send PFCs for the lossless traffic and have zero loss for lossless traffic.
Lossy traffic should be dropped.
DUT allows equal amount of traffic (lossless and lossy priorities) to the egress.
Egress traffic is around 100Gbps.

Args:
snappi_api (pytest fixture): SNAPPI session
conn_graph_facts (pytest fixture): connection graph
fanout_graph_facts_multidut (pytest fixture): fanout graph
duthosts (pytest fixture): list of DUTs
prio_dscp_map (pytest fixture): priority vs. DSCP map (key = priority).
lossless_prio_list(list): list of lossless priorities
lossy_prio_list(list): list of lossy priorities.
tbinfo(key): element to identify testbed info name.
get_snappi_ports(pytest fixture): returns list of ports based on linecards selected.
port_map(list): list for port-speed combination.
multidut_port_info : Line card classification along with ports selected as Rx and Tx port.
Returns:
N/A
"""

# port_map is defined as port-speed combination.
# first two parameters are count of egress links and its speed.
# last two parameters are count of ingress links and its speed.

# pkt_size of 1024B will be used unless imix flag is set.
# With imix flag set, the traffic_generation.py uses IMIX profile.
pkt_size = 1024

for testbed_subtype, rdma_ports in MIXED_SPEED_PORT_INFO[MULTIDUT_TESTBED].items():
tx_port_count = port_map[0]
rx_port_count = port_map[2]
snappi_port_list = get_snappi_ports
pytest_assert(MULTIDUT_TESTBED == tbinfo['conf-name'],
"The testbed name from testbed file doesn't match with MULTIDUT_TESTBED in variables.py ")
pytest_assert(len(snappi_port_list) >= tx_port_count + rx_port_count,
"Need Minimum of 2 ports defined in ansible/files/*links.csv file")

pytest_assert(len(rdma_ports['tx_ports']) >= tx_port_count,
'MULTIDUT_PORT_INFO doesn\'t have the required Tx ports defined for \
testbed {}, subtype {} in variables.py'.
format(MULTIDUT_TESTBED, testbed_subtype))

pytest_assert(len(rdma_ports['rx_ports']) >= rx_port_count,
'MULTIDUT_PORT_INFO doesn\'t have the required Rx ports defined for \
testbed {}, subtype {} in variables.py'.
format(MULTIDUT_TESTBED, testbed_subtype))
logger.info('Running test for testbed subtype: {}'.format(testbed_subtype))

snappi_ports = get_snappi_ports_for_rdma(snappi_port_list, rdma_ports,
tx_port_count, rx_port_count, MULTIDUT_TESTBED)

testbed_config, port_config_list, snappi_ports = snappi_multi_base_config(duthosts,
snappi_ports,
snappi_api)

# Percentage drop expected for lossless and lossy traffic.
# speed_tol is speed tolerance between egress link speed and actual speed.
# loss_expected to check losses on DUT and TGEN.
test_check = {'lossless': 0, 'lossy': 75, 'speed_tol': 3, 'loss_expected': True, 'pfc': True}
test_def = {'TEST_FLOW_AGGR_RATE_PERCENT': 40,
'BG_FLOW_AGGR_RATE_PERCENT': 60,
'data_flow_pkt_size': pkt_size,
'DATA_FLOW_DURATION_SEC': 300,
'data_flow_delay_sec': 0,
'SNAPPI_POLL_DELAY_SEC': 60,
'test_type': '/tmp/Single_400Gbps_Ingress_Single_100Gbps_Egress_pause_pfcwd_disable_',
'line_card_choice': testbed_subtype,
'port_map': port_map,
'enable_pfcwd': False,
'enable_credit_wd': False,
'stats_interval': 60,
'background_traffic': True,
'imix': False,
'test_check': test_check,
'verify_flows': False}

test_prio_list = lossless_prio_list
pause_prio_list = test_prio_list
bg_prio_list = random.sample(lossy_prio_list, 3)
logger.info('Selected lossless :{} and lossy priorities:{} for the test'.format(test_prio_list, bg_prio_list))

snappi_extra_params = SnappiTestParams()
snappi_extra_params.multi_dut_params.duthost1 = snappi_ports[0]['duthost']
snappi_extra_params.multi_dut_params.duthost2 = snappi_ports[-1]['duthost']

snappi_extra_params.multi_dut_params.multi_dut_ports = snappi_ports
if (snappi_ports[0]['peer_device'] == snappi_ports[-1]['peer_device']):
dut_list = [snappi_ports[0]['duthost']]
else:
dut_list = [snappi_ports[0]['duthost'], snappi_ports[-1]['duthost']]

for dut in duthosts:
clear_fabric_counters(dut)

try:
run_pfc_test(api=snappi_api,
testbed_config=testbed_config,
port_config_list=port_config_list,
conn_data=conn_graph_facts,
fanout_data=fanout_graph_facts_multidut,
global_pause=False,
pause_prio_list=pause_prio_list,
test_prio_list=test_prio_list,
bg_prio_list=bg_prio_list,
prio_dscp_map=prio_dscp_map,
test_traffic_pause=True,
test_def=test_def,
snappi_extra_params=snappi_extra_params)

for dut in duthosts:
check_fabric_counters(dut)

finally:
cleanup_config(dut_list, snappi_ports)
15 changes: 14 additions & 1 deletion tests/snappi_tests/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,20 @@
}
})
)}

# rx port is 400Gbps port receiving traffic in mixed-speed mode.
# tx port is 100Gbps port sending traffic to IXIA.
MIXED_SPEED_PORT_INFO = {MULTIDUT_TESTBED: (
({
'multiple-dut-any-asic': {
'rx_ports': [
{'port_name': 'Ethernet0', 'hostname': "sonic-s6100-dut1"}
],
'tx_ports': [
{'port_name': 'Ethernet0', 'hostname': "sonic-s6100-dut2"}
]
}
})
)}
'''
In this file user can modify the line_card_choice and it chooses the corresponding hostname
and asic values from the config_set hostnames can be modified according to the dut hostname mentioned
Expand Down
Loading