From 04eae221e7c0089ae974f86e3f6fe156d4cb56ce Mon Sep 17 00:00:00 2001 From: imarom Date: Sun, 4 Sep 2016 15:25:42 +0300 Subject: DUAL mode - phase #1 --- .../stl/trex_stl_lib/trex_stl_client.py | 40 ++++++++++++++++++---- .../stl/trex_stl_lib/trex_stl_port.py | 6 ++-- .../stl/trex_stl_lib/trex_stl_stats.py | 2 +- .../stl/trex_stl_lib/utils/parsing_opts.py | 6 ++++ 4 files changed, 45 insertions(+), 9 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py index 7101b8a2..2c1fa5e9 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py @@ -743,13 +743,17 @@ class STLClient(object): return rc - def __push_remote (self, pcap_filename, port_id_list, ipg_usec, speedup, count, duration): + def __push_remote (self, pcap_filename, port_id_list, ipg_usec, speedup, count, duration, is_dual): port_id_list = self.__ports(port_id_list) rc = RC() for port_id in port_id_list: - rc.add(self.ports[port_id].push_remote(pcap_filename, ipg_usec, speedup, count, duration)) + + # for dual, provide the slave handler as well + slave_handler = self.ports[port_id ^ 0x1].handler if is_dual else "" + + rc.add(self.ports[port_id].push_remote(pcap_filename, ipg_usec, speedup, count, duration, is_dual, slave_handler)) return rc @@ -2183,7 +2187,8 @@ class STLClient(object): ipg_usec = None, speedup = 1.0, count = 1, - duration = -1): + duration = -1, + is_dual = False): """ Push a remote server-reachable PCAP file the path must be fullpath accessible to the server @@ -2206,6 +2211,13 @@ class STLClient(object): duration: float Limit runtime by duration in seconds + + is_dual: bool + Inject from both directions. + requires ERF file with meta data for direction. + also requires that all the ports will be in master mode + with their adjacent ports as slaves + :raises: + :exc:`STLError` @@ -2218,9 +2230,23 @@ class STLClient(object): validate_type('speedup', speedup, (float, int)) validate_type('count', count, int) validate_type('duration', duration, (float, int)) + validate_type('is_dual', is_dual, bool) + + # for dual mode check that all are masters + if is_dual: + for port in ports: + master = port + slave = port ^ 0x1 + + if slave in ports: + raise STLError("dual mode: cannot provide adjacent ports ({0}, {1}) in a batch".format(master, slave)) + + if not slave in self.get_acquired_ports(): + raise STLError("dual mode: port {0} must be owned as well".format(slave)) + self.logger.pre_cmd("Pushing remote PCAP on port(s) {0}:".format(ports)) - rc = self.__push_remote(pcap_filename, ports, ipg_usec, speedup, count, duration) + rc = self.__push_remote(pcap_filename, ports, ipg_usec, speedup, count, duration, is_dual) self.logger.post_cmd(rc) if not rc: @@ -3023,7 +3049,8 @@ class STLClient(object): parsing_opts.DURATION, parsing_opts.IPG, parsing_opts.SPEEDUP, - parsing_opts.FORCE) + parsing_opts.FORCE, + parsing_opts.DUAL) opts = parser.parse_args(line.split()) if not opts: @@ -3046,7 +3073,8 @@ class STLClient(object): ipg_usec = opts.ipg_usec, speedup = opts.speedup, count = opts.count, - duration = opts.duration) + duration = opts.duration, + is_dual = opts.dual) else: self.push_pcap(opts.file[0], diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py index 890ce7de..f0e3b109 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py @@ -582,7 +582,7 @@ class Port(object): return self.ok() @writeable - def push_remote (self, pcap_filename, ipg_usec, speedup, count, duration): + def push_remote (self, pcap_filename, ipg_usec, speedup, count, duration, is_dual, slave_handler): params = {"handler": self.handler, "port_id": self.port_id, @@ -590,7 +590,9 @@ class Port(object): "ipg_usec": ipg_usec if ipg_usec is not None else -1, "speedup": speedup, "count": count, - "duration": duration} + "duration": duration, + "is_dual": is_dual, + "slave_handler": slave_handler} rc = self.transmit("push_remote", params) if rc.bad(): diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py index afb01791..4586f647 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py @@ -1008,7 +1008,7 @@ class CPortStats(CTRexStats): bps_L1 = calc_bps_L1(bps, pps) bps_rx_L1 = calc_bps_L1(rx_bps, rx_pps) snapshot['m_total_tx_bps_L1'] = bps_L1 - snapshot['m_percentage'] = (bps_L1 / self._port_obj.get_speed_bps()) * 100 + snapshot['m_percentage'] = (bps_L1 / self._port_obj.get_speed_bps()) * 100.0 # TX line util not smoothed diff_tx_pkts = snapshot.get('opackets', 0) - self.latest_stats.get('opackets', 0) diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py index 9ed6c0f8..4e57aae3 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py @@ -39,6 +39,7 @@ REMOTE_FILE = 23 LOCKED = 24 PIN_CORES = 25 CORE_MASK = 26 +DUAL = 28 GLOBAL_STATS = 50 PORT_STATS = 51 @@ -313,6 +314,11 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], 'default': False, 'help': "file path should be interpeted by the server (remote file)"}), + DUAL: ArgumentPack(['--dual'], + {"action": "store_true", + 'default': False, + 'help': "Transmit in a dual mode - requires a slave attached to the port"}), + FILE_PATH: ArgumentPack(['-f'], {'metavar': 'FILE', 'dest': 'file', -- cgit 1.2.3-korg