diff options
-rwxr-xr-x | conf/01_testcases.conf | 24 | ||||
-rw-r--r-- | conf/02_vswitch.conf | 6 | ||||
-rw-r--r-- | conf/integration/01_testcases.conf | 10 | ||||
-rw-r--r-- | docs/testing/user/configguide/trafficgen.rst | 14 | ||||
-rw-r--r-- | docs/testing/user/userguide/integration.rst | 8 | ||||
-rw-r--r-- | src/ovs/ofctl.py | 15 | ||||
-rw-r--r-- | src/trex/Makefile | 2 | ||||
-rw-r--r-- | testcases/testcase.py | 36 | ||||
-rw-r--r-- | tools/collectors/sysmetrics/pidstat.py | 48 | ||||
-rw-r--r-- | tools/report/report_rst.jinja | 4 | ||||
-rw-r--r-- | vswitches/ovs.py | 4 |
11 files changed, 105 insertions, 66 deletions
diff --git a/conf/01_testcases.conf b/conf/01_testcases.conf index 03cf78d2..4a68ab3f 100755 --- a/conf/01_testcases.conf +++ b/conf/01_testcases.conf @@ -232,6 +232,18 @@ PERFORMANCE_TESTS = [ }, }, }, + { + "Name": "phy2phy_tput_mod_vlan_cont", + "Deployment": "p2p", + "Frame Modification": "vlan", + "Description": "Phy2Phy VLAN Continuous Stream", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_continuous", + "frame_rate" : 100, + }, + }, + }, { "Name": "phy2phy_cont", "Deployment": "p2p", @@ -300,6 +312,18 @@ PERFORMANCE_TESTS = [ }, }, { + "Name": "phy2phy_scalability_cont", + "Deployment": "p2p", + "Description": "Phy2Phy Scalability Continuous Stream", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_continuous", + "frame_rate" : 100, + "multistream" : 8000, + }, + }, + }, + { "Name": "pvp_tput", "Deployment": "pvp", "Description": "LTD.Throughput.RFC2544.PacketLossRatio", diff --git a/conf/02_vswitch.conf b/conf/02_vswitch.conf index 4d0fc46b..c9ffa0b7 100644 --- a/conf/02_vswitch.conf +++ b/conf/02_vswitch.conf @@ -1,4 +1,4 @@ -# Copyright 2015-2016 Intel Corporation. +# Copyright 2015-2018 Intel Corporation, Tieto and others. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -174,6 +174,10 @@ VSWITCHD_VANILLA_ARGS = [] # Bridge name to be used by VSWTICH VSWITCH_BRIDGE_NAME = 'br0' +# A tunnel type used by OP2P and PTUNP deployments +# Supported values: 'vxlan', 'gre' or 'geneve' +TUNNEL_TYPE = 'vxlan' + # directory where hugepages will be mounted on system init HUGEPAGE_DIR = '/dev/hugepages' diff --git a/conf/integration/01_testcases.conf b/conf/integration/01_testcases.conf index 8c013d2a..142ec812 100644 --- a/conf/integration/01_testcases.conf +++ b/conf/integration/01_testcases.conf @@ -1,4 +1,4 @@ -# Copyright 2015-2017 Intel Corporation. +# Copyright 2015-2018 Intel Corporation, Tieto and others. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,10 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -# The 1st value of SUPPORTED_TUNNELING_PROTO is used as the default -# tunneling protocol for OP2P tests. -SUPPORTED_TUNNELING_PROTO = ['vxlan', 'gre', 'geneve'] - # # Generic test configuration options are described at conf/01_testcases.conf # @@ -327,7 +323,6 @@ INTEGRATION_TESTS = [ { "Name": "overlay_p2p_tput", "Deployment": "op2p", - "Tunnel Type": SUPPORTED_TUNNELING_PROTO[0], "Tunnel Operation": "encapsulation", "Description": "Overlay Encapsulation Throughput RFC2544 Test", "Parameters": { @@ -341,7 +336,6 @@ INTEGRATION_TESTS = [ { "Name": "overlay_p2p_cont", "Deployment": "op2p", - "Tunnel Type": SUPPORTED_TUNNELING_PROTO[0], "Tunnel Operation": "encapsulation", "Description": "Overlay Encapsulation RFC2544 Continuous Stream", "Parameters": { @@ -355,7 +349,6 @@ INTEGRATION_TESTS = [ { "Name": "overlay_p2p_decap_tput", "Deployment": "op2p", - "Tunnel Type": SUPPORTED_TUNNELING_PROTO[0], "Tunnel Operation": "decapsulation", "Description": "Overlay Decapsulation Throughput RFC2544 Test", "Parameters": { @@ -369,7 +362,6 @@ INTEGRATION_TESTS = [ { "Name": "overlay_p2p_decap_cont", "Deployment": "op2p", - "Tunnel Type": SUPPORTED_TUNNELING_PROTO[0], "Tunnel Operation": "decapsulation", "Description": "Overlay Decapsulation RFC2544 Continuous Stream", "Parameters": { diff --git a/docs/testing/user/configguide/trafficgen.rst b/docs/testing/user/configguide/trafficgen.rst index f9e2db11..42141c59 100644 --- a/docs/testing/user/configguide/trafficgen.rst +++ b/docs/testing/user/configguide/trafficgen.rst @@ -974,8 +974,8 @@ definition and supported network layers at: http://www.secdev.org/projects/scapy 'scapy': { 'enabled': True, - '0' : 'Ether(src={Ether_src}, dst={Ether_dst})/IP(proto={IP_proto}, src={IP_src}, dst={IP_dst})/ICMP()', - '1' : 'Ether(src={Ether_dst}, dst={Ether_src})/IP(proto={IP_proto}, src={IP_dst}, dst={IP_src})/ICMP()', + '0' : 'Ether(src={Ether_src}, dst={Ether_dst})/IP(proto="icmp", src={IP_src}, dst={IP_dst})/ICMP()', + '1' : 'Ether(src={Ether_dst}, dst={Ether_src})/IP(proto="icmp", src={IP_dst}, dst={IP_src})/ICMP()', } #. Generate IPv6 ICMP Echo Request @@ -992,17 +992,13 @@ definition and supported network layers at: http://www.secdev.org/projects/scapy '1' : 'Ether(src={Ether_dst}, dst={Ether_src})/IPv6(src={IP_dst}, dst={IP_src})/ICMPv6EchoRequest()', } -#. Generate SCTP frames: +#. Generate TCP frames: - Example uses default SCAPY frame definition, which can reflect ``TRAFFIC['l3']['proto']`` settings. The same - approach can be used to generate other protocols, e.g. TCP. + Example uses default SCAPY frame definition, which can reflect ``TRAFFIC['l3']['proto']`` settings. .. code-block:: console 'l3' : { - 'proto' : 'sctp', + 'proto' : 'tcp', }, - 'scapy': { - 'enabled': True, - } diff --git a/docs/testing/user/userguide/integration.rst b/docs/testing/user/userguide/integration.rst index 66808400..2b2246db 100644 --- a/docs/testing/user/userguide/integration.rst +++ b/docs/testing/user/userguide/integration.rst @@ -1,6 +1,6 @@ .. This work is licensed under a Creative Commons Attribution 4.0 International License. .. http://creativecommons.org/licenses/by/4.0 -.. (c) OPNFV, Intel Corporation, AT&T and others. +.. (c) OPNFV, Intel Corporation, AT&T, Tieto and others. .. _integration-tests: @@ -22,6 +22,12 @@ P2P (Physical to Physical scenarios). NOTE: The configuration for overlay tests provided in this guide is for unidirectional traffic only. +NOTE: The overlay tests require an IxNet traffic generator. The tunneled traffic +is configured by ``ixnetrfc2544v2.tcl`` script. This script can be used +with all supported deployment scenarios for generation of frames with VXLAN, GRE +or GENEVE protocols. In that case options "Tunnel Operation" and +"TRAFFICGEN_IXNET_TCL_SCRIPT" must be properly configured at testcase definition. + Executing Integration Tests --------------------------- diff --git a/src/ovs/ofctl.py b/src/ovs/ofctl.py index b023e080..21da850a 100644 --- a/src/ovs/ofctl.py +++ b/src/ovs/ofctl.py @@ -156,21 +156,6 @@ class OFBridge(OFBase): self._ports = {} self._cache_file = None - # context manager - - def __enter__(self): - """Create datapath - - :returns: self - """ - return self - - def __exit__(self, type_, value, traceback): - """Remove datapath. - """ - if not traceback: - self.destroy() - # helpers def run_ofctl(self, args, check_error=False, timeout=None): diff --git a/src/trex/Makefile b/src/trex/Makefile index 41eb52ab..9a0704af 100644 --- a/src/trex/Makefile +++ b/src/trex/Makefile @@ -29,6 +29,8 @@ all: force_pull force_pull: $(TAG_DONE_FLAG) $(AT)cd $(WORK_DIR) && git pull $(TREX_URL) $(TREX_TAG) @echo "git pull done" + $(AT)wget https://raw.githubusercontent.com/phaethon/scapy/v0.18/scapy/layers/all.py -O $(WORK_DIR)/scripts/external_libs/scapy-2.3.1/python3/scapy/layers/all.py + @echo "orignal SCAPY 2.3.1 layers/all.py was restored" $(WORK_DIR): $(AT)git clone $(TREX_URL) $(WORK_DIR) diff --git a/testcases/testcase.py b/testcases/testcase.py index f28519fa..68b8aec4 100644 --- a/testcases/testcase.py +++ b/testcases/testcase.py @@ -1,4 +1,4 @@ -# Copyright 2015-2017 Intel Corporation. +# Copyright 2015-2018 Intel Corporation, Tieto and others. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ import subprocess from datetime import datetime as dt from conf import settings as S -from conf import get_test_param, merge_spec +from conf import merge_spec import core.component_factory as component_factory from core.loader import Loader from core.results.results_constants import ResultsConstants @@ -85,6 +85,7 @@ class TestCase(object): S.setValue('VSWITCH', cfg.get('vSwitch', S.getValue('VSWITCH'))) S.setValue('VNF', cfg.get('VNF', S.getValue('VNF'))) S.setValue('TRAFFICGEN', cfg.get('Trafficgen', S.getValue('TRAFFICGEN'))) + S.setValue('TUNNEL_TYPE', cfg.get('Tunnel Type', S.getValue('TUNNEL_TYPE'))) test_params = copy.deepcopy(S.getValue('TEST_PARAMS')) tc_test_params = cfg.get('Parameters', S.getValue('TEST_PARAMS')) test_params = merge_spec(test_params, tc_test_params) @@ -125,16 +126,7 @@ class TestCase(object): self.deployment = cfg['Deployment'] self._frame_mod = cfg.get('Frame Modification', None) - self._tunnel_type = None - self._tunnel_operation = None - - if self.deployment == 'op2p': - self._tunnel_operation = cfg['Tunnel Operation'] - - if 'Tunnel Type' in cfg: - self._tunnel_type = cfg['Tunnel Type'] - self._tunnel_type = get_test_param('TUNNEL_TYPE', - self._tunnel_type) + self._tunnel_operation = cfg.get('Tunnel Operation', None) # check if test requires background load and which generator it uses self._load_cfg = cfg.get('Load', None) @@ -145,16 +137,14 @@ class TestCase(object): # set traffic details, so they can be passed to vswitch and traffic ctls self._traffic = copy.deepcopy(S.getValue('TRAFFIC')) - self._traffic.update({'bidir': bidirectional, - 'tunnel_type': self._tunnel_type,}) - - self._traffic = functions.check_traffic(self._traffic) + self._traffic.update({'bidir': bidirectional}) # Packet Forwarding mode self._vswitch_none = str(S.getValue('VSWITCH')).strip().lower() == 'none' # trafficgen configuration required for tests of tunneling protocols - if self.deployment == "op2p": + if self._tunnel_operation: + self._traffic.update({'tunnel_type': S.getValue('TUNNEL_TYPE')}) self._traffic['l2'].update({'srcmac': S.getValue('TRAFFICGEN_PORT1_MAC'), 'dstmac': @@ -166,9 +156,9 @@ class TestCase(object): S.getValue('TRAFFICGEN_PORT2_IP')}) if self._tunnel_operation == "decapsulation": - self._traffic['l2'] = S.getValue(self._tunnel_type.upper() + '_FRAME_L2') - self._traffic['l3'] = S.getValue(self._tunnel_type.upper() + '_FRAME_L3') - self._traffic['l4'] = S.getValue(self._tunnel_type.upper() + '_FRAME_L4') + self._traffic['l2'].update(S.getValue(S.getValue('TUNNEL_TYPE').upper() + '_FRAME_L2')) + self._traffic['l3'].update(S.getValue(S.getValue('TUNNEL_TYPE').upper() + '_FRAME_L3')) + self._traffic['l4'].update(S.getValue(S.getValue('TUNNEL_TYPE').upper() + '_FRAME_L4')) self._traffic['l2']['dstmac'] = S.getValue('NICS')[1]['mac'] elif len(S.getValue('NICS')) >= 2 and \ (S.getValue('NICS')[0]['type'] == 'vf' or @@ -180,6 +170,8 @@ class TestCase(object): else: self._logger.debug("MAC addresses can not be read") + self._traffic = functions.check_traffic(self._traffic) + # count how many VNFs are involved in TestSteps if self.test: for step in self.test: @@ -409,8 +401,8 @@ class TestCase(object): item[ResultsConstants.SCAL_PRE_INSTALLED_FLOWS] = self._traffic['pre_installed_flows'] if self._vnf_ctl.get_vnfs_number(): item[ResultsConstants.GUEST_LOOPBACK] = ' '.join(S.getValue('GUEST_LOOPBACK')) - if self._tunnel_type: - item[ResultsConstants.TUNNEL_TYPE] = self._tunnel_type + if self._tunnel_operation: + item[ResultsConstants.TUNNEL_TYPE] = S.getValue('TUNNEL_TYPE') return results def _copy_fwd_tools_for_all_guests(self, vm_count): diff --git a/tools/collectors/sysmetrics/pidstat.py b/tools/collectors/sysmetrics/pidstat.py index 245d8d22..277fdb11 100644 --- a/tools/collectors/sysmetrics/pidstat.py +++ b/tools/collectors/sysmetrics/pidstat.py @@ -76,7 +76,7 @@ class Pidstat(collector.ICollector): with open(self._log, 'w') as logfile: cmd = ['sudo', 'LC_ALL=' + settings.getValue('DEFAULT_CMD_LOCALE'), 'pidstat', settings.getValue('PIDSTAT_OPTIONS'), - '-p', ','.join(pids), + '-t', '-p', ','.join(pids), str(settings.getValue('PIDSTAT_SAMPLE_INTERVAL'))] self._logger.debug('%s', ' '.join(cmd)) self._pid = subprocess.Popen(cmd, stdout=logfile, bufsize=0).pid @@ -116,16 +116,48 @@ class Pidstat(collector.ICollector): # combine stored header fields with actual values tmp_res = OrderedDict(zip(tmp_header, line[8:].split())) - # use process's name and its pid as unique key - key = tmp_res.pop('Command') + '_' + tmp_res['PID'] - # store values for given command into results dict - if key in self._results: - self._results[key].update(tmp_res) - else: - self._results[key] = tmp_res + cmd = tmp_res.pop('Command') + # remove unused fields (given by option '-t') + tmp_res.pop('UID') + tmp_res.pop('TID') + if '|_' not in cmd: # main process + # use process's name and its pid as unique key + tmp_pid = tmp_res.pop('TGID') + tmp_key = "%s_%s" % (cmd, tmp_pid) + # do not trust cpu usage of pid + # see VSPERF-569 for more details + if 'CPU' not in tmp_header: + self.update_results(tmp_key, tmp_res, False) + else: # thread + # accumulate cpu usage of all threads + if 'CPU' in tmp_header: + tmp_res.pop('TGID') + self.update_results(tmp_key, tmp_res, True) line = logfile.readline() + def update_results(self, key, result, accumulate=False): + """ + Update final results dictionary. If ``accumulate`` param is set to + ``True``, try to accumulate existing values. + """ + # store values for given command into results dict + if key not in self._results: + self._results[key] = result + elif accumulate: + for field in result: + if field not in self._results[key]: + self._results[key][field] = result[field] + else: + try: + val = float(self._results[key][field]) + float(result[field]) + self._results[key][field] = '{0:.2f}'.format(val) + except ValueError: + # cannot cast to float, let's update with the previous value + self._results[key][field] = result[field] + else: + self._results[key].update(result) + def get_results(self): """Returns collected statistics. """ diff --git a/tools/report/report_rst.jinja b/tools/report/report_rst.jinja index eda0c01e..6b51807a 100644 --- a/tools/report/report_rst.jinja +++ b/tools/report/report_rst.jinja @@ -90,7 +90,9 @@ Testing Activities/Events ~~~~~~~~~~~~~~~~~~~~~~~~~ pidstat is used to collect the process statistics, as such some values such as %CPU and %USER maybe > 100% as the values are summed across multiple cores. For -more info on pidstat please see: http://linux.die.net/man/1/pidstat. +more info on pidstat please see: http://linux.die.net/man/1/pidstat. Please +note that vsperf recalculates the CPU consumption of a process by aggregating +the CPU usage of each thread. Known issues: Some reported metrics have the value "unkown". These values are marked unknown as they are not values retrieved from the external tester diff --git a/vswitches/ovs.py b/vswitches/ovs.py index 9e49b2ee..6f650005 100644 --- a/vswitches/ovs.py +++ b/vswitches/ovs.py @@ -128,6 +128,8 @@ class IVSwitchOvs(IVSwitch, tasks.Process): def stop(self): """See IVswitch for general description """ + for switch_name in list(self._bridges): + self.del_switch(switch_name) self._logger.info("Terminating vswitchd...") self.kill() self._bridges = {} @@ -147,6 +149,8 @@ class IVSwitchOvs(IVSwitch, tasks.Process): """See IVswitch for general description """ bridge = self._bridges[switch_name] + for port in list(bridge.get_ports()): + bridge.del_port(port) self._bridges.pop(switch_name) bridge.destroy() |