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
1 change: 1 addition & 0 deletions tests/common/devices/sonic.py
Original file line number Diff line number Diff line change
Expand Up @@ -2679,6 +2679,7 @@ def set_counter_poll_interval(self, counter_type, interval, wait_for_new_interva
counter_type_cli_map = {
'QUEUE_STAT': 'queue',
'PORT_STAT': 'port',
'SWITCH_STAT': 'switch',
'PORT_BUFFER_DROP': 'port-buffer-drop',
'RIF_STAT': 'rif',
'QUEUE_WATERMARK_STAT': 'watermark',
Expand Down
163 changes: 157 additions & 6 deletions tests/packet_trimming/base_packet_trimming.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
from tests.common.mellanox_data import is_mellanox_device
from tests.packet_trimming.constants import (
TRIM_SIZE, DEFAULT_PACKET_SIZE, DEFAULT_DSCP, MIN_PACKET_SIZE, TRIM_SIZE_MAX, CONFIG_TOGGLE_COUNT,
JUMBO_PACKET_SIZE, PORT_TOGGLE_COUNT)
JUMBO_PACKET_SIZE, PORT_TOGGLE_COUNT, COUNTER_DSCP, TRIM_QUEUE)
from tests.packet_trimming.packet_trimming_helper import (
configure_trimming_action, configure_trimming_acl, verify_srv6_packet_with_trimming, cleanup_trimming_acl,
verify_trimmed_packet, reboot_dut, check_connected_route_ready)
verify_trimmed_packet, reboot_dut, check_connected_route_ready, get_switch_trim_counters_json,
get_port_trim_counters_json, disable_egress_data_plane, enable_egress_data_plane,
verify_queue_and_port_trim_counter_consistency, get_queue_trim_counters_json, compare_counters)

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -38,6 +40,26 @@ def get_verify_trimmed_packet_kwargs(self, test_params):
expect_packets=True
)
base_kwargs.update(self.get_extra_trimmed_packet_kwargs())
logger.info(f"Base kwargs: {base_kwargs}")
return base_kwargs

def get_verify_trimmed_counter_packet_kwargs(self, trim_counter_params):
"""
Get kwargs for verify_trimmed_packet
"""
base_kwargs = dict(
duthost=trim_counter_params.get('duthost'),
ptfadapter=trim_counter_params.get('ptfadapter'),
ingress_port=trim_counter_params['ingress_port'],
egress_ports=trim_counter_params['egress_ports'],
block_queue=trim_counter_params['block_queue'],
send_pkt_size=DEFAULT_PACKET_SIZE,
send_pkt_dscp=COUNTER_DSCP,
recv_pkt_size=TRIM_SIZE,
expect_packets=True
)
base_kwargs.update(self.get_extra_trimmed_packet_kwargs())
logger.info(f"Base kwargs: {base_kwargs}")
return base_kwargs

