diff options
32 files changed, 325 insertions, 139 deletions
diff --git a/conf/04_vnf.conf b/conf/04_vnf.conf index 0a80c1af..ff110d93 100644 --- a/conf/04_vnf.conf +++ b/conf/04_vnf.conf @@ -35,7 +35,10 @@ GUEST_IMAGE = ['', ''] # For 2 VNFs you may use [180, 180] GUEST_TIMEOUT = [180, 180] -# packet forwarding mode: io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho +# packet forwarding mode supported by testpmd; Please see DPDK documentation +# for comprehensive list of modes supported by your version. +# e.g. io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho|... +# Note: Option "mac_retry" has been changed to "mac retry" since DPDK v16.07 GUEST_TESTPMD_FWD_MODE = 'csum' # guest loopback application method; supported options are: diff --git a/conf/06_pktfwd.conf b/conf/06_pktfwd.conf index d6a83d07..6175aa6a 100644 --- a/conf/06_pktfwd.conf +++ b/conf/06_pktfwd.conf @@ -24,7 +24,10 @@ PKTFWD = 'TestPMD' # ############################ TESTPMD_ARGS = [] -# packet forwarding mode: io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho +# packet forwarding mode supported by testpmd; Please see DPDK documentation +# for comprehensive list of modes supported by your version. +# e.g. io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho|... +# Note: Option "mac_retry" has been changed to "mac retry" since DPDK v16.07 TESTPMD_FWD_MODE = 'csum' # checksum calculation layer: ip|udp|tcp|sctp|outer-ip TESTPMD_CSUM_LAYER = 'ip' diff --git a/core/traffic_controller_rfc2544.py b/core/traffic_controller_rfc2544.py index 81e499cd..af09deff 100644 --- a/core/traffic_controller_rfc2544.py +++ b/core/traffic_controller_rfc2544.py @@ -39,7 +39,7 @@ class TrafficControllerRFC2544(ITrafficController, IResults): self._traffic_gen_class = traffic_gen_class() self._traffic_started = False self._traffic_started_call_count = 0 - self._trials = int(get_test_param('rfc2544_trials', 1)) + self._tests = int(get_test_param('rfc2544_tests', 1)) self._duration = int(get_test_param('duration', 30)) self._lossrate = float(get_test_param('lossrate', 0.0)) self._results = [] @@ -101,13 +101,13 @@ class TrafficControllerRFC2544(ITrafficController, IResults): if traffic['traffic_type'] == 'back2back': result = self._traffic_gen_class.send_rfc2544_back2back( - traffic, trials=self._trials, duration=self._duration, lossrate=self._lossrate) + traffic, tests=self._tests, duration=self._duration, lossrate=self._lossrate) elif traffic['traffic_type'] == 'continuous': result = self._traffic_gen_class.send_cont_traffic( traffic, duration=self._duration) else: result = self._traffic_gen_class.send_rfc2544_throughput( - traffic, trials=self._trials, duration=self._duration, lossrate=self._lossrate) + traffic, tests=self._tests, duration=self._duration, lossrate=self._lossrate) result = TrafficControllerRFC2544._append_results(result, packet_size) @@ -123,7 +123,7 @@ class TrafficControllerRFC2544(ITrafficController, IResults): traffic['l2'] = {'framesize': packet_size} self._traffic_gen_class.start_rfc2544_throughput( traffic, - trials=self._trials, + tests=self._tests, duration=self._duration) self._traffic_started = True if len(function['args']) > 0: @@ -156,7 +156,7 @@ class TrafficControllerRFC2544(ITrafficController, IResults): """ return self._results - def validate_send_traffic(self, result, traffic): + def validate_send_traffic(self, dummy_result, dummy_traffic): """Verify that send traffic has succeeded """ if len(self._results): diff --git a/docs/configguide/installation.rst b/docs/configguide/installation.rst index 048c2675..70572b07 100755 --- a/docs/configguide/installation.rst +++ b/docs/configguide/installation.rst @@ -186,9 +186,19 @@ parameter. In recent vswitchd versions, option VSWITCHD_DPDK_CONFIG will be used to configure vswitchd via ovs-vsctl calls. With the --socket-mem argument set to use 1 hugepage on the specified sockets as -seen above, the configuration will need 9 hugepages total to run all tests +seen above, the configuration will need 10 hugepages total to run all tests within vsperf if the pagesize is set correctly to 1GB. +VSPerf will verify hugepage amounts are free before executing test +environments. In case of hugepage amounts not being free, test initialization +will fail and testing will stop. + +**Please Note**: In some instances on a test failure dpdk resources may not +release hugepages used in dpdk configuration. It is recommended to configure a +few extra hugepages to prevent a false detection by VSPerf that not enough free +hugepages are available to execute the test environment. Normally dpdk would use +previously allocated hugepages upon initialization. + Depending on your OS selection configuration of hugepages may vary. Please refer to your OS documentation to set hugepages correctly. It is recommended to set the required amount of hugepages to be allocated by default on reboots. diff --git a/docs/configguide/trafficgen.rst b/docs/configguide/trafficgen.rst index 302a8d5e..939b6cad 100644 --- a/docs/configguide/trafficgen.rst +++ b/docs/configguide/trafficgen.rst @@ -72,12 +72,12 @@ OR from the commandline: $ ./vsperf --test-params "pkt_sizes=x,y" $TESTNAME You can also modify the traffic transmission duration and the number -of trials run by the traffic generator by extending the example +of tests run by the traffic generator by extending the example commandline above to: .. code-block:: console - $ ./vsperf --test-params "pkt_sizes=x,y;duration=10;rfc2455_trials=3" $TESTNAME + $ ./vsperf --test-params "pkt_sizes=x,y;duration=10;rfc2544_tests=1" $TESTNAME Dummy Setup ------------ diff --git a/docs/design/trafficgen_integration_guide.rst b/docs/design/trafficgen_integration_guide.rst index a30b2d61..266c6bc0 100644 --- a/docs/design/trafficgen_integration_guide.rst +++ b/docs/design/trafficgen_integration_guide.rst @@ -161,9 +161,9 @@ Example of synchronous interfaces: .. code-block:: python - def send_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): - def send_rfc2544_back2back(self, traffic=None, trials=1, duration=20, + def send_rfc2544_back2back(self, traffic=None, tests=1, duration=20, lossrate=0.0): def send_cont_traffic(self, traffic=None, duration=20): @@ -171,11 +171,11 @@ Example of asynchronous interfaces: .. code-block:: python - def start_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + def start_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): def wait_rfc2544_throughput(self): - def start_rfc2544_back2back(self, traffic=None, trials=1, duration=20, + def start_rfc2544_back2back(self, traffic=None, tests=1, duration=20, lossrate=0.0): def wait_rfc2544_back2back(self): @@ -221,7 +221,7 @@ functions: * param **vlan**: A dictionary with vlan specific parameters, e.g. **priority**, **cfi**, **id** and vlan on/off switch **enabled**. - * param **trials**: Number of trials to execute. + * param **tests**: Number of times the test is executed. * param **duration**: Duration of continuous test or per iteration duration in case of RFC2544 throughput or back2back traffic types. * param **lossrate**: Acceptable lossrate percentage. diff --git a/docs/design/vswitchperf_design.rst b/docs/design/vswitchperf_design.rst index 53515249..e61b3ea6 100755 --- a/docs/design/vswitchperf_design.rst +++ b/docs/design/vswitchperf_design.rst @@ -53,7 +53,7 @@ for development purposes: .. code-block:: console - $ ./vsperf --test-params 'duration=10;rfc2544_trials=1;pkt_sizes=64' --tests 'pvp_tput' + $ ./vsperf --test-params 'duration=10;rfc2544_tests=1;pkt_sizes=64' --tests 'pvp_tput' Typical Test Sequence ===================== @@ -155,12 +155,12 @@ ITrafficGenerator start_cont_traffic(traffic, time, framerate) stop_cont_traffic(self): - send_rfc2544_throughput(traffic, trials, duration, lossrate) - start_rfc2544_throughput(traffic, trials, duration, lossrate) + send_rfc2544_throughput(traffic, tests, duration, lossrate) + start_rfc2544_throughput(traffic, tests, duration, lossrate) wait_rfc2544_throughput(self) - send_rfc2544_back2back(traffic, trials, duration, lossrate) - start_rfc2544_back2back(traffic, , trials, duration, lossrate) + send_rfc2544_back2back(traffic, tests, duration, lossrate) + start_rfc2544_back2back(traffic, , tests, duration, lossrate) wait_rfc2544_back2back() Note ``send_xxx()`` blocks whereas ``start_xxx()`` does not and must be followed by a subsequent call to ``wait_xxx()``. diff --git a/docs/userguide/testusage.rst b/docs/userguide/testusage.rst index d807590d..b5f47998 100755 --- a/docs/userguide/testusage.rst +++ b/docs/userguide/testusage.rst @@ -396,7 +396,7 @@ Execution of test with PCI passthrough with vswitch disabled: .. code-block:: console $ ./vsperf --conf-file=<path_to_custom_conf>/10_custom.conf - --vswtich none --vnf QemuPciPassthrough pvp_tput + --vswitch none --vnf QemuPciPassthrough pvp_tput Any of supported guest-loopback-application_ can be used inside VM with PCI passthrough support. @@ -526,7 +526,10 @@ for selected Packet Forwarder: # testpmd configuration TESTPMD_ARGS = [] - # packet forwarding mode: io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho + # packet forwarding mode supported by testpmd; Please see DPDK documentation + # for comprehensive list of modes supported by your version. + # e.g. io|mac|mac_retry|macswap|flowgen|rxonly|txonly|csum|icmpecho|... + # Note: Option "mac_retry" has been changed to "mac retry" since DPDK v16.07 TESTPMD_FWD_MODE = 'csum' # checksum calculation layer: ip|udp|tcp|sctp|outer-ip TESTPMD_CSUM_LAYER = 'ip' diff --git a/docs/userguide/yardstick.rst b/docs/userguide/yardstick.rst index 3d249e1b..ec306d57 100755 --- a/docs/userguide/yardstick.rst +++ b/docs/userguide/yardstick.rst @@ -130,7 +130,7 @@ argument. Following options are supported: - **bidirectional** - specifies if traffic will be uni (False) or bi-directional (True); Default: False - **iload** - specifies frame rate; Default: 100 -- **rfc2544_trials** - specifies the number of trials performed for each packet +- **rfc2544_tests** - specifies the number of tests performed for each packet size - **multistream** - specifies the number of simulated streams; Default: 0 (i.e. multistream feature is disabled) diff --git a/systems/centos/build_base_machine.sh b/systems/centos/build_base_machine.sh index d3ac3e2b..d94dc975 100755 --- a/systems/centos/build_base_machine.sh +++ b/systems/centos/build_base_machine.sh @@ -58,6 +58,8 @@ zlib-devel glib2-devel pixman-devel socat +numactl +numactl-devel # install gvim vim-X11 diff --git a/systems/fedora/20/build_base_machine.sh b/systems/fedora/20/build_base_machine.sh index 96bb17df..839d2bee 100755 --- a/systems/fedora/20/build_base_machine.sh +++ b/systems/fedora/20/build_base_machine.sh @@ -62,6 +62,10 @@ libreport-python3 abrt-python3 abrt-addon-python3 +# libs +numactl +numactl-devel + # install git-review tool git-review -" | grep -v ^#)
\ No newline at end of file +" | grep -v ^#) diff --git a/systems/fedora/21/build_base_machine.sh b/systems/fedora/21/build_base_machine.sh index 69b067f9..e4969893 100755 --- a/systems/fedora/21/build_base_machine.sh +++ b/systems/fedora/21/build_base_machine.sh @@ -65,6 +65,10 @@ libreport-python3 abrt-python3 abrt-addon-python3 +# libs +numactl +numactl-devel + # install git-review tool git-review " | grep -v ^#) || exit 1 diff --git a/systems/fedora/22/build_base_machine.sh b/systems/fedora/22/build_base_machine.sh index 0ca565f3..3cfe0c78 100755 --- a/systems/fedora/22/build_base_machine.sh +++ b/systems/fedora/22/build_base_machine.sh @@ -66,9 +66,13 @@ libreport-python3 abrt-python3 abrt-addon-python3 +# libs +numactl +numactl-devel + # install git-review tool git-review " | grep -v ^#) # Create hugepage dirs -mkdir -p /dev/hugepages
\ No newline at end of file +mkdir -p /dev/hugepages diff --git a/systems/rhel/7.2/build_base_machine.sh b/systems/rhel/7.2/build_base_machine.sh index 86608066..2319535b 100755 --- a/systems/rhel/7.2/build_base_machine.sh +++ b/systems/rhel/7.2/build_base_machine.sh @@ -50,6 +50,8 @@ pkglist=( socat\ tk-devel\ wget\ + numactl\ + numactl-devel\ ) # python tools for proper QEMU, DPDK, and OVS make @@ -95,4 +97,4 @@ rm -f Python-3.4.2.tar.xz pip3.4 install virtualenv # Create hugepage dirs -mkdir -p /dev/hugepages
\ No newline at end of file +mkdir -p /dev/hugepages diff --git a/systems/ubuntu/14.04/build_base_machine.sh b/systems/ubuntu/14.04/build_base_machine.sh index 9fa8511c..04f4a7e1 100755 --- a/systems/ubuntu/14.04/build_base_machine.sh +++ b/systems/ubuntu/14.04/build_base_machine.sh @@ -77,6 +77,10 @@ python3-tk libpython3.4 python3-reportlab +# libs +libnuma1 +libnuma-dev + # install git-review tool git-review " | grep -v ^#) diff --git a/systems/ubuntu/build_base_machine.sh b/systems/ubuntu/build_base_machine.sh index a2b48a26..1b42a790 100755 --- a/systems/ubuntu/build_base_machine.sh +++ b/systems/ubuntu/build_base_machine.sh @@ -44,6 +44,8 @@ apt-get -y install autoconf libtool apt-get -y install libpcap-dev apt-get -y install libglib2.0 apt-get -y install libfuse-dev +apt-get -y install libnuma1 +apt-get -y install libnuma-dev # Some useful tools you may optionally install #apt-get -y install ctags diff --git a/testcases/testcase.py b/testcases/testcase.py index 5f5c9358..d88840d7 100644 --- a/testcases/testcase.py +++ b/testcases/testcase.py @@ -14,14 +14,18 @@ """TestCase base class """ +from collections import OrderedDict +import copy import csv +import logging +import math import os +import re import time -import logging import subprocess -import copy -from collections import OrderedDict +from conf import settings as S +from conf import get_test_param import core.component_factory as component_factory from core.loader import Loader from core.results.results_constants import ResultsConstants @@ -29,8 +33,7 @@ from tools import tasks from tools import hugepages from tools import functions from tools.pkt_gen.trafficgen.trafficgenhelper import TRAFFIC_DEFAULTS -from conf import settings as S -from conf import get_test_param + class TestCase(object): """TestCase base class @@ -189,6 +192,10 @@ class TestCase(object): # mount hugepages if needed self._mount_hugepages() + # verify enough hugepages are free to run the testcase + if not self._check_for_enough_hugepages(): + raise RuntimeError('Not enough hugepages free to run test.') + # copy sources of l2 forwarding tools into VM shared dir if needed self._copy_fwd_tools_for_all_guests() @@ -391,7 +398,6 @@ class TestCase(object): except subprocess.CalledProcessError: self._logger.error('Unable to copy DPDK and l2fwd to shared directory') - def _mount_hugepages(self): """Mount hugepages if usage of DPDK or Qemu is detected """ @@ -411,6 +417,80 @@ class TestCase(object): hugepages.umount_hugepages() self._hugepages_mounted = False + def _check_for_enough_hugepages(self): + """Check to make sure enough hugepages are free to satisfy the + test environment. + """ + hugepages_needed = 0 + hugepage_size = hugepages.get_hugepage_size() + # get hugepage amounts per guest + for guest in range(self.deployment.count('v')): + hugepages_needed += math.ceil((int(S.getValue( + 'GUEST_MEMORY')[guest]) * 1000) / hugepage_size) + + # get hugepage amounts for each socket on dpdk + sock0_mem, sock1_mem = 0, 0 + if S.getValue('VSWITCH').lower().count('dpdk'): + # the import below needs to remain here and not put into the module + # imports because of an exception due to settings not yet loaded + from vswitches import ovs_dpdk_vhost + if ovs_dpdk_vhost.OvsDpdkVhost.old_dpdk_config(): + match = re.search( + '-socket-mem\s+(\d+),(\d+)', + ''.join(S.getValue('VSWITCHD_DPDK_ARGS'))) + if match: + sock0_mem, sock1_mem = (int(match.group(1)) / 1024, + int(match.group(2)) / 1024) + else: + logging.info( + 'Could not parse socket memory config in dpdk params.') + else: + sock0_mem, sock1_mem = ( + S.getValue( + 'VSWITCHD_DPDK_CONFIG')['dpdk-socket-mem'].split(',')) + sock0_mem, sock1_mem = (int(sock0_mem) / 1024, + int(sock1_mem) / 1024) + + # If hugepages needed, verify the amounts are free + if any([hugepages_needed, sock0_mem, sock1_mem]): + free_hugepages = hugepages.get_free_hugepages() + if hugepages_needed: + logging.info('Need %s hugepages free for guests', + hugepages_needed) + result1 = free_hugepages >= hugepages_needed + free_hugepages -= hugepages_needed + else: + result1 = True + + if sock0_mem: + logging.info('Need %s hugepages free for dpdk socket 0', + sock0_mem) + result2 = hugepages.get_free_hugepages('0') >= sock0_mem + free_hugepages -= sock0_mem + else: + result2 = True + + if sock1_mem: + logging.info('Need %s hugepages free for dpdk socket 1', + sock1_mem) + result3 = hugepages.get_free_hugepages('1') >= sock1_mem + free_hugepages -= sock1_mem + else: + result3 = True + + logging.info('Need a total of {} total hugepages'.format( + hugepages_needed + sock1_mem + sock0_mem)) + + # The only drawback here is sometimes dpdk doesn't release + # its hugepages on a test failure. This could cause a test + # to fail when dpdk would be OK to start because it will just + # use the previously allocated hugepages. + result4 = True if free_hugepages >= 0 else False + + return all([result1, result2, result3, result4]) + else: + return True + @staticmethod def write_result_to_file(results, output): """Write list of dictionaries to a CSV file. diff --git a/tools/hugepages.py b/tools/hugepages.py index 119f94b5..02e4f29c 100644 --- a/tools/hugepages.py +++ b/tools/hugepages.py @@ -31,6 +31,7 @@ _LOGGER = logging.getLogger(__name__) # hugepage management # + def get_hugepage_size(): """Return the size of the configured hugepages """ @@ -48,7 +49,6 @@ def get_hugepage_size(): return 0 - def allocate_hugepages(): """Allocate hugepages on the fly """ @@ -72,31 +72,65 @@ def allocate_hugepages(): return False +def get_free_hugepages(socket=None): + """Get the free hugepage totals on the system. + + :param socket: optional socket param to get free hugepages on a socket. To + be passed a string. + :returns: hugepage amount as int + """ + hugepage_free_re = re.compile(r'HugePages_Free:\s+(?P<free_hp>\d+)$') + if socket: + if os.path.exists( + '/sys/devices/system/node/node{}/meminfo'.format(socket)): + meminfo_path = '/sys/devices/system/node/node{}/meminfo'.format( + socket) + else: + _LOGGER.info('No hugepage info found for socket {}'.format(socket)) + return 0 + else: + meminfo_path = '/proc/meminfo' + + with open(meminfo_path, 'r') as fh: + data = fh.readlines() + for line in data: + match = hugepage_free_re.search(line) + if match: + _LOGGER.info('Hugepages free: %s %s', match.group('free_hp'), + 'on socket {}'.format(socket) if socket else '') + return int(match.group('free_hp')) + else: + _LOGGER.info('Could not parse for hugepage size') + return 0 + + def is_hugepage_available(): - """Check if hugepages are available on the system. + """Check if hugepages are configured/available on the system. """ - hugepage_re = re.compile(r'^HugePages_Free:\s+(?P<num_hp>\d+)$') + hugepage_size_re = re.compile(r'^Hugepagesize:\s+(?P<size_hp>\d+)\s+kB', + re.IGNORECASE) # read in meminfo with open('/proc/meminfo') as mem_file: mem_info = mem_file.readlines() - # first check if module is loaded + # see if the hugepage size is the recommended value for line in mem_info: - result = hugepage_re.match(line) - if not result: - continue - - num_huge = result.group('num_hp') - if num_huge == '0': - _LOGGER.info('No free hugepages.') - if not allocate_hugepages(): - return False - else: - _LOGGER.info('Found \'%s\' free hugepage(s).', num_huge) - return True - - return False + match_size = hugepage_size_re.match(line) + if match_size: + if match_size.group('size_hp') != '1048576': + _LOGGER.info( + '%s%s%s kB', + 'Hugepages not configured for recommend 1GB size. ', + 'Currently set at ', match_size.group('size_hp')) + num_huge = get_free_hugepages() + if num_huge == 0: + _LOGGER.info('No free hugepages.') + if not allocate_hugepages(): + return False + else: + _LOGGER.info('Found \'%s\' free hugepage(s).', num_huge) + return True def is_hugepage_mounted(): @@ -112,10 +146,11 @@ def is_hugepage_mounted(): def mount_hugepages(): - """Ensure hugepages are mounted. + """Ensure hugepages are mounted. Raises RuntimeError if no configured + hugepages are available. """ if not is_hugepage_available(): - return + raise RuntimeError('No Hugepages configured.') if is_hugepage_mounted(): return diff --git a/tools/namespace.py b/tools/namespace.py index e6bcd819..9131398f 100644 --- a/tools/namespace.py +++ b/tools/namespace.py @@ -108,8 +108,8 @@ def get_system_namespace_list(): Return tuple of strings for namespaces on the system :return: tuple of namespaces as string """ - return tuple(os.listdir('/var/run/netns')) - + return tuple(os.listdir('/var/run/netns')) if os.path.exists( + '/var/run/netns') else tuple() def get_vsperf_namespace_list(): """ diff --git a/tools/pkt_gen/dummy/dummy.py b/tools/pkt_gen/dummy/dummy.py index d3d79974..3324824c 100755 --- a/tools/pkt_gen/dummy/dummy.py +++ b/tools/pkt_gen/dummy/dummy.py @@ -146,8 +146,8 @@ class Dummy(trafficgen.ITrafficGenerator): results = get_user_traffic( 'continuous', '%dmpps, multistream %s, duration %d' % (traffic['frame_rate'], - traffic['multistream'], - duration), traffic_, + traffic['multistream'], + duration), traffic_, ('frames tx', 'frames rx', 'tx rate %', 'rx rate %', 'min latency', 'max latency', 'avg latency', 'frameloss %')) @@ -169,7 +169,7 @@ class Dummy(trafficgen.ITrafficGenerator): result[ResultsConstants.FRAME_LOSS_PERCENT] = float(results[7]) return result - def send_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """ Send traffic per RFC2544 throughput test specifications. @@ -182,8 +182,8 @@ class Dummy(trafficgen.ITrafficGenerator): results = get_user_traffic( 'throughput', - '%d trials, %d seconds iterations, %f packet loss, multistream ' - '%s' % (trials, duration, lossrate, traffic['multistream']), + '%d tests, %d seconds iterations, %f packet loss, multistream ' + '%s' % (tests, duration, lossrate, traffic['multistream']), traffic_, ('frames tx', 'frames rx', 'tx rate %', 'rx rate %', 'min latency', 'max latency', 'avg latency', 'frameloss %')) diff --git a/tools/pkt_gen/ixia/ixia.py b/tools/pkt_gen/ixia/ixia.py index ae5da6d2..cd14a2a7 100755 --- a/tools/pkt_gen/ixia/ixia.py +++ b/tools/pkt_gen/ixia/ixia.py @@ -38,9 +38,9 @@ import tkinter import logging import os +from collections import OrderedDict from tools.pkt_gen import trafficgen from conf import settings -from collections import OrderedDict from core.results.results_constants import ResultsConstants _ROOT_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -252,13 +252,13 @@ class Ixia(trafficgen.ITrafficGenerator): """ return self.run_tcl('stopTraffic') - def send_rfc2544_throughput(self, traffic=None, trials=3, duration=20, lossrate=0.0): + def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """See ITrafficGenerator for description """ params = {} params['config'] = { - 'trials': trials, + 'tests': tests, 'duration': duration, 'lossrate': lossrate, 'multipleStreams': traffic['multistream'], diff --git a/tools/pkt_gen/ixia/pass_fail.tcl b/tools/pkt_gen/ixia/pass_fail.tcl index acb4443f..79b7f10d 100755 --- a/tools/pkt_gen/ixia/pass_fail.tcl +++ b/tools/pkt_gen/ixia/pass_fail.tcl @@ -675,7 +675,10 @@ proc rfcThroughputTest { testSpec trafficSpec } { # testSpec - set numTrials [dict get $testSpec trials] ;# we don't use this yet + # RFC2544 to IXIA terminology mapping (it affects Ixia configuration below): + # Test => Trial + # Trial => Iteration + set numTrials [dict get $testSpec tests] ;# we don't use this yet set duration [dict get $testSpec duration] set lossRate [dict get $testSpec lossrate] set multipleStream [dict get $testSpec multipleStreams] ;# we don't use this yet diff --git a/tools/pkt_gen/ixnet/ixnet.py b/tools/pkt_gen/ixnet/ixnet.py index 928b5a6e..5e4ae569 100755 --- a/tools/pkt_gen/ixnet/ixnet.py +++ b/tools/pkt_gen/ixnet/ixnet.py @@ -253,15 +253,15 @@ class IxNet(trafficgen.ITrafficGenerator): """ return self._wait_result() - def send_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """See ITrafficGenerator for description """ - self.start_rfc2544_throughput(traffic, trials, duration, lossrate) + self.start_rfc2544_throughput(traffic, tests, duration, lossrate) return self.wait_rfc2544_throughput() - def start_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + def start_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """Start transmission. """ @@ -270,7 +270,7 @@ class IxNet(trafficgen.ITrafficGenerator): self._params['config'] = { 'binary': True, - 'trials': trials, + 'tests': tests, 'duration': duration, 'lossrate': lossrate, 'multipleStreams': traffic['multistream'], @@ -387,18 +387,18 @@ class IxNet(trafficgen.ITrafficGenerator): # the results file return parse_ixnet_rfc_results(parse_result_string(output[0])) - def send_rfc2544_back2back(self, traffic=None, trials=50, duration=2, + def send_rfc2544_back2back(self, traffic=None, tests=1, duration=2, lossrate=0.0): """See ITrafficGenerator for description """ # NOTE 2 seconds is the recommended duration for a back 2 back # test in RFC2544. 50 trials is the recommended number from the # RFC also. - self.start_rfc2544_back2back(traffic, trials, duration, lossrate) + self.start_rfc2544_back2back(traffic, tests, duration, lossrate) return self.wait_rfc2544_back2back() - def start_rfc2544_back2back(self, traffic=None, trials=50, duration=2, + def start_rfc2544_back2back(self, traffic=None, tests=1, duration=2, lossrate=0.0): """Start transmission. """ @@ -407,7 +407,7 @@ class IxNet(trafficgen.ITrafficGenerator): self._params['config'] = { 'binary': True, - 'trials': trials, + 'tests': tests, 'duration': duration, 'lossrate': lossrate, 'multipleStreams': traffic['multistream'], diff --git a/tools/pkt_gen/ixnet/ixnetrfc2544.tcl b/tools/pkt_gen/ixnet/ixnetrfc2544.tcl index 233db040..e70ca874 100644 --- a/tools/pkt_gen/ixnet/ixnetrfc2544.tcl +++ b/tools/pkt_gen/ixnet/ixnetrfc2544.tcl @@ -83,13 +83,16 @@ proc startRfc2544Test { testSpec trafficSpec } { set duration [dict get $testSpec duration] + # RFC2544 to IXIA terminology mapping (it affects Ixia configuration inside this script): + # Test => Trial + # Trial => Iteration if {$binary} { - set numTrials [dict get $testSpec trials] + set numTests [dict get $testSpec tests] set frameRate 100 set tolerance [dict get $testSpec lossrate] set loadType binary } else { - set numTrials 1 + set numTests 1 set frameRate [dict get $testSpec framerate] set tolerance 0.0 set loadType custom @@ -7778,7 +7781,7 @@ proc startRfc2544Test { testSpec trafficSpec } { -framesize $frameSize \ -reportTputRateUnit mbps \ -duration $duration \ - -numtrials $numTrials \ + -numtrials $numTests \ -trafficType constantLoading \ -burstSize 1 \ -framesPerBurstGap 1 \ @@ -7951,7 +7954,7 @@ proc startRfc2544Test { testSpec trafficSpec } { -rfc2889ordering noOrdering \ -floodedFramesEnabled False \ -duration $duration \ - -numtrials $numTrials \ + -numtrials $numTests \ -trafficType constantLoading \ -burstSize 1 \ -framesPerBurstGap 1 \ diff --git a/tools/pkt_gen/ixnet/ixnetrfc2544v2.tcl b/tools/pkt_gen/ixnet/ixnetrfc2544v2.tcl index 0bdba9cd..539c5a5b 100755 --- a/tools/pkt_gen/ixnet/ixnetrfc2544v2.tcl +++ b/tools/pkt_gen/ixnet/ixnetrfc2544v2.tcl @@ -83,13 +83,16 @@ proc startRfc2544Test { testSpec trafficSpec } { set duration [dict get $testSpec duration] + # RFC2544 to IXIA terminology mapping (it affects Ixia configuration inside this script): + # Test => Trial + # Trial => Iteration if {$binary} { - set numTrials [dict get $testSpec trials] + set numTests [dict get $testSpec tests] set frameRate 100 set tolerance [dict get $testSpec lossrate] set loadType binary } else { - set numTrials 1 + set numTests 1 set frameRate [dict get $testSpec framerate] set tolerance 0.0 set loadType custom @@ -3218,7 +3221,7 @@ proc startRfc2544Test { testSpec trafficSpec } { -framesize $frameSize \ -reportTputRateUnit mbps \ -duration $duration \ - -numtrials $numTrials \ + -numtrials $numTests \ -trafficType constantLoading \ -burstSize 1 \ -framesPerBurstGap 1 \ @@ -3391,7 +3394,7 @@ proc startRfc2544Test { testSpec trafficSpec } { -rfc2889ordering noOrdering \ -floodedFramesEnabled False \ -duration $duration \ - -numtrials $numTrials \ + -numtrials $numTests \ -trafficType constantLoading \ -burstSize 1 \ -framesPerBurstGap 1 \ diff --git a/tools/pkt_gen/moongen/moongen.py b/tools/pkt_gen/moongen/moongen.py index e14c6a79..790286d8 100644 --- a/tools/pkt_gen/moongen/moongen.py +++ b/tools/pkt_gen/moongen/moongen.py @@ -488,10 +488,21 @@ class Moongen(ITrafficGenerator): 'PARAMETERS section of Moongen log file') frame_size = 0 - if results_match and parameters_match: + # Each packet stream in the MoonGen report is prefaced with the + # words '[REPORT]Device'. Count the instances of this string to + # get the total aggregrate throughput. For example: + # + # - If num_traffic_streams = 1, there is a single + # unidirectional stream + # + # - If num_traffic_streams = 2, there is a bidirectional + # traffic stream + num_traffic_streams = mytext.count('[REPORT]Device') + + if results_match and parameters_match and num_traffic_streams: # Assume for now 10G link speed - max_theoretical_mfps = ( - (self._moongen_line_speed / 8) / (frame_size + 20)) + max_theoretical_fps = ( + num_traffic_streams * (self._moongen_line_speed / 8) / (frame_size + 20)) moongen_results[ResultsConstants.THROUGHPUT_RX_FPS] = ( float(results_match.group(6)) * 1000000) @@ -500,8 +511,7 @@ class Moongen(ITrafficGenerator): (float(results_match.group(6)) * frame_size + 20) * 8) moongen_results[ResultsConstants.THROUGHPUT_RX_PERCENT] = ( - float(results_match.group(6)) * \ - 1000000 / max_theoretical_mfps * 100) + (100 * float(results_match.group(6)) * 1000000) / max_theoretical_fps) moongen_results[ResultsConstants.TX_RATE_FPS] = ( float(results_match.group(5)) * 1000000) @@ -510,8 +520,7 @@ class Moongen(ITrafficGenerator): float(results_match.group(5)) * (frame_size + 20) * 8) moongen_results[ResultsConstants.TX_RATE_PERCENT] = ( - float(results_match.group(5)) * - 1000000 / max_theoretical_mfps * 100) + (100 * float(results_match.group(5)) * 1000000) / max_theoretical_fps) moongen_results[ResultsConstants.B2B_TX_COUNT] = ( float(results_match.group(1))) @@ -528,7 +537,7 @@ class Moongen(ITrafficGenerator): return moongen_results def send_rfc2544_throughput(self, traffic=None, duration=20, - lossrate=0.0, trials=1): + lossrate=0.0, tests=1): # # Send traffic per RFC2544 throughput test specifications. # @@ -537,7 +546,7 @@ class Moongen(ITrafficGenerator): # detected is found. # # :param traffic: Detailed "traffic" spec, see design docs for details - # :param trials: Number of trials to execute + # :param tests: Number of tests to execute # :param duration: Per iteration duration # :param lossrate: Acceptable lossrate percentage # :returns: dictionary of strings with following data: @@ -573,7 +582,7 @@ class Moongen(ITrafficGenerator): total_max_latency_ns = 0 total_avg_latency_ns = 0 - for test_run in range(1, trials+1): + for test_run in range(1, tests+1): collected_results = ( Moongen.run_moongen_and_collect_results(self, test_run=test_run)) @@ -602,35 +611,35 @@ class Moongen(ITrafficGenerator): results = OrderedDict() results[ResultsConstants.THROUGHPUT_RX_FPS] = ( - '{:.6f}'.format(total_throughput_rx_fps / trials)) + '{:.6f}'.format(total_throughput_rx_fps / tests)) results[ResultsConstants.THROUGHPUT_RX_MBPS] = ( - '{:.3f}'.format(total_throughput_rx_mbps / trials)) + '{:.3f}'.format(total_throughput_rx_mbps / tests)) results[ResultsConstants.THROUGHPUT_RX_PERCENT] = ( - '{:.3f}'.format(total_throughput_rx_pct / trials)) + '{:.3f}'.format(total_throughput_rx_pct / tests)) results[ResultsConstants.TX_RATE_FPS] = ( - '{:.6f}'.format(total_throughput_tx_fps / trials)) + '{:.6f}'.format(total_throughput_tx_fps / tests)) results[ResultsConstants.TX_RATE_MBPS] = ( - '{:.3f}'.format(total_throughput_tx_mbps / trials)) + '{:.3f}'.format(total_throughput_tx_mbps / tests)) results[ResultsConstants.TX_RATE_PERCENT] = ( - '{:.3f}'.format(total_throughput_tx_pct / trials)) + '{:.3f}'.format(total_throughput_tx_pct / tests)) results[ResultsConstants.MIN_LATENCY_NS] = ( - '{:.3f}'.format(total_min_latency_ns / trials)) + '{:.3f}'.format(total_min_latency_ns / tests)) results[ResultsConstants.MAX_LATENCY_NS] = ( - '{:.3f}'.format(total_max_latency_ns / trials)) + '{:.3f}'.format(total_max_latency_ns / tests)) results[ResultsConstants.AVG_LATENCY_NS] = ( - '{:.3f}'.format(total_avg_latency_ns / trials)) + '{:.3f}'.format(total_avg_latency_ns / tests)) return results - def start_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + def start_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """Non-blocking version of 'send_rfc2544_throughput'. @@ -646,14 +655,14 @@ class Moongen(ITrafficGenerator): self._logger.info('In moongen wait_rfc2544_throughput') def send_rfc2544_back2back(self, traffic=None, duration=60, - lossrate=0.0, trials=1): + lossrate=0.0, tests=1): """Send traffic per RFC2544 back2back test specifications. Send packets at a fixed rate, using ``traffic`` configuration, for duration seconds. :param traffic: Detailed "traffic" spec, see design docs for details - :param trials: Number of trials to execute + :param tests: Number of tests to execute :param duration: Per iteration duration :param lossrate: Acceptable loss percentage @@ -687,7 +696,7 @@ class Moongen(ITrafficGenerator): results[ResultsConstants.SCAL_STREAM_TYPE] = 0 results[ResultsConstants.SCAL_PRE_INSTALLED_FLOWS] = 0 - for test_run in range(1, trials+1): + for test_run in range(1, tests+1): collected_results = ( Moongen.run_moongen_and_collect_results(self, test_run=test_run)) @@ -717,28 +726,28 @@ class Moongen(ITrafficGenerator): # Calculate average results results[ResultsConstants.B2B_RX_FPS] = ( - results[ResultsConstants.B2B_RX_FPS] / trials) + results[ResultsConstants.B2B_RX_FPS] / tests) results[ResultsConstants.B2B_RX_PERCENT] = ( - results[ResultsConstants.B2B_RX_PERCENT] / trials) + results[ResultsConstants.B2B_RX_PERCENT] / tests) results[ResultsConstants.B2B_TX_FPS] = ( - results[ResultsConstants.B2B_TX_FPS] / trials) + results[ResultsConstants.B2B_TX_FPS] / tests) results[ResultsConstants.B2B_TX_PERCENT] = ( - results[ResultsConstants.B2B_TX_PERCENT] / trials) + results[ResultsConstants.B2B_TX_PERCENT] / tests) results[ResultsConstants.B2B_TX_COUNT] = ( - results[ResultsConstants.B2B_TX_COUNT] / trials) + results[ResultsConstants.B2B_TX_COUNT] / tests) results[ResultsConstants.B2B_FRAMES] = ( - results[ResultsConstants.B2B_FRAMES] / trials) + results[ResultsConstants.B2B_FRAMES] / tests) results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] = ( - results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] / trials) + results[ResultsConstants.B2B_FRAME_LOSS_FRAMES] / tests) results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] = ( - results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] / trials) + results[ResultsConstants.B2B_FRAME_LOSS_PERCENT] / tests) results[ResultsConstants.SCAL_STREAM_COUNT] = 0 results[ResultsConstants.SCAL_STREAM_TYPE] = 0 @@ -746,7 +755,7 @@ class Moongen(ITrafficGenerator): return results - def start_rfc2544_back2back(self, traffic=None, trials=1, duration=20, + def start_rfc2544_back2back(self, traffic=None, tests=1, duration=20, lossrate=0.0): # # Non-blocking version of 'send_rfc2544_back2back'. diff --git a/tools/pkt_gen/testcenter/testcenter.py b/tools/pkt_gen/testcenter/testcenter.py index a1f38d8b..c242269a 100644 --- a/tools/pkt_gen/testcenter/testcenter.py +++ b/tools/pkt_gen/testcenter/testcenter.py @@ -211,7 +211,7 @@ class TestCenter(trafficgen.ITrafficGenerator): return self.get_rfc2544_results(filec) - def send_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """ Send traffic per RFC2544 throughput test specifications. @@ -243,7 +243,7 @@ class TestCenter(trafficgen.ITrafficGenerator): return self.get_rfc2544_results(filec) - def send_rfc2544_back2back(self, traffic=None, trials=1, duration=20, + def send_rfc2544_back2back(self, traffic=None, tests=1, duration=20, lossrate=0.0): """ Send traffic per RFC2544 BacktoBack test specifications. diff --git a/tools/pkt_gen/trafficgen/trafficgen.py b/tools/pkt_gen/trafficgen/trafficgen.py index 3953bbb1..fb40cd92 100755 --- a/tools/pkt_gen/trafficgen/trafficgen.py +++ b/tools/pkt_gen/trafficgen/trafficgen.py @@ -133,7 +133,7 @@ class ITrafficGenerator(object): """ raise NotImplementedError('Please call an implementation.') - def send_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """Send traffic per RFC2544 throughput test specifications. @@ -142,7 +142,7 @@ class ITrafficGenerator(object): detected is found. :param traffic: Detailed "traffic" spec, see design docs for details - :param trials: Number of trials to execute + :param tests: Number of tests to execute :param duration: Per iteration duration :param lossrate: Acceptable lossrate percentage :returns: dictionary of strings with following data: @@ -158,7 +158,7 @@ class ITrafficGenerator(object): """ raise NotImplementedError('Please call an implementation.') - def start_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + def start_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """Non-blocking version of 'send_rfc2544_throughput'. @@ -172,7 +172,7 @@ class ITrafficGenerator(object): """ raise NotImplementedError('Please call an implementation.') - def send_rfc2544_back2back(self, traffic=None, trials=1, duration=20, + def send_rfc2544_back2back(self, traffic=None, tests=1, duration=20, lossrate=0.0): """Send traffic per RFC2544 back2back test specifications. @@ -180,7 +180,7 @@ class ITrafficGenerator(object): configuration, for duration seconds. :param traffic: Detailed "traffic" spec, see design docs for details - :param trials: Number of trials to execute + :param tests: Number of tests to execute :param duration: Per iteration duration :param lossrate: Acceptable loss percentage @@ -191,7 +191,7 @@ class ITrafficGenerator(object): """ raise NotImplementedError('Please call an implementation.') - def start_rfc2544_back2back(self, traffic=None, trials=1, duration=20, + def start_rfc2544_back2back(self, traffic=None, tests=1, duration=20, lossrate=0.0): """Non-blocking version of 'send_rfc2544_back2back'. diff --git a/tools/pkt_gen/xena/XenaDriver.py b/tools/pkt_gen/xena/XenaDriver.py index aa8443c9..d3862312 100644 --- a/tools/pkt_gen/xena/XenaDriver.py +++ b/tools/pkt_gen/xena/XenaDriver.py @@ -1001,9 +1001,21 @@ class XenaTXStats(object): mydict = statdict return mydict - def aggregate_stats(stat1, stat2): """ + Judge whether stat1 and stat2 both have same key, if both have same key, + call the aggregate fuction, else use the stat1's value + """ + newstat = dict() + for keys in stat1.keys(): + if keys in stat2 and isinstance(stat1[keys], dict): + newstat[keys] = aggregate(stat1[keys], stat2[keys]) + else: + newstat[keys] = stat1[keys] + return newstat + +def aggregate(stat1, stat2): + """ Recursive function to aggregate two sets of statistics. This is used when bi directional traffic is done and statistics need to be calculated based on two sets of statistics. @@ -1014,7 +1026,7 @@ def aggregate_stats(stat1, stat2): newstat = dict() for (keys1, keys2) in zip(stat1.keys(), stat2.keys()): if isinstance(stat1[keys1], dict): - newstat[keys1] = aggregate_stats(stat1[keys1], stat2[keys2]) + newstat[keys1] = aggregate(stat1[keys1], stat2[keys2]) else: if not isinstance(stat1[keys1], int) and not isinstance( [keys1], float): diff --git a/tools/pkt_gen/xena/xena.py b/tools/pkt_gen/xena/xena.py index 67e9984f..449ef5b4 100755 --- a/tools/pkt_gen/xena/xena.py +++ b/tools/pkt_gen/xena/xena.py @@ -275,10 +275,10 @@ class Xena(ITrafficGenerator): return result_dict - def _setup_json_config(self, trials, loss_rate, testtype=None): + def _setup_json_config(self, tests, loss_rate, testtype=None): """ Create a 2bUsed json file that will be used for xena2544.exe execution. - :param trials: Number of trials + :param tests: Number of tests :param loss_rate: The acceptable loss rate as float :param testtype: Either '2544_b2b' or '2544_throughput' as string :return: None @@ -305,7 +305,7 @@ class Xena(ITrafficGenerator): if testtype == '2544_throughput': j_file.set_test_options_tput( packet_sizes=self._params['traffic']['l2']['framesize'], - iterations=trials, loss_rate=loss_rate, + iterations=tests, loss_rate=loss_rate, duration=self._duration, micro_tpld=True if self._params[ 'traffic']['l2']['framesize'] == 64 else False) j_file.enable_throughput_test() @@ -313,7 +313,7 @@ class Xena(ITrafficGenerator): elif testtype == '2544_b2b': j_file.set_test_options_back2back( packet_sizes=self._params['traffic']['l2']['framesize'], - iterations=trials, duration=self._duration, + iterations=tests, duration=self._duration, startvalue=self._params['traffic']['frame_rate'], endvalue=self._params['traffic']['frame_rate'], micro_tpld=True if self._params[ @@ -590,7 +590,7 @@ class Xena(ITrafficGenerator): """ return self._stop_api_traffic() - def send_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + def send_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """Send traffic per RFC2544 throughput test specifications. @@ -603,14 +603,14 @@ class Xena(ITrafficGenerator): if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) - self._setup_json_config(trials, lossrate, '2544_throughput') + self._setup_json_config(tests, lossrate, '2544_throughput') self._start_xena_2544() self._wait_xena_2544_complete() root = ET.parse(r'./tools/pkt_gen/xena/xena2544-report.xml').getroot() return Xena._create_throughput_result(root) - def start_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + def start_rfc2544_throughput(self, traffic=None, tests=1, duration=20, lossrate=0.0): """Non-blocking version of 'send_rfc2544_throughput'. @@ -622,7 +622,7 @@ class Xena(ITrafficGenerator): if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) - self._setup_json_config(trials, lossrate, '2544_throughput') + self._setup_json_config(tests, lossrate, '2544_throughput') self._start_xena_2544() def wait_rfc2544_throughput(self): @@ -634,7 +634,7 @@ class Xena(ITrafficGenerator): root = ET.parse(r'./tools/pkt_gen/xena/xena2544-report.xml').getroot() return Xena._create_throughput_result(root) - def send_rfc2544_back2back(self, traffic=None, trials=1, duration=20, + def send_rfc2544_back2back(self, traffic=None, tests=1, duration=20, lossrate=0.0): """Send traffic per RFC2544 back2back test specifications. @@ -647,13 +647,13 @@ class Xena(ITrafficGenerator): if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) - self._setup_json_config(trials, lossrate, '2544_b2b') + self._setup_json_config(tests, lossrate, '2544_b2b') self._start_xena_2544() self._wait_xena_2544_complete() root = ET.parse(r'./tools/pkt_gen/xena/xena2544-report.xml').getroot() return Xena._create_throughput_result(root) - def start_rfc2544_back2back(self, traffic=None, trials=1, duration=20, + def start_rfc2544_back2back(self, traffic=None, tests=1, duration=20, lossrate=0.0): """Non-blocking version of 'send_rfc2544_back2back'. @@ -665,7 +665,7 @@ class Xena(ITrafficGenerator): if traffic: self._params['traffic'] = merge_spec(self._params['traffic'], traffic) - self._setup_json_config(trials, lossrate, '2544_b2b') + self._setup_json_config(tests, lossrate, '2544_b2b') self._start_xena_2544() def wait_rfc2544_back2back(self): diff --git a/vnfs/qemu/qemu_pci_passthrough.py b/vnfs/qemu/qemu_pci_passthrough.py index 14810f0a..951d6086 100644 --- a/vnfs/qemu/qemu_pci_passthrough.py +++ b/vnfs/qemu/qemu_pci_passthrough.py @@ -44,8 +44,8 @@ class QemuPciPassthrough(IVnfQemu): # in case of SRIOV and PCI passthrough we must ensure, that MAC addresses are swapped if S.getValue('SRIOV_ENABLED') and not self._testpmd_fwd_mode.startswith('mac'): self._logger.info("SRIOV detected, forwarding mode of testpmd was changed from '%s' to '%s'", - self._testpmd_fwd_mode, 'mac_retry') - self._testpmd_fwd_mode = 'mac_retry' + self._testpmd_fwd_mode, 'mac') + self._testpmd_fwd_mode = 'mac' for nic in self._nics: self._cmd += ['-device', 'vfio-pci,host=' + nic['pci']] @@ -180,7 +180,7 @@ def parse_arguments(): group.add_argument('--test-params', action=_SplitTestParamsAction, help='csv list of test parameters: key=val; e.g.' 'including pkt_sizes=x,y; duration=x; ' - 'rfc2544_trials=x ...') + 'rfc2544_tests=x ...') group.add_argument('--opnfvpod', help='name of POD in opnfv') args = vars(parser.parse_args()) @@ -557,13 +557,13 @@ def main(): _LOGGER.error("Cannot specify tests with both positional args and --test.") sys.exit(1) - # sriov handling - settings.setValue('SRIOV_ENABLED', enable_sriov(settings.getValue('WHITELIST_NICS'))) - # modify NIC configuration to decode enhanced PCI IDs wl_nics_orig = list(networkcard.check_pci(pci) for pci in settings.getValue('WHITELIST_NICS')) settings.setValue('WHITELIST_NICS_ORIG', wl_nics_orig) + # sriov handling is performed on checked/expanded PCI IDs + settings.setValue('SRIOV_ENABLED', enable_sriov(wl_nics_orig)) + nic_list = [] for nic in wl_nics_orig: tmp_nic = networkcard.get_nic_info(nic) |