diff options
author | Miroslav Miklus <mmiklus@cisco.com> | 2016-05-13 00:35:53 +0200 |
---|---|---|
committer | Miroslav Miklus <mmiklus@cisco.com> | 2016-05-18 09:01:05 +0000 |
commit | 180d17939d123c04bf142cedf02daa325e3f4fa6 (patch) | |
tree | e4dd5b1ed815f3e33cecc0da4a7e150f01b2d8ad /resources/libraries | |
parent | 824fb1d6a1d94636d7a73ad6b1fc69fabf8efad7 (diff) |
T-REX stl traffic send improvement for async calls
JIRA: CSIT-68
- show runtime statistics with running traffic
- T-REX driver async. driver
Change-Id: Ie5eb7021f610fb58383b033dda5b1b867f7d3d2c
Signed-off-by: Miroslav Miklus <mmiklus@cisco.com>
Diffstat (limited to 'resources/libraries')
-rw-r--r-- | resources/libraries/python/TrafficGenerator.py | 100 | ||||
-rw-r--r-- | resources/libraries/python/VppCounters.py | 22 | ||||
-rw-r--r-- | resources/libraries/robot/counters.robot | 15 | ||||
-rw-r--r-- | resources/libraries/robot/performance.robot | 31 |
4 files changed, 138 insertions, 30 deletions
diff --git a/resources/libraries/python/TrafficGenerator.py b/resources/libraries/python/TrafficGenerator.py index 7f53836494..3969891cf9 100644 --- a/resources/libraries/python/TrafficGenerator.py +++ b/resources/libraries/python/TrafficGenerator.py @@ -35,7 +35,7 @@ class TGDropRateSearchImpl(DropRateSearch): loss_acceptance_type, traffic_type): # we need instance of TrafficGenerator instantiated by Robot Framework - # to be able to use trex_stateless_remote_exec method + # to be able to use trex_stl-*() tg_instance = BuiltIn().get_library_instance( 'resources.libraries.python.TrafficGenerator') @@ -43,9 +43,9 @@ class TGDropRateSearchImpl(DropRateSearch): raise Exception('TG subtype not defined') elif tg_instance._node['subtype'] == NodeSubTypeTG.TREX: unit_rate = str(rate) + self.get_rate_type_str() - tg_instance.trex_stateless_remote_exec(self.get_duration(), + tg_instance.trex_stl_start_remote_exec(self.get_duration(), unit_rate, frame_size, - traffic_type) + traffic_type, False) # TODO: getters for tg_instance and loss_acceptance_type logger.trace("comparing: {} < {} ".format(tg_instance._loss, @@ -73,6 +73,7 @@ class TrafficGenerator(object): # T-REX interface order mapping self._ifaces_reordered = 0 + #pylint: disable=too-many-arguments, too-many-locals def initialize_traffic_generator(self, tg_node, tg_if1, tg_if2, dut1_node, dut1_if1, dut1_if2, dut2_node, dut2_if1, dut2_if2, @@ -197,19 +198,54 @@ class TrafficGenerator(object): logger.error('pkill t-rex failed: {0}'.format(stdout + stderr)) raise RuntimeError('pkill t-rex failed') - def trex_stateless_remote_exec(self, duration, rate, framesize, - traffic_type): - """Execute stateless script on remote node over ssh. + @staticmethod + def trex_stl_stop_remote_exec(node): + """Execute script on remote node over ssh to stop running traffic. + + :param node: T-REX generator node. + :type node: dict + :return: Nothing + """ + ssh = SSH() + ssh.connect(node) + + (ret, stdout, stderr) = ssh.exec_command( + "sh -c '/tmp/openvpp-testing/resources/tools/t-rex/" + "t-rex-stateless-stop.py'") + logger.trace(ret) + logger.trace(stdout) + logger.trace(stderr) + + if int(ret) != 0: + raise RuntimeError('T-rex stateless runtime error') + + def trex_stl_start_remote_exec(self, duration, rate, framesize, + traffic_type, async_call, warmup_time=5): + """Execute script on remote node over ssh to start traffic. + :param duration: Time expresed in seconds for how long to send traffic. + :param rate: Traffic rate expressed with units (pps, %) + :param framesize: L2 frame size to send (without padding and IPG). :param traffic_type: Traffic profile. + :param async_call: If enabled then don't wait for all incomming trafic. + :param warmup_time: Warmup time period. + :type duration: int + :type rate: str + :type framesize: int :type traffic_type: str + :type async_call: bool + :type warmup_time: int + :return: Nothing """ ssh = SSH() ssh.connect(self._node) _p0 = 1 _p1 = 2 + _async = "" + if async_call: + _async = "--async" if self._ifaces_reordered != 0: _p0, _p1 = _p1, _p0 @@ -217,40 +253,43 @@ class TrafficGenerator(object): (ret, stdout, stderr) = ssh.exec_command( "sh -c '/tmp/openvpp-testing/resources/tools/t-rex/" "t-rex-stateless.py " - "-d {0} -r {1} -s {2} " + "--duration={0} -r {1} -s {2} " "--p{3}_src_start_ip 10.10.10.1 " "--p{3}_src_end_ip 10.10.10.254 " "--p{3}_dst_start_ip 20.20.20.1 " "--p{4}_src_start_ip 20.20.20.1 " "--p{4}_src_end_ip 20.20.20.254 " - "--p{4}_dst_start_ip 10.10.10.1'".\ - format(duration, rate, framesize, _p0, _p1),\ + "--p{4}_dst_start_ip 10.10.10.1 " + "{5} --warmup_time={6}'".format(duration, rate, framesize, _p0, + _p1, _async, warmup_time), timeout=int(duration)+60) elif traffic_type in ["3-node-IPv4"]: (ret, stdout, stderr) = ssh.exec_command( "sh -c '/tmp/openvpp-testing/resources/tools/t-rex/" "t-rex-stateless.py " - "-d {0} -r {1} -s {2} " + "--duration={0} -r {1} -s {2} " "--p{3}_src_start_ip 10.10.10.2 " "--p{3}_src_end_ip 10.10.10.254 " "--p{3}_dst_start_ip 20.20.20.2 " "--p{4}_src_start_ip 20.20.20.2 " "--p{4}_src_end_ip 20.20.20.254 " - "--p{4}_dst_start_ip 10.10.10.2'".\ - format(duration, rate, framesize, _p0, _p1),\ + "--p{4}_dst_start_ip 10.10.10.2 " + "{5} --warmup_time={6}'".format(duration, rate, framesize, _p0, + _p1, _async, warmup_time), timeout=int(duration)+60) elif traffic_type in ["3-node-IPv6"]: (ret, stdout, stderr) = ssh.exec_command( "sh -c '/tmp/openvpp-testing/resources/tools/t-rex/" "t-rex-stateless.py " - "-d {0} -r {1} -s {2} -6 " + "--duration={0} -r {1} -s {2} -6 " "--p{3}_src_start_ip 2001:1::2 " "--p{3}_src_end_ip 2001:1::FE " "--p{3}_dst_start_ip 2001:2::2 " "--p{4}_src_start_ip 2001:2::2 " "--p{4}_src_end_ip 2001:2::FE " - "--p{4}_dst_start_ip 2001:1::2'".\ - format(duration, rate, framesize, _p0, _p1),\ + "--p{4}_dst_start_ip 2001:1::2 " + "{5} --warmup_time={6}'".format(duration, rate, framesize, _p0, + _p1, _async, warmup_time), timeout=int(duration)+60) else: raise NotImplementedError('Unsupported traffic type') @@ -261,6 +300,11 @@ class TrafficGenerator(object): if int(ret) != 0: raise RuntimeError('T-rex stateless runtime error') + elif async_call: + #no result + self._received = None + self._sent = None + self._loss = None else: # last line from console output line = stdout.splitlines()[-1] @@ -272,16 +316,24 @@ class TrafficGenerator(object): self._sent = self._result.split(', ')[2].split('=')[1] self._loss = self._result.split(', ')[3].split('=')[1] - def send_traffic_on(self, node, duration, rate, - framesize, traffic_type): + def stop_traffic_on_tg(self): + """Stop all traffic on TG + + :return: Nothing + """ + if self._node is None: + raise RuntimeError("TG is not set") + if self._node['subtype'] == NodeSubTypeTG.TREX: + self.trex_stl_stop_remote_exec(self._node) + + def send_traffic_on_tg(self, duration, rate, framesize, + traffic_type, warmup_time=5, async_call=False): """Send traffic from all configured interfaces on TG. - :param node: Dictionary containing TG information. :param duration: Duration of test traffic generation in seconds. :param rate: Offered load per interface (e.g. 1%, 3gbps, 4mpps, ...). :param framesize: Frame size (L2) in Bytes. :param traffic_type: Traffic profile. - :type node: dict :type duration: str :type rate: str :type framesize: str @@ -289,14 +341,20 @@ class TrafficGenerator(object): :return: TG output. :rtype: str """ + + node = self._node + if node is None: + raise RuntimeError("TG is not set") + if node['type'] != NodeType.TG: raise Exception('Node type is not a TG') if node['subtype'] is None: raise Exception('TG subtype not defined') elif node['subtype'] == NodeSubTypeTG.TREX: - self.trex_stateless_remote_exec(duration, rate, framesize, - traffic_type) + self.trex_stl_start_remote_exec(duration, rate, framesize, + traffic_type, async_call, + warmup_time=warmup_time) else: raise NotImplementedError("TG subtype not supported") diff --git a/resources/libraries/python/VppCounters.py b/resources/libraries/python/VppCounters.py index d8d4554899..4bb7d63135 100644 --- a/resources/libraries/python/VppCounters.py +++ b/resources/libraries/python/VppCounters.py @@ -58,8 +58,18 @@ class VppCounters(object): vat.execute_script("show_errors_verbose.vat", node, json_out=False) @staticmethod + def vpp_show_runtime(node): + """Run "show runtime" CLI command. + + :param node: Node to run command on. + :type node: dict + """ + vat = VatExecutor() + vat.execute_script("show_runtime.vat", node, json_out=False) + + @staticmethod def vpp_show_runtime_verbose(node): - """Run "show runtime" debug CLI command. + """Run "show runtime verbose" CLI command. :param node: Node to run command on. :type node: dict @@ -78,6 +88,16 @@ class VppCounters(object): vat.execute_script("show_hardware_detail.vat", node, json_out=False) @staticmethod + def vpp_clear_runtime(node): + """Run "clear runtime" CLI command. + + :param node: Node to run command on. + :type node: dict + """ + vat = VatExecutor() + vat.execute_script("clear_runtime.vat", node, json_out=False) + + @staticmethod def vpp_clear_interface_counters(node): """Clear interface counters on VPP node. diff --git a/resources/libraries/robot/counters.robot b/resources/libraries/robot/counters.robot index b4db3febd9..0cb18c15db 100644 --- a/resources/libraries/robot/counters.robot +++ b/resources/libraries/robot/counters.robot @@ -43,6 +43,17 @@ | | [Arguments] | ${node} | | Vpp Dump Stats Table | ${node} | | Vpp Show Errors | ${node} -| | Vpp Show Errors Verbose | ${node} | | Vpp Show Hardware Detail | ${node} -| | Vpp Show Runtime Verbose | ${node} +| | Vpp Show Runtime | ${node} + +| Clear runtime statistics on all DUTs +| | [Documentation] | Clear VPP runtime statistics on all DUTs +| | ${duts}= | Get Matches | ${nodes} | DUT* +| | :FOR | ${dut} | IN | @{duts} +| | | Vpp clear runtime | ${nodes['${dut}']} + +| Show runtime statistics on all DUTs +| | [Documentation] | Show VPP runtime statistics on all DUTs +| | ${duts}= | Get Matches | ${nodes} | DUT* +| | :FOR | ${dut} | IN | @{duts} +| | | Vpp show runtime | ${nodes['${dut}']} diff --git a/resources/libraries/robot/performance.robot b/resources/libraries/robot/performance.robot index d43073d30d..e26bc19283 100644 --- a/resources/libraries/robot/performance.robot +++ b/resources/libraries/robot/performance.robot @@ -162,7 +162,8 @@ | | [Documentation] | Find throughput by using RFC2544 linear search | | [Arguments] | ${framesize} | ${start_rate} | ${step_rate} | | ... | ${topology_type} | ${min_rate} | ${max_rate} -| | Set Duration | 60 +| | ${duration}= | Set Variable | 60 +| | Set Duration | ${duration} | | Set Search Rate Boundaries | ${max_rate} | ${min_rate} | | Set Search Linear Step | ${step_rate} | | Set Search Frame Size | ${framesize} @@ -170,12 +171,15 @@ | | Linear Search | ${start_rate} | ${topology_type} | | ${rate_per_stream}= | Verify Search Result | | Display result of NDR search | ${rate_per_stream} | ${framesize} | 2 +| | Clear and show runtime stats with running traffic | ${duration} +| | ... | ${rate_per_stream}pps | ${framesize} | ${topology_type} | Find NDR using binary search and pps | | [Documentation] | Find throughput by using RFC2544 binary search | | [Arguments] | ${framesize} | ${binary_min} | ${binary_max} | | ... | ${topology_type} | ${min_rate} | ${max_rate} | ${threshold} -| | Set Duration | 60 +| | ${duration}= | Set Variable | 60 +| | Set Duration | ${duration} | | Set Search Rate Boundaries | ${max_rate} | ${min_rate} | | Set Search Frame Size | ${framesize} | | Set Search Rate Type pps @@ -183,13 +187,16 @@ | | Binary Search | ${binary_min} | ${binary_max} | ${topology_type} | | ${rate_per_stream}= | Verify Search Result | | Display result of NDR search | ${rate_per_stream} | ${framesize} | 2 +| | Clear and show runtime stats with running traffic | ${duration} +| | ... | ${rate_per_stream}pps | ${framesize} | ${topology_type} | Find NDR using combined search and pps | | [Documentation] | Find throughput by using RFC2544 combined search | | ... | (linear + binary) | | [Arguments] | ${framesize} | ${start_rate} | ${step_rate} | | ... | ${topology_type} | ${min_rate} | ${max_rate} | ${threshold} -| | Set Duration | 60 +| | ${duration}= | Set Variable | 60 +| | Set Duration | ${duration} | | Set Search Rate Boundaries | ${max_rate} | ${min_rate} | | Set Search Linear Step | ${step_rate} | | Set Search Frame Size | ${framesize} @@ -198,6 +205,8 @@ | | Combined Search | ${start_rate} | ${topology_type} | | ${rate_per_stream}= | Verify Search Result | | Display result of NDR search | ${rate_per_stream} | ${framesize} | 2 +| | Clear and show runtime stats with running traffic | ${duration} +| | ... | ${rate_per_stream}pps | ${framesize} | ${topology_type} | Display result of NDR search | | [Documentation] | Display result of NDR search in packet per seconds (total @@ -209,9 +218,19 @@ | | Set Test Message | (${nr_streams}x ${rate_per_stream} pps) | append=yes | | Set Test Message | FINAL_BANDWIDTH: ${bandwidth_total} Gbps | append=yes - | Traffic should pass with no loss | | [Arguments] | ${duration} | ${rate} | ${framesize} | ${topology_type} -| | Send traffic on | ${tg} | ${duration} -| | ... | ${rate} | ${framesize} | ${topology_type} +| | Clear and show runtime stats with running traffic | ${duration} +| | ... | ${rate} | ${framesize} | ${topology_type} +| | Send traffic on tg | ${duration} | ${rate} | ${framesize} +| | ... | ${topology_type} | | No traffic loss occurred + +| Clear and show runtime stats with running traffic +| | [Arguments] | ${duration} | ${rate} | ${framesize} | ${topology_type} +| | Send traffic on tg | -1 | ${rate} | ${framesize} +| | ... | ${topology_type} | warmup_time=0 | async_call=True +| | Clear runtime statistics on all DUTs +| | Sleep | ${duration} +| | Show runtime statistics on all DUTs +| | Stop traffic on tg |