Skip to content

Commit

Permalink
Revert "Add test case for trap flow counter feature (#4456)"
Browse files Browse the repository at this point in the history
This reverts commit c630ea1.
  • Loading branch information
neethajohn authored Nov 22, 2021
1 parent 7a4b31e commit e4651f2
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 218 deletions.
119 changes: 24 additions & 95 deletions ansible/roles/test/files/ptftests/copp_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,6 @@ def __init__(self):
self.myip = test_params.get('myip', None)
self.peerip = test_params.get('peerip', None)
self.default_server_send_rate_limit_pps = test_params.get('send_rate_limit', 2000)

# For counter test
self.expect_send_pkt_number = test_params.get('sent_pkt_number', None)
self.send_duration = test_params.get('send_duration', None)
self.is_counter_test = self.expect_send_pkt_number is not None and self.send_duration is not None

self.needPreSend = None

Expand Down Expand Up @@ -115,9 +110,6 @@ def copp_test(self, packet, send_intf, recv_intf):
'''
Pre-send some packets for a second to absorb the CBS capacity.
'''
if self.is_counter_test:
return self.copp_counter_test(packet, send_intf, recv_intf)

if self.needPreSend:
pre_send_count = 0
end_time = datetime.datetime.now() + datetime.timedelta(seconds=self.DEFAULT_PRE_SEND_INTERVAL_SEC)
Expand Down Expand Up @@ -186,67 +178,6 @@ def copp_test(self, packet, send_intf, recv_intf):

return send_count, recv_count, time_delta, time_delta_ms, tx_pps, rx_pps

def copp_counter_test(self, packet, send_intf, recv_intf):
pre_test_ptf_tx_counter = self.dataplane.get_counters(*send_intf)
pre_test_ptf_rx_counter = self.dataplane.get_counters(*recv_intf)
pre_test_nn_tx_counter = self.dataplane.get_nn_counters(*send_intf)
pre_test_nn_rx_counter = self.dataplane.get_nn_counters(*recv_intf)

send_count = 0
start_time = datetime.datetime.now()
send_window = float(self.send_duration) / float(self.expect_send_pkt_number)
while send_count < self.expect_send_pkt_number:
begin = time.time()
testutils.send_packet(self, send_intf, packet)
send_count += 1
elapse = time.time() - begin

# Depending on the server/platform combination it is possible for the server to
# overwhelm the DUT, so we add an artificial delay here to rate-limit the server.
if elapse > 0:
time.sleep(send_window - elapse)

end_time = datetime.datetime.now()
time.sleep(self.DEFAULT_RECEIVE_WAIT_TIME) # Wait a little bit for all the packets to make it through
recv_count = testutils.count_matched_packets(self, packet, recv_intf[1], recv_intf[0])

post_test_ptf_tx_counter = self.dataplane.get_counters(*send_intf)
post_test_ptf_rx_counter = self.dataplane.get_counters(*recv_intf)
post_test_nn_tx_counter = self.dataplane.get_nn_counters(*send_intf)
post_test_nn_rx_counter = self.dataplane.get_nn_counters(*recv_intf)

ptf_tx_count = int(post_test_ptf_tx_counter[1] - pre_test_ptf_tx_counter[1])
nn_tx_count = int(post_test_nn_tx_counter[1] - pre_test_nn_tx_counter[1])
ptf_rx_count = int(post_test_ptf_rx_counter[0] - pre_test_ptf_rx_counter[0])
nn_rx_count = int(post_test_nn_rx_counter[0] - pre_test_nn_rx_counter[0])

self.log("", True)
self.log("Counters before the test:", True)
self.log("If counter (0, n): %s" % str(pre_test_ptf_tx_counter), True)
self.log("NN counter (0, n): %s" % str(pre_test_nn_tx_counter), True)
self.log("If counter (1, n): %s" % str(pre_test_ptf_rx_counter), True)
self.log("NN counter (1, n): %s" % str(pre_test_nn_rx_counter), True)
self.log("", True)
self.log("Counters after the test:", True)
self.log("If counter (0, n): %s" % str(post_test_ptf_tx_counter), True)
self.log("NN counter (0, n): %s" % str(post_test_nn_tx_counter), True)
self.log("If counter (1, n): %s" % str(post_test_ptf_rx_counter), True)
self.log("NN counter (1, n): %s" % str(post_test_nn_rx_counter), True)
self.log("")
self.log("Sent through NN to local ptf_nn_agent: %d" % ptf_tx_count)
self.log("Sent through If to remote ptf_nn_agent: %d" % nn_tx_count)
self.log("Recv from If on remote ptf_nn_agent: %d" % ptf_rx_count)
self.log("Recv from NN on from remote ptf_nn_agent: %d" % nn_rx_count)

time_delta = end_time - start_time
self.log("Sent out %d packets in %ds" % (send_count, time_delta.seconds))
time_delta_ms = (time_delta.microseconds + time_delta.seconds * 10**6) / 1000
tx_pps = int(send_count / (float(time_delta_ms) / 1000))
rx_pps = int(recv_count / (float(time_delta_ms) / 1000))

return send_count, recv_count, time_delta, time_delta_ms, tx_pps, rx_pps