def get_extra_trimmed_packet_kwargs(self):
Expand Down Expand Up @@ -227,7 +249,6 @@ def test_stability_during_feature_toggles(self, duthost, ptfadapter, test_params
logger.info(f"Trimming config toggle test iteration {i + 1}")
for buffer_profile in test_params['trim_buffer_profiles']:
configure_trimming_action(duthost, test_params['trim_buffer_profiles'][buffer_profile], "off")
for buffer_profile in test_params['trim_buffer_profiles']:
configure_trimming_action(duthost, test_params['trim_buffer_profiles'][buffer_profile], "on")

with allure.step(f"Verify trimming still works after feature toggles in {self.trimming_mode} mode"):
Expand Down Expand Up @@ -262,14 +283,24 @@ def test_trimming_during_port_admin_toggle(self, duthost, ptfadapter, test_param
logger.info(f"Ports admin status toggle test iteration {i+1}")
duthost.shutdown(egress_port['name'])
duthost.no_shutdown(egress_port['name'])
pytest_assert(wait_until(30, 5, 0, duthost.check_intf_link_state, egress_port['name']),
"Interfaces are not restored to up after the flap")
pytest_assert(wait_until(30, 5, 0, duthost.check_intf_link_state, egress_port['name']),
"Interfaces are not restored to up after the flap")

with allure.step("Verify connected route is ready after port toggles"):
for egress_port in test_params['egress_ports']:
pytest_assert(wait_until(30, 5, 0, check_connected_route_ready, duthost, egress_port),
"Connected route is not ready")

with allure.step("Verify trimming still works after admin toggles"):
kwargs = self.get_verify_trimmed_packet_kwargs({**test_params})
kwargs.update({'duthost': duthost, 'ptfadapter': ptfadapter})
verify_trimmed_packet(**kwargs)

with allure.step("Verify packet trimming counter"):
for egress_port in test_params['egress_ports']:
for port in egress_port['dut_members']:
verify_queue_and_port_trim_counter_consistency(duthost, port)

def test_trimming_with_reload_and_reboot(self, duthost, ptfadapter, test_params, localhost, request):
"""
Test Case: Verify Trimming Persistence After Reload and Reboot
Expand Down Expand Up @@ -308,7 +339,7 @@ def test_trimming_with_reload_and_reboot(self, duthost, ptfadapter, test_params,

with allure.step("Verify connected route is ready after reload/cold reboot"):
for egress_port in test_params['egress_ports']:
pytest_assert(wait_until(30, 5, 0, check_connected_route_ready, duthost, egress_port['name']),
pytest_assert(wait_until(30, 5, 0, check_connected_route_ready, duthost, egress_port),
"Connected route is not ready")

if is_mellanox_device(duthost):
Expand All @@ -319,3 +350,123 @@ def test_trimming_with_reload_and_reboot(self, duthost, ptfadapter, test_params,
kwargs = self.get_verify_trimmed_packet_kwargs({**test_params})
kwargs.update({'duthost': duthost, 'ptfadapter': ptfadapter})
verify_trimmed_packet(**kwargs)

with allure.step("Verify packet trimming counter"):
for egress_port in test_params['egress_ports']:
for port in egress_port['dut_members']:
verify_queue_and_port_trim_counter_consistency(duthost, port)

def test_trimming_counters(self, duthost, ptfadapter, test_params, trim_counter_params):
"""
Test Case: Verify PacketTrimming Counters
"""
with allure.step(f"Configure packet trimming in global level for {self.trimming_mode} mode"):
self.configure_trimming_global_by_mode(duthost)

with allure.step("Enable trimming in buffer profile"):
for buffer_profile in test_params['trim_buffer_profiles']:
configure_trimming_action(duthost, test_params['trim_buffer_profiles'][buffer_profile], "on")
for buffer_profile in trim_counter_params['trim_buffer_profiles']:
configure_trimming_action(duthost, trim_counter_params['trim_buffer_profiles'][buffer_profile], "on")

# Packets are trimmed on two queues, verify trimming counters in queue and port level
with allure.step("Verify trimming counters on two queues"):
# Trigger trimmed packets on queue0
counter_kwargs = self.get_verify_trimmed_counter_packet_kwargs({**trim_counter_params})
counter_kwargs.update({'duthost': duthost, 'ptfadapter': ptfadapter})
verify_trimmed_packet(**counter_kwargs)

# Verify the consistency of the trim counter on the queue and the port level
for egress_port in test_params['egress_ports']:
for port in egress_port['dut_members']:
verify_queue_and_port_trim_counter_consistency(duthost, port)

with allure.step("Verify TrimSent counters on switch level"):
switch_trim_sent_value = get_switch_trim_counters_json(duthost)['trim_sent']
logger.info(f"switch_trim_sent_value: {switch_trim_sent_value}")

# Verify the trim sent counter on the switch level is equal to the sum of the trim sent counter on the
# port level
ports_trim_sent_counters = []
for egress_port in test_params['egress_ports']:
for port in egress_port['dut_members']:
port_trim_tx_value = get_port_trim_counters_json(duthost, port)['TRIM_TX_PKTS']
ports_trim_sent_counters.append(port_trim_tx_value)

# Verify the trim sent counter on the switch level is equal to the sum of the trim sent counter on the
# port level
pytest_assert(sum(ports_trim_sent_counters) == switch_trim_sent_value and switch_trim_sent_value != 0,
"Trim sent counter on switch level is not equal to the sum of trim sent counter on port "
"level")

with allure.step("Verify TrimDrop counters on switch level"):
original_schedulers = {}
try:
# Block the trimmed queue
for port in trim_counter_params['egress_ports']:
for dut_member in port['dut_members']:
original_scheduler = disable_egress_data_plane(duthost, dut_member, TRIM_QUEUE)
original_schedulers[dut_member] = original_scheduler

# Trigger trimmed packets on queue6
counter_kwargs = self.get_verify_trimmed_counter_packet_kwargs({**trim_counter_params})
counter_kwargs.update({'duthost': duthost, 'ptfadapter': ptfadapter, 'expect_packets': False})
verify_trimmed_packet(**counter_kwargs)

# Get the TrimDrop counters on switch level
switch_trim_drop_value = get_switch_trim_counters_json(duthost)['trim_drop']
logger.info(f"switch_trim_drop_value: {switch_trim_drop_value}")
pytest_assert(switch_trim_drop_value > 0, "Trim drop counter on switch level is not greater than 0")

finally:
# Enable the trimmed queue with original scheduler
for port in trim_counter_params['egress_ports']:
for dut_member in port['dut_members']:
original_scheduler = original_schedulers.get(dut_member)
enable_egress_data_plane(duthost, dut_member, TRIM_QUEUE, original_scheduler)

with allure.step("Verify trimming counter when trimming feature toggles"):
trim_queue = 'UC'+str(TRIM_QUEUE)

# Get queue level and port level counter when trimming is enabled
port = test_params['egress_ports'][0]['dut_members'][0]
queue_trim_counter_trim_enable = get_queue_trim_counters_json(duthost, port)[trim_queue]
logger.info(f"Queue trim counter when trimming is enabled: {queue_trim_counter_trim_enable}")

port_trim_counters_trim_enable = get_port_trim_counters_json(duthost, port)
logger.info(f"Port trim counter when trimming is enabled: {port_trim_counters_trim_enable}")

# Disable trimming
for buffer_profile in test_params['trim_buffer_profiles']:
configure_trimming_action(duthost, test_params['trim_buffer_profiles'][buffer_profile], "off")
for buffer_profile in trim_counter_params['trim_buffer_profiles']:
configure_trimming_action(duthost, trim_counter_params['trim_buffer_profiles'][buffer_profile], "off")

# Get queue level and port level counter when trimming is disabled
queue_trim_counter_trim_disable = get_queue_trim_counters_json(duthost, port)[trim_queue]
logger.info(f"Queue trim counter when trimming is disabled: {queue_trim_counter_trim_disable}")

port_trim_counters_trim_disable = get_port_trim_counters_json(duthost, port)
logger.info(f"Port trim counter when trimming is disabled: {port_trim_counters_trim_disable}")

# Compare trim counters when trimming enable and disable
compare_counters(queue_trim_counter_trim_enable, queue_trim_counter_trim_disable, ['trimpacket'])
compare_counters(port_trim_counters_trim_enable, port_trim_counters_trim_disable, ['TRIM_PKTS'])

# Enable trimming again
for buffer_profile in test_params['trim_buffer_profiles']:
configure_trimming_action(duthost, test_params['trim_buffer_profiles'][buffer_profile], "on")
for buffer_profile in trim_counter_params['trim_buffer_profiles']:
configure_trimming_action(duthost, trim_counter_params['trim_buffer_profiles'][buffer_profile], "on")

# Get queue level and port level counter after trimming feature toggles
queue_trim_counter_after_toggle = get_queue_trim_counters_json(duthost, port)[trim_queue]
logger.info(f"Queue trim counter after trimming feature toggles: {queue_trim_counter_after_toggle}")

port_trim_counters_after_toggle = get_port_trim_counters_json(duthost, port)
logger.info(f"Port trim counter after trimming feature toggles: {port_trim_counters_after_toggle}")

# Compare trim counters when trimming enable and feature toggles
compare_counters(queue_trim_counter_trim_enable, queue_trim_counter_after_toggle, ['trimpacket'])
compare_counters(port_trim_counters_trim_enable, port_trim_counters_after_toggle,
['TRIM_PKTS', 'TRIM_TX_PKTS', 'TRIM_DRP_PKTS'])
61 changes: 30 additions & 31 deletions tests/packet_trimming/conftest.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import logging
import pytest
import copy

from tests.common.plugins.allure_wrapper import allure_step_wrapper as allure
from tests.common.utilities import get_dscp_to_queue_value, configure_packet_aging
from tests.common.utilities import configure_packet_aging
from tests.common.helpers.ptf_tests_helper import downstream_links, upstream_links, peer_links # noqa F401
from tests.common.mellanox_data import is_mellanox_device
from tests.common.helpers.srv6_helper import create_srv6_locator, del_srv6_locator, create_srv6_sid, del_srv6_sid
from tests.packet_trimming.constants import (SERVICE_PORT, COUNTERPOLL_INTERVAL, DEFAULT_DSCP,
SRV6_TUNNEL_MODE, SRV6_MY_LOCATOR_LIST, SRV6_MY_SID_LIST)
from tests.packet_trimming.packet_trimming_helper import (delete_blocking_scheduler, check_trimming_capability,
prepare_service_port, get_test_ports,
get_interface_peer_addresses, configure_tc_to_dscp_map,
set_buffer_profiles_for_block_and_trim_queues,
create_blocking_scheduler, configure_trimming_action,
cleanup_trimming_acl)
from tests.packet_trimming.constants import (
SERVICE_PORT, DEFAULT_DSCP, SRV6_TUNNEL_MODE, SRV6_MY_LOCATOR_LIST, SRV6_MY_SID_LIST,
COUNTER_DSCP, COUNTER_TYPE)
from tests.packet_trimming.packet_trimming_helper import (
delete_blocking_scheduler, check_trimming_capability, prepare_service_port, get_interface_peer_addresses,
configure_tc_to_dscp_map, set_buffer_profiles_for_block_and_trim_queues, create_blocking_scheduler,
configure_trimming_action, cleanup_trimming_acl, get_queue_id_by_dscp, get_test_ports)


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -87,28 +87,8 @@ def test_params(duthost, mg_facts, dut_qos_maps_module, downstream_links, upstre
f"egress_port_2_ipv4: {egress_port_2_ipv4}, egress_port_2_ipv6: {egress_port_2_ipv6}")

with allure.step(f"Get queue id for packet with dscp value {DEFAULT_DSCP}"):
# Get port QoS map for the downlink port
port_qos_map = dut_qos_maps_module['port_qos_map']
logger.info(f"Retrieving QoS maps for port: {ingress_port_name}")

# Extract the DSCP to TC map name from the port QoS configuration
dscp_to_tc_map_name = port_qos_map[ingress_port_name]['dscp_to_tc_map'].split('|')[-1].strip(']')
logger.info(f"DSCP to TC map name: {dscp_to_tc_map_name}")

# Extract the TC to Queue map name from the port QoS configuration
tc_to_queue_map_name = port_qos_map[ingress_port_name]['tc_to_queue_map'].split('|')[-1].strip(']')
logger.info(f"TC to Queue map name: {tc_to_queue_map_name}")

# Get the actual DSCP to TC mapping from the QoS maps
dscp_to_tc_map = dut_qos_maps_module['dscp_to_tc_map'][dscp_to_tc_map_name]
logger.debug(f"DSCP to TC mapping details: {dscp_to_tc_map}")

# Get the actual TC to Queue mapping from the QoS maps
tc_to_queue_map = dut_qos_maps_module['tc_to_queue_map'][tc_to_queue_map_name]
logger.debug(f"TC to Queue mapping details: {tc_to_queue_map}")

# Calculate the queue ID, this queue will be blocked during testing
block_queue = get_dscp_to_queue_value(DEFAULT_DSCP, dscp_to_tc_map, tc_to_queue_map)
block_queue = get_queue_id_by_dscp(DEFAULT_DSCP, ingress_port_name, dut_qos_maps_module)
logger.info(f"The tested queue: {block_queue}")

# Build egress_port_1 dictionary
Expand Down Expand Up @@ -153,6 +133,20 @@ def test_params(duthost, mg_facts, dut_qos_maps_module, downstream_links, upstre
return test_param


@pytest.fixture(scope="module")
def trim_counter_params(duthost, test_params, dut_qos_maps_module):
counter_queue = get_queue_id_by_dscp(COUNTER_DSCP, test_params['ingress_port']['name'], dut_qos_maps_module)
counter_param = copy.deepcopy(test_params)
counter_param['block_queue'] = counter_queue
counter_param['trim_buffer_profiles'] = {
'uplink': f"queue{counter_queue}_uplink_lossy_profile",
'downlink': f"queue{counter_queue}_downlink_lossy_profile",
}
logger.info(f"The counter parameters: {counter_param}")

return counter_param


@pytest.fixture(scope="module", autouse=True)
def setup_trimming(duthost, test_params):
"""
Expand Down Expand Up @@ -206,7 +200,12 @@ def setup_trimming(duthost, test_params):
configure_tc_to_dscp_map(duthost, test_params['egress_ports'])

with allure.step("Configure counterpoll interval"):
duthost.command(f"counterpoll queue interval {COUNTERPOLL_INTERVAL}")
for counter_level, stat_type, interval in COUNTER_TYPE:
duthost.shell(f"counterpoll {counter_level} enable")
duthost.set_counter_poll_interval(stat_type, interval)

status = duthost.get_counter_poll_status()
logger.info(f"Counter poll status: {status}")

with allure.step("Clear ports and queue counters"):
duthost.command("sonic-clear queuecounters")
Expand Down
13 changes: 12 additions & 1 deletion tests/packet_trimming/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@

PACKET_TYPE = ['ipv4_tcp', 'ipv4_udp', 'ipv6_tcp', 'ipv6_udp']
SERVICE_PORT = "Ethernet512"
COUNTERPOLL_INTERVAL = 2000

# Constants for packet trimming with SRv6 tests
SRV6_INNER_SRC_IP = '1.1.1.1'
Expand Down Expand Up @@ -164,3 +163,15 @@
[SRV6_MY_LOCATOR_LIST[8][0], SRV6_MY_LOCATOR_LIST[8][1], SRV6_UN, 'default'],
[SRV6_MY_LOCATOR_LIST[9][0], SRV6_MY_LOCATOR_LIST[9][1], SRV6_UN, 'default']
]

# Drop counter
SWITCH_INTERVAL = 10000
PORT_INTERVAL = 100
QUEUE_INTERVAL = 100

COUNTER_DSCP = 0
COUNTER_TYPE = [
("switch", "SWITCH_STAT", SWITCH_INTERVAL),
("port", "PORT_STAT", PORT_INTERVAL),
("queue", "QUEUE_STAT", QUEUE_INTERVAL),
]
Loading