[SDFAB-552] QoS test for Leaf pair with mobile traffic classification
Also, adding a check to ensure we are generating congestion, based on the live ports stats rather than directly on average TRex port stats.
Change-Id: I4337fe8ad8f59e6873a73e4d105853b18d199921
diff --git a/TestON/drivers/common/api/controller/trexclientdriver.py b/TestON/drivers/common/api/controller/trexclientdriver.py
index a3923c9..50c8c39 100644
--- a/TestON/drivers/common/api/controller/trexclientdriver.py
+++ b/TestON/drivers/common/api/controller/trexclientdriver.py
@@ -230,11 +230,13 @@
self.all_sender_port.add(trex_port)
return True
- def startAndWaitTraffic(self, duration=10):
+ def startAndWaitTraffic(self, duration=10, ports=[]):
"""
Start generating traffic and wait traffic to be send
+
:param duration: Traffic generation duration
- :return:
+ :param ports: Ports IDs to monitor while traffic is active
+ :return: port statistics collected while traffic is active
"""
if not self.trex_client:
main.log.error(
@@ -244,6 +246,7 @@
self.trex_client.start(list(self.all_sender_port), mult="1",
duration=duration)
main.log.info("Waiting until all traffic is sent..")
+ result = self.__monitor_port_stats(ports)
self.trex_client.wait_on_traffic(ports=list(self.all_sender_port),
rx_delay_ms=100)
main.log.info("...traffic sent!")
@@ -251,7 +254,7 @@
self.all_sender_port = set()
main.log.info("Getting stats")
self.stats = self.trex_client.get_stats()
- main.log.info("GOT stats")
+ return result
def getFlowStats(self, flow_id):
if self.stats is None:
@@ -319,7 +322,8 @@
trex_daemon_client.start_stateless(cfg=trex_config_file_on_server)
except ConnectionRefusedError:
main.log.error(
- "Unable to connect to server %s.\n" + "Did you start the Trex daemon?" % trex_address)
+ "Unable to connect to server %s.\n" +
+ "Did you start the Trex daemon?" % trex_address)
return False
return True
@@ -354,6 +358,87 @@
M = 1000 * K
G = 1000 * M
+ def __monitor_port_stats(self, ports, time_interval=1):
+ """
+ List some port stats continuously while traffic is active
+
+ :param ports: List of ports ids to monitor
+ :param time_interval: Interval between read
+ :return: Statistics read while traffic is active
+ """
+
+ results = {
+ port_id: {"rx_bps": [], "tx_bps": [], "rx_pps": [], "tx_pps": []}
+ for port_id in ports
+ }
+ results["duration"] = []
+
+ prev = {
+ port_id: {
+ "opackets": 0,
+ "ipackets": 0,
+ "obytes": 0,
+ "ibytes": 0,
+ "time": time.time(),
+ }
+ for port_id in ports
+ }
+
+ s_time = time.time()
+ while self.trex_client.is_traffic_active():
+ stats = self.trex_client.get_stats(ports=ports)
+ if not stats:
+ break
+
+ main.log.debug(
+ "\nTRAFFIC RUNNING {:.2f} SEC".format(time.time() - s_time))
+ main.log.debug(
+ "{:^4} | {:<10} | {:<10} | {:<10} | {:<10} |".format(
+ "Port", "RX bps", "TX bps", "RX pps", "TX pps"
+ )
+ )
+ main.log.debug(
+ "----------------------------------------------------------")
+
+ for port in ports:
+ opackets = stats[port]["opackets"]
+ ipackets = stats[port]["ipackets"]
+ obytes = stats[port]["obytes"]
+ ibytes = stats[port]["ibytes"]
+ time_diff = time.time() - prev[port]["time"]
+
+ rx_bps = 8 * (ibytes - prev[port]["ibytes"]) / time_diff
+ tx_bps = 8 * (obytes - prev[port]["obytes"]) / time_diff
+ rx_pps = ipackets - prev[port]["ipackets"] / time_diff
+ tx_pps = opackets - prev[port]["opackets"] / time_diff
+
+ main.log.debug(
+ "{:^4} | {:<10} | {:<10} | {:<10} | {:<10} |".format(
+ port,
+ TrexClientDriver.__to_readable(rx_bps, "bps"),
+ TrexClientDriver.__to_readable(tx_bps, "bps"),
+ TrexClientDriver.__to_readable(rx_pps, "pps"),
+ TrexClientDriver.__to_readable(tx_pps, "pps"),
+ )
+ )
+
+ results["duration"].append(time.time() - s_time)
+ results[port]["rx_bps"].append(rx_bps)
+ results[port]["tx_bps"].append(tx_bps)
+ results[port]["rx_pps"].append(rx_pps)
+ results[port]["tx_pps"].append(tx_pps)
+
+ prev[port]["opackets"] = opackets
+ prev[port]["ipackets"] = ipackets
+ prev[port]["obytes"] = obytes
+ prev[port]["ibytes"] = ibytes
+ prev[port]["time"] = time.time()
+
+ time.sleep(time_interval)
+ main.log.debug("")
+
+ return results
+
@staticmethod
def __to_readable(src, unit="bps"):
"""