def contruct_packet(self, port_number):
raise NotImplementedError

Expand Down Expand Up @@ -283,22 +214,21 @@ def __init__(self):
self.needPreSend = False

def check_constraints(self, send_count, recv_count, time_delta_ms, rx_pps):
if not self.is_counter_test:
pkt_rx_limit = send_count * 0.90
pkt_rx_limit = send_count * 0.90

self.log("")
self.log("Checking constraints (NoPolicy):")
self.log(
"rx_pps (%d) > NO_POLICER_LIMIT (%d): %s" %
(int(rx_pps), int(self.NO_POLICER_LIMIT), str(rx_pps > self.NO_POLICER_LIMIT))
)
self.log(
"recv_count (%d) > pkt_rx_limit (%d): %s" %
(int(recv_count), int(pkt_rx_limit), str(recv_count > pkt_rx_limit))
)
self.log("")
self.log("Checking constraints (NoPolicy):")
self.log(
"rx_pps (%d) > NO_POLICER_LIMIT (%d): %s" %
(int(rx_pps), int(self.NO_POLICER_LIMIT), str(rx_pps > self.NO_POLICER_LIMIT))
)
self.log(
"recv_count (%d) > pkt_rx_limit (%d): %s" %
(int(recv_count), int(pkt_rx_limit), str(recv_count > pkt_rx_limit))
)

assert(rx_pps > self.NO_POLICER_LIMIT)
assert(recv_count > pkt_rx_limit)
assert(rx_pps > self.NO_POLICER_LIMIT)
assert(recv_count > pkt_rx_limit)


class PolicyTest(ControlPlaneBaseTest):
Expand All @@ -307,18 +237,17 @@ def __init__(self):
self.needPreSend = True

def check_constraints(self, send_count, recv_count, time_delta_ms, rx_pps):
if not self.is_counter_test:
self.log("")
self.log("Checking constraints (PolicyApplied):")
self.log(
"PPS_LIMIT_MIN (%d) <= rx_pps (%d) <= PPS_LIMIT_MAX (%d): %s" %
(int(self.PPS_LIMIT_MIN),
int(rx_pps),
int(self.PPS_LIMIT_MAX),
str(self.PPS_LIMIT_MIN <= rx_pps <= self.PPS_LIMIT_MAX))
)

assert(self.PPS_LIMIT_MIN <= rx_pps <= self.PPS_LIMIT_MAX)
self.log("")
self.log("Checking constraints (PolicyApplied):")
self.log(
"PPS_LIMIT_MIN (%d) <= rx_pps (%d) <= PPS_LIMIT_MAX (%d): %s" %
(int(self.PPS_LIMIT_MIN),
int(rx_pps),
int(self.PPS_LIMIT_MAX),
str(self.PPS_LIMIT_MIN <= rx_pps <= self.PPS_LIMIT_MAX))
)

assert(self.PPS_LIMIT_MIN <= rx_pps <= self.PPS_LIMIT_MAX)


# SONIC config contains policer CIR=600 for ARP
Expand Down
131 changes: 8 additions & 123 deletions tests/copp/test_copp.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,12 @@
import logging
import pytest
import json
import random
import threading
import time
from collections import namedtuple

from tests.copp import copp_utils
from tests.ptf_runner import ptf_runner
from tests.common import config_reload, constants
from tests.common.system_utils import docker
from tests.common.utilities import wait_until

# Module-level fixtures
from tests.common.fixtures.ptfhost_utils import copy_ptftests_directory # lgtm[py/unused-import]
Expand All @@ -58,8 +54,6 @@
_SUPPORTED_T2_TOPOS = ["t2"]
_TOR_ONLY_PROTOCOL = ["DHCP"]
_TEST_RATE_LIMIT = 600
_SEND_PACKET_NUMBER = 1500
_SEND_DURATION = 30


class TestCOPP(object):
Expand Down Expand Up @@ -104,51 +98,6 @@ def test_no_policer(self, protocol, duthosts, enum_rand_one_per_hwsku_frontend_h
copp_testbed,
dut_type)

@pytest.mark.parametrize("protocol", ["LACP",
"LLDP",
"UDLD",
"IP2ME"])
def test_counter(self, protocol, duthosts, rand_one_dut_hostname, ptfhost, copp_testbed, dut_type, counter_test):
duthost = duthosts[rand_one_dut_hostname]
trap_type = protocol.lower()

# wait until the trap counter is enabled
assert wait_until(10, 1, 0, _check_trap_counter_enabled, duthost, trap_type), 'counter is not created for {}'.format(trap_type)

# clean previous counter value
duthost.command('sonic-clear flowcnt-trap')

# start a thread to collect the max PPS value
actual_rate = []
t = threading.Thread(target=_collect_counter_rate, args=(duthost, trap_type, actual_rate))
t.start()

# init and start PTF
_copp_runner(duthost,
ptfhost,
protocol,
copp_testbed,
dut_type,
True)

# wait for thread finish
t.join()

