diff options
21 files changed, 439 insertions, 59 deletions
diff --git a/conf/03_traffic.conf b/conf/03_traffic.conf index a88e4bcc..3c7bd2f5 100644 --- a/conf/03_traffic.conf +++ b/conf/03_traffic.conf @@ -451,11 +451,11 @@ TRAFFICGEN_TREX_RFC2544_TPUT_THRESHOLD = 0.05 # Parameter below defines frequency of packets used for latency measurement in PPS. # Value 0 will disable latency specific streams. TRAFFICGEN_TREX_LATENCY_PPS = 1000 -# Example 10 Gbps: TRAFFICGEN_TREXINE_SPEED_GBPS = '10' -# Today only 10 Gbps is supported -TRAFFICGEN_TREX_LINE_SPEED_GBPS = '10' +# Enablement of learning packets before sending test traffic +TRAFFICGEN_TREX_LEARNING_MODE = True +TRAFFICGEN_TREX_LEARNING_DURATION = 5 # FOR SR-IOV or multistream layer 2 tests to work with T-Rex enable Promiscuous mode -TRAFFICGEN_TREX_PROMISCUOUS=False +TRAFFICGEN_TREX_PROMISCUOUS = False PATHS['trafficgen'] = { 'Trex': { 'type' : 'src', @@ -464,5 +464,9 @@ PATHS['trafficgen'] = { } } } +# TRex validation option for RFC2544 +TRAFFICGEN_TREX_VERIFICATION_MODE = False +TRAFFICGEN_TREX_VERIFICATION_DURATION = 60 +TRAFFICGEN_TREX_MAXIMUM_VERIFICATION_TRIALS = 10 # TREX Configuration and Connection Info-- END ############################################## diff --git a/conf/10_custom.conf b/conf/10_custom.conf index 8020bb93..917d16b4 100644 --- a/conf/10_custom.conf +++ b/conf/10_custom.conf @@ -133,11 +133,15 @@ TRAFFICGEN_TREX_PORT2 = '' # Parameter below defines frequency of packets used for latency measurement in PPS. # Value 0 will disable latency specific streams. TRAFFICGEN_TREX_LATENCY_PPS = 1000 -# Example 10 Gbps: TRAFFICGEN_TREXINE_SPEED_GBPS = '10' -# Today only 10 Gbps is supported -TRAFFICGEN_TREX_LINE_SPEED_GBPS = '10' +# Enablement of learning packets before sending test traffic +TRAFFICGEN_TREX_LEARNING_MODE = True +TRAFFICGEN_TREX_LEARNING_DURATION = 5 # FOR SR-IOV or multistream layer 2 tests to work with T-Rex enable Promiscuous mode -TRAFFICGEN_TREX_PROMISCUOUS=False +TRAFFICGEN_TREX_PROMISCUOUS = False +# TRex validation option for RFC2544 +TRAFFICGEN_TREX_VERIFICATION_MODE = False +TRAFFICGEN_TREX_VERIFICATION_DURATION = 60 +TRAFFICGEN_TREX_MAXIMUM_VERIFICATION_TRIALS = 10 # TREX Configuration and Connection Info-- END #################################################### @@ -161,3 +165,4 @@ PACKAGE_LIST = "src/package-list.mk" # 'openvswitch'] #PATHS['vswitch']['OvsVanilla']['type'] = 'bin' + diff --git a/docs/testing/user/configguide/installation.rst b/docs/testing/user/configguide/installation.rst index b08bfa86..7f4d640b 100644 --- a/docs/testing/user/configguide/installation.rst +++ b/docs/testing/user/configguide/installation.rst @@ -49,6 +49,8 @@ Supported Operating Systems * Fedora 25 (kernel 4.9 requires DPDK 16.11 and newer) * openSUSE 42.2 * openSUSE 42.3 +* openSUSE Tumbleweed +* SLES 15 * RedHat 7.2 Enterprise Linux * RedHat 7.3 Enterprise Linux * Ubuntu 14.04 diff --git a/docs/testing/user/configguide/trafficgen.rst b/docs/testing/user/configguide/trafficgen.rst index 4b9eec6e..91c4084e 100644 --- a/docs/testing/user/configguide/trafficgen.rst +++ b/docs/testing/user/configguide/trafficgen.rst @@ -826,6 +826,15 @@ Default value of this parameter is defined in conf/03_traffic.conf as follows: TRAFFICGEN_TREX_RFC2544_TPUT_THRESHOLD = '' +T-Rex can have learning packets enabled. For certain tests it may be beneficial +to send some packets before starting test traffic to allow switch learning to take +place. This can be adjusted with the following configurations: + +.. code-block:: console + + TRAFFICGEN_TREX_LEARNING_MODE=True + TRAFFICGEN_TREX_LEARNING_DURATION=5 + SR-IOV and Multistream layer 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ T-Rex by default only accepts packets on the receive side if the destination mac matches the @@ -840,3 +849,23 @@ modified. Enable Promiscuous mode when doing multistream at layer 2 testing with .. code-block:: console TRAFFICGEN_TREX_PROMISCUOUS=True + +RFC2544 Validation +~~~~~~~~~~~~~~~~~~ + +T-Rex can perform a verification run for a longer duration once the binary search of the +RFC2544 trials have completed. This duration should be at least 60 seconds. This is similar +to other traffic generator functionality where a more sustained time can be attempted to +verify longer runs from the result of the search. This can be configured with the following +params + +.. code-block:: console + + TRAFFICGEN_TREX_VERIFICATION_MODE = False + TRAFFICGEN_TREX_VERIFICATION_DURATION = 60 + TRAFFICGEN_TREX_MAXIMUM_VERIFICATION_TRIALS = 10 + +The duration and maximum number of attempted verification trials can be set to change the +behavior of this step. If the verification step fails, it will resume the binary search +with new values where the maximum output will be the last attempted frame rate minus the +current set thresh hold. diff --git a/docs/testing/user/userguide/teststeps.rst b/docs/testing/user/userguide/teststeps.rst index 8be67310..40cc732c 100644 --- a/docs/testing/user/userguide/teststeps.rst +++ b/docs/testing/user/userguide/teststeps.rst @@ -131,6 +131,21 @@ of supported objects and their most common functions follows: ['vnf2', 'stop'], ['vnf1', 'stop'], + * ``VNF[ID]`` - provides access to VNFs deployed automatically by testcase deployment + scenario. For Example ``pvvp`` deployment automatically starts two VNFs before any + TestStep is executed. It is possible to access these VNFs by VNF0 and VNF1 labels. + + List of supported functions is identical to ``vnf[ID]`` option above except functions + ``start`` and ``stop``. + + Examples: + + .. code-block:: python + + ['VNF0', 'execute_and_wait', 'ifconfig eth2 5.5.5.1/24 up'], + ['VNF1', 'execute_and_wait', 'ifconfig eth2 5.5.5.2/24 up', 120, 'root.*#'], + ['VNF2', 'execute_and_wait', 'ping -c1 5.5.5.1'], + * ``trafficgen`` - triggers traffic generation List of supported functions: diff --git a/systems/centos/prepare_python_env.sh b/systems/centos/prepare_python_env.sh index 5777448b..8bce53cc 100755 --- a/systems/centos/prepare_python_env.sh +++ b/systems/centos/prepare_python_env.sh @@ -2,7 +2,7 @@ # # Prepare Python 3 environment for vsperf execution # -# Copyright 2015 OPNFV +# Copyright 2015-2017 OPNFV # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ if [ -d "$VSPERFENV_DIR" ] ; then fi scl enable python33 " -virtualenv "$VSPERFENV_DIR" +virtualenv "$VSPERFENV_DIR" --python /usr/bin/python3 source "$VSPERFENV_DIR"/bin/activate pip install -r ../requirements.txt pip install pylint diff --git a/systems/fedora/24/prepare_python_env.sh b/systems/fedora/24/prepare_python_env.sh index b099df5e..920604c2 100644 --- a/systems/fedora/24/prepare_python_env.sh +++ b/systems/fedora/24/prepare_python_env.sh @@ -23,7 +23,7 @@ fi # enable virtual environment in a subshell, so QEMU build can use python 2.7 -(virtualenv-3.5 "$VSPERFENV_DIR" +(virtualenv-3.5 "$VSPERFENV_DIR" --python /usr/bin/python3 source "$VSPERFENV_DIR"/bin/activate pip install -r ../requirements.txt pip install pylint) diff --git a/systems/fedora/25/prepare_python_env.sh b/systems/fedora/25/prepare_python_env.sh index 4a85eb35..c4613ca4 100644 --- a/systems/fedora/25/prepare_python_env.sh +++ b/systems/fedora/25/prepare_python_env.sh @@ -23,7 +23,7 @@ fi # enable virtual environment in a subshell, so QEMU build can use python 2.7 -(virtualenv-3.5 "$VSPERFENV_DIR" +(virtualenv-3.5 "$VSPERFENV_DIR" --python /usr/bin/python3 source "$VSPERFENV_DIR"/bin/activate pip install -r ../requirements.txt pip install pylint diff --git a/systems/fedora/26/prepare_python_env.sh b/systems/fedora/26/prepare_python_env.sh index 33615cbd..05eedfd9 100644 --- a/systems/fedora/26/prepare_python_env.sh +++ b/systems/fedora/26/prepare_python_env.sh @@ -23,7 +23,7 @@ fi # enable virtual environment in a subshell, so QEMU build can use python 2.7 -(virtualenv-3.6 "$VSPERFENV_DIR" +(virtualenv-3.6 "$VSPERFENV_DIR" --python /usr/bin/python3 source "$VSPERFENV_DIR"/bin/activate pip install -r ../requirements.txt pip install pylint diff --git a/systems/opensuse/42.2/prepare_python_env.sh b/systems/opensuse/42.2/prepare_python_env.sh index 66f94cf7..ab668ca4 100755 --- a/systems/opensuse/42.2/prepare_python_env.sh +++ b/systems/opensuse/42.2/prepare_python_env.sh @@ -21,7 +21,7 @@ if [ -d "$VSPERFENV_DIR" ] ; then exit fi -virtualenv "$VSPERFENV_DIR" +virtualenv "$VSPERFENV_DIR" --python /usr/bin/python3 source "$VSPERFENV_DIR"/bin/activate pip install -r ../requirements.txt pip install pylint diff --git a/systems/opensuse/42.3/prepare_python_env.sh b/systems/opensuse/42.3/prepare_python_env.sh index 66f94cf7..ab668ca4 100755 --- a/systems/opensuse/42.3/prepare_python_env.sh +++ b/systems/opensuse/42.3/prepare_python_env.sh @@ -21,7 +21,7 @@ if [ -d "$VSPERFENV_DIR" ] ; then exit fi -virtualenv "$VSPERFENV_DIR" +virtualenv "$VSPERFENV_DIR" --python /usr/bin/python3 source "$VSPERFENV_DIR"/bin/activate pip install -r ../requirements.txt pip install pylint diff --git a/systems/opensuse/build_base_machine.sh b/systems/opensuse/build_base_machine.sh new file mode 100755 index 00000000..8b26440c --- /dev/null +++ b/systems/opensuse/build_base_machine.sh @@ -0,0 +1,95 @@ +#!/bin/bash +# +# Build a base machine for openSUSE Tumbleweed systems +# +# Copyright (c) 2017 SUSE LLC. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Contributors: +# Jose Lausuch, SUSE LINUX GmbH + +zypper -q -n dup +zypper -q -n in -y $(echo " +# compiler, tools and dependencies +make +automake +gcc +gcc-c++ +glibc +glibc-devel +fuse +fuse-devel +glib2-devel +zlib-devel +ncurses-devel +kernel-default +kernel-default-devel +pkg-config +findutils-locate +curl +automake +autoconf +vim +wget +git +pciutils +cifs-utils +socat +sysstat +java-1_8_0-openjdk +git-review +mlocate + +# python +python3 +python-pip +python3-pip +python3-setuptools +python3-devel +python3-tk +python3-virtualenv + +# libraries +libnuma1 +libnuma-devel +libpixman-1-0 +libpixman-1-0-devel +libtool +libpcap-devel +libnet9 +libncurses6 +libcurl4 +libcurl-devel +libxml2 +libfuse2 +libopenssl1_1_0 +libopenssl-devel +libpython3_6m1_0 + +" | grep -v ^#) + +updatedb + +# fix for the Ixia TclClient +ln -sf $(locate libc.so.6) /lib/libc.so.6 + +# virtual environment for python +pip3 install virtualenv + +# hugepages setup +mkdir -p /dev/hugepages + +# fix for non-utf8 characters in file +cp /etc/services /etc/services.bak +iconv -o /etc/services -f utf-8 -t utf-8 -c /etc/services.bak diff --git a/systems/opensuse/prepare_python_env.sh b/systems/opensuse/prepare_python_env.sh new file mode 100755 index 00000000..69871670 --- /dev/null +++ b/systems/opensuse/prepare_python_env.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# +# Prepare Python environment for vsperf execution on openSUSE Tumbleweed systems +# +# Copyright (c) 2017 SUSE LLC. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if [ -d "$VSPERFENV_DIR" ] ; then + echo "Directory $VSPERFENV_DIR already exists. Skipping python virtualenv creation." + exit +fi + +virtualenv "$VSPERFENV_DIR" --python /usr/bin/python3 +source "$VSPERFENV_DIR"/bin/activate +pip install -r ../requirements.txt +pip install pylint + diff --git a/systems/rhel/7.2/prepare_python_env.sh b/systems/rhel/7.2/prepare_python_env.sh index bd468d80..fb5882f1 100755 --- a/systems/rhel/7.2/prepare_python_env.sh +++ b/systems/rhel/7.2/prepare_python_env.sh @@ -2,7 +2,7 @@ # # Prepare Python environment for vsperf execution on Red Hat 7.2 systems. # -# Copyright 2016 OPNFV, Intel Corporation, Red Hat Inc. +# Copyright 2016-2017 OPNFV, Intel Corporation, Red Hat Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ if [ -d "$VSPERFENV_DIR" ] ; then fi scl enable python33 " -virtualenv "$VSPERFENV_DIR" +virtualenv "$VSPERFENV_DIR" --python /opt/rh/python33/root/usr/bin/python3 source "$VSPERFENV_DIR"/bin/activate pip install -r ../requirements.txt pip install pylint diff --git a/systems/rhel/7.3/prepare_python_env.sh b/systems/rhel/7.3/prepare_python_env.sh index 3ba049e8..b573bb9f 100755 --- a/systems/rhel/7.3/prepare_python_env.sh +++ b/systems/rhel/7.3/prepare_python_env.sh @@ -2,7 +2,7 @@ # # Prepare Python environment for vsperf execution on RHEL 7.3 systems. # -# Copyright 2016 OPNFV, Intel Corporation, Red Hat Inc. +# Copyright 2016-2017 OPNFV, Intel Corporation, Red Hat Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ if [ -d "$VSPERFENV_DIR" ] ; then fi scl enable python33 " -virtualenv "$VSPERFENV_DIR" +virtualenv "$VSPERFENV_DIR" --python /opt/rh/python33/root/usr/bin/python3 source "$VSPERFENV_DIR"/bin/activate pip install -r ../requirements.txt pip install pylint diff --git a/systems/sles/15/build_base_machine.sh b/systems/sles/15/build_base_machine.sh new file mode 100755 index 00000000..9c161dd7 --- /dev/null +++ b/systems/sles/15/build_base_machine.sh @@ -0,0 +1,89 @@ +#!/bin/bash +# +# Build a base machine for SLES15 systems +# +# Copyright (c) 2017 SUSE LLC. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Contributors: +# Jose Lausuch, SUSE LINUX GmbH + +zypper -q -n dup +zypper -q -n in -y $(echo " +# compiler, tools and dependencies +make +automake +gcc +gcc-c++ +glibc +glibc-devel +fuse +fuse-devel +glib2-devel +zlib-devel +ncurses-devel +kernel-default +kernel-default-devel +pkg-config +findutils-locate +curl +automake +autoconf +vim +wget +git +pciutils +cifs-utils +socat +sysstat +java-9-openjdk +mlocate + +# python +python3 +python3-pip +python3-setuptools +python3-devel +python3-tk + +# libraries +libnuma1 +libnuma-devel +libpixman-1-0 +libpixman-1-0-devel +libtool +libpcap-devel +libnet9 +libncurses5 +libcurl4 +libcurl-devel +libxml2 +libfuse2 +libopenssl1_1_0 +libopenssl-devel +libpython3_6m1_0 + +" | grep -v ^#) + +updatedb + +# fix for the Ixia TclClient +ln -sf $(locate libc.so.6) /lib/libc.so.6 + +# virtual environment for python +pip3 install virtualenv + +# hugepages setup +mkdir -p /dev/hugepages + diff --git a/systems/sles/15/prepare_python_env.sh b/systems/sles/15/prepare_python_env.sh new file mode 100755 index 00000000..12ada3cc --- /dev/null +++ b/systems/sles/15/prepare_python_env.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# +# Prepare Python environment for vsperf execution on SLES15 systems +# +# Copyright (c) 2017 SUSE LLC. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if [ -d "$VSPERFENV_DIR" ] ; then + echo "Directory $VSPERFENV_DIR already exists. Skipping python virtualenv creation." + exit +fi + +virtualenv "$VSPERFENV_DIR" --python /usr/bin/python3 +source "$VSPERFENV_DIR"/bin/activate +pip install -r ../requirements.txt +pip install pylint + diff --git a/systems/ubuntu/14.04/prepare_python_env.sh b/systems/ubuntu/14.04/prepare_python_env.sh index 6ef8680d..4c98dc42 100755 --- a/systems/ubuntu/14.04/prepare_python_env.sh +++ b/systems/ubuntu/14.04/prepare_python_env.sh @@ -2,7 +2,7 @@ # # Prepare Python environment for vsperf execution on Ubuntu 14.04 systems # -# Copyright 2015 OPNFV, Intel Corporation. +# Copyright 2015-2017 OPNFV, Intel Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ fi # enable virtual environment in a subshell, so QEMU build can use python 2.7 -(virtualenv "$VSPERFENV_DIR" +(virtualenv "$VSPERFENV_DIR" --python /usr/bin/python3 source "$VSPERFENV_DIR"/bin/activate pip install -r ../requirements.txt pip install pylint) diff --git a/testcases/testcase.py b/testcases/testcase.py index 37cdefa6..b3300b89 100644 --- a/testcases/testcase.py +++ b/testcases/testcase.py @@ -78,6 +78,7 @@ class TestCase(object): self._step_result_mapping = {} self._step_status = None self._step_send_traffic = False # indication if send_traffic was called within test steps + self._vnf_list = [] self._testcase_run_time = None S.setValue('VSWITCH', cfg.get('vSwitch', S.getValue('VSWITCH'))) @@ -201,6 +202,8 @@ class TestCase(object): loader.get_vnf_class(), len(self._step_vnf_list)) + self._vnf_list = self._vnf_ctl.get_vnfs() + # 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.') @@ -792,10 +795,21 @@ class TestCase(object): # so it is not sent again after the execution of teststeps self._step_send_traffic = True elif step[0].startswith('vnf'): + # use vnf started within TestSteps if not self._step_vnf_list[step[0]]: # initialize new VM self._step_vnf_list[step[0]] = loader.get_vnf_class()() test_object = self._step_vnf_list[step[0]] + elif step[0].startswith('VNF'): + if step[1] in ('start', 'stop'): + raise RuntimeError("Cannot execute start() or stop() method of " + "VNF deployed automatically by scenario.") + # use vnf started by scenario deployment (e.g. pvp) + vnf_index = int(step[0][3:]) + try: + test_object = self._vnf_list[vnf_index] + except IndexError: + raise RuntimeError("VNF with index {} is not running.".format(vnf_index)) elif step[0] == 'wait': input(os.linesep + "Step {}: Press Enter to continue with " "the next step...".format(i) + os.linesep + os.linesep) diff --git a/tools/functions.py b/tools/functions.py index c0d1e5f7..d35f1f84 100644 --- a/tools/functions.py +++ b/tools/functions.py @@ -190,17 +190,15 @@ def filter_output(output, regex): """ result = [] if isinstance(output, str): - for line in output.split('\n'): + for line in output.splitlines(): result += re.findall(regex, line) - return result - elif isinstance(output, list) or isinstance(output, tuple): - tmp_res = [] + elif isinstance(output, (list, tuple)): for item in output: - tmp_res.append(filter_output(item, regex)) - return tmp_res + result.append(filter_output(item, regex)) else: raise RuntimeError('Only strings and lists are supported by filter_output(), ' 'but output has type {}'.format(type(output))) + return result def format_description(desc, length): """ Split description into multiple lines based on given line length. diff --git a/tools/pkt_gen/trex/trex.py b/tools/pkt_gen/trex/trex.py index acdaf287..82118f6f 100644 --- a/tools/pkt_gen/trex/trex.py +++ b/tools/pkt_gen/trex/trex.py @@ -19,6 +19,7 @@ Trex Traffic Generator Model import logging import subprocess import sys +import time from collections import OrderedDict # pylint: disable=unused-import import netaddr @@ -81,6 +82,7 @@ class Trex(ITrafficGenerator): settings.getValue('TRAFFICGEN_TREX_BASE_DIR')) self._trex_user = settings.getValue('TRAFFICGEN_TREX_USER') self._stlclient = None + self._verification_params = None def connect(self): '''Connect to Trex traffic generator @@ -325,6 +327,69 @@ class Trex(ITrafficGenerator): result[ResultsConstants.AVG_LATENCY_NS] = 'Unknown' return result + def learning_packets(self, traffic): + """ + Send learning packets before testing + :param traffic: traffic structure as per send_cont_traffic guidelines + :return: None + """ + self._logger.info("T-Rex sending learning packets") + learning_thresh_traffic = copy.deepcopy(traffic) + learning_thresh_traffic["frame_rate"] = 1 + self.generate_traffic(learning_thresh_traffic, settings.getValue("TRAFFICGEN_TREX_LEARNING_DURATION")) + self._logger.info("T-Rex finished learning packets") + time.sleep(3) # allow packets to complete before starting test traffic + + def run_trials(self, traffic, boundaries, duration, lossrate): + """ + Run rfc2544 trial loop + :param traffic: traffic profile dictionary + :param boundaries: A dictionary of three keys left, right, center to dictate + the highest, lowest, and starting point of the binary search. + Values are percentages of line rates for each key. + :param duration: length in seconds for trials + :param lossrate: loweset loss rate percentage calculated from + comparision between received and sent packets + :return: passing stats as dictionary + """ + threshold = settings.getValue('TRAFFICGEN_TREX_RFC2544_TPUT_THRESHOLD') + stats_ok = _EMPTY_STATS + new_params = copy.deepcopy(traffic) + iteration = 1 + left = boundaries['left'] + right = boundaries['right'] + center = boundaries['center'] + self._logger.info('Starting RFC2544 trials') + while (right - left) > threshold: + stats = self.generate_traffic(new_params, duration) + test_lossrate = ((stats["total"]["opackets"] - stats[ + "total"]["ipackets"]) * 100) / stats["total"]["opackets"] + if stats["total"]["ipackets"] == 0: + self._logger.error('No packets recieved. Test failed') + return _EMPTY_STATS + if settings.getValue('TRAFFICGEN_TREX_VERIFICATION_MODE'): + if test_lossrate <= lossrate: + # save the last passing trial for verification + self._verification_params = copy.deepcopy(new_params) + self._logger.debug("Iteration: %s, frame rate: %s, throughput_rx_fps: %s, frame_loss_percent: %s", + iteration, "{:.3f}".format(new_params['frame_rate']), stats['total']['rx_pps'], + "{:.3f}".format(test_lossrate)) + if test_lossrate == 0.0 and new_params['frame_rate'] == traffic['frame_rate']: + return copy.deepcopy(stats) + elif test_lossrate > lossrate: + right = center + center = (left + right) / 2 + new_params = copy.deepcopy(traffic) + new_params['frame_rate'] = center + else: + stats_ok = copy.deepcopy(stats) + left = center + center = (left + right) / 2 + new_params = copy.deepcopy(traffic) + new_params['frame_rate'] = center + iteration += 1 + return stats_ok + def send_cont_traffic(self, traffic=None, duration=30): """See ITrafficGenerator for description """ @@ -336,6 +401,8 @@ class Trex(ITrafficGenerator): self._params['traffic'] = merge_spec( self._params['traffic'], traffic) + if settings.getValue('TRAFFICGEN_TREX_LEARNING_MODE'): + self.learning_packets(traffic) stats = self.generate_traffic(traffic, duration) return self.calculate_results(stats) @@ -356,45 +423,51 @@ class Trex(ITrafficGenerator): """ self._logger.info("In Trex send_rfc2544_throughput method") self._params.clear() - threshold = settings.getValue('TRAFFICGEN_TREX_RFC2544_TPUT_THRESHOLD') - test_lossrate = 0 - left = 0 - iteration = 1 - stats_ok = _EMPTY_STATS self._params['traffic'] = self.traffic_defaults.copy() if traffic: self._params['traffic'] = merge_spec( self._params['traffic'], traffic) - new_params = copy.deepcopy(traffic) - stats = self.generate_traffic(traffic, duration) - right = traffic['frame_rate'] - center = traffic['frame_rate'] + if settings.getValue('TRAFFICGEN_TREX_LEARNING_MODE'): + self.learning_packets(traffic) + self._verification_params = copy.deepcopy(traffic) - # Loops until the preconfigured difference between frame rate + binary_bounds = {'right' : traffic['frame_rate'], + 'left' : 0, + 'center': traffic['frame_rate'],} + + # Loops until the preconfigured differencde between frame rate # of successful and unsuccessful iterations is reached - while (right - left) > threshold: - test_lossrate = ((stats["total"]["opackets"] - stats["total"] - ["ipackets"]) * 100) / stats["total"]["opackets"] - self._logger.debug("Iteration: %s, frame rate: %s, throughput_rx_fps: %s, frame_loss_percent: %s", - iteration, "{:.3f}".format(new_params['frame_rate']), stats['total']['rx_pps'], - "{:.3f}".format(test_lossrate)) - if test_lossrate == 0.0 and new_params['frame_rate'] == traffic['frame_rate']: - stats_ok = copy.deepcopy(stats) - break - elif test_lossrate > lossrate: - right = center - center = (left+right) / 2 - new_params = copy.deepcopy(traffic) - new_params['frame_rate'] = center - stats = self.generate_traffic(new_params, duration) + stats_ok = self.run_trials(boundaries=binary_bounds, duration=duration, + lossrate=lossrate, traffic=traffic) + if settings.getValue('TRAFFICGEN_TREX_VERIFICATION_MODE'): + verification_iterations = 1 + while verification_iterations <= settings.getValue('TRAFFICGEN_TREX_MAXIMUM_VERIFICATION_TRIALS'): + self._logger.info('Starting Trex Verification trial for %s seconds at frame rate %s', + settings.getValue('TRAFFICGEN_TREX_VERIFICATION_DURATION'), + self._verification_params['frame_rate']) + stats = self.generate_traffic(self._verification_params, + settings.getValue('TRAFFICGEN_TREX_VERIFICATION_DURATION')) + verification_lossrate = ((stats["total"]["opackets"] - stats[ + "total"]["ipackets"]) * 100) / stats["total"]["opackets"] + if verification_lossrate <= lossrate: + self._logger.info('Trex Verification passed, %s packets were lost', + stats["total"]["opackets"] - stats["total"]["ipackets"]) + stats_ok = copy.deepcopy(stats) + break + else: + self._logger.info('Trex Verification failed, %s packets were lost', + stats["total"]["opackets"] - stats["total"]["ipackets"]) + new_right = self._verification_params['frame_rate'] - settings.getValue( + 'TRAFFICGEN_TREX_RFC2544_TPUT_THRESHOLD') + self._verification_params['frame_rate'] = new_right + binary_bounds = {'right': new_right, + 'left': 0, + 'center': new_right,} + stats_ok = self.run_trials(boundaries=binary_bounds, duration=duration, + lossrate=lossrate, traffic=self._verification_params) + verification_iterations += 1 else: - stats_ok = copy.deepcopy(stats) - left = center - center = (left+right) / 2 - new_params = copy.deepcopy(traffic) - new_params['frame_rate'] = center - stats = self.generate_traffic(new_params, duration) - iteration += 1 + self._logger.error('Could not pass Trex Verification. Test failed') return self.calculate_results(stats_ok) def start_rfc2544_throughput(self, traffic=None, tests=1, duration=60, |