# get final packet count from CLI
expect_rate = float(_SEND_PACKET_NUMBER / _SEND_DURATION)
actual_packet_number = None
cli_data = duthost.show_and_parse('show flowcnt-trap stats')
for line in cli_data:
if 'trap name' in line and line['trap name'] == trap_type:
actual_packet_number = int(line['packets'].replace(',', ''))
break

assert actual_packet_number == _SEND_PACKET_NUMBER, 'Trap {} expect send packet number: {}, but actual: {}'.format(trap_type, _SEND_PACKET_NUMBER, actual_packet_number)
assert len(actual_rate) == 1, 'Failed to collect PPS value for trap {}'.format(trap_type)
# Allow a 10 percent threshold for trap rate
assert (expect_rate * 0.9) < actual_rate[0] < (expect_rate * 1.1), 'Trap {} expect send packet rate: {}, but actual: {}'.format(trap_type, expect_rate, actual_rate)


@pytest.fixture(scope="class")
def dut_type(duthosts, enum_rand_one_per_hwsku_frontend_hostname):
duthost = duthosts[enum_rand_one_per_hwsku_frontend_hostname]
Expand Down Expand Up @@ -208,33 +157,17 @@ def ignore_expected_loganalyzer_exceptions(enum_rand_one_per_hwsku_frontend_host
if loganalyzer: # Skip if loganalyzer is disabled
loganalyzer[enum_rand_one_per_hwsku_frontend_hostname].ignore_regex.extend(ignoreRegex)

@pytest.fixture(scope="function")
def counter_test(duthosts, rand_one_dut_hostname):
duthost = duthosts[rand_one_dut_hostname]
duthost.command('counterpoll flowcnt-trap enable')

yield

duthost.command('counterpoll flowcnt-trap disable')

def _copp_runner(dut, ptf, protocol, test_params, dut_type, counter_test=False):
def _copp_runner(dut, ptf, protocol, test_params, dut_type):
"""
Configures and runs the PTF test cases.
"""
if not counter_test:
params = {"verbose": False,
"target_port": test_params.nn_target_port,
"myip": test_params.myip,
"peerip": test_params.peerip,
"send_rate_limit": test_params.send_rate_limit}
else:
params = {"verbose": False,
"target_port": test_params.nn_target_port,
"myip": test_params.myip,
"peerip": test_params.peerip,
"send_rate_limit": test_params.send_rate_limit,
"sent_pkt_number": _SEND_PACKET_NUMBER,
"send_duration": _SEND_DURATION}

params = {"verbose": False,
"target_port": test_params.nn_target_port,
"myip": test_params.myip,
"peerip": test_params.peerip,
"send_rate_limit": test_params.send_rate_limit}

dut_ip = dut.mgmt_ip
device_sockets = ["0-{}@tcp://127.0.0.1:10900".format(test_params.nn_target_port),
"1-{}@tcp://{}:10900".format(test_params.nn_target_port, dut_ip)]
Expand Down Expand Up @@ -398,51 +331,3 @@ def _teardown_multi_asic_proxy(dut, creds, test_params, tbinfo):
ns_ip = dut.shell("sudo ip -n {} -4 -o addr show eth0".format(test_params.nn_target_namespace) + " | awk '{print $4}' | cut -d'/' -f1")["stdout"]
dut.command("sudo iptables -t nat -D PREROUTING -p tcp --dport 10900 -j DNAT --to-destination {}".format(ns_ip))
dut.command("sudo ip -n {} rule delete from {} to {} pref 3 lookup default".format(test_params.nn_target_namespace, ns_ip, tbinfo["ptf_ip"]))

def _check_trap_counter_enabled(duthost, trap_type):
lines = duthost.command('show flowcnt-trap stats')['stdout']
return trap_type in lines

def _collect_counter_rate(duthost, trap_type, actual_rate):
rate_values = []
# Wait up to _SEND_DURATION + 5 seconds for PTF to stop sending packet,
# as it might take some time for PTF to initialize itself
max_wait = _SEND_DURATION + 5
packets = None
while max_wait > 0:
cli_data = duthost.show_and_parse('show flowcnt-trap stats')
for line in cli_data:
if 'trap name' in line and line['trap name'] == trap_type:
packets = line['packets']
if packets == 'N/A':
# Packets value is not available yet
logging.debug('Trap {} packets value is not available yet'.format(trap_type))
break

pps_value = line['pps']
if pps_value == 'N/A':
# PPS value is not available yet
logging.debug('Trap {} PPS value is not available yet'.format(trap_type))
break

packets = int(packets.replace(',', ''))
if packets == 0:
# PTF has not started yet
logging.debug('Trap {} packets value is still 0, PTF has not started yet'.format(trap_type))
break

logging.info('Trap {} current PPS value is {}, packets value is {}'.format(trap_type, pps_value, packets))
rate_values.append(float(pps_value[:-2]))
break
if packets == _SEND_PACKET_NUMBER:
# Enough packets are sent, stop
break
time.sleep(0.5)
max_wait -= 0.5

if rate_values:
# Calculate max PPS
max_pps = max(rate_values)
logging.info('Trap {} max PPS is {}'.format(trap_type, max_pps))
actual_rate.append(max_pps)

0 comments on commit e4651f2

Please sign in to comment.