summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/dts_gsg/Makefile156
-rw-r--r--doc/dts_gsg/conf.py40
-rw-r--r--doc/dts_gsg/config.rst254
-rw-r--r--doc/dts_gsg/image/dts_network_arch.pngbin0 -> 147605 bytes
-rw-r--r--doc/dts_gsg/image/dts_result.pngbin0 -> 7885 bytes
-rw-r--r--doc/dts_gsg/image/dts_soft_arch.pngbin0 -> 92092 bytes
-rw-r--r--doc/dts_gsg/index.rst42
-rw-r--r--doc/dts_gsg/intro.rst124
-rw-r--r--doc/dts_gsg/review.rst104
-rw-r--r--doc/dts_gsg/sys_reqs.rst186
-rwxr-xr-xdts (renamed from dcts)0
-rw-r--r--framework/crb.py187
-rw-r--r--framework/crbs.py31
-rw-r--r--framework/dts.py (renamed from framework/dcts.py)211
-rw-r--r--framework/dut.py142
-rw-r--r--framework/etgen.py172
-rw-r--r--framework/excel_reporter.py31
-rw-r--r--framework/exception.py5
-rw-r--r--framework/ixia_buffer_parser.py31
-rw-r--r--framework/ixiacfg.py10
-rw-r--r--framework/logger.py212
-rwxr-xr-xframework/main.py47
-rw-r--r--framework/plotgraph.py33
-rw-r--r--framework/plotting.py39
-rw-r--r--framework/pmd_output.py50
-rw-r--r--framework/project_dpdk.py161
-rw-r--r--framework/rst.py37
-rw-r--r--framework/serializer.py31
-rw-r--r--framework/settings.py35
-rw-r--r--framework/ssh_connection.py31
-rw-r--r--framework/ssh_pexpect.py20
-rw-r--r--framework/stats_reporter.py31
-rw-r--r--framework/tclclient.tgzbin0 -> 191206 bytes
-rw-r--r--framework/test_case.py31
-rw-r--r--framework/test_result.py31
-rw-r--r--framework/tester.py148
-rw-r--r--tests/TestSuite_blacklist.py62
-rw-r--r--tests/TestSuite_checksum_offload.py64
-rw-r--r--tests/TestSuite_cmdline.py48
-rw-r--r--tests/TestSuite_fdir.py129
-rw-r--r--tests/TestSuite_hello_world.py49
-rw-r--r--tests/TestSuite_ieee1588.py56
-rw-r--r--tests/TestSuite_ip_pipeline.py192
-rw-r--r--tests/TestSuite_ipfrag.py70
-rw-r--r--tests/TestSuite_jumboframes.py154
-rw-r--r--tests/TestSuite_l2fwd.py70
-rw-r--r--tests/TestSuite_l3fwd.py91
-rw-r--r--tests/TestSuite_link_flowctrl.py61
-rw-r--r--tests/TestSuite_multiprocess.py62
-rw-r--r--tests/TestSuite_pmd.py199
-rw-r--r--tests/TestSuite_pmd_bonded.py1819
-rw-r--r--tests/TestSuite_timer.py50
-rw-r--r--tests/TestSuite_vlan.py64
-rw-r--r--tests/TestSuite_whitelist.py71
54 files changed, 4706 insertions, 1268 deletions
diff --git a/doc/dts_gsg/Makefile b/doc/dts_gsg/Makefile
new file mode 100644
index 0000000..e69cfc7
--- /dev/null
+++ b/doc/dts_gsg/Makefile
@@ -0,0 +1,156 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = build
+SOURCEDIR = ./
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCEDIR)
+
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SOURCEDIR)
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -E -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/DPDKDTFTestFramework.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/DPDKDTFTestFramework.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/DPDKDTFTestFramework"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/DPDKDTFTestFramework"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/doc/dts_gsg/conf.py b/doc/dts_gsg/conf.py
new file mode 100644
index 0000000..9213b01
--- /dev/null
+++ b/doc/dts_gsg/conf.py
@@ -0,0 +1,40 @@
+# BSD LICENSE
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import subprocess
+
+project = 'DPDK Test Suite'
+
+copyright = '2014, dpdk.org'
+
+#version = subprocess.check_output(["make","-sRrC","../../", "showversion"])
+
+master_doc = 'index'
+
diff --git a/doc/dts_gsg/config.rst b/doc/dts_gsg/config.rst
new file mode 100644
index 0000000..7276681
--- /dev/null
+++ b/doc/dts_gsg/config.rst
@@ -0,0 +1,254 @@
+Configuring DPDK Test Suite
+===========================
+
+DPDK Test Suite command line
+----------------------------
+
+DPDK Test Suite supports multiple parameters and these parameters, which will select different of working mode of test framework. In the meantime, DPDK Test Suite can work with none parameter, then every parameter will set to its default value.
+For Example, please see specific usage, you can get these information via DPDK Test Suite help messages.
+
+.. code-block:: console
+
+ usage: main.py [-h] [--config-file CONFIG_FILE] [--git GIT] [--patch PATCH]
+ [--snapshot SNAPSHOT] [--output OUTPUT] [-s] [-r] [-p PROJECT]
+ [--suite-dir SUITE_DIR] [-t TEST_CASES [TEST_CASES ...]]
+ [-d DIR]
+
+DPDK Test Suite supports the following parameters:
+
+.. table::
+
+ +---------------------------+---------------------------------------------------+------------------+
+ | parameter | description | Default Value |
+ +---------------------------+---------------------------------------------------+------------------+
+ | -h,--help | show this help message and exit | |
+ +---------------------------+---------------------------------------------------+------------------+
+ | --config-file CONFIG_FILE | configuration file that describes the test cases, | ../execution.cfg |
+ | | DUTs and targets | |
+ +---------------------------+---------------------------------------------------+------------------+
+ | --git GIT | Indicate git label to use as input | None |
+ +---------------------------+---------------------------------------------------+------------------+
+ | --patch PATCH | apply a patch to the package under test | None |
+ +---------------------------+---------------------------------------------------+------------------+
+ | --snapshot SNAPSHOT | snapshot .tgz file to use as input | ../dpdk.tar.gz |
+ +---------------------------+---------------------------------------------------+------------------+
+ | --output OUTPUT | Output directory where DPDK Test Suite log and | ../output |
+ | | result saved | |
+ +---------------------------+---------------------------------------------------+------------------+
+ | -s --skip-setup | Skips all possible setup steps done on both DUT | |
+ | | and tester boards. | |
+ +---------------------------+---------------------------------------------------+------------------+
+ | -r | Reads the DUT configuration from a cache. If not | |
+ | | specified, the DUT configuration will be | |
+ | | calculated as usual and cached. | |
+ +---------------------------+---------------------------------------------------+------------------+
+ | -p PROJECT | Specify that which project will be tested dpdk | |
+ | --project PROJECT | | |
+ +---------------------------+---------------------------------------------------+------------------+
+ | -t TEST_CASES | Executes only the followings test cases | None |
+ | [TEST_CASES ...] | | |
+ | --test-cases | | |
+ | TEST_CASES | | |
+ | [TEST_CASES ...] | | |
+ +---------------------------+---------------------------------------------------+------------------+
+ | -d DIR --dir DIR | Output directory where dpdk package is extracted | dpdk |
+ +---------------------------+---------------------------------------------------+------------------+
+ | --suite-dir | Test suite directory where test suites will be | ../tests |
+ | | imported | |
+ +---------------------------+---------------------------------------------------+------------------+
+ | -v, --verbose | Enable verbose output, all log shown on screen | |
+ +---------------------------+---------------------------------------------------+------------------+
+
+Please see more information about some critical parameters as the following:
+
+**--config-file**
+
+DPDK Test Suite configure file defines some critical parameters. It must contain the DUT CRB IP address, wish list of test suites, DPDK target information and test mode parameter.
+
+**--git**
+
+When we use –-git parameter, DPDK Test Suite will clone the source code from dpdk.org git repository, then checkout branch specified by the parameter.
+
+**--patch**
+
+DPDK Test Suite also support apply specified patch list by --patch parameter before build DPDK packet.
+**--skip-setup**
+
+If DPDK source code doesn’t changed, you can use --skip-setup to skip unzip and compilation of DPDK source code, just reuse original source code.
+
+**--project**
+
+Parameter –-project can load customized project model and do its own project initialization.
+
+**--output**
+
+If we perform multiple validation at the same time, result files in output folder maybe overwritten. Then we can use –-output parameter to specify the output folder and save execution log and result files. This option will make sure that all test result will be stored in the different excel files and rst files, doesn’t conflict each other.
+
+.. note::
+ The current working folder of DPDK Test Suite is “framework” and default output folder is “../output”
+
+**--t**
+
+You can only run some specified cases in test suites.
+
+We can use parameter –-t to determine those cases.
+
+**--suite-dir**
+
+DPDK Test Suite support load suites from different folders, this will be helpful when there’s several projects existing in the same time.
+
+**--verbose**
+
+DPDK Test Suite support verbose mode. When enable this mode, all log messages will be output on screen and helpful for debug.
+
+DPDK Release Preparation
+------------------------
+
+Firstly, you need to download the latest code from dpdk.org, then archive and compress it in the source code folder. After that, please move this zipped file to DPDK Test Suite folder. Once launch test framework, DPDK Test Suite will copy this zipped file to root folder on DUT. Finally this source code zip file will be unzipped and built.
+
+.. code-block:: console
+
+ [root@tester dcts]# ls
+ [root@tester dcts]# dts dpdk.tar.gz execution.cfg framework output test_plans tests
+
+If enables patch option, DPDK Test Suite will also make patch the unzipped folder and compile it.
+
+.. code-block:: console
+
+ [root@tester dcts]# ./dts --patch 1.patch --patch 2.patch
+
+Create your own execution configuration
+---------------------------------------
+
+First of all, you must create a file named execution.cfg as below.
+
+.. code-block:: console
+
+ [Execution1]
+ crbs=10.239.128.117
+ test_suites=
+ hello_world,
+ l2fwd
+ targets=
+ x86_64-default-linuxapp-gcc,
+ parameters=nic_type=niantic:func=true
+
+* crbs: IP address of the DUT CRB. The detail information of this CRB is defined in file crbs.py.
+* test_suites: defines list of test suites, which will plan to be executed.
+* gets: list of DPDK targets to be tested.
+* parameters: you can define multiple keywords
+
+ – nic_type : is the type of the NIC to use. The types are defined in the file settings.py.
+
+ – func=true run only functional test
+
+ – perf=true run only performance test
+
+Then please add the detail information about your CRB in **crbs.py** as follows:
+
+.. code-block:: console
+
+ crbs = [
+ {'IP': '10.239.128.117',
+ 'name': 'CrownPassCRB1',
+ 'user': 'root',
+ 'pass': 'tester',
+ 'tester IP': '10.239.128.116',
+ IXIA: None,
+ 'memory channels': 4,
+ 'bypass core0': True},
+ ]
+
+.. table::
+
+ +-----------------+----------------------------------------------------+
+ | Item | description |
+ +-----------------+----------------------------------------------------+
+ | IP | IP address of DUT |
+ +-----------------+----------------------------------------------------+
+ | name | Name of DUT |
+ +-----------------+----------------------------------------------------+
+ | user | UserName of DPDK Test Suite used to login into DUT |
+ +-----------------+----------------------------------------------------+
+ | pass | Password of DPDK Test Suite used to login into DUT |
+ +-----------------+----------------------------------------------------+
+ | Tester IP | IP address of tester |
+ +-----------------+----------------------------------------------------+
+ | memory channels | number of memory channels for DPDK EAL |
+ +-----------------+----------------------------------------------------+
+ | bypass core0 | skip the first core when initialize DPDK |
+ +-----------------+----------------------------------------------------+
+
+Launch DPDK Test Suite
+----------------------
+
+After we have prepared the zipped dpdk file and configuration file, just type the followed command “./dts”, it will start the validation process.
+
+DPDK Test Suite will create communication sessions first.
+
+.. code-block:: console
+
+ DUT 10.239.128.117
+ DTS_DUT_CMD: ssh root@10.239.128.117
+ DTS_DUT_CMD: ssh root@10.239.128.117
+ DTS_TESTER_CMD: ssh root@10.239.128.116
+ DCS_TESTER_CMD: ssh root@10.239.128.116
+
+
+Then copy snapshot zipped dpdk source code to DUT.
+.. code-block:: console
+
+ DTS_DUT_CMD: scp ../dpdk.tar.gz root@10.239.128.117:
+
+Collect CPU core and network device information of DUT and tester.
+
+Automatically detect the network topology of DUT and tester.
+
+.. code-block:: console
+
+ DTS_TESTER_RESULT: DUT PORT MAP: [4, 5, 6, 7]
+
+Build dpdk source code and then setup the running environment.
+
+.. code-block:: console
+
+ DTS_DUT_CMD: make -j install T=x86_64-native-linuxapp-gcc
+ DTS_DUT_CMD: awk '/Hugepagesize/ {print $2}' /proc/meminfo
+ DTS_DUT_CMD: awk '/HugePages_Total/ { print $2 }' /proc/meminfo
+ DTS_DUT_CMD: umount `awk '/hugetlbfs/ { print $2 }' /proc/mounts`
+ DTS_DUT_CMD: mkdir -p /mnt/huge
+ DTS_DUT_CMD: mount -t hugetlbfs nodev /mnt/huge
+ DTS_DUT_CMD: modprobe uio
+ DTS_DUT_CMD: rmmod -f igb_uio
+ DTS_DUT_CMD: insmod ./x86_64-native-linuxapp-gcc/kmod/igb_uio.ko
+ DTS_DUT_CMD: lsmod | grep igb_uio
+ DTS_DUT_CMD: tools/dpdk_nic_bind.py --bind=igb_uio 08:00.0 08:00.1 0a:00.0 0a:00.1
+
+Begin the validation process of test suite.
+
+.. code-block:: console
+
+ TEST SUITE : TestCmdline
+ INFO: NIC : niantic
+ SUITE_DUT_CMD: make -j -C examples/cmdline
+ SUITE_DUT_CMD: ./examples/cmdline/build/app/cmdline -n 1 -c 0x2
+ INFO: Test Case test_cmdline_sample_commands Begin
+
+
+Clean-up DUT and tester after all validation finished.
+
+.. code-block:: console
+
+ DTS_DUT_CMD: rmmod igb_uio
+ DTS_DUT_CMD: modprobe igb
+ DTS_DUT_CMD: modprobe ixgbe
+ DTS_DUT_CMD: modprobe e1000e
+ DTS_DUT_CMD: modprobe e1000
+ DTS_DUT_CMD: modprobe virtio_net
+ DTS_TESTER_CMD: rmmod igb_uio
+ DTS_TESTER_CMD: modprobe igb
+ DTS_TESTER_CMD: modprobe ixgbe
+ DTS_TESTER_CMD: modprobe e1000e
+ DTS_TESTER_CMD: modprobe e1000
+ DTS_TESTER_CMD: modprobe virtio_net
+
diff --git a/doc/dts_gsg/image/dts_network_arch.png b/doc/dts_gsg/image/dts_network_arch.png
new file mode 100644
index 0000000..6861cea
--- /dev/null
+++ b/doc/dts_gsg/image/dts_network_arch.png
Binary files differ
diff --git a/doc/dts_gsg/image/dts_result.png b/doc/dts_gsg/image/dts_result.png
new file mode 100644
index 0000000..f39f5f8
--- /dev/null
+++ b/doc/dts_gsg/image/dts_result.png
Binary files differ
diff --git a/doc/dts_gsg/image/dts_soft_arch.png b/doc/dts_gsg/image/dts_soft_arch.png
new file mode 100644
index 0000000..c489c5d
--- /dev/null
+++ b/doc/dts_gsg/image/dts_soft_arch.png
Binary files differ
diff --git a/doc/dts_gsg/index.rst b/doc/dts_gsg/index.rst
new file mode 100644
index 0000000..e13cec3
--- /dev/null
+++ b/doc/dts_gsg/index.rst
@@ -0,0 +1,42 @@
+.. BSD LICENSE
+ Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Getting Started Guide
+=====================
+
+.. toctree::
+ :maxdepth: 2
+ :numbered:
+
+ intro
+ sys_reqs
+ config
+ review
+
diff --git a/doc/dts_gsg/intro.rst b/doc/dts_gsg/intro.rst
new file mode 100644
index 0000000..cacdd8b
--- /dev/null
+++ b/doc/dts_gsg/intro.rst
@@ -0,0 +1,124 @@
+Introduction
+============
+
+This document describes how to install and configure the Data Plane Development Kit Test Suite (DPDK Test Suite) in a Linux environment. Users can refer this document to enable this test infrastructure in their environment and don’t need go deeply with too much details about this framework.
+DPDK Test Suite is an automation test tool for DPDK software, a python-base library. It can run on remote tester machine, and communicate/manage DUT by SSH connection. DTF supports different kind of traffic generators, including DPDK-based PacketGen, third-party professional tester equipment (IXIA®).
+Data Plane Development Kit Test Suite (DPDK Test Suite) includes one set of test cases and DPDK generic test framework . DPDK Test Suite provides test example, references and framework for open source community. Based on DPDK Test Suite, everyone can develop their test plan, automation script and configuration for own features and platform. In addition, DPDK Test Suite provides a solution to allow that DPDK developers contribute their function test to certify their patch integration. It only requires limitation effort to maintain test cases once merged into DPDK Test Suite. Everyone can utilize DPDK Test Suite to measure performance and functionality for features.
+
+Please see DPDK Test Suite architecture in the following figures:
+
+.. figure:: image/dts_soft_arch.png
+
+As generic test framework, DPDK Test Suite provides the following functions:
+
+* Able to work with DUT (Device Under Test), which installed Fedora, Ubuntu, WindRiver, FreeBSD, RedHat and SUSE
+* Support both software and hardware traffic generators, including Scapy, DPDK-based PacketGen and IXIA traffic generator, even third party packet generator via TCL or Python library.
+* Provide configure files to customize test suite and test cases to run under DUT.
+* Support to output test result by excel, log text file, etc.
+* In addition, Test Framework will manage communication with DUT by SSH, provides library to manage SSH connections.
+* DPDK Test Suite provides one set of basic library to manage tester, DUT, test case, exception, generate report, and configure test plan by user configure files. It’s easy to develop user-defined test suite and test plan by self, and these test cases are able to integrate into DPDK Test Suite.
+* With this test framework, user can automatically identify network topology, and easy to configure/deploy environment for DUT and tester, and provides flexibility to scale test capability by configuration.
+
+DPDK Test Suite environment includes DUT (Device under Test), Tester and packet generator. DPDK software will deployed and run on DUT. DPDK Test Suite test Framework and test code will be stored into tester.
+
+Please see architecture in the following figures:
+
+
+.. figure:: image/dts_network_arch.png
+
+This architecture provides automatically mechanism to manage tester, DUT and packet generators, and remove dependency between test script and test environment/hardware. It defines one abstraction layer for DPDK Test Suite, and provides extensibility to add more test script.
+In the DPDK Test Suite Test Framework, it provides the following modules to help to manage device, platform, configure and test results.
+
+.. table::
+
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | File Name | Description |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | dts.py | Main Application for DPDK Test Suite |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | main.py | Test script to parse input parameter |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | dut.py | Setup device under test including tool chain, IP address |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | tester.py | Provide API to setup tester environment including IP, port, etc. |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | Exception.py | Manage User-defined exceptions used across the framework. |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | Test_cases.py | Provides a base class for creating DPDK Test Suite test cases. |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | logger.py | Deal with different log files to record event or message |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | serializer.py | Provide wrapper class to manage temporary variables during execution |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | settings.py | Setting for default network card and its identifiers supported by the framework |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | ssh_connection.py | Create session to host, implement send_expect and copy function |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | ssh_pexpect.py | Handle ssh sessions between tester and DUT, Implement send_expect function to send command and get output data, Aslo support transfer files to tester or DUT |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | pmd_output.py | Module for get all statics value by port in testpmd |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | rst.py | Generate Rst Test Result Report |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | stats_reporter.py | Simple text file statistics generator |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | test_result.py | Generic result container. Useful to store/retrieve results during a DTF execution |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | excel_reporter.py | Excel spreadsheet generator |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | plotgraph.py | Generate graphs for each test suite |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | plotting.py | Generate Plots for performance test results |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | etgen.py | Software packet generator |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | ixia_buffer_parser.py | Helper class that parses a list of files containing IXIA captured frames extracting a sequential number on them |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | ixiacfg.py | IXIA Configuration file |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | ixiaDCB.tcl | Third party Library which provided by IXIA, used to configure IXIA tester |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | ixiaPing6.tcl | Third party Library which provided by IXIA, used to ping IXIA tester |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | IxiaWish.tcl | Third party Library which provided by IXIA, set up TCL environment to use correct multiversion-compatible applications |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | texttable.py | Third party Library , create simple ASCII tables |
+ +-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+Beside Framework tool, DPDK Test Suite also defines one set of test cases. It includes basic test suite to verify basic functionality of DPDK library. These test script provides example and reference. Everyone can develop their test cases, verify their features functionality, and commit generic test report to maintainer. However, user-defined test cases, plan and script must follow DPDK Test Suite standard including code standard, naming conventions, configure format, rst test plan, API.
+
+Please see test cases, which included in the DPDK compliance test suites:
+
+.. table::
+
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | Test Suite | Descriptions |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | Command line | Define a demo example of command line interface in RTE |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | hello_world | Print a ``helloworld`` message on every enabled logic core. |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | Multi process | Demonstrates the basics of sharing information between DPDK processes. |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | Timer | Shows how timer can be used in a RTE application. |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | Blacklist/WhiteList | Tests Whitelist/Blacklist Features by Poll Mode Drivers. |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | checksum_offload | Tests RX/TX L3/L4 Checksum offload features by Poll Mode Drivers |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | jumbo_frame | Tests jumbo frames features by Poll Mode Drivers |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | testpmd | Provides benchmark tests for the Intel Ethernet Controller (Niantic) Poll Mode Driver. |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | l2fwd | Provides a basic packet processing application using DPDK. It is a layer-2 (L2) forwarding application which takes traffic from a single RX port and transmits it with few modification on a single TX port. |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | L3fwd | Verifies Layer-3 Forwarding results using ``l3fwd`` application. |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | IP fragment | Verifies IPv4 fragmentation using ``ipv4_frag`` application. |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | Flow direction | Verifies the Flow Director feature of the Intel 82599 10GbE Ethernet Controller |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | link_flowctrl | Verifies Ethernet Link Flow Control Features by Poll Mode Drivers |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+ | ieee1588 | Tests the IEEE1588 Precise Time Protocol offload supported in Poll Mode Drivers. |
+ +---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
diff --git a/doc/dts_gsg/review.rst b/doc/dts_gsg/review.rst
new file mode 100644
index 0000000..b808b30
--- /dev/null
+++ b/doc/dts_gsg/review.rst
@@ -0,0 +1,104 @@
+Review Test Result
+==================
+
+Browse the result files
+-----------------------
+After DPDK Test Suite finished the validation, we can find the result files as below in output folder. The files in output folder maybe different when change the CRB or choose different suites.
+
+For Example, You can find the following in output folder after execution.
+
+.. code-block:: console
+
+ [root@tester output]# ls
+ CrownPassCRB1 dts.log statistics.txt TestHelloWorld.log test_results.xls
+
+Please see details about these files:
+
+* CrownPassCRB1: contains the result RST file and graph of performance data
+* dts.log: Full execution log of DPDK Test Suite framework
+* statstics.txt: summary statistics of DPDK Test Suite executed suites
+* TestHelloWorld.log: log message of TestHelloWorld case
+* test_result.xls: excel format result file
+
+Check test result of DPDK Test Suite
+------------------------------------
+
+You can go through the summary of execution result via statistic.txt. This file includes the number of passed test cases, the number of failed case, the number of blocked and pass ratio.
+
+Please see example as the following. You can cat the sample file, then show this information of execution, totally executed two test cases, all cases passed the criterion and no failed or blocked cases.
+
+.. code-block:: console
+
+ [root@tester output]# cat statistics.txt
+ Passed = 2
+ Failed = 0
+ Blocked = 0
+ Pass rate = 100.0
+
+If you need more detail information of test result, please open excel formatted file test_result.xls. This file contains of both detailed case information and case results. Also you can find description of the failure reason if DPDK Test Suite can track it.
+
+.. figure:: image/dts_result.png
+
+If you want to track more details about the process of each suite, please go to log file which named by this suite, all related information will stored in this file.
+
+DPDK Test Suite log module provides several levels to track event or output in log file. Every message level will have its own scopes. Separated log messages will help us get to known what happening in DPDK Test Suite and what happening in DUT and tester.
+
+
+.. table::
+
+ +---------------------+---------------------------------------------------------------------------------------------+
+ | Level | description |
+ +---------------------+---------------------------------------------------------------------------------------------+
+ | INFO | DPDK Test Suite system level log, show start and stop process in this suite |
+ +---------------------+---------------------------------------------------------------------------------------------+
+ | SUITE_DUT_CMD | Commands send to DUT CRB |
+ +---------------------+---------------------------------------------------------------------------------------------+
+ | SUITE_DUT_OUTPUT | Output after the send the commands to DUT |
+ +---------------------+---------------------------------------------------------------------------------------------+
+ | SUITE_TESTER_CMD | Commands send to tester, most of they are Scapy commands which will send packet to DUT port |
+ +---------------------+---------------------------------------------------------------------------------------------+
+ | SUITE_TESTER_OUTPUT | Output after the send the commands to tester |
+ +---------------------+---------------------------------------------------------------------------------------------+
+
+
+Please see example for TestHelloWorld suite log as the following. This log file showed that application helloworld sent hello message from core1, and finally matched the pass criterion.
+
+.. code-block:: console
+
+ 22/08/2014 11:04:45 INFO:
+ TEST SUITE : TestHelloWorld
+ 22/08/2014 11:04:45 INFO: NIC : niantic
+ 22/08/2014 11:04:45 SUITE_DUT_CMD: make -j -C examples/helloworld
+ 22/08/2014 11:04:45 SUITE_DUT_OUTPUT: make: Entering directory `/root/dpdk/examples/helloworld'^M
+ CC main.o^M
+ LD helloworld^M
+ INSTALL-MAP helloworld.map^M
+ INSTALL-APP helloworld^M
+ make: Leaving directory `/root/dpdk/examples/helloworld'
+ 22/08/2014 11:04:45 INFO: Test Case test_hello_world_single_core Begin
+ 22/08/2014 11:04:45 SUITE_DUT_CMD: ./examples/helloworld/build/app/helloworld -n 1 -c 0x1fffffffff
+ 22/08/2014 11:04:48 SUITE_DUT_OUTPUT: EAL: Detected lcore 0 as core 0 on socket 0^M
+ …
+ hello from core 1
+ 22/08/2014 11:05:08 INFO: Test Case test_hello_world_single_core Result PASSED:
+ 22/08/2014 11:05:09 SUITE_DUT_CMD: uname
+ 22/08/2014 11:05:09 SUITE_DUT_OUTPUT:
+ 22/08/2014 11:05:09 SUITE_TESTER_CMD: killall scapy 2>/dev/null; echo tester
+ 22/08/2014 11:05:09 SUITE_TESTER_OUTPUT: tester
+ 22/08/2014 11:05:10 SUITE_TESTER_CMD: uname
+ 22/08/2014 11:05:10 SUITE_TESTER_OUTPUT:
+ 22/08/2014 11:05:10 INFO:
+ TEST SUITE ENDED: TestHelloWorld
+
+Generate PDF doc from RST
+-------------------------
+
+Since DPDK Test Suite stores test result as RST by default, you may be want to transfer it to PDF formatted which make it more readable. Firstly, please enter the folder which contained the RST results, then use python tool ``rst2pdf`` to convert RST. If there’s no error return, you can find the pdf file generated with same name.
+
+.. code-block:: console
+
+ [root@tester dcts]# cd output/CrownPassCRB1/x86_64-native-linuxapp-gcc/Niantic
+ [root@tester niantic]# rst2pdf TestResult_hello_world.rst
+ [root@tester niantic]# ls
+ TestResult_hello_world.pdf TestResult_hello_world.rst
+
diff --git a/doc/dts_gsg/sys_reqs.rst b/doc/dts_gsg/sys_reqs.rst
new file mode 100644
index 0000000..fad5617
--- /dev/null
+++ b/doc/dts_gsg/sys_reqs.rst
@@ -0,0 +1,186 @@
+System Requirements
+===================
+
+The board assigned to be tester should be installed the latest Fedora distribution for easily installed DPDK Test Suite required python modules. Tester board needs plug at least 2 x Intel® 82599 (Niantic) NICs (2x 10GbE full duplex optical ports per NIC) in the PCI express slots, then connect these four Niantic ports to the DUT board and make sure the link has been started up and speed is 10000Mb/s.
+
+Beside the four Niantic ports, tester and DUT should also have one interface connected to the same intranet. So that they can be accessed by each other from local IP address.
+
+.. note::
+
+ Firewall should be disabled that all packets can be accepted by Niantic Interface.
+
+.. code-block:: console
+
+ systemctl disable firewalld.service
+
+Setup Tester Environment
+------------------------
+
+.. note::
+
+ Please install the latest Fedora distribution on the tester before install DPDK Test Suite on tester. Currently we recommend Fedora 20 for tester. The setup instruction and required packages may be different on different operation systems.
+
+To enable tester environment, you need to install script language, tool chain and third party packet generator, etc.
+
+Please follow the guidance to finish install as the below section.
+
+SSH Service
+~~~~~~~~~~~
+Since DPDK Test Suite Tester communicates with DUT via SSH, please install and start sshd service in your tester.
+
+.. code-block:: console
+
+ yum install sshd # download / install ssh software
+ systemctl enable sshd.service # start ssh service
+
+For create authorized login session, user needs to generate RSA authentication keys to ssh connection.
+
+Please use the following commands:
+
+.. code-block:: console
+
+ ssh-keygen -t rsa
+
+TCL Language Support modules
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Since some third party tools required TCL (Tool Command Language) supports, please install TCL package to control and connect third party package generator. (For example, third-party professional tester IXIA required TCL support)
+
+.. code-block:: console
+
+ yum install tcl # download / install ssh software
+
+Install Third Party python modules
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+With third party module, DPDK Test Suite is able to export test result as MS Excel file or graphs. To support this feature, please install the following modules in the tester.
+Python Module “xlwt”: this module is used to generate spreadsheet files which compatible with MS Excel 97/2000/XP/2003 XLS files.
+Python Module “numpy”: this module provides method to deal with array-processing test results.
+Python Module “matplotlib”: this module is used to produce quality 2D test result summary as graphics
+Python Module “pexpect”: this module provides API to automate interactive SSH sessions.
+Python Module “docutils”: Docutils is a modular system for processing documentation into useful formats, such as HTML, XML, and LaTeX.
+Python Module “pcapy”: Pcapy is a Python extension module that interfaces with the libpcap packet capture library. Pcapy enables python scripts to capture packets on the network.
+
+Please see installation instruction as the following:
+
+
+.. code-block:: console
+
+ yum install python-xlwt
+ yum install python-pexpect
+ yum install numpy
+ yum install python-matplotlib
+ yum install python-docutils
+ yum install pcapy
+
+
+Setup and configure Scapy
+~~~~~~~~~~~~~~~~~~~~~~~~~
+Scapy is a powerful interactive packet manipulation program. It is able to forge or decode packets of a wide number of protocols, send them on the wire, capture them, match requests and replies, and much more. It can easily handle most classical tasks like scanning, tracerouting, probing, unit tests, attacks or network discovery.
+
+DTCS uses python module scapy to forge or decode packets of a wide number of protocols, send them over the wire, capture them, and analyse the packets.
+
+.. code-block:: console
+
+ yum install scapy
+
+Fedora20 default kernel will strip vlan header automatically and thus it will cause that scapy can’t detect vlan packet normally. To solve this issue, we need to configure scapy use libpcap which is a low-level network traffic monitoring tool.
+
+.. code-block:: console
+
+ vim /usr/lib/python2.7/site-packages/scapy/config.py # open configure python files
+ use_pcap = True # find use_pcap and set it to True
+
+Install DPDK Test Suite on tester
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After configure environment, we need to install DPDK Test Suite into tester. First of all, download the latest DPDK Test Suite code from remote repo.
+
+.. code-block:: console
+
+ [root@tester ~]# git clone http://dpdk.org/git/tools/dcts
+ [root@tester ~]# cd dcts
+ [root@tester dcts]# ls
+ [root@tester dcts]# dts execution.cfg framework output test_plans tests
+
+High Precision Timer (HPET) must be enabled in the platform BIOS if the HPET is to be used. Otherwise, the Time Stamp Counter (TSC) is used by default. The user can then navigate to the HPET option. On the Crystal Forest platform BIOS, the path is:
+**Advanced -> PCH-IO Configuration -> High Precision Timer**
+
+The DPDK Test Suite is composed of several file and directories:
+
+* dts: Main module of DPDK Test Suite suite
+* exectution.cfg: configuration file of DPDK Test Suite suite
+* framework: folder with dts framework modules
+* output: folder which contain running log files and result files
+* test_plans: folder with rst files which contain the description of test case
+* tests: folder with test case scripts
+
+Setup Target Environment
+------------------------
+
+This section describes how to deploy DPDK Test Suite packages into DUT target.So far, DPDK Test Suite supports the following OS on DUT:
+
+* Fedora18/19/20
+* Ubuntu12.04/14.04
+* WindRiver 6.0
+* FreeBSD 10
+* RedHat 6.5/7.0
+* SUSE 11
+
+Before run DPDK Test Suite on target, we need to configure target environment, it includes BIOS setting, Network configure, compiler environment, etc.
+
+BIOS setting Prerequisite
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In general, enter BIOS Menu by pressing F2 while the platform is starting up.
+
+.. note::
+ strongly recommend to install DPDK on Intel latest platform and processor.
+
+The High Precision Timer (HPET) must be enabled in the platform BIOS if the HPET is to be used. Otherwise, the Time Stamp Counter (TSC) is used by default. The user can then navigate to the HPET option. On the Crystal Forest platform BIOS, the path is:
+
+**Advanced -> PCH-IO Configuration -> High Precision Timer**
+
+Enhanced Intel SpeedStep® Technology must be disabled in the platform BIOS. Thus we will disable dynamically adjust processor voltage and core frequency which may cause unstable performance data. On the Crystal Forest platform BIOS, the path is:
+
+**Advanced -> Processor Configuration -> Enhanced Intel SpeedStep**
+
+Processor sate C3 and C6 must be disabled for performance measure too. On the Crystal Forest platform BIOS, the path is:
+
+**Advanced -> Processor Configuration -> Processor C3
+Advanced -> Processor Configuration -> Processor C6**
+
+Hyper-Threading Technology must be enabled. On the Crystal Forest platform BIOS, the path is:
+
+**Advanced -> Processor Configuration -> Intel® Hyper-Threading Tech**
+
+If the platform BIOS has any particular performance option, select the settings for best performance.
+
+DPDK running Prerequisite
+~~~~~~~~~~~~~~~~~~~~~~~~~
+Compilation of DPDK need GNU maker, gcc, libc-header, kernel header installed. For 32-bit compilation on 64-bit systems, there’re some additional packages required. For Intel® C++ Compiler (icc) additional libraries may be required. For more detail information of required packets, please refer to Data Plane Development Kit Getting Started Guide.
+
+The DPDK igb_uio kernel module depends on traditional Linux kernel uio support to operate. Linux traditional uio support may be compiled as a module, so this module should be loaded using the modprobe program.
+Kernel must support the allocation of hugepages. Hugepage support is required for the large memory pool allocation used for packet buffers. By using hugepage allocations, performance will be improved since only fewer pages are needed, and therefore less Translation Lookaside Buffers (TLBs, high speed translation caches), which reduce the time it takes to translate a virtual page address to a physical page address. Without hugepages, high TLB miss rates would occur, slowing performance.
+
+The DPDK igb_uio kernel module depends on traditional Linux kernel ``uio`` support to operate. Linux traditional ``uio`` support may be compiled as a module, so this module should be loaded using the ``modprobe`` program.
+Kernel must support the allocation of hugepages. Hugepage support is required for the large memory pool allocation used for packet buffers. By using hugepage allocations, performance will be improved since only fewer pages are needed, and therefore less Translation Lookaside Buffers (TLBs, high speed translation caches), which reduce the time it takes to translate a virtual page address to a physical page address. Without hugepages, high TLB miss rates would occur, slowing performance.
+
+For more detail information of system requirements, also refer to `Data Plane Development Kit Getting Started Guide <http://dpdk.org/doc/intel/dpdk-start-linux-1.7.0.pdf>`_.
+
+Authorized login session
+------------------------
+In DPDK Test Suite, communication was established based on authorized ssh session. All ssh connection to each other will skip password interactive phase for remote server has been authorized.
+
+In tester, you can use tool ssh-copy-id to save local available keys on DUT, thus create authorise login session between tester and DUT. By the same way, you can create authorise login session between tester and itself.
+
+.. code-block:: console
+
+ ssh-copy-id -i “IP of DUT”
+ ssh-copy-id -i “IP of tester”
+
+In DUT, You also can use tool ssh-copy-id to save local available keys in tester, thus create authorise login session between DUT and tester.
+
+.. code-block:: console
+
+ ssh-copy-id –i “IP of Tester”
+
diff --git a/dcts b/dts
index f408e5b..f408e5b 100755
--- a/dcts
+++ b/dts
diff --git a/framework/crb.py b/framework/crb.py
index 75d0751..4c93661 100644
--- a/framework/crb.py
+++ b/framework/crb.py
@@ -1,14 +1,53 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import time
-import dcts
+import dts
import re
import os
from settings import TIMEOUT, IXIA
+"""
+CRB (customer reference board) basic functions and handlers
+"""
+
class Crb(object):
+ """
+ Basic module for customer reference board. This module implement functions
+ interact with CRB. With these function, we can get the information of
+ CPU/PCI/NIC on the board and setup running environment for DPDK.
+ """
+
def __init__(self, crb, serializer):
self.crb = crb
self.read_cache = False
@@ -17,6 +56,11 @@ class Crb(object):
self.ports_info = None
def send_expect(self, cmds, expected, timeout=TIMEOUT, alt_session=False):
+ """
+ Send commands to crb and return string before expected string. If
+ there's no expected string found before timeout, TimeoutException will
+ be raised.
+ """
if alt_session:
return self.alt_session.session.send_expect(cmds, expected, timeout)
@@ -24,64 +68,78 @@ class Crb(object):
return self.session.send_expect(cmds, expected, timeout)
def set_test_types(self, func_tests, perf_tests):
+ """
+ Enable or disable function/performance test.
+ """
self.want_func_tests = func_tests
self.want_perf_tests = perf_tests
- def has_external_traffic_generator(self):
- try:
- if self.crb[IXIA] is not None:
- return True
- except Exception as e:
- return False
-
- return False
-
- def get_external_traffic_generator(self):
- return self.crb[IXIA]
-
def get_total_huge_pages(self):
+ """
+ Get the huge page number of CRB.
+ """
huge_pages = self.send_expect("awk '/HugePages_Total/ { print $2 }' /proc/meminfo", "# ")
if huge_pages != "":
return int(huge_pages)
return 0
def mount_huge_pages(self):
+ """
+ Mount hugepage file system on CRB.
+ """
self.send_expect("umount `awk '/hugetlbfs/ { print $2 }' /proc/mounts`", '# ')
self.send_expect('mkdir -p /mnt/huge', '# ')
self.send_expect('mount -t hugetlbfs nodev /mnt/huge', '# ')
def set_huge_pages(self, huge_pages):
+ """
+ Set numbers of huge pages
+ """
self.send_expect('echo %d > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages' % huge_pages, '# ', 5)
def set_speedup_options(self, read_cache, skip_setup):
+ """
+ Configure skip network topology scan or skip DPDK packet setup.
+ """
self.read_cache = read_cache
self.skip_setup = skip_setup
def set_directory(self, base_dir):
+ """
+ Set DPDK package folder name.
+ """
self.base_dir = base_dir
def admin_ports(self, port, status):
+ """
+ Force set port's interface status.
+ """
admin_ports_freebsd = getattr(self, 'admin_ports_freebsd_%s' % self.get_os_type())
return admin_ports_freebsd()
def admin_ports_freebsd(self, port, status):
"""
- force set remote interface link status in FreeBSD
+ Force set remote interface link status in FreeBSD.
"""
eth = self.ports_info[port]['intf']
self.send_expect("ifconfig %s %s" % (eth, status), "# ")
def admin_ports_linux(self, eth, status):
"""
- force set remote interface link status in Linux
+ Force set remote interface link status in Linux.
"""
self.send_expect("ip link set %s %s" % (eth, status), "# ")
def restore_interfaces(self):
"""
- Restore Linux interfaces
+ Restore Linux interfaces.
"""
- self.send_expect("rmmod igb_uio", "# ", 10)
+ if dts.drivername == "vfio-pci":
+ self.send_expect("rmmod vfio_iommu_type1", "# ", 10)
+ self.send_expect("rmmod vfio_pci", "# ", 10)
+ self.send_expect("rmmod vfio", "# ", 10)
+ else:
+ self.send_expect("rmmod igb_uio", "# ", 10)
self.send_expect("modprobe igb", "# ", 20)
self.send_expect("modprobe ixgbe", "# ", 20)
self.send_expect("modprobe e1000e", "# ", 20)
@@ -102,10 +160,18 @@ class Crb(object):
self.send_expect("echo 0000%s > /sys/bus/pci/drivers/virtio-pci/bind" % pci_bus, "# ")
else:
continue
+
+ addr_array = pci_bus.split(':')
+ itf = self.get_interface_name(addr_array[0], addr_array[1])
+ self.send_expect("ifconfig %s up" % itf, "# ")
+
except Exception as e:
self.logger.error(" !!! Restore ITF: " + e.message)
def pci_devices_information(self):
+ """
+ Scan CRB pci device information and save it into cache file.
+ """
if self.read_cache:
self.pci_devices_info = self.serializer.load(self.PCI_DEV_CACHE_KEY)
@@ -114,12 +180,15 @@ class Crb(object):
self.serializer.save(self.PCI_DEV_CACHE_KEY, self.pci_devices_info)
def pci_devices_information_uncached(self):
+ """
+ Scan CRB NIC's information on different OS.
+ """
pci_devices_information_uncached = getattr(self, 'pci_devices_information_uncached_%s' % self.get_os_type())
return pci_devices_information_uncached()
def pci_devices_information_uncached_linux(self):
"""
- Look for the NIC's information (PCI Id and card type)
+ Look for the NIC's information (PCI Id and card type).
"""
out = self.send_expect("lspci -nn | grep -i eth", "# ")
rexp = r"([\da-f]{2}:[\da-f]{2}.\d{1}) Ethernet .* Intel Corporation .*?([\da-f]{4}:[\da-f]{4})"
@@ -131,7 +200,7 @@ class Crb(object):
def pci_devices_information_uncached_freebsd(self):
"""
- Look for the NIC's information (PCI Id and card type)
+ Look for the NIC's information (PCI Id and card type).
"""
out = self.send_expect("pciconf -l", "# ")
rexp = r"pci0:([\da-f]{1,3}:[\da-f]{1,2}:\d{1}):\s*class=0x020000.*chip=0x([\da-f]{4})8086"
@@ -144,14 +213,23 @@ class Crb(object):
self.pci_devices_info.append((match[i][0], card_type))
def get_interface_name(self, bus_id, devfun_id=''):
+ """
+ Get interface name of specified pci device.
+ """
get_interface_name = getattr(self, 'get_interface_name_%s' % self.get_os_type())
return get_interface_name(bus_id, devfun_id)
def get_interface_name_linux(self, bus_id, devfun_id):
+ """
+ Get interface name of specified pci device on linux.
+ """
command = 'ls /sys/bus/pci/devices/0000:%s:%s/net' % (bus_id, devfun_id)
return self.send_expect(command, '# ')
def get_interface_name_freebsd(self, bus_id, devfun_id):
+ """
+ Get interface name of specified pci device on Freebsd.
+ """
out = self.send_expect("pciconf -l", "# ")
rexp = r"(\w*)@pci0:%s" % bus_id
pattern = re.compile(rexp)
@@ -159,15 +237,24 @@ class Crb(object):
return match[0]
def get_mac_addr(self, intf, bus_id='', devfun_id=''):
+ """
+ Get mac address of specified pci device.
+ """
get_mac_addr = getattr(self, 'get_mac_addr_%s' % self.get_os_type())
return get_mac_addr(intf, bus_id, devfun_id)
def get_mac_addr_linux(self, intf, bus_id, devfun_id):
+ """
+ Get mac address of specified pci device on linux.
+ """
command = ('cat /sys/bus/pci/devices/0000:%s:%s/net/%s/address' %
(bus_id, devfun_id, intf))
return self.send_expect(command, '# ')
def get_mac_addr_freebsd(self, intf, bus_id, devfun_id):
+ """
+ Get mac address of specified pci device on Freebsd.
+ """
out = self.send_expect('ifconfig %s' % intf, '# ')
rexp = r"ether ([\da-f:]*)"
pattern = re.compile(rexp)
@@ -175,15 +262,24 @@ class Crb(object):
return match[0]
def get_ipv6_addr(self, intf):
+ """
+ Get ipv6 address of specified pci device.
+ """
get_ipv6_addr = getattr(self, 'get_ipv6_addr_%s' % self.get_os_type())
return get_ipv6_addr(intf)
def get_ipv6_addr_linux(self, intf):
+ """
+ Get ipv6 address of specified pci device on linux.
+ """
out = self.send_expect("ip -family inet6 address show dev %s | awk '/inet6/ { print $2 }'"
% intf, "# ")
return out.split('/')[0]
def get_ipv6_addr_freebsd(self, intf):
+ """
+ Get ipv6 address of specified pci device on Freebsd.
+ """
out = self.send_expect('ifconfig %s' % intf, '# ')
rexp = r"inet6 ([\da-f:]*)%"
pattern = re.compile(rexp)
@@ -194,11 +290,17 @@ class Crb(object):
return match[0]
def create_file(self, contents, fileName):
+ """
+ Create file with contents and copy it to CRB.
+ """
with open(fileName, "w") as f:
f.write(contents)
self.session.copy_file_to(fileName)
def kill_all(self):
+ """
+ Kill all dpdk applications on CRB.
+ """
cmd = "for i in `lsof /var/run/.rte_config /var/run/dpdk_config \
| awk '/config/ {print $2}'` ; do kill -9 $i; done"
self.alt_session.session.send_expect(cmd, "# ", 10)
@@ -206,10 +308,16 @@ class Crb(object):
self.check_os_type()
def close(self):
+ """
+ Close ssh session of CRB.
+ """
self.session.close()
self.alt_session.close()
def get_os_type(self):
+ """
+ Get OS type from execution configuration file.
+ """
from dut import Dut
if isinstance(self, Dut) and 'OS' in self.crb:
return str(self.crb['OS']).lower()
@@ -217,6 +325,9 @@ class Crb(object):
return 'linux'
def check_os_type(self):
+ """
+ Check real OS type whether match configured type.
+ """
from dut import Dut
expected = 'Linux.*#'
if isinstance(self, Dut) and self.get_os_type() == 'freebsd':
@@ -225,6 +336,9 @@ class Crb(object):
self.send_expect('uname', expected, 2)
def init_core_list(self):
+ """
+ Load or create core information of CRB.
+ """
if self.read_cache:
self.number_of_cores = self.serializer.load(self.NUMBER_CORES_CACHE_KEY)
self.cores = self.serializer.load(self.CORE_LIST_CACHE_KEY)
@@ -235,10 +349,16 @@ class Crb(object):
self.serializer.save(self.CORE_LIST_CACHE_KEY, self.cores)
def init_core_list_uncached(self):
+ """
+ Scan cores on CRB and create core information list.
+ """
init_core_list_uncached = getattr(self, 'init_core_list_uncached_%s' % self.get_os_type())
init_core_list_uncached()
def init_core_list_uncached_freebsd(self):
+ """
+ Scan cores in Freebsd and create core information list.
+ """
self.cores = []
import xml.etree.ElementTree as ET
@@ -247,9 +367,7 @@ class Crb(object):
cpu_xml = ET.fromstring(out)
- #
# WARNING: HARDCODED VALUES FOR CROWN PASS IVB
- #
thread = 0
socket_id = 0
@@ -269,6 +387,9 @@ class Crb(object):
self.number_of_cores = len(self.cores)
def init_core_list_uncached_linux(self):
+ """
+ Scan cores in linux and create core information list.
+ """
self.cores = []
cpuinfo = \
@@ -292,9 +413,15 @@ class Crb(object):
self.number_of_cores = len(self.cores)
def get_all_cores(self):
+ """
+ Return core information list.
+ """
return self.cores
def remove_hyper_core(self, core_list, key=None):
+ """
+ Remove hyperthread locre for core list.
+ """
found = set()
for core in core_list:
val = core if key is None else key(core)
@@ -303,17 +430,26 @@ class Crb(object):
found.add(val)
def init_reserved_core(self):
+ """
+ Remove hyperthread cores from reserved list.
+ """
partial_cores = self.cores
# remove hyper-threading core
self.reserved_cores = list(self.remove_hyper_core(partial_cores, key=lambda d: (d['core'], d['socket'])))
def remove_reserved_cores(self, core_list, args):
+ """
+ Remove cores from reserved cores.
+ """
indexes = sorted(args, reverse=True)
for index in indexes:
del core_list[index]
return core_list
def get_reserved_core(self, config, socket):
+ """
+ Get reserved cores by core config and socket id.
+ """
m = re.match("([1-9]+)C", config)
nr_cores = int(m.group(1))
if m is None:
@@ -333,6 +469,10 @@ class Crb(object):
return map(str, thread_list)
def get_core_list(self, config, th=False, socket=-1):
+ """
+ Get lcore array according to the core config like "all", "1S/1C/1T".
+ We can specify the physical CPU socket by paramter "socket".
+ """
if config == 'all':
if th:
@@ -420,6 +560,9 @@ class Crb(object):
return map(str, thread_list)
def get_lcore_id(self, config):
+ """
+ Get lcore id of specified core by config "C{socket.core.thread}"
+ """
m = re.match("C{([01]).(\d).([01])}", config)
diff --git a/framework/crbs.py b/framework/crbs.py
index 0e01db2..0a37b18 100644
--- a/framework/crbs.py
+++ b/framework/crbs.py
@@ -1,4 +1,33 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
Static configuration data for any CRBs that can be used.
diff --git a/framework/dcts.py b/framework/dts.py
index 646760e..30c3f23 100644
--- a/framework/dcts.py
+++ b/framework/dts.py
@@ -1,4 +1,33 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import re # regression module
import ConfigParser # config parse module
@@ -75,18 +104,26 @@ def regexp(s, to_match, allString=False):
def pprint(some_dict):
+ """
+ Print JSON format dictionary object.
+ """
return json.dumps(some_dict, sort_keys=True, indent=4)
def report(text, frame=False, annex=False):
+ """
+ Save report text into rst file.
+ """
if frame:
rst.write_frame(text, annex)
else:
rst.write_text(text, annex)
-# exit function will close session to DUT and tester
def close_crb_sessions():
+ """
+ Close session to DUT and tester.
+ """
if dut is not None:
dut.close()
if tester is not None:
@@ -120,16 +157,19 @@ def get_crb_os(crb):
return 'linux'
-# Parse execution file parameters
-def dcts_parse_param(section):
+def dts_parse_param(section):
+ """
+ Parse execution file parameters.
+ """
global performance_only
global functional_only
global paramDict
+ global drivername
performance_only = False
functional_only = False
# Set parameters
parameters = config.get(section, 'parameters').split(':')
- drivername = config.get(section, "drivername").split('=')[-1]
+ drivername = config.get(section, 'drivername').split('=')[-1]
paramDict = dict()
for param in parameters:
(key, _, value) = param.partition('=')
@@ -144,8 +184,10 @@ def dcts_parse_param(section):
functional_only = True
-# Parse execution file configuration
-def dcts_parse_config(section):
+def dts_parse_config(section):
+ """
+ Parse execution file configuration.
+ """
duts = [dut_.strip() for dut_ in config.get(section,
'crbs').split(',')]
targets = [target.strip()
@@ -158,8 +200,10 @@ def dcts_parse_config(section):
return duts, targets, test_suites, nics
-# load project module and return crb instance
def get_project_obj(project_name, super_class, crbInst, serializer):
+ """
+ Load project module and return crb instance.
+ """
project_obj = None
try:
project_module = __import__("project_" + project_name)
@@ -169,17 +213,19 @@ def get_project_obj(project_name, super_class, crbInst, serializer):
if project_obj is None:
project_obj = super_class(crbInst, serializer)
except Exception as e:
- log_handler.info("LOAD PROJECT MODULE INFO: " + e)
+ log_handler.info("LOAD PROJECT MODULE INFO: " + str(e))
project_obj = super_class(crbInst, serializer)
return project_obj
-# config logger to SUITE.log
-def dcts_log_testsuite(test_suite, log_handler, test_classname):
+def dts_log_testsuite(test_suite, log_handler, test_classname):
+ """
+ Change to SUITE self logger handler.
+ """
test_suite.logger = getLogger(test_classname)
test_suite.logger.config_suite(test_classname)
- log_handler.config_suite(test_classname, 'dcts')
+ log_handler.config_suite(test_classname, 'dts')
dut.logger.config_suite(test_classname, 'dut')
tester.logger.config_suite(test_classname, 'tester')
try:
@@ -190,9 +236,11 @@ def dcts_log_testsuite(test_suite, log_handler, test_classname):
pass
-# config logger to dcts.log
-def dcts_log_execution(log_handler):
- log_handler.config_execution('dcts')
+def dts_log_execution(log_handler):
+ """
+ Change to DTS default logger handler.
+ """
+ log_handler.config_execution('dts')
dut.logger.config_execution('dut')
tester.logger.config_execution('tester')
try:
@@ -203,8 +251,10 @@ def dcts_log_execution(log_handler):
pass
-# create dcts crbs and initialize them
-def dcts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir):
+def dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir):
+ """
+ Create dts dut/tester instance and initialize them.
+ """
global dut
global tester
serializer.set_serialized_filename('../.%s.cache' % crbInst['IP'])
@@ -223,14 +273,18 @@ def dcts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir):
tester.init_ext_gen()
-# when crbs exit remove logger handler
-def dcts_crbs_exit():
+def dts_crbs_exit():
+ """
+ Remove logger handler when exit.
+ """
dut.logger.logger_exit()
tester.logger.logger_exit()
-# run dcts prerequisties function
-def dcts_run_prerequisties(pkgName, patch):
+def dts_run_prerequisties(pkgName, patch):
+ """
+ Run dts prerequisties function.
+ """
try:
dut.prerequisites(pkgName, patch)
tester.prerequisites(performance_only)
@@ -244,8 +298,10 @@ def dcts_run_prerequisties(pkgName, patch):
return False
-# run each target in execution
-def dcts_run_target(crbInst, targets, test_suites, nics):
+def dts_run_target(crbInst, targets, test_suites, nics):
+ """
+ Run each target in execution targets.
+ """
for target in targets:
log_handler.info("\nTARGET " + target)
result.target = target
@@ -267,7 +323,7 @@ def dcts_run_target(crbInst, targets, test_suites, nics):
nic = nics[0]
result.nic = nic
- dcts_run_suite(crbInst, test_suites, target, nic)
+ dts_run_suite(crbInst, test_suites, target, nic)
dut.restore_interfaces()
dut.close()
@@ -275,8 +331,10 @@ def dcts_run_target(crbInst, targets, test_suites, nics):
tester.close()
-# run each suite in target
-def dcts_run_suite(crbInst, test_suites, target, nic):
+def dts_run_suite(crbInst, test_suites, target, nic):
+ """
+ Run each suite in test suite list.
+ """
try:
for test_suite in test_suites:
# prepare rst report file
@@ -286,7 +344,7 @@ def dcts_run_suite(crbInst, test_suites, target, nic):
for test_classname, test_class in get_subclasses(test_module, TestCase):
test_suite = test_class(dut, tester, target, nic)
- dcts_log_testsuite(test_suite, log_handler, test_classname)
+ dts_log_testsuite(test_suite, log_handler, test_classname)
log_handler.info("\nTEST SUITE : " + test_classname)
log_handler.info("NIC : " + nic)
@@ -297,23 +355,24 @@ def dcts_run_suite(crbInst, test_suites, target, nic):
test_cases_as_blocked(test_suite)
log_handler.info("\nTEST SUITE ENDED: " + test_classname)
- dcts_log_execution(log_handler)
+ dts_log_execution(log_handler)
dut.kill_all()
except VerifyFailure:
log_handler.error(" !!! DEBUG IT: " + traceback.format_exc())
except KeyboardInterrupt:
log_handler.error(" !!! STOPPING DCTS")
+ except Exception as e:
+ log_handler.error(str(e))
finally:
execute_test_tear_down_all(test_suite)
-# main process of dcts
def run_all(config_file, pkgName, git, patch, skip_setup,
read_cache, project, suite_dir, test_cases,
- base_dir, output_dir):
+ base_dir, output_dir, verbose):
"""
- Run all test suites in the config file
+ Main process of DTS, it will run all test suites in the config file.
"""
global config
@@ -330,9 +389,12 @@ def run_all(config_file, pkgName, git, patch, skip_setup,
os.mkdir(output_dir)
# init log_handler handler
+ if verbose is True:
+ logger.set_verbose()
+
logger.log_dir = output_dir
- log_handler = getLogger('dcts')
- log_handler.config_execution('dcts')
+ log_handler = getLogger('dts')
+ log_handler.config_execution('dts')
# run designated test case
requested_tests = test_cases
@@ -357,10 +419,10 @@ def run_all(config_file, pkgName, git, patch, skip_setup,
# for all Exectuion sections
for section in config.sections():
- dcts_parse_param(section)
+ dts_parse_param(section)
# verify if the delimiter is good if the lists are vertical
- duts, targets, test_suites, nics = dcts_parse_config(section)
+ duts, targets, test_suites, nics = dts_parse_config(section)
for dutIP in duts:
log_handler.info("\nDUT " + dutIP)
@@ -380,22 +442,24 @@ def run_all(config_file, pkgName, git, patch, skip_setup,
result.dut = dutIP
# init dut, tester crb
- dcts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir)
+ dts_crbs_init(crbInst, skip_setup, read_cache, project, base_dir)
# Run DUT prerequisites
- if dcts_run_prerequisties(pkgName, patch) is False:
- dcts_crbs_exit()
+ if dts_run_prerequisties(pkgName, patch) is False:
+ dts_crbs_exit()
continue
- dcts_run_target(crbInst, targets, test_suites, nics)
+ dts_run_target(crbInst, targets, test_suites, nics)
- dcts_crbs_exit()
+ dts_crbs_exit()
save_all_results()
-# save result as test case blocked
def test_cases_as_blocked(test_suite):
+ """
+ Save result as test case blocked.
+ """
if functional_only:
for test_case in get_functional_test_cases(test_suite):
result.test_case = test_case.__name__
@@ -406,25 +470,33 @@ def test_cases_as_blocked(test_suite):
result.test_case_blocked('set_up_all failed')
-# get module attribute name and attribute
def get_subclasses(module, clazz):
+ """
+ Get module attribute name and attribute.
+ """
for subclazz_name, subclazz in inspect.getmembers(module):
if hasattr(subclazz, '__bases__') and clazz in subclazz.__bases__:
yield (subclazz_name, subclazz)
-# get all functional test cases
def get_functional_test_cases(test_suite):
+ """
+ Get all functional test cases.
+ """
return get_test_cases(test_suite, r'test_(?!perf_)')
-# get all performance test cases
def get_performance_test_cases(test_suite):
+ """
+ Get all performance test cases.
+ """
return get_test_cases(test_suite, r'test_perf_')
-# check if test case has been requested
def has_it_been_requested(test_case, test_name_regex):
+ """
+ Check whether test case has been requested for validation.
+ """
name_matches = re.match(test_name_regex, test_case.__name__)
if requested_tests is not None:
@@ -433,16 +505,20 @@ def has_it_been_requested(test_case, test_name_regex):
return name_matches
-# return all case list which matched regex
def get_test_cases(test_suite, test_name_regex):
+ """
+ Return case list which name matched regex.
+ """
for test_case_name in dir(test_suite):
test_case = getattr(test_suite, test_case_name)
if callable(test_case) and has_it_been_requested(test_case, test_name_regex):
yield test_case
-# execute suite setup_all function
def execute_test_setup_all(test_case):
+ """
+ Execute suite setup_all function before cases.
+ """
try:
test_case.set_up_all()
return True
@@ -451,8 +527,10 @@ def execute_test_setup_all(test_case):
return False
-# execute all test cases in one suite
def execute_all_test_cases(test_suite):
+ """
+ Execute all test cases in one suite.
+ """
if functional_only:
for test_case in get_functional_test_cases(test_suite):
execute_test_case(test_suite, test_case)
@@ -461,8 +539,11 @@ def execute_all_test_cases(test_suite):
execute_test_case(test_suite, test_case)
-# execute one test case in one suite
def execute_test_case(test_suite, test_case):
+ """
+ Execute specified test case in specified suite. If any exception occured in
+ validation process, save the result and tear down this case.
+ """
result.test_case = test_case.__name__
rst.write_title("Test Case: " + test_case.__name__)
@@ -491,8 +572,10 @@ def execute_test_case(test_suite, test_case):
raise KeyboardInterrupt("Stop DCTS")
except TimeoutException as e:
rst.write_result("FAIL")
- result.test_case_failed(str(e))
- log_handler.error('Test Case %s Result FAILED: ' % (test_case.__name__) + str(e))
+ msg = str(e)
+ result.test_case_failed(msg)
+ log_handler.error('Test Case %s Result FAILED: ' % (test_case.__name__) + msg)
+ log_handler.error('%s' % (e.get_output()))
except Exception:
trace = traceback.format_exc()
result.test_case_failed(trace)
@@ -502,8 +585,10 @@ def execute_test_case(test_suite, test_case):
save_all_results()
-# execute suite tear_down_all function
def execute_test_tear_down_all(test_case):
+ """
+ execute suite tear_down_all function
+ """
try:
test_case.tear_down_all()
except Exception:
@@ -513,8 +598,14 @@ def execute_test_tear_down_all(test_case):
tester.kill_all()
-# add header to result table
def results_table_add_header(header):
+ """
+ Add the title of result table.
+ Usage:
+ results_table_add_header(header)
+ results_table_add_row(row)
+ results_table_print()
+ """
global table, results_table_header, results_table_rows
results_table_rows = []
@@ -524,11 +615,16 @@ def results_table_add_header(header):
def results_table_add_row(row):
+ """
+ Add one row to result table.
+ """
results_table_rows.append(row)
-# show off result table
def results_table_print():
+ """
+ Show off result table.
+ """
table.add_rows(results_table_rows)
table.header(results_table_header)
@@ -552,6 +648,9 @@ def results_plot_print(image, width=90):
def create_mask(indexes):
+ """
+ Convert index to hex mask.
+ """
val = 0
for index in indexes:
val |= 1 << int(index)
@@ -571,7 +670,9 @@ def show_speedup_options_messages(read_cache, skip_setup):
log_handler.info('SKIP: The DPDK setup steps will be executed.')
-# save all result to files
def save_all_results():
+ """
+ Save all result to files.
+ """
excel_report.save(result)
stats.save(result)
diff --git a/framework/dut.py b/framework/dut.py
index 6444901..4def144 100644
--- a/framework/dut.py
+++ b/framework/dut.py
@@ -1,26 +1,55 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
import re
-import dcts
+import time
+import dts
from settings import NICS
from ssh_connection import SSHConnection
from crb import Crb
from logger import getLogger
-"""
-A connection to the CRB under test.
-This class sends commands to the CRB and validates the responses. It is
-implemented using either ssh for linuxapp or the terminal server for
-baremetal.
-
-All operations are in fact delegated to an instance of either CRBLinuxApp
-or CRBBareMetal.
-"""
+class Dut(Crb):
+ """
+ A connection to the CRB under test.
+ This class sends commands to the CRB and validates the responses. It is
+ implemented using either ssh for linuxapp or the terminal server for
+ baremetal.
+ All operations are in fact delegated to an instance of either CRBLinuxApp
+ or CRBBareMetal.
+ """
-class Dut(Crb):
PORT_INFO_CACHE_KEY = 'dut_port_info'
NUMBER_CORES_CACHE_KEY = 'dut_number_cores'
CORE_LIST_CACHE_KEY = 'dut_core_list'
@@ -70,6 +99,9 @@ class Dut(Crb):
self.architecture = arch
def mount_procfs(self):
+ """
+ Mount proc file system.
+ """
mount_procfs = getattr(self, 'mount_procfs_%s' % self.get_os_type())
mount_procfs()
@@ -77,12 +109,24 @@ class Dut(Crb):
pass
def mount_procfs_freebsd(self):
+ """
+ Mount proc file system in Freebsd.
+ """
self.send_expect('mount -t procfs proc /proc', '# ')
def get_ip_address(self):
+ """
+ Get DUT's ip address.
+ """
return self.crb['IP']
def dut_prerequisites(self):
+ """
+ Prerequest function should be called before execute any test case.
+ Will call function to scan all lcore's information which on DUT.
+ Then call pci scan function to collect nic device information.
+ At last setup DUT' environment for validation.
+ """
self.send_expect("cd %s" % self.base_dir, "# ")
self.send_expect("alias ls='ls --color=none'", "#")
@@ -97,18 +141,24 @@ class Dut(Crb):
self.mount_procfs()
def restore_interfaces(self):
+ """
+ Restore all ports's interfaces.
+ """
restore_interfaces = getattr(self, 'restore_interfaces_%s' % self.get_os_type())
return restore_interfaces()
def restore_interfaces_freebsd(self):
"""
- Restore FreeBSD interfaces
+ Restore FreeBSD interfaces.
"""
self.send_expect("kldunload nic_uio.ko", "#")
self.send_expect("kldunload contigmem.ko", "#")
self.send_expect("kldload if_ixgbe.ko", "#", 20)
def restore_interfaces_linux(self):
+ """
+ Restore Linux interfaces.
+ """
Crb.restore_interfaces(self)
if self.ports_info is not None:
@@ -116,6 +166,9 @@ class Dut(Crb):
self.admin_ports_linux(port['intf'], 'up')
def setup_memory(self, hugepages=-1):
+ """
+ Setup hugepage on DUT.
+ """
try:
function_name = 'setup_memory_%s' % self.get_os_type()
setup_memory = getattr(self, function_name)
@@ -124,6 +177,9 @@ class Dut(Crb):
self.logger.error("%s is not implemented" % function_name)
def setup_memory_linux(self, hugepages=-1):
+ """
+ Setup Linux hugepages.
+ """
hugepages_size = self.send_expect("awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# ")
if int(hugepages_size) < (1024 * 1024):
@@ -139,6 +195,9 @@ class Dut(Crb):
self.set_huge_pages(arch_huge_pages)
def setup_memory_freebsd(self, hugepages=-1):
+ """
+ Setup Freebsd hugepages.
+ """
if hugepages is -1:
hugepages = 2048
@@ -165,7 +224,7 @@ class Dut(Crb):
current_nic = 0
for (pci_bus, pci_id) in self.pci_devices_info:
- if dcts.accepted_nic(pci_id):
+ if dts.accepted_nic(pci_id):
if nics_to_bind is None or current_nic in nics_to_bind:
binding_list += '%s ' % (pci_bus)
@@ -176,14 +235,14 @@ class Dut(Crb):
def unbind_interfaces_linux(self, nics_to_bind=None):
"""
- Unbind the interfaces
+ Unbind the interfaces.
"""
binding_list = '-u '
current_nic = 0
for (pci_bus, pci_id) in self.pci_devices_info:
- if dcts.accepted_nic(pci_id):
+ if dts.accepted_nic(pci_id):
if nics_to_bind is None or current_nic in nics_to_bind:
binding_list += '%s ' % (pci_bus)
@@ -193,6 +252,10 @@ class Dut(Crb):
self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list, '# ', 30)
def get_ports(self, nic_type, perf=None, socket=None):
+ """
+ Return DUT port list with the filter of NIC type, whether run IXIA
+ performance test, whether request specified socket.
+ """
ports = []
candidates = []
@@ -225,7 +288,7 @@ class Dut(Crb):
continue
ports.append(portid)
- if perf and not self.has_external_traffic_generator():
+ if perf and not self.tester.has_external_traffic_generator():
return candidates
else:
return ports
@@ -291,17 +354,17 @@ class Dut(Crb):
def lcore_table_print(self, horizontal=False):
if not horizontal:
- dcts.results_table_add_header(['Socket', 'Core', 'Thread'])
+ dts.results_table_add_header(['Socket', 'Core', 'Thread'])
for lcore in self.cores:
- dcts.results_table_add_row([lcore['socket'], lcore['core'], lcore['thread']])
- dcts.results_table_print()
+ dts.results_table_add_row([lcore['socket'], lcore['core'], lcore['thread']])
+ dts.results_table_print()
else:
- dcts.results_table_add_header(['X'] + [''] * len(self.cores))
- dcts.results_table_add_row(['Thread'] + [n['thread'] for n in self.cores])
- dcts.results_table_add_row(['Core'] + [n['core'] for n in self.cores])
- dcts.results_table_add_row(['Socket'] + [n['socket'] for n in self.cores])
- dcts.results_table_print()
+ dts.results_table_add_header(['X'] + [''] * len(self.cores))
+ dts.results_table_add_row(['Thread'] + [n['thread'] for n in self.cores])
+ dts.results_table_add_row(['Core'] + [n['core'] for n in self.cores])
+ dts.results_table_add_row(['Socket'] + [n['socket'] for n in self.cores])
+ dts.results_table_print()
def get_memory_channels(self):
n = self.crb['memory channels']
@@ -311,6 +374,9 @@ class Dut(Crb):
return 1
def scan_ports(self):
+ """
+ Scan ports information or just read it from cache file.
+ """
if self.read_cache:
self.ports_info = self.serializer.load(self.PORT_INFO_CACHE_KEY)
@@ -318,21 +384,27 @@ class Dut(Crb):
self.scan_ports_uncached()
self.serializer.save(self.PORT_INFO_CACHE_KEY, self.ports_info)
- self.logger.info(dcts.pprint(self.ports_info))
+ self.logger.info(dts.pprint(self.ports_info))
def scan_ports_uncached(self):
+ """
+ Scan ports and collect port's pci id, mac adress, ipv6 address.
+ """
scan_ports_uncached = getattr(self, 'scan_ports_uncached_%s' % self.get_os_type())
return scan_ports_uncached()
def scan_ports_uncached_linux(self):
+ """
+ Scan Linux ports and collect port's pci id, mac adress, ipv6 address.
+ """
self.ports_info = []
- skipped = dcts.RED('Skipped: Unknown/not selected')
- unknow_interface = dcts.RED('Skipped: unknow_interface')
+ skipped = dts.RED('Skipped: Unknown/not selected')
+ unknow_interface = dts.RED('Skipped: unknow_interface')
for (pci_bus, pci_id) in self.pci_devices_info:
- if not dcts.accepted_nic(pci_id):
+ if not dts.accepted_nic(pci_id):
self.logger.info("DUT: [000:%s %s] %s" % (pci_bus, pci_id,
skipped))
continue
@@ -345,6 +417,11 @@ class Dut(Crb):
self.send_expect("echo 0000:%s > /sys/bus/pci/drivers/ixgbe/bind" % pci_bus, "# ")
intf = self.get_interface_name(bus_id, devfun_id)
+ out = self.send_expect("ip link show %s" % intf, "# ")
+ if "DOWN" in out:
+ self.send_expect("ip link set %s up" % intf, "# ")
+ time.sleep(5)
+
self.logger.info("DUT: [000:%s %s] %s" % (pci_bus,
pci_id,
intf))
@@ -378,13 +455,16 @@ class Dut(Crb):
intf, 'mac': macaddr, 'ipv6': ipv6, 'numa': numa})
def scan_ports_uncached_freebsd(self):
+ """
+ Scan Freebsd ports and collect port's pci id, mac adress, ipv6 address.
+ """
self.ports_info = []
- skipped = dcts.RED('Skipped: Unknown/not selected')
+ skipped = dts.RED('Skipped: Unknown/not selected')
for (pci_bus, pci_id) in self.pci_devices_info:
- if not dcts.accepted_nic(pci_id):
+ if not dts.accepted_nic(pci_id):
self.logger.info("DUT: [%s %s] %s" % (pci_bus, pci_id,
skipped))
continue
diff --git a/framework/etgen.py b/framework/etgen.py
index 62c9cd7..cd144ae 100644
--- a/framework/etgen.py
+++ b/framework/etgen.py
@@ -1,9 +1,38 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import re
import string
import time
-import dcts
+import dts
import ixiacfg
from ssh_connection import SSHConnection
from settings import SCAPY2IXIA
@@ -13,6 +42,10 @@ from exception import VerifyFailure
class SoftwarePacketGenerator():
+ """
+ Software WindRiver packet generator for performance measurement.
+ """
+
def __init__(self, tester):
self.tester = tester
@@ -55,7 +88,7 @@ class SoftwarePacketGenerator():
pcap_cmd += " -s %d:%s" % (port_map[tx_port], pcap_file)
# Selected 2 for -n to optimize results on Burage
- cores_mask = dcts.create_mask(self.tester.get_core_list("all"))
+ cores_mask = dts.create_mask(self.tester.get_core_list("all"))
self.tester.send_expect("./pktgen -n 2 -c %s --proc-type auto --socket-mem 256,256 -- -P -m \"%s\" %s"
% (cores_mask, map_cmd, pcap_cmd), "Pktgen>", 100)
@@ -96,6 +129,10 @@ class SoftwarePacketGenerator():
class IxiaPacketGenerator(SSHConnection):
+ """
+ IXIA packet generator for performance measurement.
+ """
+
def __init__(self, tester):
self.tester = tester
self.NAME = 'ixia'
@@ -134,13 +171,22 @@ class IxiaPacketGenerator(SSHConnection):
return self.tester.get_ip_address()
def add_tcl_cmd(self, cmd):
+ """
+ Add one tcl command into command list.
+ """
self.tcl_cmds.append(cmd)
def clean(self):
+ """
+ Clean ownership of IXIA devices and logout tcl session.
+ """
self.close()
self.send_expect("clearOwnershipAndLogout", "% ")
def parse_pcap(self, fpcap):
+ """
+ Parse packet in pcap file and convert it into tcl commands.
+ """
self.send_expect("echo {print [i.command() for i in rdpcap('%s', -1)]; exit()} > dumppcap.py" %
fpcap, "% ")
out = self.send_expect("scapy -c dumppcap.py 2>/dev/null", "% ", 120)
@@ -148,11 +194,17 @@ class IxiaPacketGenerator(SSHConnection):
return flows
def ether(self, port, src, dst, type):
+ """
+ Configure Ether protocal.
+ """
self.add_tcl_cmd("protocol config -ethernetType ethernetII")
self.add_tcl_cmd('stream config -sa "%s"' % self.macToTclFormat(src))
self.add_tcl_cmd('stream config -da "%s"' % self.macToTclFormat(dst))
def ip(self, port, frag, src, proto, tos, dst, chksum, len, version, flags, ihl, ttl, id, options=None):
+ """
+ Configure IP protocal.
+ """
self.add_tcl_cmd("protocol config -name ip")
self.add_tcl_cmd('ip config -sourceIpAddr "%s"' % src)
self.add_tcl_cmd('ip config -destIpAddr "%s"' % dst)
@@ -165,10 +217,16 @@ class IxiaPacketGenerator(SSHConnection):
self.add_tcl_cmd("ip set %d %d %d" % (self.chasId, port['card'], port['port']))
def macToTclFormat(self, macAddr):
+ """
+ Convert normal mac adress format into IXIA's format.
+ """
macAddr = macAddr.upper()
return "%s %s %s %s %s %s" % (macAddr[:2], macAddr[3:5], macAddr[6:8], macAddr[9:11], macAddr[12:14], macAddr[15:17])
def ipv6(self, port, version, tc, fl, plen, nh, hlim, src, dst):
+ """
+ Configure IPv6 protocal.
+ """
self.add_tcl_cmd("protocol config -name ipV6")
self.add_tcl_cmd('ipV6 setDefault')
self.add_tcl_cmd('ipV6 config -destAddr "%s"' % self.ipv6_to_tcl_format(dst))
@@ -184,6 +242,9 @@ class IxiaPacketGenerator(SSHConnection):
self.add_tcl_cmd("ipV6 set %d %d %d" % (self.chasId, port['card'], port['port']))
def udp(self, port, dport, sport, len, chksum):
+ """
+ Configure UDP protocal.
+ """
self.add_tcl_cmd("udp setDefault")
self.add_tcl_cmd("udp config -sourcePort %d" % sport)
self.add_tcl_cmd("udp config -destPort %d" % dport)
@@ -191,23 +252,35 @@ class IxiaPacketGenerator(SSHConnection):
self.add_tcl_cmd("udp set %d %d %d" % (self.chasId, port['card'], port['port']))
def tcp(self, port, sport, dport, seq, ack, dataofs, reserved, flags, window, chksum, urgptr, options=None):
+ """
+ Configure TCP protocal.
+ """
self.add_tcl_cmd("tcp setDefault")
self.add_tcl_cmd("tcp config -sourcePort %d" % sport)
self.add_tcl_cmd("tcp config -destPort %d" % dport)
self.add_tcl_cmd("tcp set %d %d %d" % (self.chasId, port['card'], port['port']))
def sctp(self, port, sport, dport, tag, chksum):
+ """
+ Configure SCTP protocal.
+ """
self.add_tcl_cmd("tcp config -sourcePort %d" % sport)
self.add_tcl_cmd("tcp config -destPort %d" % dport)
self.add_tcl_cmd("tcp set %d %d %d" % (self.chasId, port['card'], port['port']))
def dot1q(self, port, prio, id, vlan, type):
+ """
+ Configure 8021Q protocal.
+ """
self.add_tcl_cmd("protocol config -enable802dot1qTag true")
self.add_tcl_cmd("vlan config -vlanID %d" % vlan)
self.add_tcl_cmd("vlan config -userPriority %d" % prio)
self.add_tcl_cmd("vlan set %d %d %d" % (self.chasId, port['card'], port['port']))
def config_stream(self, fpcap, txport, rate_percent, stream_id=1, latency=False):
+ """
+ Configure IXIA stream and enable mutliple flows.
+ """
flows = self.parse_pcap(fpcap)
self.add_tcl_cmd("ixGlobalSetDefault")
@@ -235,6 +308,7 @@ class IxiaPacketGenerator(SSHConnection):
def config_ixia_stream(self, rate_percent, flows, latency):
"""
+ Configure IXIA stream with rate and latency.
Override this method if you want to add custom stream configuration.
"""
self.add_tcl_cmd("stream config -rateMode usePercentRate")
@@ -249,7 +323,9 @@ class IxiaPacketGenerator(SSHConnection):
self.add_tcl_cmd("stream config -fir true")
def tcl_server_login(self):
- # connect to tcl server
+ """
+ Connect to tcl server and take ownership of all the ports needed.
+ """
out = self.send_expect("ixConnectToTclServer %s" % self.tclServerIP, "% ", 30)
self.logger.debug("ixConnectToTclServer return:" + out)
if out.strip()[-1] != '0':
@@ -272,12 +348,17 @@ class IxiaPacketGenerator(SSHConnection):
return True
def tcl_server_logout(self):
-
+ """
+ Disconnect to tcl server and make sure has been logged out.
+ """
self.send_expect("ixDisconnectFromChassis %s" % self.tclServerIP, "%")
self.send_expect("ixLogout", "%")
self.send_expect("ixDisconnectTclServer %s" % self.tclServerIP, "%")
def config_port(self, pList):
+ """
+ Configure ports and make them ready for performance validation.
+ """
pl = list()
for item in pList:
self.add_tcl_cmd("port setFactoryDefaults chasId %d %d" % (
@@ -292,17 +373,26 @@ class IxiaPacketGenerator(SSHConnection):
self.add_tcl_cmd("ixCheckLinkState portList")
def set_ixia_port_list(self, pList):
+ """
+ Implement ports/streams configuration on specified ports.
+ """
self.add_tcl_cmd("set portList [list %s]" %
string.join(['[list %d %d %d]' %
(self.chasId, item['card'], item['port']) for item in pList], ' '))
def send_ping6(self, intf, mac, ipv6):
- self.send_expect("source ./ixiaPing6.tcl", "% ")
+ """
+ Send ping6 packet from IXIA ports.
+ """
+ self.send_expect("source ./ixTcl1.0/ixiaPing6.tcl", "% ")
out = self.send_expect('ping6 "%s" "%s" %d %d %d' %
(self.ipv6_to_tcl_format(ipv6), self.macToTclFormat(mac), self.chasId, self.interface_to_port(intf)['card'], self.interface_to_port(intf)['port']), "% ", 90)
return out
def ipv6_to_tcl_format(self, ipv6):
+ """
+ Convert normal IPv6 address to IXIA format.
+ """
ipv6 = ipv6.upper()
singleAddr = ipv6.split(":")
if '' == singleAddr[0]:
@@ -333,13 +423,22 @@ class IxiaPacketGenerator(SSHConnection):
return plist
def interface_to_port(self, intf):
+ """
+ Convert IXIA interface to IXIA port.
+ """
return {'card': int(intf.split('.')[0]), 'port': int(intf.split('.')[1])}
def loss(self, portList, ratePercent):
+ """
+ Run loss performance test and return loss rate.
+ """
rxPortlist, txPortlist = self._configure_everything(portList, ratePercent)
return self.get_loss_packet_rate(rxPortlist, txPortlist)
def get_loss_packet_rate(self, rxPortlist, txPortlist):
+ """
+ Get RX/TX packet statistics and calculate loss rate.
+ """
time.sleep(3)
self.send_expect("ixStopTransmit portList", "%", 10)
@@ -363,10 +462,16 @@ class IxiaPacketGenerator(SSHConnection):
return float(sendNumber - revNumber) / sendNumber
def latency(self, portList, ratePercent, delay=5):
+ """
+ Run latency performance test and return latency statistics.
+ """
rxPortlist, txPortlist = self._configure_everything(portList, ratePercent, True)
return self.get_packet_latency(rxPortlist)
def get_packet_latency(self, rxPortlist):
+ """
+ Stop IXIA transmit and return latency statistics.
+ """
latencyList = []
time.sleep(10)
self.send_expect("ixStopTransmit portList", "%", 10)
@@ -380,10 +485,16 @@ class IxiaPacketGenerator(SSHConnection):
return latencyList
def throughput(self, port_list, rate_percent=100, delay=5):
+ """
+ Run throughput performance test and return throughput statistics.
+ """
rxPortlist, txPortlist = self._configure_everything(port_list, rate_percent)
return self.get_transmission_results(rxPortlist, txPortlist, delay)
def _configure_everything(self, port_list, rate_percent, latency=False):
+ """
+ Prepare and configure IXIA ports for performance test.
+ """
rxPortlist, txPortlist = self.prepare_port_list(port_list, rate_percent, latency)
self.prepare_ixia_for_transmission(txPortlist, rxPortlist)
self.configure_transmission()
@@ -392,17 +503,29 @@ class IxiaPacketGenerator(SSHConnection):
return rxPortlist, txPortlist
def clear_tcl_commands(self):
+ """
+ Clear all commands in command list.
+ """
del self.tcl_cmds[:]
def start_transmission(self):
+ """
+ Run commands in command list.
+ """
fileContent = "\n".join(self.tcl_cmds) + "\n"
self.tester.create_file(fileContent, 'ixiaConfig.tcl')
self.send_expect("source ixiaConfig.tcl", "% ", 75)
def configure_transmission(self, latency=False):
+ """
+ Start IXIA ports transmition.
+ """
self.add_tcl_cmd("ixStartTransmit portList")
def prepare_port_list(self, portList, rate_percent=100, latency=False):
+ """
+ Configure stream and flow on every IXIA ports.
+ """
txPortlist = set()
rxPortlist = set()
@@ -427,6 +550,9 @@ class IxiaPacketGenerator(SSHConnection):
return rxPortlist, txPortlist
def prepare_ixia_for_transmission(self, txPortlist, rxPortlist):
+ """
+ Clear all statistics and implement configuration to IXIA hareware.
+ """
self.add_tcl_cmd("ixClearStats portList")
self.set_ixia_port_list([self.interface_to_port(self.tester.get_interface(port)) for port in txPortlist])
self.add_tcl_cmd("ixWriteConfigToHardware portList")
@@ -458,28 +584,35 @@ class IxiaPacketGenerator(SSHConnection):
return (bpsRate, rate)
- # Configure Ixia for DCB
def config_ixia_dcb_init(self, rxPort, txPort):
- self.send_expect("source ./ixiaDCB.tcl", "% ")
+ """
+ Configure Ixia for DCB.
+ """
+ self.send_expect("source ./ixTcl1.0/ixiaDCB.tcl", "% ")
self.send_expect("configIxia %d %s" % (self.chasId, string.join(["%s" % (
repr(self.conRelation[port][n])) for port in [rxPort, txPort] for n in range(3)])), "% ", 100)
- # Configure Port for DCB
def config_port_dcb(self, direction, tc):
+ """
+ Configure Port for DCB.
+ """
self.send_expect("configPort %s %s" % (direction, tc), "% ", 100)
- # Configure Stream for DCB
def cfgStreamDcb(self, stream, rate, prio, types):
+ """
+ Configure Stream for DCB.
+ """
self.send_expect("configStream %s %s %s %s" % (stream, rate, prio, types), "% ", 100)
- # Get the connect relations between DUT and Ixia
def get_connection_relation(self, dutPorts):
+ """
+ Get the connect relations between DUT and Ixia.
+ """
for port in dutPorts:
info = self.tester.get_interface(self.tester.get_local_port(port)).split('.')
self.conRelation[port] = [int(info[0]), int(info[1]), repr(self.tester.dut.get_mac_address(port).replace(':', ' ').upper())]
return self.conRelation
- # enable packetGroup on port
def config_pktGroup_rx(self, rxport):
"""
Sets the transmit Packet Group configuration of the stream
@@ -493,12 +626,18 @@ class IxiaPacketGenerator(SSHConnection):
self.add_tcl_cmd("packetGroup setTx %d %d %d 1" % (self.chasId, rxport['card'], rxport['port']))
def config_pktGroup_tx(self, txport):
+ """
+ Configure tx port pktGroup for latency.
+ """
self.add_tcl_cmd("packetGroup setDefault")
self.add_tcl_cmd("packetGroup config -insertSignature true")
self.add_tcl_cmd("packetGroup setTx %d %d %d 1" % (self.chasId,
txport['card'], txport['port']))
def start_pktGroup(self, port):
+ """
+ Start tx port pktGroup for latency.
+ """
self.add_tcl_cmd("ixStartPortPacketGroups %d %d %d" % (self.chasId,
port['card'], port['port']))
@@ -540,6 +679,9 @@ class IxiaPacketGenerator(SSHConnection):
self.send_expect(command, '% ', 30)
def stat_get_rate_stat_all_stats(self, port_number):
+ """
+ All statistics of specified IXIA port.
+ """
port = self.interface_to_port(self.tester.get_interface(port_number))
command = 'stat getRate statAllStats {0} {1} {2}'
command = command.format(self.chasId, port['card'], port['port'])
@@ -573,11 +715,17 @@ class IxiaPacketGenerator(SSHConnection):
return int(result.strip())
def _capture_cget_value(self, requested_value):
+ """
+ Sends a IXIA TCL command to capture certain number of packets.
+ """
command = "capture cget -" + requested_value
result = self.send_expect(command, '%', 10)
return int(result.strip())
def _packetgroup_cget_value(self, requested_value):
+ """
+ Sends a IXIA TCL command to get pktGroup stat value.
+ """
command = "packetGroupStats cget -" + requested_value
result = self.send_expect(command, '%', 10)
return int(result.strip())
diff --git a/framework/excel_reporter.py b/framework/excel_reporter.py
index 764edcf..809dead 100644
--- a/framework/excel_reporter.py
+++ b/framework/excel_reporter.py
@@ -1,4 +1,33 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
Excel spreadsheet generator
diff --git a/framework/exception.py b/framework/exception.py
index ef56ef2..be38c16 100644
--- a/framework/exception.py
+++ b/framework/exception.py
@@ -1,5 +1,3 @@
-# <COPYRIGHT_TAG>
-
"""
User-defined exceptions used across the framework.
"""
@@ -19,6 +17,9 @@ class TimeoutException(Exception):
msg = 'TIMEOUT on %s' % (self.command)
return msg
+ def get_output(self):
+ return self.output
+
class VerifyFailure(Exception):
diff --git a/framework/ixia_buffer_parser.py b/framework/ixia_buffer_parser.py
index b0d3443..e7a0e50 100644
--- a/framework/ixia_buffer_parser.py
+++ b/framework/ixia_buffer_parser.py
@@ -1,4 +1,33 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
Helper class that parses a list of files containing IXIA captured frames
diff --git a/framework/ixiacfg.py b/framework/ixiacfg.py
index 9bf09ff..579cda9 100644
--- a/framework/ixiacfg.py
+++ b/framework/ixiacfg.py
@@ -1,5 +1,3 @@
-# <COPYRIGHT_TAG>
-
"""
ixiaPorts Structure
@@ -20,10 +18,10 @@ ixiaPorts = {
'Group1': {"Version": "6.62",
"IP": "10.239.128.121",
"Ports": [
- {"card": 1, "port": 1},
- {"card": 1, "port": 2},
- {"card": 1, "port": 3},
- {"card": 1, "port": 4}
+ {"card": 4, "port": 5},
+ {"card": 4, "port": 6},
+ {"card": 4, "port": 7},
+ {"card": 4, "port": 8}
]
}
diff --git a/framework/logger.py b/framework/logger.py
index 1669c60..1829e18 100644
--- a/framework/logger.py
+++ b/framework/logger.py
@@ -1,4 +1,34 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
import logging
import os
import sys
@@ -6,16 +36,18 @@ import inspect
import re
"""
-DCTS logger module with several log level. DCTS framwork and TestSuite log
+DTS logger module with several log level. DTS framwork and TestSuite log
will saved into different log files.
"""
-logging.DCTS_DUT_CMD = logging.INFO + 1
-logging.DCTS_DUT_OUTPUT = logging.DEBUG + 1
-logging.DCTS_DUT_RESULT = logging.WARNING + 1
+verbose = False
+
+logging.DTS_DUT_CMD = logging.INFO + 1
+logging.DTS_DUT_OUTPUT = logging.DEBUG + 1
+logging.DTS_DUT_RESULT = logging.WARNING + 1
-logging.DCTS_TESTER_CMD = logging.INFO + 2
-logging.DCTS_TESTER_OUTPUT = logging.DEBUG + 2
-logging.DCTS_TESTER_RESULT = logging.WARNING + 2
+logging.DTS_TESTER_CMD = logging.INFO + 2
+logging.DTS_TESTER_OUTPUT = logging.DEBUG + 2
+logging.DTS_TESTER_RESULT = logging.WARNING + 2
logging.SUITE_DUT_CMD = logging.INFO + 3
logging.SUITE_DUT_OUTPUT = logging.DEBUG + 3
@@ -23,16 +55,16 @@ logging.SUITE_DUT_OUTPUT = logging.DEBUG + 3
logging.SUITE_TESTER_CMD = logging.INFO + 4
logging.SUITE_TESTER_OUTPUT = logging.DEBUG + 4
-logging.DCTS_IXIA_CMD = logging.INFO + 5
-logging.DCTS_IXIA_OUTPUT = logging.DEBUG + 5
+logging.DTS_IXIA_CMD = logging.INFO + 5
+logging.DTS_IXIA_OUTPUT = logging.DEBUG + 5
-logging.addLevelName(logging.DCTS_DUT_CMD, 'DCTS_DUT_CMD')
-logging.addLevelName(logging.DCTS_DUT_OUTPUT, 'DCTS_DUT_OUTPUT')
-logging.addLevelName(logging.DCTS_DUT_RESULT, 'DCTS_DUT_RESUTL')
+logging.addLevelName(logging.DTS_DUT_CMD, 'DTS_DUT_CMD')
+logging.addLevelName(logging.DTS_DUT_OUTPUT, 'DTS_DUT_OUTPUT')
+logging.addLevelName(logging.DTS_DUT_RESULT, 'DTS_DUT_RESUTL')
-logging.addLevelName(logging.DCTS_TESTER_CMD, 'DCTS_TESTER_CMD')
-logging.addLevelName(logging.DCTS_TESTER_OUTPUT, 'DCTS_TESTER_OUTPUT')
-logging.addLevelName(logging.DCTS_TESTER_RESULT, 'DCTS_TESTER_RESULT')
+logging.addLevelName(logging.DTS_TESTER_CMD, 'DTS_TESTER_CMD')
+logging.addLevelName(logging.DTS_TESTER_OUTPUT, 'DTS_TESTER_OUTPUT')
+logging.addLevelName(logging.DTS_TESTER_RESULT, 'DTS_TESTER_RESULT')
logging.addLevelName(logging.SUITE_DUT_CMD, 'SUITE_DUT_CMD')
logging.addLevelName(logging.SUITE_DUT_OUTPUT, 'SUITE_DUT_OUTPUT')
@@ -40,8 +72,8 @@ logging.addLevelName(logging.SUITE_DUT_OUTPUT, 'SUITE_DUT_OUTPUT')
logging.addLevelName(logging.SUITE_TESTER_CMD, 'SUITE_TESTER_CMD')
logging.addLevelName(logging.SUITE_TESTER_OUTPUT, 'SUITE_TESTER_OUTPUT')
-logging.addLevelName(logging.DCTS_IXIA_CMD, 'DCTS_IXIA_CMD')
-logging.addLevelName(logging.DCTS_IXIA_OUTPUT, 'DCTS_IXIA_OUTPUT')
+logging.addLevelName(logging.DTS_IXIA_CMD, 'DTS_IXIA_CMD')
+logging.addLevelName(logging.DTS_IXIA_OUTPUT, 'DTS_IXIA_OUTPUT')
message_fmt = '%(asctime)s %(levelname)20s: %(message)s'
date_fmt = '%d/%m/%Y %H:%M:%S'
@@ -54,25 +86,33 @@ def RED(text):
return "\x1B[" + "31;1m" + text + "\x1B[" + "0m"
+def set_verbose():
+ global verbose
+ verbose = True
+
+
class BaseLoggerAdapter(logging.LoggerAdapter):
+ """
+ Upper layer of original logging module.
+ """
- def dcts_dut_cmd(self, msg, *args, **kwargs):
- self.log(logging.DCTS_DUT_CMD, msg, *args, **kwargs)
+ def dts_dut_cmd(self, msg, *args, **kwargs):
+ self.log(logging.DTS_DUT_CMD, msg, *args, **kwargs)
- def dcts_dut_output(self, msg, *args, **kwargs):
- self.log(logging.DCTS_DUT_OUTPUT, msg, *args, **kwargs)
+ def dts_dut_output(self, msg, *args, **kwargs):
+ self.log(logging.DTS_DUT_OUTPUT, msg, *args, **kwargs)
- def dcts_dut_result(self, msg, *args, **kwargs):
- self.log(logging.DCTS_DUT_RESULT, msg, *args, **kwargs)
+ def dts_dut_result(self, msg, *args, **kwargs):
+ self.log(logging.DTS_DUT_RESULT, msg, *args, **kwargs)
- def dcts_tester_cmd(self, msg, *args, **kwargs):
- self.log(logging.DCTS_TESTER_CMD, msg, *args, **kwargs)
+ def dts_tester_cmd(self, msg, *args, **kwargs):
+ self.log(logging.DTS_TESTER_CMD, msg, *args, **kwargs)
- def dcts_tester_output(self, msg, *args, **kwargs):
- self.log(logging.DCTS_TESTER_CMD, msg, *args, **kwargs)
+ def dts_tester_output(self, msg, *args, **kwargs):
+ self.log(logging.DTS_TESTER_CMD, msg, *args, **kwargs)
- def dcts_tester_result(self, msg, *args, **kwargs):
- self.log(logging.DCTS_TESTER_RESULT, msg, *args, **kwargs)
+ def dts_tester_result(self, msg, *args, **kwargs):
+ self.log(logging.DTS_TESTER_RESULT, msg, *args, **kwargs)
def suite_dut_cmd(self, msg, *args, **kwargs):
self.log(logging.SUITE_DUT_CMD, msg, *args, **kwargs)
@@ -86,30 +126,33 @@ class BaseLoggerAdapter(logging.LoggerAdapter):
def suite_tester_output(self, msg, *args, **kwargs):
self.log(logging.SUITE_TESTER_OUTPUT, msg, *args, **kwargs)
- def dcts_ixia_cmd(self, msg, *args, **kwargs):
- self.log(logging.DCTS_IXIA_CMD, msg, *args, **kwargs)
+ def dts_ixia_cmd(self, msg, *args, **kwargs):
+ self.log(logging.DTS_IXIA_CMD, msg, *args, **kwargs)
- def dcts_ixia_output(self, msg, *args, **kwargs):
- self.log(logging.DCTS_IXIA_OUTPUT, msg, *args, **kwargs)
+ def dts_ixia_output(self, msg, *args, **kwargs):
+ self.log(logging.DTS_IXIA_OUTPUT, msg, *args, **kwargs)
class ColorHandler(logging.StreamHandler):
+ """
+ Color of DTS log format.
+ """
LEVEL_COLORS = {
logging.DEBUG: '', # SYSTEM
- logging.DCTS_DUT_OUTPUT: '\033[00;37m', # WHITE
- logging.DCTS_TESTER_OUTPUT: '\033[00;37m', # WHITE
+ logging.DTS_DUT_OUTPUT: '\033[00;37m', # WHITE
+ logging.DTS_TESTER_OUTPUT: '\033[00;37m', # WHITE
logging.SUITE_DUT_OUTPUT: '\033[00;37m', # WHITE
logging.SUITE_TESTER_OUTPUT: '\033[00;37m', # WHITE
logging.INFO: '\033[00;36m', # CYAN
- logging.DCTS_DUT_CMD: '', # SYSTEM
- logging.DCTS_TESTER_CMD: '', # SYSTEM
+ logging.DTS_DUT_CMD: '', # SYSTEM
+ logging.DTS_TESTER_CMD: '', # SYSTEM
logging.SUITE_DUT_CMD: '', # SYSTEM
logging.SUITE_TESTER_CMD: '', # SYSTEM
- logging.DCTS_IXIA_CMD: '', # SYSTEM
- logging.DCTS_IXIA_OUTPUT: '', # SYSTEM
+ logging.DTS_IXIA_CMD: '', # SYSTEM
+ logging.DTS_IXIA_OUTPUT: '', # SYSTEM
logging.WARN: '\033[01;33m', # BOLD YELLOW
- logging.DCTS_DUT_RESULT: '\033[01;34m', # BOLD BLUE
- logging.DCTS_TESTER_RESULT: '\033[01;34m', # BOLD BLUE
+ logging.DTS_DUT_RESULT: '\033[01;34m', # BOLD BLUE
+ logging.DTS_TESTER_RESULT: '\033[01;34m', # BOLD BLUE
logging.ERROR: '\033[01;31m', # BOLD RED
logging.CRITICAL: '\033[01;31m', # BOLD RED
}
@@ -119,10 +162,9 @@ class ColorHandler(logging.StreamHandler):
return logging.StreamHandler.format(self, record)
-class DCTSLOG(BaseLoggerAdapter):
-
+class DTSLOG(BaseLoggerAdapter):
"""
- dcts log class for framework and testsuite
+ DTS log class for framework and testsuite.
"""
def __init__(self, logger, crb="suite"):
@@ -138,24 +180,32 @@ class DCTSLOG(BaseLoggerAdapter):
if log_dir is None:
self.log_path = os.getcwd() + "/../output"
else:
- self.log_path = log_dir # log dir should contain tag/crb global value and mod in dcts
- self.dcts_log = "dcts.log"
+ self.log_path = log_dir # log dir should contain tag/crb global value and mod in dts
+ self.dts_log = "dts.log"
self.logger = logger
self.logger.setLevel(logging.DEBUG)
self.crb = crb
- super(DCTSLOG, self).__init__(self.logger, dict(crb=self.crb))
+ super(DTSLOG, self).__init__(self.logger, dict(crb=self.crb))
self.fh = None
self.ch = None
def __log_hander(self, fh, ch):
+ """
+ Config stream handler and file handler.
+ """
fh.setFormatter(logging.Formatter(message_fmt, date_fmt))
ch.setFormatter(logging.Formatter(stream_fmt, date_fmt))
fh.setLevel(logging.DEBUG) # file hander default level
- ch.setLevel(logging.INFO) # console handler default level
+ global verbose
+ if verbose is True:
+ ch.setLevel(logging.DEBUG)
+ else:
+ ch.setLevel(logging.INFO) # console handler default level
+
self.logger.addHandler(fh)
self.logger.addHandler(ch)
@@ -168,43 +218,69 @@ class DCTSLOG(BaseLoggerAdapter):
self.ch = ch
def warning(self, message):
+ """
+ DTS warnning level log function.
+ """
self.logger.log(self.warn_lvl, message)
def info(self, message):
+ """
+ DTS information level log function.
+ """
self.logger.log(self.info_lvl, message)
def error(self, message):
+ """
+ DTS error level log function.
+ """
self.logger.log(self.error_lvl, message)
def debug(self, message):
+ """
+ DTS debug level log function.
+ """
self.logger.log(self.debug_lvl, message)
def set_logfile_path(self, path):
+ """
+ Configure the log file path.
+ """
self.log_path = path
def set_stream_level(self, lvl):
+ """
+ Configure the stream level, logger level >= stream level will be
+ output on the screen.
+ """
self.ch.setLevel(lvl)
def set_logfile_level(self, lvl):
+ """
+ Configure the file handler level, logger level >= logfile level will
+ be saved into log file.
+ """
self.fh.setLevel(lvl)
def config_execution(self, crb):
- log_file = self.log_path + '/' + self.dcts_log
+ """
+ Reconfigure stream&logfile level and reset info,debug,warn level.
+ """
+ log_file = self.log_path + '/' + self.dts_log
fh = logging.FileHandler(log_file)
ch = ColorHandler()
self.__log_hander(fh, ch)
if crb == "dut":
- self.info_lvl = logging.DCTS_DUT_CMD
- self.debug_lvl = logging.DCTS_DUT_OUTPUT
- self.warn_lvl = logging.DCTS_DUT_RESULT
+ self.info_lvl = logging.DTS_DUT_CMD
+ self.debug_lvl = logging.DTS_DUT_OUTPUT
+ self.warn_lvl = logging.DTS_DUT_RESULT
elif crb == "tester":
- self.info_lvl = logging.DCTS_TESTER_CMD
- self.debug_lvl = logging.DCTS_TESTER_OUTPUT
- self.warn_lvl = logging.DCTS_TESTER_RESULT
+ self.info_lvl = logging.DTS_TESTER_CMD
+ self.debug_lvl = logging.DTS_TESTER_OUTPUT
+ self.warn_lvl = logging.DTS_TESTER_RESULT
elif crb == "ixia":
- self.info_lvl = logging.DCTS_IXIA_CMD
- self.debug_lvl = logging.DCTS_IXIA_OUTPUT
+ self.info_lvl = logging.DTS_IXIA_CMD
+ self.debug_lvl = logging.DTS_IXIA_OUTPUT
else:
self.error_lvl = logging.ERROR
self.warn_lvl = logging.WARNING
@@ -212,6 +288,9 @@ class DCTSLOG(BaseLoggerAdapter):
self.debug_lvl = logging.DEBUG
def config_suite(self, suitename, crb=None):
+ """
+ Reconfigure stream&logfile level and reset info,debug level.
+ """
log_file = self.log_path + '/' + suitename + '.log'
fh = logging.FileHandler(log_file)
ch = ColorHandler()
@@ -224,10 +303,13 @@ class DCTSLOG(BaseLoggerAdapter):
self.info_lvl = logging.SUITE_TESTER_CMD
self.debug_lvl = logging.SUITE_TESTER_OUTPUT
elif crb == "ixia":
- self.info_lvl = logging.DCTS_IXIA_CMD
- self.debug_lvl = logging.DCTS_IXIA_OUTPUT
+ self.info_lvl = logging.DTS_IXIA_CMD
+ self.debug_lvl = logging.DTS_IXIA_OUTPUT
def logger_exit(self):
+ """
+ Remove stream handler and logfile handler.
+ """
if self.fh is not None:
self.logger.removeHandler(self.fh)
if self.ch is not None:
@@ -235,7 +317,10 @@ class DCTSLOG(BaseLoggerAdapter):
def getLogger(name, crb="suite"):
- logger = DCTSLOG(logging.getLogger(name), crb)
+ """
+ Get logger handler and if there's no handler for specified CRB will create one.
+ """
+ logger = DTSLOG(logging.getLogger(name), crb)
return logger
@@ -246,6 +331,9 @@ _TESTCASE_RESULT_FORMAT_PATTERN = r'Test Case (.*) Result (.*):'
class LogParser(object):
+ """
+ Module for parsing saved log file, will implement later.
+ """
def __init__(self, log_path):
self.log_path = log_path
@@ -320,7 +408,7 @@ class LogParser(object):
def parse_logfile(self):
loglist = []
- out_type = 'DCTS_DUT_OUTPUT'
+ out_type = 'DTS_DUT_OUTPUT'
for line in self.log_handler:
tmp = {}
line = line.replace('\n', '')
diff --git a/framework/main.py b/framework/main.py
index 2db86ef..21815dd 100755
--- a/framework/main.py
+++ b/framework/main.py
@@ -1,6 +1,34 @@
#!/usr/bin/python
-
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
A test framework for testing DPDK.
@@ -8,7 +36,7 @@ A test framework for testing DPDK.
import os
import argparse
-import dcts
+import dts
def git_build_package(gitLabel, gitPkg, output):
@@ -49,7 +77,7 @@ parser.add_argument('--snapshot',
parser.add_argument('--output',
default='../output',
- help='Output directory where dcts log and result saved')
+ help='Output directory where dts log and result saved')
parser.add_argument('-s', '--skip-setup',
action='store_true',
@@ -78,6 +106,9 @@ parser.add_argument('-d', '--dir',
default='dpdk',
help='Output directory where dpdk package is extracted')
+parser.add_argument('-v', '--verbose',
+ action='store_true',
+ help='enable verbose output, all message output on screen')
args = parser.parse_args()
@@ -86,7 +117,7 @@ args = parser.parse_args()
if args.git is not None:
git_build_package(args.git, args.snapshot, args.output)
-dcts.run_all(args.config_file, args.snapshot, args.git,
- args.patch, args.skip_setup, args.read_cache,
- args.project, args.suite_dir, args.test_cases,
- args.dir, args.output)
+dts.run_all(args.config_file, args.snapshot, args.git,
+ args.patch, args.skip_setup, args.read_cache,
+ args.project, args.suite_dir, args.test_cases,
+ args.dir, args.output, args.verbose)
diff --git a/framework/plotgraph.py b/framework/plotgraph.py
index 64454e1..07e849b 100644
--- a/framework/plotgraph.py
+++ b/framework/plotgraph.py
@@ -1,3 +1,34 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
import math
import matplotlib as mp
mp.use('Agg')
@@ -133,7 +164,7 @@ class Plot2DGraph:
self.child.close(force=True)
self.child = None
-#
+
#
# Setup/add data functions
#
diff --git a/framework/plotting.py b/framework/plotting.py
index c70bd35..a9f5d2c 100644
--- a/framework/plotting.py
+++ b/framework/plotting.py
@@ -1,9 +1,36 @@
-#!/usr/bin/python
-
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
-import dcts
+import dts
import shutil
from plotgraph import Plot2DGraph
from docutils.parsers.rst.directives import path
@@ -67,7 +94,7 @@ class Plotting(object):
self.plots_path = path
except Exception as e:
- raise dcts.VerifyFailure("Plot Error: " + str(e))
+ raise dts.VerifyFailure("Plot Error: " + str(e))
def clear_all_plots(self, crb, target):
shutil.rmtree(self.plots_path, True)
@@ -78,7 +105,7 @@ class Plotting(object):
for yseries in ydata:
if len(xdata) != len(yseries):
- print dcts.RED("The number of items in X axis (%s) and Y axis (%s) does not match." % (xdata, ydata))
+ print dts.RED("The number of items in X axis (%s) and Y axis (%s) does not match." % (xdata, ydata))
return ''
image_path = "%s/%s.%s" % (self.plots_path, image_filename,
diff --git a/framework/pmd_output.py b/framework/pmd_output.py
index 49213bd..97274a5 100644
--- a/framework/pmd_output.py
+++ b/framework/pmd_output.py
@@ -1,5 +1,37 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
import os
import re
+import dts
class PmdOutput():
@@ -20,6 +52,8 @@ class PmdOutput():
self.tx_pkts_prefix = "TX-packets:"
self.tx_error_prefix = "TX-errors:"
self.tx_bytes_prefix = "TX-bytes:"
+ self.bad_ipcsum_prefix = "Bad-ipcsum:"
+ self.bad_l4csum_prefix = "Bad-l4csum:"
def get_pmd_value(self, prefix, out):
pattern = re.compile(prefix + "(\s+)([0-9]+)")
@@ -43,4 +77,20 @@ class PmdOutput():
stats["TX-packets"] = self.get_pmd_value(self.tx_pkts_prefix, out)
stats["TX-errors"] = self.get_pmd_value(self.tx_error_prefix, out)
stats["TX-bytes"] = self.get_pmd_value(self.tx_bytes_prefix, out)
+
+ # display when testpmd config forward engine to csum
+ stats["Bad-ipcsum"] = self.get_pmd_value(self.bad_ipcsum_prefix, out)
+ stats["Bad-l4csum"] = self.get_pmd_value(self.bad_l4csum_prefix, out)
return stats
+
+ def get_pmd_cmd(self):
+ return self.command
+
+ def start_testpmd(self, cores, param='', eal_param='', socket=0):
+ core_list = self.dut.get_core_list(cores, socket)
+ self.coremask = dts.create_mask(core_list)
+ command = "./%s/app/testpmd -c %s -n %d %s -- -i %s" \
+ % (self.dut.target, self.coremask, self.dut.get_memory_channels(), eal_param, param)
+ out = self.dut.send_expect(command, "testpmd> ", 120)
+ self.command = command
+ return out
diff --git a/framework/project_dpdk.py b/framework/project_dpdk.py
index 6b48208..5f4fcc7 100644
--- a/framework/project_dpdk.py
+++ b/framework/project_dpdk.py
@@ -1,8 +1,37 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
import re
-import dcts
+import dts
from settings import NICS
from ssh_connection import SSHConnection
@@ -16,7 +45,7 @@ from settings import IXIA
class DPDKdut(Dut):
"""
- DPDK project class for DUT. DCTS will call set_target function to setup
+ DPDK project class for DUT. DTS will call set_target function to setup
build, memory and kernel module.
"""
@@ -25,14 +54,18 @@ class DPDKdut(Dut):
super(DPDKdut, self).__init__(crb, serializer)
def set_target(self, target):
+ """
+ Set env variable, these have to be setup all the time. Some tests
+ need to compile example apps by themselves and will fail otherwise.
+ Set hugepage on DUT and install modules required by DPDK.
+ Configure default ixgbe PMD function.
+ """
self.set_toolchain(target)
- # set env variable
- # These have to be setup all the time. Some tests need to compile
- # example apps by themselves and will fail otherwise.
self.send_expect("export RTE_TARGET=" + target, "#")
self.send_expect("export RTE_SDK=`pwd`", "#")
+ self.set_rxtx_mode()
if not self.skip_setup:
self.build_install_dpdk(target)
@@ -40,24 +73,39 @@ class DPDKdut(Dut):
self.setup_modules(target)
if self.get_os_type() == 'linux':
- self.bind_interfaces_linux()
+ self.bind_interfaces_linux(dts.drivername)
def setup_modules(self, target):
+ """
+ Install DPDK required kernel module on DUT.
+ """
setup_modules = getattr(self, 'setup_modules_%s' % self.get_os_type())
setup_modules(target)
def setup_modules_linux(self, target):
- self.send_expect("modprobe uio", "#", 70)
- self.send_expect("rmmod -f igb_uio", "#", 70)
- self.send_expect("insmod ./" + target + "/kmod/igb_uio.ko", "#", 60)
- out = self.send_expect("lsmod | grep igb_uio", "#")
- assert ("igb_uio" in out), "Failed to insmod igb_uio"
+ if dts.drivername == "vfio-pci":
+ self.send_expect("rmmod vfio_pci", "#", 70)
+ self.send_expect("rmmod vfio_iommu_type1", "#", 70)
+ self.send_expect("rmmod vfio", "#", 70)
+ self.send_expect("modprobe vfio", "#", 70)
+ self.send_expect("modprobe vfio-pci", "#", 70)
+ out = self.send_expect("lsmod | grep vfio_iommu_type1", "#")
+ assert ("vfio_iommu_type1" in out), "Failed to setup vfio-pci"
+ else:
+ self.send_expect("modprobe uio", "#", 70)
+ self.send_expect("rmmod -f igb_uio", "#", 70)
+ self.send_expect("insmod ./" + target + "/kmod/igb_uio.ko", "#", 60)
+ out = self.send_expect("lsmod | grep igb_uio", "#")
+ assert ("igb_uio" in out), "Failed to insmod igb_uio"
def setup_modules_freebsd(self, target):
+ """
+ Install DPDK required Freebsd kernel module on DUT.
+ """
binding_list = ''
for (pci_bus, pci_id) in self.pci_devices_info:
- if dcts.accepted_nic(pci_id):
+ if dts.accepted_nic(pci_id):
binding_list += '%s,' % (pci_bus)
self.send_expect("kldunload if_ixgbe.ko", "#")
@@ -66,11 +114,43 @@ class DPDKdut(Dut):
out = self.send_expect("kldstat", "#")
assert ("nic_uio" in out), "Failed to insmod nic_uio"
+ def set_rxtx_mode(self):
+ """
+ Set default RX/TX PMD function, now only take effect on ixgbe.
+ """
+ [arch, machine, env, toolchain] = self.target.split('-')
+ if 'mode' not in self.crb:
+ mode = 'default'
+ else:
+ mode = self.crb['mode']
+
+ if mode is 'scalar':
+ self.send_expect("sed -i -e 's/CONFIG_RTE_IXGBE_INC_VECTOR=.*$/"
+ + "CONFIG_RTE_IXGBE_INC_VECTOR=n/' config/common_%s" % env, "# ", 30)
+ self.send_expect("sed -i -e 's/CONFIG_RTE_LIBRTE_IXGBE_RX_ALLOW_BULK_ALLOC=.*$/"
+ + "CONFIG_RTE_LIBRTE_IXGBE_RX_ALLOW_BULK_ALLOC=y/' config/common_%s" % env, "# ", 30)
+ if mode is 'full':
+ self.send_expect("sed -i -e 's/CONFIG_RTE_IXGBE_INC_VECTOR=.*$/"
+ + "CONFIG_RTE_IXGBE_INC_VECTOR=n/' config/common_%s" % env, "# ", 30)
+ self.send_expect("sed -i -e 's/CONFIG_RTE_LIBRTE_IXGBE_RX_ALLOW_BULK_ALLOC=.*$/"
+ + "CONFIG_RTE_LIBRTE_IXGBE_RX_ALLOW_BULK_ALLOC=n/' config/common_%s" % env, "# ", 30)
+ if mode is 'vector':
+ self.send_expect("sed -i -e 's/CONFIG_RTE_IXGBE_INC_VECTOR=.*$/"
+ + "CONFIG_RTE_IXGBE_INC_VECTOR=y/' config/common_%s" % env, "# ", 30)
+ self.send_expect("sed -i -e 's/CONFIG_RTE_LIBRTE_IXGBE_RX_ALLOW_BULK_ALLOC=.*$/"
+ + "CONFIG_RTE_LIBRTE_IXGBE_RX_ALLOW_BULK_ALLOC=y/' config/common_%s" % env, "# ", 30)
+
def build_install_dpdk(self, target, extra_options=''):
+ """
+ Build DPDK source code with specified target.
+ """
build_install_dpdk = getattr(self, 'build_install_dpdk_%s' % self.get_os_type())
build_install_dpdk(target, extra_options)
def build_install_dpdk_linux(self, target, extra_options):
+ """
+ Build DPDK source code on linux with specified target.
+ """
# clean all
self.send_expect("rm -rf " + target, "#")
@@ -86,6 +166,9 @@ class DPDKdut(Dut):
assert ("No rule to make" not in out), "No rule to make error..."
def build_install_dpdk_freebsd(self, target, extra_options):
+ """
+ Build DPDK source code on Freebsd with specified target.
+ """
# clean all
self.send_expect("rm -rf " + target, "#")
@@ -104,6 +187,9 @@ class DPDKdut(Dut):
assert ("No rule to make" not in out), "No rule to make error..."
def prerequisites(self, pkgName, patch):
+ """
+ Copy DPDK package to DUT and apply patch files.
+ """
if not self.skip_setup:
assert (os.path.isfile(pkgName) is True), "Invalid package"
@@ -146,7 +232,7 @@ class DPDKdut(Dut):
current_nic = 0
for (pci_bus, pci_id) in self.pci_devices_info:
- if dcts.accepted_nic(pci_id):
+ if dts.accepted_nic(pci_id):
if nics_to_bind is None or current_nic in nics_to_bind:
binding_list += '%s ' % (pci_bus)
@@ -164,7 +250,7 @@ class DPDKdut(Dut):
current_nic = 0
for (pci_bus, pci_id) in self.pci_devices_info:
- if dcts.accepted_nic(pci_id):
+ if dts.accepted_nic(pci_id):
if nics_to_bind is None or current_nic in nics_to_bind:
binding_list += '%s ' % (pci_bus)
@@ -174,22 +260,37 @@ class DPDKdut(Dut):
self.send_expect('tools/dpdk_nic_bind.py %s' % binding_list, '# ', 30)
def build_dpdk_apps(self, folder, extra_options=''):
+ """
+ Build dpdk sample applications.
+ """
build_dpdk_apps = getattr(self, 'build_dpdk_apps_%s' % self.get_os_type())
return build_dpdk_apps(folder, extra_options)
def build_dpdk_apps_linux(self, folder, extra_options):
+ """
+ Build dpdk sample applications on linux.
+ """
return self.send_expect("make -j -C %s %s" % (folder, extra_options),
"# ", 90)
def build_dpdk_apps_freebsd(self, folder, extra_options):
+ """
+ Build dpdk sample applications on Freebsd.
+ """
return self.send_expect("make -j -C %s %s CC=gcc48" % (folder, extra_options),
"# ", 90)
- def create_blacklist_string(self, target, nic):
- create_blacklist_string = getattr(self, 'create_blacklist_string_%s' % self.get_os_type())
- return create_blacklist_string(target, nic)
+ def get_blacklist_string(self, target, nic):
+ """
+ Get black list command string.
+ """
+ get_blacklist_string = getattr(self, 'get_blacklist_string_%s' % self.get_os_type())
+ return get_blacklist_string(target, nic)
- def create_blacklist_string_linux(self, target, nic):
+ def get_blacklist_string_linux(self, target, nic):
+ """
+ Get black list command string on Linux.
+ """
blacklist = ''
dutPorts = self.get_ports(nic)
self.restore_interfaces()
@@ -200,7 +301,10 @@ class DPDKdut(Dut):
blacklist += '-b 0000:%s ' % self.ports_info[port]['pci']
return blacklist
- def create_blacklist_string_freebsd(self, target, nic):
+ def get_blacklist_string_freebsd(self, target, nic):
+ """
+ Get black list command string on Freebsd.
+ """
blacklist = ''
# No blacklist option in FreeBSD
return blacklist
@@ -209,7 +313,7 @@ class DPDKdut(Dut):
class DPDKtester(Tester):
"""
- DPDK project class for tester. DCTS will call prerequisites function to setup
+ DPDK project class for tester. DTS will call prerequisites function to setup
interface and generate port map.
"""
@@ -218,6 +322,9 @@ class DPDKtester(Tester):
super(DPDKtester, self).__init__(crb, serializer)
def prerequisites(self, perf_test=False):
+ """
+ Setup hugepage on tester and copy validation required files to tester.
+ """
self.kill_all()
if not self.skip_setup:
@@ -227,9 +334,13 @@ class DPDKtester(Tester):
self.set_huge_pages(1024)
self.session.copy_file_to("tgen.tgz")
+ self.session.copy_file_to("tclclient.tgz")
# unpack tgen
out = self.send_expect("tar zxf tgen.tgz", "# ")
assert "Error" not in out
+ # unpack tclclient
+ out = self.send_expect("tar zxf tclclient.tgz", "# ")
+ assert "Error" not in out
self.send_expect("modprobe uio", "# ")
@@ -242,11 +353,13 @@ class DPDKtester(Tester):
self.logger.info("Use hardware packet generator")
except Exception as e:
self.logger.warning("Use default software pktgen")
-
- assert (os.path.isfile("/root/igb_uio.ko") is True), "Can not find igb_uio for performance"
- self.setup_memory()
+ assert (os.path.isfile("/root/igb_uio.ko") is True), "Can not find /root/igb_uio.ko for performance"
+ self.setup_memory()
def setup_memory(self, hugepages=-1):
+ """
+ Setup hugepage on tester.
+ """
hugepages_size = self.send_expect("awk '/Hugepagesize/ {print $2}' /proc/meminfo", "# ")
if int(hugepages_size) < (1024 * 1024):
diff --git a/framework/rst.py b/framework/rst.py
index 5c41809..8c2d6c5 100644
--- a/framework/rst.py
+++ b/framework/rst.py
@@ -1,9 +1,36 @@
-#!/usr/bin/python
-
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
-import dcts
+import dts
import shutil
import re
@@ -65,7 +92,7 @@ def generate_results_rst(crbName, target, nic, suite, perf=False):
rstReport.close()
except Exception as e:
- raise dcts.VerifyFailure("RST Error: " + str(e))
+ raise dts.VerifyFailure("RST Error: " + str(e))
def clear_all_rst(crbName, target):
diff --git a/framework/serializer.py b/framework/serializer.py
index d4aeaf1..2f0545d 100644
--- a/framework/serializer.py
+++ b/framework/serializer.py
@@ -1,4 +1,33 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
Wrapper class for serializer module
diff --git a/framework/settings.py b/framework/settings.py
index 994151d..0d4ed82 100644
--- a/framework/settings.py
+++ b/framework/settings.py
@@ -1,4 +1,33 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
Nics and its identifiers supported by the framework.
@@ -58,8 +87,6 @@ SCAPY2IXIA = [
'SCTP'
]
-"""
-"""
USERNAME = 'root'
@@ -82,6 +109,6 @@ TIMEOUT = 15
"""
-Global macro for dcts.
+Global macro for dts.
"""
IXIA = "ixia"
diff --git a/framework/ssh_connection.py b/framework/ssh_connection.py
index dfdad2f..be1fb76 100644
--- a/framework/ssh_connection.py
+++ b/framework/ssh_connection.py
@@ -1,4 +1,33 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from ssh_pexpect import SSHPexpect
from settings import USERNAME
diff --git a/framework/ssh_pexpect.py b/framework/ssh_pexpect.py
index 4efa5de..8fb441b 100644
--- a/framework/ssh_pexpect.py
+++ b/framework/ssh_pexpect.py
@@ -1,5 +1,3 @@
-# <COPYRIGHT_TAG>
-
import time
import pexpect
import pxssh
@@ -37,8 +35,7 @@ class SSHPexpect(object):
def __prompt(self, command, timeout):
if not self.session.prompt(timeout):
- self.session.read(len(self.session.before))
- raise TimeoutException(command, self.get_output_before())
+ raise TimeoutException(command, self.get_output_all())
def __sendline(self, command):
if len(command) == 2 and command.startswith('^'):
@@ -54,6 +51,12 @@ class SSHPexpect(object):
return before[0]
+ def get_output_all(self):
+ self.session.flush()
+ output = self.session.before
+ output.replace("[PEXPECT]", "")
+ return output
+
def close(self):
if self.isalive():
self.session.logout()
@@ -75,6 +78,13 @@ class SSHPexpect(object):
command = 'scp {0} {1}@{2}:'.format(filename, self.username, self.host)
self._spawn_scp(command, password)
+ def copy_file_from(self, filename, password=''):
+ """
+ copy a remote file to a local place.
+ """
+ command = 'scp {1}@{2}:{0} .'.format(filename, self.username, self.host)
+ self._spawn_scp(command, password)
+
def _spawn_scp(self, scp_cmd, password):
"""
Transfer a file with SCP
@@ -84,7 +94,7 @@ class SSHPexpect(object):
time.sleep(0.5)
ssh_newkey = 'Are you sure you want to continue connecting'
i = p.expect([ssh_newkey, 'password: ', "# ", pexpect.EOF,
- pexpect.TIMEOUT], 8)
+ pexpect.TIMEOUT], 120)
if i == 0: # add once in trust list
p.sendline('yes')
i = p.expect([ssh_newkey, '[pP]assword: ', pexpect.EOF], 2)
diff --git a/framework/stats_reporter.py b/framework/stats_reporter.py
index 83b8a38..3793ca5 100644
--- a/framework/stats_reporter.py
+++ b/framework/stats_reporter.py
@@ -1,4 +1,33 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
Simple text file statistics generator
diff --git a/framework/tclclient.tgz b/framework/tclclient.tgz
new file mode 100644
index 0000000..f4de955
--- /dev/null
+++ b/framework/tclclient.tgz
Binary files differ
diff --git a/framework/test_case.py b/framework/test_case.py
index 6181003..706003f 100644
--- a/framework/test_case.py
+++ b/framework/test_case.py
@@ -1,4 +1,33 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
A base class for creating DTF test cases.
diff --git a/framework/test_result.py b/framework/test_result.py
index 1c133eb..79faee1 100644
--- a/framework/test_result.py
+++ b/framework/test_result.py
@@ -1,4 +1,33 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
Generic result container and reporters
diff --git a/framework/tester.py b/framework/tester.py
index 96a823f..3554271 100644
--- a/framework/tester.py
+++ b/framework/tester.py
@@ -1,8 +1,36 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
Interface for bulk traffic generators.
-
"""
import re
@@ -12,15 +40,16 @@ from ssh_connection import SSHConnection
from crb import Crb
from etgen import IxiaPacketGenerator, SoftwarePacketGenerator
from logger import getLogger
-
-"""
-Start the DPDK traffic generator on the machine `target`.
-A config file and pcap file must have previously been copied
-to this machine.
-"""
+from settings import IXIA
class Tester(Crb):
+
+ """
+ Start the DPDK traffic generator on the machine `target`.
+ A config file and pcap file must have previously been copied
+ to this machine.
+ """
PORT_MAP_CACHE_KEY = 'tester_port_map'
PORT_INFO_CACHE_KEY = 'tester_port_info'
CORE_LIST_CACHE_KEY = 'tester_core_list'
@@ -46,17 +75,51 @@ class Tester(Crb):
self.bgItf = ''
def init_ext_gen(self):
+ """
+ Initialize tester packet generator object.
+ """
if self.it_uses_external_generator():
self.ixia_packet_gen = IxiaPacketGenerator(self)
self.packet_gen = SoftwarePacketGenerator(self)
def get_ip_address(self):
+ """
+ Get ip address of tester CRB.
+ """
return self.crb['tester IP']
+ def has_external_traffic_generator(self):
+ """
+ Check whether performance test will base on IXIA equipment.
+ """
+ try:
+ if self.crb[IXIA] is not None:
+ return True
+ except Exception as e:
+ return False
+
+ return False
+
+ def get_external_traffic_generator(self):
+ """
+ Return IXIA object.
+ """
+ return self.crb[IXIA]
+
def it_uses_external_generator(self):
+ """
+ Check whether IXIA generator is ready for performance test.
+ """
return self.want_perf_tests and self.has_external_traffic_generator()
def tester_prerequisites(self):
+ """
+ Prerequest function should be called before execute any test case.
+ Will call function to scan all lcore's information which on Tester.
+ Then call pci scan function to collect nic device information.
+ Then discovery the network topology and save it into cache file.
+ At last setup DUT' environment for validation.
+ """
self.init_core_list()
self.pci_devices_information()
self.restore_interfaces()
@@ -65,15 +128,27 @@ class Tester(Crb):
assert len(self.ports_map) > 0
def get_local_port(self, remotePort):
+ """
+ Return tester local port connect to specified dut port.
+ """
return self.ports_map[remotePort]
def get_local_port_type(self, remotePort):
+ """
+ Return tester local port type connect to specified dut port.
+ """
return self.ports_info[self.get_local_port(remotePort)]['type']
def get_interface(self, localPort):
+ """
+ Return tester local port interface name.
+ """
return self.ports_info[localPort]['intf']
def get_mac(self, localPort):
+ """
+ Return tester local port mac address.
+ """
if self.ports_info[localPort]['type'] == 'ixia':
return "00:00:00:00:00:01"
else:
@@ -81,7 +156,7 @@ class Tester(Crb):
def get_port_status(self, port):
"""
- return link status of eth
+ Return link status of ethernet.
"""
eth = self.ports_info[port]['intf']
out = self.send_expect("ethtool %s" % eth, "# ")
@@ -96,6 +171,9 @@ class Tester(Crb):
return 'down'
def scan_ports(self):
+ """
+ Scan all ports on tester and save port's pci/mac/interface.
+ """
if self.read_cache:
self.ports_info = self.serializer.load(self.PORT_INFO_CACHE_KEY)
@@ -108,6 +186,9 @@ class Tester(Crb):
self.logger.info(self.ports_info)
def scan_ports_uncached(self):
+ """
+ Return tester port pci/mac/interface information.
+ """
self.ports_info = []
self.logger.warning("Skipped: Unknown kernel interface")
@@ -141,12 +222,18 @@ class Tester(Crb):
'mac': macaddr})
def send_ping6(self, localPort, ipv6, mac):
+ """
+ Send ping6 packet from local port with destination ipv6 address.
+ """
if self.ports_info[localPort]['type'] == 'ixia':
return self.ixia_packet_gen.send_ping6(self.ports_info[localPort]['intf'], mac, ipv6)
else:
return self.send_expect("ping6 -w 5 -c 5 -A -I %s %s" % (self.ports_info[localPort]['intf'], ipv6), "# ", 10)
def map_available_ports(self):
+ """
+ Load or generate network connection mapping list.
+ """
if self.read_cache:
self.ports_map = self.serializer.load(self.PORT_MAP_CACHE_KEY)
@@ -156,6 +243,9 @@ class Tester(Crb):
self.logger.warning("DUT PORT MAP: " + str(self.ports_map))
def map_available_ports_uncached(self):
+ """
+ Generate network connection mapping list.
+ """
nrPorts = len(self.dut.ports_info)
if nrPorts == 0:
@@ -183,11 +273,17 @@ class Tester(Crb):
break
def get_port_numa(self, port):
+ """
+ Return tester local port numa.
+ """
pci = self.ports_info[port]['pci']
out = self.send_expect("cat /sys/bus/pci/devices/0000:%s/numa_node" % pci, "#")
return int(out)
def check_port_list(self, portList, ftype='normal'):
+ """
+ Check specified port is IXIA port or normal port.
+ """
dtype = None
plist = set()
for txPort, rxPort, _ in portList:
@@ -208,9 +304,15 @@ class Tester(Crb):
return True
def scapy_append(self, cmd):
+ """
+ Append command into scapy command list.
+ """
self.scapyCmds.append(cmd)
def scapy_execute(self, timeout=60):
+ """
+ Execute scapy command list.
+ """
self.kill_all()
self.send_expect("scapy", ">>> ")
@@ -227,9 +329,16 @@ class Tester(Crb):
self.send_expect("exit()", "# ")
def scapy_background(self):
+ """
+ Configure scapy running in backgroud mode which mainly purpose is
+ that save RESULT into scapyResult.txt.
+ """
self.inBg = True
def scapy_foreground(self):
+ """
+ Running backgroup scapy and convert to foregroup mode.
+ """
self.send_expect("echo -n '' > scapyResult.txt", "# ")
if self.inBg:
self.scapyCmds.append('f = open(\'scapyResult.txt\',\'w\')')
@@ -249,12 +358,18 @@ class Tester(Crb):
self.inBg = False
def scapy_get_result(self):
+ """
+ Return RESULT which saved in scapyResult.txt.
+ """
out = self.send_expect("cat scapyResult.txt", "# ")
self.logger.info('SCAPY Result:\n' + out + '\n\n\n')
return out.rpartition('[')[0]
def traffic_generator_throughput(self, portList, rate_percent=100, delay=5):
+ """
+ Run throughput performance test on specified ports.
+ """
if self.check_port_list(portList, 'ixia'):
return self.ixia_packet_gen.throughput(portList, rate_percent, delay)
if not self.check_port_list(portList):
@@ -263,6 +378,9 @@ class Tester(Crb):
return self.packet_gen.throughput(portList, rate_percent)
def traffic_generator_loss(self, portList, ratePercent):
+ """
+ Run loss performance test on specified ports.
+ """
if self.check_port_list(portList, 'ixia'):
return self.ixia_packet_gen.loss(portList, ratePercent)
elif not self.check_port_list(portList):
@@ -271,12 +389,18 @@ class Tester(Crb):
return self.packet_gen.loss(portList, ratePercent)
def traffic_generator_latency(self, portList, ratePercent=100, delay=5):
+ """
+ Run latency performance test on specified ports.
+ """
if self.check_port_list(portList, 'ixia'):
return self.ixia_packet_gen.latency(portList, ratePercent, delay)
else:
return None
def extend_external_packet_generator(self, clazz, instance):
+ """
+ Update packet generator function, will implement later.
+ """
if self.it_uses_external_generator():
self.ixia_packet_gen.__class__ = clazz
current_attrs = instance.__dict__
@@ -284,11 +408,17 @@ class Tester(Crb):
instance.__dict__.update(current_attrs)
def kill_all(self):
+ """
+ Kill all scapy process and DPDK applications on tester.
+ """
if not self.has_external_traffic_generator():
self.alt_session.send_expect('killall scapy 2>/dev/null; echo tester', '# ', 5)
super(Tester, self).kill_all()
def close(self):
+ """
+ Close ssh session and IXIA tcl session.
+ """
super(Tester, self).close()
if self.it_uses_external_generator():
self.ixia_packet_gen.close()
diff --git a/tests/TestSuite_blacklist.py b/tests/TestSuite_blacklist.py
index a7e5ca3..510a2ad 100644
--- a/tests/TestSuite_blacklist.py
+++ b/tests/TestSuite_blacklist.py
@@ -1,4 +1,33 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
@@ -7,24 +36,15 @@ Test device blacklisting.
"""
-import dcts
+import dts
from test_case import TestCase
+from pmd_output import PmdOutput
-#
-#
-# Test class.
-#
class TestBlacklist(TestCase):
- #
- #
- #
- # Test cases.
- #
-
def set_up_all(self):
"""
Run at the start of each test suite.
@@ -37,6 +57,7 @@ class TestBlacklist(TestCase):
self.ports = self.dut.get_ports(self.nic)
self.verify(len(self.ports) >= 2, "Insufficient ports for testing")
self.regexp_blacklisted_port = "EAL: PCI device 0000:%s on NUMA socket [-0-9]+[^\n]*\nEAL: probe driver[^\n]*\nEAL: Device is blacklisted, not initializing"
+ self.pmdout = PmdOutput(self.dut)
def set_up(self):
"""
@@ -53,13 +74,12 @@ class TestBlacklist(TestCase):
in `ports` have not been blacklisted.
"""
for port in ports:
-
# Look for the PCI ID of each card followed by
# "Device is blacklisted, not initializing" but avoid to consume more
# than one device.
regexp_blacklisted_port = self.regexp_blacklisted_port % self.dut.ports_info[port]['pci']
- matching_ports = dcts.regexp(output, regexp_blacklisted_port, True)
+ matching_ports = dts.regexp(output, regexp_blacklisted_port, True)
if blacklisted:
self.verify(len(matching_ports) == 1,
@@ -72,11 +92,9 @@ class TestBlacklist(TestCase):
"""
Run testpmd with no blacklisted device.
"""
-
- cmdline = r"./%s/build/app/test-pmd/testpmd -n 1 -c 3 -- -i" % self.target
- out = self.dut.send_expect(cmdline, "testpmd> ", 120)
+ out = self.pmdout.start_testpmd("all")
rexp = r"Link"
- match_status = dcts.regexp(out, rexp, True)
+ match_status = dts.regexp(out, rexp, True)
self.check_blacklisted_ports(out, self.ports)
@@ -86,8 +104,7 @@ class TestBlacklist(TestCase):
"""
self.dut.kill_all()
- cmdline = r"./%s/build/app/test-pmd/testpmd -n 1 -c 3 -b 0000:%s -- -i" % (self.target, self.dut.ports_info[0]['pci'])
- out = self.dut.send_expect(cmdline, "testpmd> ", 120)
+ out = self.pmdout.start_testpmd("all", eal_param="-b 0000:%s -- -i" % self.dut.ports_info[0]['pci'])
self.check_blacklisted_ports(out, self.ports[1:])
@@ -99,12 +116,11 @@ class TestBlacklist(TestCase):
ports_to_blacklist = self.ports[:-1]
- cmdline = "./%s/build/app/test-pmd/testpmd -n 1 -c 3" % self.target
+ cmdline = ""
for port in ports_to_blacklist:
cmdline += " -b 0000:%s" % self.dut.ports_info[port]['pci']
- cmdline += " -- -i"
- out = self.dut.send_expect(cmdline, "testpmd> ", 180)
+ out = self.pmdout.start_testpmd("all", eal_param=cmdline)
blacklisted_ports = self.check_blacklisted_ports(out,
ports_to_blacklist,
diff --git a/tests/TestSuite_checksum_offload.py b/tests/TestSuite_checksum_offload.py
index e80c26a..e5ca136 100644
--- a/tests/TestSuite_checksum_offload.py
+++ b/tests/TestSuite_checksum_offload.py
@@ -1,4 +1,33 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
@@ -7,27 +36,17 @@ Test support of RX/TX Checksum Offload Features by Poll Mode Drivers.
"""
-import dcts
+import dts
import string
import re
import rst
from test_case import TestCase
-
-#
-#
-# Test class.
-#
+from pmd_output import PmdOutput
class TestChecksumOffload(TestCase):
- #
- #
- #
- # Test cases.
- #
-
def set_up_all(self):
"""
Run at the start of each test suite.
@@ -44,8 +63,10 @@ class TestChecksumOffload(TestCase):
cores = self.dut.get_core_list("1S/2C/2T")
self.verify(cores is not None, "Insufficient cores for speed testing")
- self.coreMask = dcts.create_mask(cores)
- self.portMask = dcts.create_mask([self.dut_ports[0], self.dut_ports[1]])
+ self.pmdout = PmdOutput(self.dut)
+
+ self.coreMask = dts.create_mask(cores)
+ self.portMask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])
self.ports_socket = self.dut.get_numa_id(self.dut_ports[0])
def set_up(self):
@@ -53,7 +74,7 @@ class TestChecksumOffload(TestCase):
Run before each test case.
"""
if self.dut.want_func_tests:
- self.dut.send_expect("./%s/build/app/test-pmd/testpmd -c %s -n 1 -- -i --burst=1 --txpt=32 --txht=8 --txwt=0 --txfreet=0 --rxfreet=64 --mbcache=250 --portmask=%s --disable-hw-vlan --enable-rx-cksum --crc-strip" % (self.target, self.coreMask, self.portMask), "testpmd>", 120)
+ self.pmdout.start_testpmd("1S/2C/2T", "--portmask=%s " % (self.portMask) + "--disable-hw-vlan --enable-rx-cksum --crc-strip")
self.dut.send_expect("set verbose 1", "testpmd>")
self.dut.send_expect("set fwd csum", "testpmd>")
@@ -250,7 +271,7 @@ class TestChecksumOffload(TestCase):
result.append(Pps[str(size)])
result.append(Pct[str(size)])
- dcts.results_table_add_row(result)
+ dts.results_table_add_row(result)
def test_perf_checksum_throughtput(self):
"""
@@ -269,8 +290,7 @@ class TestChecksumOffload(TestCase):
}
lcore = "1S/2C/1T"
- coreMask = dcts.create_mask(self.dut.get_core_list(lcore, socket=self.ports_socket))
- portMask = dcts.create_mask([self.dut_ports[0], self.dut_ports[1]])
+ portMask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])
for mode in ["sw", "hw"]:
self.logger.info("%s performance" % mode)
@@ -280,9 +300,9 @@ class TestChecksumOffload(TestCase):
tblheader.append("%sB mpps" % str(size))
tblheader.append("%sB %% " % str(size))
- dcts.results_table_add_header(tblheader)
+ dts.results_table_add_header(tblheader)
- self.dut.send_expect("./%s/build/app/test-pmd/testpmd -c%s -n %d -- -i --nb-cores=1 --txpt=40 --txht=4 --txwt=0 --rxfreet=64 --mbcache=250 --portmask=%s" % (self.target, coreMask, self.dut.get_memory_channels(), portMask), "testpmd>", 120)
+ self.pmdout.start_testpmd(lcore, "--portmask=%s" % self.portMask, socket=self.ports_socket)
self.dut.send_expect("set verbose 1", "testpmd> ")
self.dut.send_expect("set fwd csum", "testpmd> ")
@@ -301,7 +321,7 @@ class TestChecksumOffload(TestCase):
self.dut.send_expect("stop", "testpmd> ")
self.dut.send_expect("quit", "#", 10)
- dcts.results_table_print()
+ dts.results_table_print()
def tear_down(self):
"""
diff --git a/tests/TestSuite_cmdline.py b/tests/TestSuite_cmdline.py
index db3f205..7eeed2e 100644
--- a/tests/TestSuite_cmdline.py
+++ b/tests/TestSuite_cmdline.py
@@ -1,31 +1,47 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Test cmdline.
-
"""
-import dcts
+import dts
from test_case import TestCase
-#
-#
-# Test class.
-#
-
class TestCmdline(TestCase):
- #
- #
- #
- # Test cases.
- #
-
def set_up_all(self):
"""
Run at the start of each test suite.
@@ -41,7 +57,7 @@ class TestCmdline(TestCase):
# Run cmdline app
cores = self.dut.get_core_list('1S/1C/1T')
- coreMask = dcts.create_mask(cores)
+ coreMask = dts.create_mask(cores)
self.dut.send_expect("./examples/cmdline/build/app/cmdline -n 1 -c " + coreMask, "> ", 5)
def set_up(self):
diff --git a/tests/TestSuite_fdir.py b/tests/TestSuite_fdir.py
index 61c7091..e7f43e6 100644
--- a/tests/TestSuite_fdir.py
+++ b/tests/TestSuite_fdir.py
@@ -1,29 +1,66 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Test 82599 Flow Director Support in DPDK
"""
-import dcts
+import dts
import time
from test_case import TestCase
-
-#
-#
-# Test class.
-#
+from pmd_output import PmdOutput
class TestFdir(TestCase):
- #
- #
- # Utility methods and other non-test code.
- #
+ def set_up_all(self):
+ """
+ Run at the start of each test suite.
+ """
+ self.verify('bsdapp' not in self.target, "FDIR not support freebsd")
+ self.verify(self.nic in ["kawela", "niantic"], "NIC Unsupported: " + str(self.nic))
+
+ ports = self.dut.get_ports(self.nic)
+ self.verify(len(ports) >= 2, "Not enough ports available")
+
+ self.pmdout = PmdOutput(self.dut)
+
+ def set_up(self):
+ """
+ Run before each test case.
+ """
+ pass
def send_and_verify(self, condition, packet):
"""
@@ -42,27 +79,6 @@ class TestFdir(TestCase):
else:
self.verify("PKT_RX_PKT_RX_FDIR" not in out, "FDIR hash displayed when not required")
- #
- #
- #
- # Test cases.
- #
- def set_up_all(self):
- """
- Run at the start of each test suite.
- """
- self.verify('bsdapp' not in self.target, "FDIR not support freebsd")
- self.verify(self.nic in ["kawela", "niantic"], "NIC Unsupported: " + str(self.nic))
-
- ports = self.dut.get_ports(self.nic)
- self.verify(len(ports) >= 2, "Not enough ports available")
-
- def set_up(self):
- """
- Run before each test case.
- """
- pass
-
def test_fdir_space(self):
"""
Setting memory reserved for FDir filters.
@@ -70,17 +86,17 @@ class TestFdir(TestCase):
dutPorts = self.dut.get_ports(self.nic)
- self.dut.send_expect("./%s/app/testpmd -c 0xff -n 1 -- -i --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-size=64K" % self.target, "testpmd>", 120)
+ self.pmdout.start_testpmd("all", "--rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-size=64K")
out = self.dut.send_expect("show port fdir %s" % dutPorts[0], "testpmd>")
self.dut.send_expect("quit", "# ", 30)
self.verify("free: 2048" in out, "Free space doesn't match the expected value")
- self.dut.send_expect("./%s/app/testpmd -c 0xff -n 1 -- -i --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-size=128K" % self.target, "testpmd>", 120)
+ self.pmdout.start_testpmd("all", "--rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-size=128K")
out = self.dut.send_expect("show port fdir %s" % dutPorts[0], "testpmd>")
self.dut.send_expect("quit", "# ", 30)
self.verify("free: 4096" in out, "Free space doesn't match the expected value")
- self.dut.send_expect("./%s/app/testpmd -c 0xff -n 1 -- -i --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-size=256K" % self.target, "testpmd>", 120)
+ self.pmdout.start_testpmd("all", "--rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-size=256K")
out = self.dut.send_expect("show port fdir %s" % dutPorts[0], "testpmd>")
self.dut.send_expect("quit", "# ", 30)
self.verify("free: 8192" in out, "Free space doesn't match the expected value")
@@ -88,6 +104,14 @@ class TestFdir(TestCase):
def test_fdir_signatures(self):
"""
FDir signature matching mode.
+ There are three different reporting modes, that can be set in testpmd using the ``--pkt-filter-report-hash`` command line
+ argument:
+ --pkt-filter-report-hash=none
+ --pkt-filter-report-hash=match
+ --pkt-filter-report-hash=always
+ The test for each mode is following the steps below.
+ - Start the ``testpmd`` application by using paramter of each mode.
+ - Send the ``p_udp`` packet with Scapy on the traffic generator and check that FDir information is printed
"""
dutPorts = self.dut.get_ports(self.nic)
@@ -95,7 +119,7 @@ class TestFdir(TestCase):
itf = self.tester.get_interface(localPort)
self.dut.kill_all()
- self.dut.send_expect("./%s/app/testpmd -c 0xff -n 1 -- -i --portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-report-hash=none" % (self.target, dcts.create_mask([dutPorts[0]])), "testpmd>", 120)
+ self.pmdout.start_testpmd("all", "--portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-report-hash=none" % dts.create_mask([dutPorts[0]]))
self.dut.send_expect("set verbose 1", "testpmd>")
self.dut.send_expect("set fwd rxonly", "testpmd>")
self.dut.send_expect("set nbcore 3", "testpmd>")
@@ -107,7 +131,7 @@ class TestFdir(TestCase):
self.dut.send_expect("quit", "# ", 30)
- self.dut.send_expect("./%s/app/testpmd -c 0xff -n 1 -- -i --portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-report-hash=match" % (self.target, dcts.create_mask([dutPorts[0]])), "testpmd>", 120)
+ self.pmdout.start_testpmd("all", "--portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-report-hash=match" % dts.create_mask([dutPorts[0]]))
self.dut.send_expect("set verbose 1", "testpmd>")
self.dut.send_expect("set fwd rxonly", "testpmd>")
self.dut.send_expect("set nbcore 3", "testpmd>")
@@ -129,7 +153,7 @@ class TestFdir(TestCase):
self.dut.send_expect("quit", "# ", 30)
- self.dut.send_expect("./%s/app/testpmd -c 0xff -n 1 -- -i --portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-report-hash=always" % (self.target, dcts.create_mask([dutPorts[0]])), "testpmd>", 120)
+ self.pmdout.start_testpmd("all", "--portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-report-hash=always" % dts.create_mask([dutPorts[0]]))
self.dut.send_expect("set verbose 1", "testpmd>")
self.dut.send_expect("set fwd rxonly", "testpmd>")
self.dut.send_expect("set nbcore 3", "testpmd>")
@@ -144,6 +168,12 @@ class TestFdir(TestCase):
def test_fdir_matching(self):
"""
FDir matching mode
+ This test adds signature filters to the hardware, and then checks
+ whether sent packets match those filters.
+ The test for each mode is following the steps below.
+ - Start the ``testpmd`` application
+ - Add filter with upd, tcp sctp, IP4 or IP6
+ - Send the packet and validate the filter function.
"""
dutPorts = self.dut.get_ports(self.nic)
@@ -151,7 +181,7 @@ class TestFdir(TestCase):
itf = self.tester.get_interface(localPort)
self.dut.kill_all()
- self.dut.send_expect("./%s/app/testpmd -c 0xff -n 1 -- -i --portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=signature --pkt-filter-report-hash=match" % (self.target, dcts.create_mask([dutPorts[0]])), "testpmd>", 120)
+ self.pmdout.start_testpmd("all", "--portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=signature --pkt-filter-report-hash=match" % dts.create_mask([dutPorts[0]]))
self.dut.send_expect("set verbose 1", "testpmd>")
self.dut.send_expect("set fwd rxonly", "testpmd>")
self.dut.send_expect("set nbcore 3", "testpmd>")
@@ -196,6 +226,11 @@ class TestFdir(TestCase):
def test_fdir_perfect_matching(self):
"""
FDir perfect matching mode.
+ This test adds perfect-match filters to the hardware, and then checks whether sent packets match those filters.
+ The test for each mode is following the steps below.
+ - Start the ``testpmd`` application with perfect match;
+ - Add filter with upd, tcp sctp, IP4;
+ - Send the packet and validate the perfect filter function.
"""
dutPorts = self.dut.get_ports(self.nic)
@@ -203,7 +238,7 @@ class TestFdir(TestCase):
itf = self.tester.get_interface(localPort)
self.dut.kill_all()
- self.dut.send_expect("./%s/app/testpmd -c 0xff -n 1 -- -i --portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-report-hash=match" % (self.target, dcts.create_mask([dutPorts[0]])), "testpmd>", 120)
+ self.pmdout.start_testpmd("all", "--portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-report-hash=match" % dts.create_mask([dutPorts[0]]))
self.dut.send_expect("set verbose 1", "testpmd>")
self.dut.send_expect("set fwd rxonly", "testpmd>")
self.dut.send_expect("set nbcore 3", "testpmd>")
@@ -225,6 +260,8 @@ class TestFdir(TestCase):
def test_fdir_filter_masks(self):
"""
FDir filter masks.
+ This tests the functionality of the setting FDir masks to to affect which
+ fields, or parts of fields are used in the matching process.
"""
dutPorts = self.dut.get_ports(self.nic)
@@ -232,7 +269,7 @@ class TestFdir(TestCase):
itf = self.tester.get_interface(localPort)
self.dut.kill_all()
- self.dut.send_expect("./%s/app/testpmd -c 0xff -n 1 -- -i --portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-size=64K --pkt-filter-report-hash=match" % (self.target, dcts.create_mask([dutPorts[0]])), "testpmd>", 120)
+ self.pmdout.start_testpmd("all", "--portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-size=64K --pkt-filter-report-hash=match" % dts.create_mask([dutPorts[0]]))
self.dut.send_expect("set verbose 1", "testpmd>")
self.dut.send_expect("set fwd rxonly", "testpmd>")
self.dut.send_expect("set nbcore 3", "testpmd>")
@@ -266,6 +303,10 @@ class TestFdir(TestCase):
def test_fdir_flexbytes_filtering(self):
"""
FDir flexbytes filtering
+ The FDir feature supports setting up filters that can match on any two byte field
+ within the first 64 bytes of a packet. Which byte offset to use is set by passing
+ command line arguments to ``testpmd``. In this test a value of ``18`` corresponds
+ to the bytes at offset 36 and 37, as the offset is in 2-byte units
"""
dutPorts = self.dut.get_ports(self.nic)
@@ -273,7 +314,7 @@ class TestFdir(TestCase):
itf = self.tester.get_interface(localPort)
self.dut.kill_all()
- self.dut.send_expect("./%s/app/testpmd -c 0xff -n 1 -- -i --portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-size=64K --pkt-filter-report-hash=match --pkt-filter-flexbytes-offset=18" % (self.target, dcts.create_mask([dutPorts[0]])), "testpmd>", 120)
+ self.pmdout.start_testpmd("all", "--portmask=%s --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect --pkt-filter-size=64K --pkt-filter-report-hash=match --pkt-filter-flexbytes-offset=18" % dts.create_mask([dutPorts[0]]))
self.dut.send_expect("set verbose 1", "testpmd>")
self.dut.send_expect("set fwd rxonly", "testpmd>")
self.dut.send_expect("set nbcore 3", "testpmd>")
@@ -302,7 +343,7 @@ class TestFdir(TestCase):
itf = self.tester.get_interface(localPort)
self.dut.kill_all()
- self.dut.send_expect("./%s/app/testpmd -c 0xff -n 1 -- -i --portmask=%s --nb-cores=2 --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect" % (self.target, dcts.create_mask([dutPorts[0]])), "testpmd>", 120)
+ self.pmdout.start_testpmd("all", "--portmask=%s --nb-cores=2 --rxq=2 --txq=2 --disable-rss --pkt-filter-mode=perfect" % dts.create_mask([dutPorts[0]]))
self.dut.send_expect("set verbose 1", "testpmd>")
self.dut.send_expect("set fwd rxonly", "testpmd>")
# "rx_vlan add all" has been removed from testpmd
diff --git a/tests/TestSuite_hello_world.py b/tests/TestSuite_hello_world.py
index 3633ed7..985d8b5 100644
--- a/tests/TestSuite_hello_world.py
+++ b/tests/TestSuite_hello_world.py
@@ -1,28 +1,45 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Test HelloWorld example.
"""
-import dcts
+import dts
from test_case import TestCase
-#
-#
-# Test class.
-#
-
class TestHelloWorld(TestCase):
- #
- #
- #
- # Test cases.
- #
-
def set_up_all(self):
"""
Run at the start of each test suite.
@@ -49,7 +66,7 @@ class TestHelloWorld(TestCase):
# get the mask for the first core
cores = self.dut.get_core_list('1S/1C/1T')
- coreMask = dcts.create_mask(cores)
+ coreMask = dts.create_mask(cores)
cmdline = "./examples/helloworld/build/app/helloworld -n 1 -c " + coreMask
out = self.dut.send_expect(cmdline, "# ", 3)
@@ -63,7 +80,7 @@ class TestHelloWorld(TestCase):
# get the maximun logical core number
cores = self.dut.get_core_list('all')
- coreMask = dcts.create_mask(cores)
+ coreMask = dts.create_mask(cores)
cmdline = "./examples/helloworld/build/app/helloworld -n 1 -c " + coreMask
out = self.dut.send_expect(cmdline, "# ", 5)
diff --git a/tests/TestSuite_ieee1588.py b/tests/TestSuite_ieee1588.py
index 09c1729..c6fdd61 100644
--- a/tests/TestSuite_ieee1588.py
+++ b/tests/TestSuite_ieee1588.py
@@ -1,31 +1,49 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Test support of IEEE1588 Precise Time Protocol.
"""
-import dcts
+import dts
import time
from test_case import TestCase
-
-#
-#
-# Test class.
-#
+from pmd_output import PmdOutput
class TestIeee1588(TestCase):
- #
- #
- #
- # Test cases.
- #
-
def set_up_all(self):
"""
Run at the start of each test suite.
@@ -45,8 +63,8 @@ class TestIeee1588(TestCase):
self.dut.skip_setup = False
self.dut.build_install_dpdk(self.target)
- self.dut.send_expect("./%s/app/testpmd -c ffffff -n 3 -- -i --rxpt=0 --rxht=0 --rxwt=0 --txpt=39 --txht=0 --txwt=0" % self.target,
- "testpmd> ", 100)
+ self.pmdout = PmdOutput(self.dut)
+ self.pmdout.start_testpmd("all")
def set_up(self):
"""
@@ -88,11 +106,11 @@ class TestIeee1588(TestCase):
time.sleep(1)
out = self.dut.send_expect("stop", "testpmd> ")
- text = dcts.regexp(out, "(.*) by hardware")
+ text = dts.regexp(out, "(.*) by hardware")
self.verify("IEEE1588 PTP V2 SYNC" in text, "Not filtered " + text)
- rx_time = dcts.regexp(out, "RX timestamp value (0x[0-9a-fA-F]+)")
- tx_time = dcts.regexp(out, "TX timestamp value (0x[0-9a-fA-F]+)")
+ rx_time = dts.regexp(out, "RX timestamp value (0x[0-9a-fA-F]+)")
+ tx_time = dts.regexp(out, "TX timestamp value (0x[0-9a-fA-F]+)")
self.verify(rx_time is not None, "RX timestamp error ")
self.verify(tx_time is not None, "TX timestamp error ")
diff --git a/tests/TestSuite_ip_pipeline.py b/tests/TestSuite_ip_pipeline.py
index 5fade77..9fb8226 100644
--- a/tests/TestSuite_ip_pipeline.py
+++ b/tests/TestSuite_ip_pipeline.py
@@ -1,10 +1,37 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Test userland 10Gb PMD
-
"""
from scapy.layers.inet import Ether, IP, TCP
@@ -12,20 +39,10 @@ from scapy.utils import struct, socket, PcapWriter
from settings import HEADER_SIZE
from test_case import TestCase
from time import sleep
-import dcts
-
-#
-#
-# Test class.
-#
+import dts
class TestIPPipeline(TestCase):
-
- #
- #
- # Utility methods and other non-test code.
- #
payload_watermark = 'TestPF'
frame_sizes = [64, 65, 128, 1024]
@@ -141,7 +158,7 @@ class TestIPPipeline(TestCase):
pcap0_file,
pcap1_file)
- command_line = "./examples/ip_pipeline/build/ip_pipeline -c %s -n %d --use-device %s -- -p 0x3" % \
+ command_line = "./examples/ip_pipeline/build/ip_pipeline -c %s -n %d -vdev %s -- -p 0x3" % \
(self.coremask,
self.dut.get_memory_channels(),
pcap_config)
@@ -260,11 +277,7 @@ class TestIPPipeline(TestCase):
for port in ['rx', 'tx']:
self.verify(stats[port] == expected[port],
'Frames expected (%s) and received (%s) mismatch on %s port' % (
- expected[
- port],
- stats[
- port],
- port))
+ expected[port], stats[port], port))
def pipeline_command(self, command):
out = self.dut.send_expect(command, 'pipeline>')
@@ -303,11 +316,6 @@ class TestIPPipeline(TestCase):
self.dut.send_expect('link 0 down', 'pipeline>')
self.dut.send_expect('link 1 down', 'pipeline>')
- #
- #
- #
- # Test cases.
- #
def set_up_all(self):
"""
Run at the start of each test suite.
@@ -326,7 +334,7 @@ class TestIPPipeline(TestCase):
out = self.dut.build_dpdk_apps("./examples/ip_pipeline")
self.verify("Error" not in out, "Compilation error")
- self.ports_mask = dcts.create_mask(
+ self.ports_mask = dts.create_mask(
[self.dut_ports[0], self.dut_ports[1]])
self.coremask = "0x3e" # IP Pipeline app requires FIVE cores
@@ -358,7 +366,7 @@ class TestIPPipeline(TestCase):
for frames_number in TestIPPipeline.number_of_frames:
for inter in TestIPPipeline.inter:
- print dcts.BLUE(
+ print dts.BLUE(
"\tNumber of frames %d, interval %.1f" % (frames_number,
inter))
stats = self.send_and_sniff_pcap_file(pcap_file, frames_number,
@@ -392,8 +400,8 @@ class TestIPPipeline(TestCase):
self.create_pcap_file(pcap_file, frame_size, 100, True)
self.tester.session.copy_file_to(pcap_file)
- print dcts.BLUE("\tFrame size %d, interval %.1f" % (frame_size,
- inter))
+ print dts.BLUE("\tFrame size %d, interval %.1f" % (frame_size,
+ inter))
stats = self.send_and_sniff_pcap_file(pcap_file, frames_number,
1, 0, inter)
@@ -407,6 +415,132 @@ class TestIPPipeline(TestCase):
expected = {'tx': frames_number, 'rx': 0}
self.check_results(stats, expected)
+ def test_pcap_incremental_ip(self):
+ """
+ Check variable number of frames with incremental IP addresses using
+ PCAP driver as input for the pipeline.
+ """
+ pcap_file = 'ip_pipeline.pcap'
+ frame_size = 64
+
+ self.dut.session.copy_file_to(TestIPPipeline.dummy_pcap)
+
+ for number in TestIPPipeline.number_of_frames:
+
+ print dts.BLUE("\t%d frames, incremental IP address" % (number))
+
+ self.create_pcap_file(pcap_file, frame_size, number, True)
+ self.dut.session.copy_file_to(pcap_file)
+
+ self.start_ip_pipeline_pcap(TestIPPipeline.dummy_pcap,
+ pcap_file)
+ self.dut.send_expect(
+ 'run examples/ip_pipeline/ip_pipeline.sh', 'pipeline>', 10)
+
+ self.dut.send_expect('link 0 up', 'pipeline>')
+ self.dut.send_expect('link 1 up', 'pipeline>')
+
+ sleep(1)
+
+ self.dut.send_expect('link 0 down', 'pipeline>')
+ self.dut.send_expect('link 1 down', 'pipeline>')
+
+ self.quit_ip_pipeline()
+
+ rx_stats = self.number_of_packets('/tmp/port0out.pcap', 'dut')
+ tx_stats = self.number_of_packets('/tmp/port1out.pcap', 'dut')
+
+ stats = {'tx': tx_stats, 'rx': rx_stats}
+ expected = {'tx': 0, 'rx': number}
+
+ self.check_results(stats, expected)
+
+ def test_pcap_frame_sizes(self):
+ """
+ Check variable number of frames with different sizes and
+ incremental IP addresses using PCAP driver as input for the pipeline.
+ """
+ pcap_file = 'ip_pipeline.pcap'
+ self.dut.session.copy_file_to(TestIPPipeline.dummy_pcap)
+
+ for frame_size in TestIPPipeline.frame_sizes:
+ for number in TestIPPipeline.number_of_frames:
+
+ print dts.BLUE("\t%d frames of size %d frames" % (
+ number, frame_size))
+
+ self.create_pcap_file(pcap_file, frame_size, number, True)
+ self.dut.session.copy_file_to(pcap_file)
+
+ self.start_ip_pipeline_pcap(TestIPPipeline.dummy_pcap,
+ pcap_file)
+ self.dut.send_expect(
+ 'run examples/ip_pipeline/ip_pipeline.sh', 'pipeline>', 10)
+
+ self.dut.send_expect('link 0 up', 'pipeline>')
+ self.dut.send_expect('link 1 up', 'pipeline>')
+
+ sleep(5)
+
+ self.dut.send_expect('link 0 down', 'pipeline>')
+ self.dut.send_expect('link 1 down', 'pipeline>')
+
+ self.quit_ip_pipeline()
+
+ rx_stats = self.number_of_packets('/tmp/port0out.pcap', 'dut')
+ tx_stats = self.number_of_packets('/tmp/port1out.pcap', 'dut')
+
+ stats = {'tx': tx_stats, 'rx': rx_stats}
+ expected = {'tx': 0, 'rx': number}
+
+ self.check_results(stats, expected)
+
+ def _test_pcap(self):
+ """
+ Check variable number of frames with different sizes and
+ incremental/fixed IP addresses using PCAP driver as input for the
+ pipeline.
+ """
+ pcap_file = 'ip_pipeline.pcap'
+
+ self.dut.session.copy_file_to(TestIPPipeline.dummy_pcap)
+
+ for frame_size in TestIPPipeline.frame_sizes:
+ for increment in TestIPPipeline.incremental_ip_address:
+ for number in TestIPPipeline.number_of_frames:
+
+ print dts.BLUE("\t%d frames of size %d frames, incremental IP address %s" % (
+ number, frame_size, increment))
+
+ self.create_pcap_file(pcap_file, frame_size, number,
+ increment)
+ self.dut.session.copy_file_to(pcap_file)
+
+ self.start_ip_pipeline_pcap(TestIPPipeline.dummy_pcap,
+ pcap_file)
+ self.dut.send_expect(
+ 'run examples/ip_pipeline/ip_pipeline.sh', 'pipeline>', 10)
+
+ self.dut.send_expect('link 0 up', 'pipeline>')
+ self.dut.send_expect('link 1 up', 'pipeline>')
+
+ sleep(5)
+
+ self.dut.send_expect('link 0 down', 'pipeline>')
+ self.dut.send_expect('link 1 down', 'pipeline>')
+
+ self.quit_ip_pipeline()
+
+ rx_stats = self.number_of_packets(
+ '/tmp/port0out.pcap', 'dut')
+ tx_stats = self.number_of_packets(
+ '/tmp/port1out.pcap', 'dut')
+
+ stats = {'tx': tx_stats, 'rx': rx_stats}
+ expected = {'tx': 0, 'rx': number}
+
+ self.check_results(stats, expected)
+
def test_flow_management(self):
"""
Add several flows and check only frames with matching IPs passes
diff --git a/tests/TestSuite_ipfrag.py b/tests/TestSuite_ipfrag.py
index 8f33f7c..5b79aef 100644
--- a/tests/TestSuite_ipfrag.py
+++ b/tests/TestSuite_ipfrag.py
@@ -1,11 +1,40 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
"""
DPDK Test suite.
-
Test IPv4 fragmentation features in DPDK.
-
"""
-import dcts
+import dts
import string
import re
@@ -33,11 +62,6 @@ lpm_table_ipv6 = [
from test_case import TestCase
-#
-#
-# Test class.
-#
-
class TestIpfrag(TestCase):
@@ -49,16 +73,6 @@ class TestIpfrag(TestCase):
portid = match.group(1)
self.verify(int(portid) in range(4), "invalid port id")
return '%s' % eval("P" + str(portid))
- #
- #
- # Utility methods and other non-test code.
- #
- # Insert or move non-test functions here.
- #
- #
- #
- # Test cases.
- #
def set_up_all(self):
"""
@@ -112,8 +126,8 @@ l3fwd_ipv4_route_array[] = {\\\n"
Perform functional fragmentation checks.
"""
- coremask = dcts.create_mask(cores)
- portmask = dcts.create_mask([P0, P2])
+ coremask = dts.create_mask(cores)
+ portmask = dts.create_mask([P0, P2])
numPortThread = len([P0, P2]) / len(cores)
result = True
errString = ''
@@ -169,8 +183,8 @@ l3fwd_ipv4_route_array[] = {\\\n"
"""
Perform functional fragmentation checks.
"""
- coremask = dcts.create_mask(cores)
- portmask = dcts.create_mask([P0, P2])
+ coremask = dts.create_mask(cores)
+ portmask = dts.create_mask([P0, P2])
numPortThread = len([P0, P2]) / len(cores)
result = True
errString = ''
@@ -292,11 +306,11 @@ l3fwd_ipv4_route_array[] = {\\\n"
Pct = dict()
if int(lcore[0]) == 1:
- core_mask = dcts.create_mask(self.dut.get_core_list(lcore, socket=self.ports_socket))
+ core_mask = dts.create_mask(self.dut.get_core_list(lcore, socket=self.ports_socket))
else:
- core_mask = dcts.create_mask(self.dut.get_core_list(lcore))
+ core_mask = dts.create_mask(self.dut.get_core_list(lcore))
- portmask = dcts.create_mask([P0, P2])
+ portmask = dts.create_mask([P0, P2])
self.dut.send_expect("examples/ip_fragmentation/build/ip_fragmentation -c %s -n %d -- -p %s -q %s" % (
core_mask, self.dut.get_memory_channels(), portmask, num_pthreads), "IP_FRAG:", 120)
@@ -334,7 +348,7 @@ l3fwd_ipv4_route_array[] = {\\\n"
result.append(Pps[str(size)])
result.append(Pct[str(size)])
- dcts.results_table_add_row(result)
+ dts.results_table_add_row(result)
self.dut.send_expect("^C", "#")
@@ -354,7 +368,7 @@ l3fwd_ipv4_route_array[] = {\\\n"
tblheader.append("%dB Mpps" % size)
tblheader.append("%d" % size)
- dcts.results_table_add_header(tblheader)
+ dts.results_table_add_header(tblheader)
lcores = [("1S/1C/1T", 2), ("1S/1C/2T", 2), ("1S/2C/1T", 2), ("2S/1C/1T", 2)]
index = 1
@@ -362,7 +376,7 @@ l3fwd_ipv4_route_array[] = {\\\n"
self.benchmark(index, lcore, numThr, sizes)
index += 1
- dcts.results_table_print()
+ dts.results_table_print()
self.tester.send_expect("ifconfig %s mtu 1500" % self.tester.get_interface(self.tester.get_local_port(P0)), "#")
self.tester.send_expect("ifconfig %s mtu 1500" % self.tester.get_interface(self.tester.get_local_port(P2)), "#")
diff --git a/tests/TestSuite_jumboframes.py b/tests/TestSuite_jumboframes.py
index a563769..2b862af 100644
--- a/tests/TestSuite_jumboframes.py
+++ b/tests/TestSuite_jumboframes.py
@@ -1,32 +1,53 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Test the support of Jumbo Frames by Poll Mode Drivers
-
"""
-import dcts
+import dts
import re
from time import sleep
from test_case import TestCase
from pmd_output import PmdOutput
-#
-#
-# Test class.
-#
+ETHER_HEADER_LEN = 18
+IP_HEADER_LEN = 20
+ETHER_STANDARD_MTU = 1518
+ETHER_JUMBO_FRAME_MTU = 9000
class TestJumboframes(TestCase):
- #
- #
- # Utility methods and other non-test code.
- #
-
- # Insert or move non-test functions here.
def jumboframes_get_stat(self, portid, rx_tx):
"""
@@ -44,15 +65,16 @@ class TestJumboframes(TestCase):
"""
Send 1 packet to portid
"""
+ gp0tx_pkts, _, gp0tx_bytes = [int(_) for _ in self.jumboframes_get_stat(self.rx_port, "tx")]
+ gp1rx_pkts, gp1rx_err, gp1rx_bytes = [int(_) for _ in self.jumboframes_get_stat(self.tx_port, "rx")]
- gp0tx_pkts, _, gp0tx_bytes = [int(_) for _ in self.jumboframes_get_stat(self.dut_ports[0], "tx")]
- gp1rx_pkts, gp1rx_err, gp1rx_bytes = [int(_) for _ in self.jumboframes_get_stat(self.dut_ports[1], "rx")]
-
- itf = self.tester.get_interface(self.tester.get_local_port(self.dut_ports[1]))
- mac = self.dut.get_mac_address(self.dut_ports[1])
+ itf = self.tester.get_interface(self.tester.get_local_port(self.tx_port))
+ mac = self.dut.get_mac_address(self.tx_port)
- pktlen = pktsize - 18
- padding = pktlen - 20
+ # The packet total size include ethernet header, ip header, and payload.
+ # ethernet header length is 18 bytes, ip standard header length is 20 bytes.
+ pktlen = pktsize - ETHER_HEADER_LEN
+ padding = pktlen - IP_HEADER_LEN
self.tester.scapy_foreground()
self.tester.scapy_append('nutmac="%s"' % mac)
@@ -61,9 +83,9 @@ class TestJumboframes(TestCase):
out = self.tester.scapy_execute()
sleep(5)
- p0tx_pkts, _, p0tx_bytes = [int(_) for _ in self.jumboframes_get_stat(self.dut_ports[0], "tx")]
+ p0tx_pkts, _, p0tx_bytes = [int(_) for _ in self.jumboframes_get_stat(self.rx_port, "tx")]
# p0tx_pkts, p0tx_err, p0tx_bytes
- p1rx_pkts, p1rx_err, p1rx_bytes = [int(_) for _ in self.jumboframes_get_stat(self.dut_ports[1], "rx")]
+ p1rx_pkts, p1rx_err, p1rx_bytes = [int(_) for _ in self.jumboframes_get_stat(self.tx_port, "rx")]
p0tx_pkts -= gp0tx_pkts
p0tx_bytes -= gp0tx_bytes
@@ -88,83 +110,72 @@ class TestJumboframes(TestCase):
#
def set_up_all(self):
"""
- Run at the start of each test suite.
-
-
- Dynamic config Prerequistites
+ Prerequisite steps for each test suit.
"""
self.dut_ports = self.dut.get_ports(self.nic)
self.verify(len(self.dut_ports) >= 2, "Insufficient ports")
+ self.rx_port = self.dut_ports[0]
+ self.tx_port = self.dut_ports[1]
cores = self.dut.get_core_list('1S/2C/2T')
- self.coremask = dcts.create_mask(cores)
+ self.coremask = dts.create_mask(cores)
- self.port_mask = dcts.create_mask([self.dut_ports[0], self.dut_ports[1]])
+ self.port_mask = dts.create_mask([self.rx_port, self.tx_port])
- self.tester.send_expect("ifconfig %s mtu %s" % (self.tester.get_interface(self.tester.get_local_port(self.dut_ports[0])), 9200), "# ")
- self.tester.send_expect("ifconfig %s mtu %s" % (self.tester.get_interface(self.tester.get_local_port(self.dut_ports[1])), 9200), "# ")
+ self.tester.send_expect("ifconfig %s mtu %s" % (self.tester.get_interface(self.tester.get_local_port(self.rx_port)), ETHER_JUMBO_FRAME_MTU + 200), "# ")
+ self.tester.send_expect("ifconfig %s mtu %s" % (self.tester.get_interface(self.tester.get_local_port(self.tx_port)), ETHER_JUMBO_FRAME_MTU + 200), "# ")
self.pmdout = PmdOutput(self.dut)
def set_up(self):
"""
- Run before each test case.
+ This is to clear up environment before the case run.
"""
- pass
+ self.dut.kill_all()
def test_jumboframes_normal_nojumbo(self):
"""
- Dynamic config default mode test
+ This case aims to test transmitting normal size packet without jumbo
+ frame on testpmd app.
"""
self.dut.kill_all()
- cmd = r"./%s/build/app/test-pmd/testpmd -c%s -n 3 -- -i --rxd=1024 --txd=1024 \
- --burst=144 --txpt=32 --txht=0 --txfreet=0 --rxfreet=64 \
- --mbcache=200 --portmask=%s --mbuf-size=2048 --max-pkt-len=1518" % (self.target, self.coremask, self.port_mask)
-
- self.dut.send_expect(cmd, "testpmd> ", 120)
-
+ self.pmdout.start_testpmd("all", "--max-pkt-len=%d" % (ETHER_STANDARD_MTU))
self.dut.send_expect("start", "testpmd> ")
- self.jumboframes_send_packet(1517)
- self.jumboframes_send_packet(1518)
+ self.jumboframes_send_packet(ETHER_STANDARD_MTU - 1)
+ self.jumboframes_send_packet(ETHER_STANDARD_MTU)
self.dut.send_expect("stop", "testpmd> ")
self.dut.send_expect("quit", "# ", 30)
def test_jumboframes_jumbo_nojumbo(self):
"""
- Dynamic config diable promiscuous test
+ This case aims to test transmitting jumbo frame packet on testpmd without
+ jumbo frame support.
"""
self.dut.kill_all()
- cmd = r"./%s/build/app/test-pmd/testpmd -c%s -n 3 -- -i --rxd=1024 --txd=1024 \
- --burst=144 --txpt=32 --txht=8 --txwt=0 --txfreet=0 --rxfreet=64 \
- --mbcache=200 --portmask=%s --mbuf-size=2048 --max-pkt-len=1518" % (self.target, self.coremask, self.port_mask)
-
- self.dut.send_expect(cmd, "testpmd> ", 120)
+ self.pmdout.start_testpmd("all", "--max-pkt-len=%d" % (ETHER_STANDARD_MTU))
self.dut.send_expect("start", "testpmd> ")
- self.jumboframes_send_packet(1519, False)
+ self.jumboframes_send_packet(ETHER_STANDARD_MTU + 1, False)
self.dut.send_expect("stop", "testpmd> ")
self.dut.send_expect("quit", "# ", 30)
def test_jumboframes_normal_jumbo(self):
"""
- Dynamic config enable promiscuous test
+ When jumbo frame supported, this case is to verify that the normal size
+ packet forwrding should be support correct.
"""
self.dut.kill_all()
- cmd = r"./%s/build/app/test-pmd/testpmd -c%s -n 3 -- -i --rxd=1024 --txd=1024 \
- --burst=144 --txpt=32 --txht=8 --txwt=0 --txfreet=0 --rxfreet=64 \
- --mbcache=200 --portmask=%s --mbuf-size=2048 --max-pkt-len=%s" % (self.target, self.coremask, self.port_mask, 9000)
-
- self.dut.send_expect(cmd, "testpmd> ", 120)
+ self.pmdout.start_testpmd("all", "--max-pkt-len=%s" % (ETHER_JUMBO_FRAME_MTU))
self.dut.send_expect("start", "testpmd> ")
self.jumboframes_send_packet(1517)
@@ -175,41 +186,34 @@ class TestJumboframes(TestCase):
def test_jumboframes_jumbo_jumbo(self):
"""
- Dynamic config enable promiscuous test
+ When jumbo frame supported, this case is to verify that jumbo frame
+ packet can be forwarded correct.
"""
self.dut.kill_all()
- cmd = r"./%s/build/app/test-pmd/testpmd -c%s -n 3 -- -i --rxd=1024 --txd=1024 \
- --burst=144 --txpt=32 --txht=8 --txwt=0 --txfreet=0 --rxfreet=64 \
- --mbcache=200 --portmask=%s --mbuf-size=2048 --max-pkt-len=%s" % (self.target, self.coremask, self.port_mask, 9000)
-
- self.dut.send_expect(cmd, "testpmd> ", 120)
+ self.pmdout.start_testpmd("all", "--max-pkt-len=%s" % (ETHER_JUMBO_FRAME_MTU))
self.dut.send_expect("start", "testpmd> ")
- self.jumboframes_send_packet(1519)
- self.jumboframes_send_packet(9000 - 1)
- self.jumboframes_send_packet(9000)
+ self.jumboframes_send_packet(ETHER_STANDARD_MTU + 1)
+ self.jumboframes_send_packet(ETHER_JUMBO_FRAME_MTU - 1)
+ self.jumboframes_send_packet(ETHER_JUMBO_FRAME_MTU)
self.dut.send_expect("stop", "testpmd> ")
self.dut.send_expect("quit", "# ", 30)
def test_jumboframes_bigger_jumbo(self):
"""
- Dynamic config enable promiscuous test
+ When the jubmo frame MTU set as 9000, this case is to verify that the
+ packet which the length bigger than MTU can not be forwarded.
"""
self.dut.kill_all()
- cmd = r"./%s/build/app/test-pmd/testpmd -c%s -n 3 -- -i --rxd=1024 --txd=1024 \
- --burst=144 --txpt=32 --txht=8 --txwt=0 --txfreet=0 --rxfreet=64 \
- --mbcache=200 --portmask=%s --mbuf-size=2048 --max-pkt-len=%s" % (
- self.target, self.coremask, self.port_mask, 9000)
-
- self.dut.send_expect(cmd, "testpmd> ", 120)
+ self.pmdout.start_testpmd("1S/2C/1T", "--max-pkt-len=%s" % (ETHER_JUMBO_FRAME_MTU))
self.dut.send_expect("start", "testpmd> ")
- self.jumboframes_send_packet(9000 + 1, False)
+ self.jumboframes_send_packet(ETHER_JUMBO_FRAME_MTU + 1, False)
self.dut.send_expect("quit", "# ", 30)
@@ -221,6 +225,8 @@ class TestJumboframes(TestCase):
def tear_down_all(self):
"""
- Run after each test suite.
+ When the case of this test suite finished, the enviroment should
+ clear up.
"""
- pass
+ self.tester.send_expect("ifconfig %s mtu %s" % (self.tester.get_interface(self.tester.get_local_port(self.rx_port)), ETHER_STANDARD_MTU), "# ")
+ self.tester.send_expect("ifconfig %s mtu %s" % (self.tester.get_interface(self.tester.get_local_port(self.tx_port)), ETHER_STANDARD_MTU), "# ")
diff --git a/tests/TestSuite_l2fwd.py b/tests/TestSuite_l2fwd.py
index 6233330..b75163c 100644
--- a/tests/TestSuite_l2fwd.py
+++ b/tests/TestSuite_l2fwd.py
@@ -1,30 +1,47 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Test Layer-2 Forwarding support
-
"""
-import dcts
+import dts
from test_case import TestCase
from plotting import Plotting
from settings import HEADER_SIZE
-#
-#
-# Test class.
-#
-
class TestL2fwd(TestCase):
- #
- #
- # Utility methods and other non-test code.
- #
-
def plot_results(self):
queues = []
@@ -45,13 +62,8 @@ class TestL2fwd(TestCase):
ylabel='% linerate',
legend=queues)
- dcts.results_plot_print(image_path)
+ dts.results_plot_print(image_path)
- #
- #
- #
- # Test cases.
- #
def set_up_all(self):
"""
Run at the start of each test suite.
@@ -88,7 +100,7 @@ class TestL2fwd(TestCase):
self.table_header.append("%d queues Mpps" % queue['queues'])
self.table_header.append("% linerate")
- dcts.results_table_add_header(self.table_header)
+ dts.results_table_add_header(self.table_header)
self.plotting = Plotting(self.dut.crb['name'], self.target, self.nic)
def set_up(self):
@@ -106,7 +118,7 @@ class TestL2fwd(TestCase):
Check port forwarding.
"""
# the cases use the first two ports
- port_mask = dcts.create_mask([self.dut_ports[0], self.dut_ports[1]])
+ port_mask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])
self.dut.send_expect("./examples/l2fwd/build/app/l2fwd -n 1 -c f -- -q 8 -p %s &" % port_mask, "L2FWD: entering main loop", 60)
@@ -139,9 +151,9 @@ class TestL2fwd(TestCase):
for port in xrange(self.number_of_ports):
ports.append(self.dut_ports[port])
- port_mask = dcts.create_mask(ports)
- core_mask = dcts.create_mask(self.dut.get_core_list(self.core_config,
- socket=self.ports_socket))
+ port_mask = dts.create_mask(ports)
+ core_mask = dts.create_mask(self.dut.get_core_list(self.core_config,
+ socket=self.ports_socket))
for frame_size in self.frame_sizes:
@@ -171,8 +183,8 @@ class TestL2fwd(TestCase):
(queues['queues'], frame_size, self.core_config)
self.logger.info(info)
- dcts.report(info, annex=True)
- dcts.report(command_line + "\n\n", frame=True, annex=True)
+ dts.report(info, annex=True)
+ dts.report(command_line + "\n\n", frame=True, annex=True)
_, pps = self.tester.traffic_generator_throughput(tgen_input)
Mpps = pps / 1000000.0
queues['Mpps'][frame_size] = Mpps
@@ -197,10 +209,10 @@ class TestL2fwd(TestCase):
results_row.append(queue['Mpps'][frame_size])
results_row.append(queue['pct'][frame_size])
- dcts.results_table_add_row(results_row)
+ dts.results_table_add_row(results_row)
self.plot_results()
- dcts.results_table_print()
+ dts.results_table_print()
def tear_down(self):
"""
diff --git a/tests/TestSuite_l3fwd.py b/tests/TestSuite_l3fwd.py
index 2753631..31b2a74 100644
--- a/tests/TestSuite_l3fwd.py
+++ b/tests/TestSuite_l3fwd.py
@@ -1,13 +1,40 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
-
Layer-3 forwarding test script.
"""
-import dcts
+import dts
import string
import re
from plotting import Plotting
@@ -16,12 +43,6 @@ from exception import VerifyFailure
from settings import HEADER_SIZE
-#
-#
-# Test class.
-#
-
-
class TestL3fwd(TestCase):
path = "./examples/l3fwd/build/"
@@ -167,7 +188,7 @@ class TestL3fwd(TestCase):
ylabel='% linerate',
legend=TestL3fwd.methods)
- dcts.results_plot_print(image_path, 50)
+ dts.results_plot_print(image_path, 50)
except VerifyFailure as e:
self.logger.error(str(e))
@@ -213,7 +234,7 @@ class TestL3fwd(TestCase):
ylabel='% linerate',
legend=TestL3fwd.methods)
- dcts.results_plot_print(image_path)
+ dts.results_plot_print(image_path)
except VerifyFailure as e:
self.logger.error(str(e))
@@ -246,7 +267,7 @@ class TestL3fwd(TestCase):
ylabel='% linerate',
legend=cores)
- dcts.results_plot_print(image_path, 50)
+ dts.results_plot_print(image_path, 50)
# If testing only one mode, do nothing else.
if len(TestL3fwd.methods) == 1:
@@ -278,7 +299,7 @@ class TestL3fwd(TestCase):
ylabel='% linerate',
legend=TestL3fwd.methods)
- dcts.results_plot_print(image_path)
+ dts.results_plot_print(image_path)
def set_up_all(self):
"""
@@ -395,7 +416,7 @@ class TestL3fwd(TestCase):
command_line = output_pattern.sub(self.repl, command_line)
self.logger.debug("%s\n" % str(corelist))
- core_mask = dcts.create_mask(set(corelist))
+ core_mask = dts.create_mask(set(corelist))
# First, measure by two different methods
for method in TestL3fwd.methods:
@@ -403,9 +424,9 @@ class TestL3fwd(TestCase):
method_command_line = command_line % (TestL3fwd.path + "l3fwd_" + method,
core_mask,
self.dut.get_memory_channels(),
- dcts.create_mask(valports[:4]))
+ dts.create_mask(valports[:4]))
- dcts.report(method_command_line + "\n", frame=True, annex=True)
+ dts.report(method_command_line + "\n", frame=True, annex=True)
out = self.dut.send_expect(method_command_line, "L3FWD:", 120)
@@ -437,7 +458,7 @@ class TestL3fwd(TestCase):
data_row.append(pct[method])
# generate report table
- dcts.results_table_add_row(data_row)
+ dts.results_table_add_row(data_row)
self.l3fwd_test_results['data'].append(data_row)
def set_up(self):
@@ -462,7 +483,7 @@ class TestL3fwd(TestCase):
header_row.append('%s Mpps' % method)
header_row.append('% linerate')
- dcts.results_table_add_header(header_row)
+ dts.results_table_add_header(header_row)
self.l3fwd_test_results['header'] = header_row
self.l3fwd_test_results['data'] = []
@@ -479,10 +500,10 @@ class TestL3fwd(TestCase):
self.tester.scapy_execute()
- dcts.report("Flows for 4 ports, %d frame size.\n" % (frame_size),
- annex=True)
- dcts.report("%s" % string.join(flows, '\n'),
- frame=True, annex=True)
+ dts.report("Flows for 4 ports, %d frame size.\n" % (frame_size),
+ annex=True)
+ dts.report("%s" % string.join(flows, '\n'),
+ frame=True, annex=True)
# Get the number of sockets of the board
number_sockets = self.dut.send_expect("grep \"processor\|physical id\|core id\|^$\" /proc/cpuinfo | grep physical | sort -u | wc -l", "# ")
@@ -496,7 +517,7 @@ class TestL3fwd(TestCase):
self.get_throughput(frame_size, *test_case)
self.plot_4_ports()
- dcts.results_table_print()
+ dts.results_table_print()
def test_perf_l3fwd_2ports(self):
"""
@@ -505,7 +526,7 @@ class TestL3fwd(TestCase):
header_row = ["Frame", "Ports", "S/C/T", "Mpps", "% linerate", "mode"]
self.l3fwd_test_results['header'] = header_row
- dcts.results_table_add_header(header_row)
+ dts.results_table_add_header(header_row)
self.l3fwd_test_results['data'] = []
for frame_size in TestL3fwd.frame_sizes:
@@ -516,10 +537,10 @@ class TestL3fwd(TestCase):
flows = ['Ether()/%s/("X"*%d)' % (flow, payload_size) for flow in self.flows()[:4]]
- dcts.report("Flows for 2 ports, %d frame size.\n" % (frame_size),
- annex=True)
- dcts.report("%s" % string.join(flows, '\n'),
- frame=True, annex=True)
+ dts.report("Flows for 2 ports, %d frame size.\n" % (frame_size),
+ annex=True)
+ dts.report("%s" % string.join(flows, '\n'),
+ frame=True, annex=True)
self.tester.scapy_append('wrpcap("test2ports.pcap", [%s])' % string.join(flows, ','))
self.tester.scapy_execute()
@@ -534,7 +555,7 @@ class TestL3fwd(TestCase):
while pat.search(rtCmdLines[key]):
rtCmdLines[key] = pat.sub(self.repl, rtCmdLines[key])
self.logger.info("%s\n" % str(corelist))
- coreMask[key] = dcts.create_mask(set(corelist))
+ coreMask[key] = dts.create_mask(set(corelist))
# measure by two different mode
for mode in TestL3fwd.methods:
@@ -548,13 +569,13 @@ class TestL3fwd(TestCase):
mode, cores, frame_size)
self.logger.info(info)
- dcts.report(info, annex=True)
+ dts.report(info, annex=True)
subtitle.append(cores)
cmdline = rtCmdLines[cores] % (TestL3fwd.path + "l3fwd_" + mode, coreMask[cores],
- self.dut.get_memory_channels(), dcts.create_mask(valports[:2]))
+ self.dut.get_memory_channels(), dts.create_mask(valports[:2]))
- dcts.report(cmdline + "\n", frame=True, annex=True)
+ dts.report(cmdline + "\n", frame=True, annex=True)
out = self.dut.send_expect(cmdline, "L3FWD:", 120)
@@ -583,11 +604,11 @@ class TestL3fwd(TestCase):
self.dut.send_expect("^C", "#")
data_row = [frame_size, 2, cores, str(pps), str(pct), mode]
- dcts.results_table_add_row(data_row)
+ dts.results_table_add_row(data_row)
self.l3fwd_test_results['data'].append(data_row)
self.plot_2_ports()
- dcts.results_table_print()
+ dts.results_table_print()
def tear_down(self):
"""
diff --git a/tests/TestSuite_link_flowctrl.py b/tests/TestSuite_link_flowctrl.py
index 98ff84b..3c195c9 100644
--- a/tests/TestSuite_link_flowctrl.py
+++ b/tests/TestSuite_link_flowctrl.py
@@ -1,31 +1,49 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Test for Ethernet Link Flow Control Features by Poll Mode Drivers
-
"""
-import dcts
+import dts
import re
from time import sleep
from test_case import TestCase
-
-#
-#
-# Test class.
-#
+from pmd_output import PmdOutput
+from settings import HEADER_SIZE
class TestLinkFlowctrl(TestCase):
-
- #
- #
- #
- # Test cases.
- #
pause_frame_dst = "01:80:C2:00:00:01"
pause_frame_type = "0x8808"
pause_frame_opcode = "\\x00\\x01"
@@ -37,10 +55,7 @@ class TestLinkFlowctrl(TestCase):
frames_to_sent = 10
packet_size = 66 # 66 allows frame loss
- ip_header_size = 20
- udp_header_size = 8
- eth_header_size = 18
- payload_size = packet_size - eth_header_size - ip_header_size - udp_header_size
+ payload_size = packet_size - HEADER_SIZE['eth'] - HEADER_SIZE['ip'] - HEADER_SIZE['udp']
def set_up_all(self):
"""
@@ -57,13 +72,11 @@ class TestLinkFlowctrl(TestCase):
self.tx_port = self.dutPorts[1]
- self.portMask = dcts.create_mask([self.rx_port, self.tx_port])
+ self.portMask = dts.create_mask([self.rx_port, self.tx_port])
self.memChannels = self.dut.get_memory_channels()
- cmdline = "./%s/app/testpmd -c ffffff -n %s -- -i --burst=1" % (self.target, self.memChannels) + \
- "--txpt=32 --txht=8 --txwt=0 --txfreet=0 --mbcache=250 --portmask=%s" % self.portMask
-
- self.dut.send_expect(cmdline, "testpmd> ", 120)
+ self.pmdout = PmdOutput(self.dut)
+ self.pmdout.start_testpmd("all", "--portmask=%s" % self.portMask)
def pause_frame_loss_test(self, rx_flow_control='off',
tx_flow_control='off',
diff --git a/tests/TestSuite_multiprocess.py b/tests/TestSuite_multiprocess.py
index 3fbc31e..2c8eeba 100644
--- a/tests/TestSuite_multiprocess.py
+++ b/tests/TestSuite_multiprocess.py
@@ -1,33 +1,49 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Multi-process Test.
-
"""
-import dcts
+import dts
import time
from etgen import IxiaPacketGenerator
executions = []
from test_case import TestCase
-#
-#
-# Test class.
-#
-
class TestMultiprocess(TestCase, IxiaPacketGenerator):
- #
- #
- #
- # Test cases.
- #
-
def set_up_all(self):
"""
Run at the start of each test suite.
@@ -160,9 +176,9 @@ class TestMultiprocess(TestCase, IxiaPacketGenerator):
"""
self.dut.kill_all()
-
- self.dut.send_expect("./examples/multi_process/simple_mp/simple_mp/%s/simple_mp -n 1 -c 3 -m 64 &" % self.target, "Finished Process Init")
+ self.dut.send_expect("./examples/multi_process/simple_mp/simple_mp/%s/simple_mp -n 1 -c 3 -m 64 &" % self.target, "Finished Process Init", 20)
out = self.dut.send_expect("./examples/multi_process/simple_mp/simple_mp/%s/simple_mp -n 1 -c C" % self.target, "# ")
+
self.verify("Is another primary process running" in out,
"No other primary process detected")
@@ -197,15 +213,15 @@ class TestMultiprocess(TestCase, IxiaPacketGenerator):
for execution in validExecutions:
coreList = self.dut.get_core_list(execution['cores'])
- coreMask = dcts.create_mask(self.dut.get_core_list('1S/1C/1T'))
- portMask = dcts.create_mask([dutPorts[0], dutPorts[1]])
+ coreMask = dts.create_mask(self.dut.get_core_list('1S/1C/1T'))
+ portMask = dts.create_mask([dutPorts[0], dutPorts[1]])
self.dut.send_expect("./examples/multi_process/client_server_mp/mp_server/client_server_mp/mp_server/%s/mp_server -n %d -c %s -- -p %s -n %d" % (self.target, self.dut.get_memory_channels(), "0xA0", portMask, execution['nprocs']), "Finished Process Init", 20)
self.dut.send_expect("^Z", "\r\n")
self.dut.send_expect("bg", "# ")
for n in range(execution['nprocs']):
time.sleep(5)
- coreMask = dcts.create_mask([coreList[n]])
+ coreMask = dts.create_mask([coreList[n]])
self.dut.send_expect("./examples/multi_process/client_server_mp/mp_client/client_server_mp/mp_client/%s/mp_client -n %d -c %s --proc-type=secondary -- -n %d" % (self.target, self.dut.get_memory_channels(), coreMask, n), "Finished Process Init")
self.dut.send_expect("^Z", "\r\n")
self.dut.send_expect("bg", "# ")
@@ -220,12 +236,12 @@ class TestMultiprocess(TestCase, IxiaPacketGenerator):
for n in range(len(executions)):
self.verify(executions[n]['pps'] is not 0, "No traffic detected")
- dcts.results_table_add_header(['Server threads', 'Server Cores/Threads', 'Num-procs', 'Sockets/Cores/Threads', 'Num Ports', 'Frame Size', '%-age Line Rate', 'Packet Rate(mpps)'])
+ dts.results_table_add_header(['Server threads', 'Server Cores/Threads', 'Num-procs', 'Sockets/Cores/Threads', 'Num Ports', 'Frame Size', '%-age Line Rate', 'Packet Rate(mpps)'])
for execution in validExecutions:
- dcts.results_table_add_row([1, '1S/1C/1T', execution['nprocs'], execution['cores'], 2, 64, execution['pps'] / float(100000000 / (8 * 84)), execution['pps'] / float(1000000)])
+ dts.results_table_add_row([1, '1S/1C/1T', execution['nprocs'], execution['cores'], 2, 64, execution['pps'] / float(100000000 / (8 * 84)), execution['pps'] / float(1000000)])
- dcts.results_table_print()
+ dts.results_table_print()
def ip(self, port, frag, src, proto, tos, dst, chksum, len, options, version, flags, ihl, ttl, id):
self.add_tcl_cmd("protocol config -name ip")
diff --git a/tests/TestSuite_pmd.py b/tests/TestSuite_pmd.py
index 502ca79..b8b5af7 100644
--- a/tests/TestSuite_pmd.py
+++ b/tests/TestSuite_pmd.py
@@ -1,33 +1,51 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Test userland 10Gb PMD
-
"""
-import dcts
+import dts
import re
import time
from test_case import TestCase
from plotting import Plotting
from time import sleep
from settings import HEADER_SIZE
-
-#
-#
-# Test class.
-#
+from pmd_output import PmdOutput
class TestPmd(TestCase):
- #
- #
- # Utility methods and other non-test code.
- #
-
def plot_results(self, number_ports):
cores_configs = []
@@ -50,13 +68,8 @@ class TestPmd(TestCase):
ylabel='% linerate',
legend=cores_configs)
- dcts.results_plot_print(image_path)
+ dts.results_plot_print(image_path)
- #
- #
- #
- # Test cases.
- #
def set_up_all(self):
"""
Run at the start of each test suite.
@@ -105,6 +118,8 @@ class TestPmd(TestCase):
self.plotting = Plotting(self.dut.crb['name'], self.target, self.nic)
+ self.pmdout = PmdOutput(self.dut)
+
def set_up(self):
"""
Run before each test case.
@@ -115,7 +130,7 @@ class TestPmd(TestCase):
"""
PMD Performance Benchmarking with 4 ports.
"""
- all_cores_mask = dcts.create_mask(self.dut.get_core_list("all"))
+ all_cores_mask = dts.create_mask(self.dut.get_core_list("all"))
# prepare traffic generator input
self.verify(len(self.dut_ports) >= 4,
@@ -147,29 +162,17 @@ class TestPmd(TestCase):
else:
queues = 1
- core_mask = dcts.create_mask(core_list)
- port_mask = dcts.create_mask(self.dut.get_ports(self.nic))
-
- commandLine = "./%s/app/testpmd -c %s -n %d %s-- -i \
---coremask=%s --rxq=%d --txq=%d --rxd=512 --txd=512 --burst=32 --rxfreet=64 --mbcache=128 \
---portmask=%s --txpt=36 --txht=0 --txwt=0 --txfreet=32 --txrst=32" % (self.target,
- all_cores_mask,
- self.dut.get_memory_channels(
- ),
- self.blacklist,
- core_mask,
- queues,
- queues,
- port_mask
- )
+ core_mask = dts.create_mask(core_list)
+ port_mask = dts.create_mask(self.dut.get_ports(self.nic))
+
+ self.pmdout.start_testpmd("all", "--coremask=%s --rxq=%d --txq=%d --portmask=%s" % (core_mask, queues, queues, port_mask))
info = "Executing PMD (mac fwd) using %s\n" % test_cycle['cores']
- dcts.report(info, annex=True)
+ dts.report(info, annex=True)
self.logger.info(info)
- dcts.report(commandLine + "\n\n", frame=True, annex=True)
+ dts.report(commandLine + "\n\n", frame=True, annex=True)
- self.dut.send_expect(commandLine, "testpmd> ", 100)
# self.dut.send_expect("set fwd mac", "testpmd> ", 100)
self.dut.send_expect("start", "testpmd> ")
@@ -200,7 +203,7 @@ class TestPmd(TestCase):
frame_size] is not 0, "No traffic detected")
# Print results
- dcts.results_table_add_header(self.table_header)
+ dts.results_table_add_header(self.table_header)
for frame_size in self.frame_sizes:
table_row = [frame_size]
@@ -209,17 +212,17 @@ class TestPmd(TestCase):
table_row.append(test_cycle['Mpps'][frame_size])
table_row.append(test_cycle['pct'][frame_size])
- dcts.results_table_add_row(table_row)
+ dts.results_table_add_row(table_row)
self.plot_results(number_ports=4)
- dcts.results_table_print()
+ dts.results_table_print()
def test_perf_pmd_performance_2ports(self):
"""
PMD Performance Benchmarking with 2 ports.
"""
- all_cores_mask = dcts.create_mask(self.dut.get_core_list("all"))
+ all_cores_mask = dts.create_mask(self.dut.get_core_list("all"))
# prepare traffic generator input
tgen_input = []
@@ -242,27 +245,16 @@ class TestPmd(TestCase):
else:
queues = 1
- core_mask = dcts.create_mask(core_list)
- port_mask = dcts.create_mask([self.dut_ports[0], self.dut_ports[1]])
-
- command_line = "./%s/app/testpmd -c %s -n %d %s-- -i --coremask=%s \
---rxq=%d --txq=%d --rxd=512 --txd=512 --burst=32 --rxfreet=64 --mbcache=128 \
---portmask=%s --txpt=36 --txht=0 --txwt=0 --txfreet=32 --txrst=32" % (self.target,
- all_cores_mask,
- self.dut.get_memory_channels(
- ),
- self.blacklist,
- core_mask,
- queues,
- queues,
- port_mask)
+ core_mask = dts.create_mask(core_list)
+ port_mask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])
+
+ self.pmdout.start_testpmd("all", "--coremask=%s --rxq=%d --txq=%d --portmask=%s" % (core_mask, queues, queues, port_mask))
+ command_line = self.pmdout.get_pmd_cmd()
info = "Executing PMD using %s\n" % test_cycle['cores']
self.logger.info(info)
- dcts.report(info, annex=True)
- dcts.report(command_line + "\n\n", frame=True, annex=True)
-
- self.dut.send_expect(command_line, "testpmd> ", 100)
+ dts.report(info, annex=True)
+ dts.report(command_line + "\n\n", frame=True, annex=True)
self.dut.send_expect("start", "testpmd> ")
for frame_size in self.frame_sizes:
@@ -292,17 +284,17 @@ class TestPmd(TestCase):
frame_size] > 0, "No traffic detected")
# Print results
- dcts.results_table_add_header(self.table_header)
+ dts.results_table_add_header(self.table_header)
for frame_size in self.frame_sizes:
table_row = [frame_size]
for test_cycle in self.test_cycles:
table_row.append(test_cycle['Mpps'][frame_size])
table_row.append(test_cycle['pct'][frame_size])
- dcts.results_table_add_row(table_row)
+ dts.results_table_add_row(table_row)
self.plot_results(number_ports=2)
- dcts.results_table_print()
+ dts.results_table_print()
def test_checksum_checking(self):
"""
@@ -311,26 +303,15 @@ class TestPmd(TestCase):
self.dut.kill_all()
- all_cores_mask = dcts.create_mask(self.dut.get_core_list("all"))
- core_mask = dcts.create_mask(self.dut.get_core_list('1S/1C/1T',
- socket=self.ports_socket))
- port_mask = dcts.create_mask([self.dut_ports[0], self.dut_ports[1]])
+ all_cores_mask = dts.create_mask(self.dut.get_core_list("all"))
+ core_mask = dts.create_mask(self.dut.get_core_list('1S/1C/1T',
+ socket=self.ports_socket))
+ port_mask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])
for rxfreet_value in self.rxfreet_values:
- cmd = "./%s/app/testpmd -c %s -n %d %s-- \
---coremask=%s --portmask=%s --nb-cores=2 --enable-rx-cksum --disable-hw-vlan \
---disable-rss --crc-strip --rxd=1024 --txd=1024 --rxfreet=%d -i" % (self.target,
- all_cores_mask,
- self.dut.get_memory_channels(),
- self.blacklist,
- core_mask,
- port_mask,
- rxfreet_value
- )
-
- self.dut.send_expect(cmd, "testpmd> ", 120)
- # self.dut.send_expect("set fwd csum", "testpmd> ")
+ self.pmdout.start_testpmd("all", "--coremask=%s --portmask=%s --nb-cores=2 --enable-rx-cksum --disable-hw-vlan --disable-rss --crc-strip --rxd=1024 --txd=1024 --rxfreet=%d" % (core_mask, port_mask, rxfreet_value))
+ self.dut.send_expect("set fwd csum", "testpmd> ")
self.dut.send_expect("start", "testpmd> ")
self.send_packet(self.frame_sizes[0], checksum_test=True)
@@ -352,23 +333,12 @@ class TestPmd(TestCase):
self.dut.kill_all()
- all_cores_mask = dcts.create_mask(self.dut.get_core_list("all"))
- core_mask = dcts.create_mask(self.dut.get_core_list('1S/1C/1T',
- socket=self.ports_socket))
- port_mask = dcts.create_mask([self.dut_ports[0], self.dut_ports[1]])
-
- cmd = "./%s/app/testpmd -c %s -n %d %s-- -i \
---coremask=%s --rxd=512 --txd=512 --burst=32 --rxfreet=64 --mbcache=128 \
---portmask=%s --txpt=36 --txht=0 --txwt=0 --txfreet=32 --txrst=32" % (self.target,
- all_cores_mask,
- self.dut.get_memory_channels(
- ),
- self.blacklist,
- core_mask,
- port_mask
- )
-
- self.dut.send_expect(cmd, "testpmd> ", 120)
+ all_cores_mask = dts.create_mask(self.dut.get_core_list("all"))
+ core_mask = dts.create_mask(self.dut.get_core_list('1S/1C/1T',
+ socket=self.ports_socket))
+ port_mask = dts.create_mask([self.dut_ports[0], self.dut_ports[1]])
+
+ self.pmdout.start_testpmd("all", "--coremask=%s --portmask=%s" % (core_mask, port_mask))
self.dut.send_expect("start", "testpmd> ")
for size in self.frame_sizes:
self.send_packet(size)
@@ -389,34 +359,23 @@ class TestPmd(TestCase):
return m
- def get_stat(self, portid, rx_tx):
+ def get_stats(self, portid):
"""
Get packets number from port statistic
"""
- out = self.dut.send_expect("show port stats %d" % portid, "testpmd> ")
-
- if rx_tx == "rx":
- result_scanner = r"RX-packets: ([0-9]+) \s* RX-errors: ([0-9]+) \s* RX-bytes: ([0-9]+)"
- elif rx_tx == "tx":
- result_scanner = r"TX-packets: ([0-9]+) \s* TX-errors: ([0-9]+) \s* TX-bytes: ([0-9]+)"
- else:
- return None
-
- scanner = re.compile(result_scanner, re.DOTALL)
- m = scanner.search(out)
-
- return m.groups()
+ stats = self.pmdout.get_pmd_stats(portid)
+ return stats
def send_packet(self, frame_size, checksum_test=False):
"""
Send 1 packet to portid
"""
- gp0tx_pkts, _, gp0tx_bytes = [int(
- _) for _ in self.get_stat(self.dut_ports[0], "tx")]
- gp1rx_pkts, gp1rx_err, gp1rx_bytes = [int(
- _) for _ in self.get_stat(self.dut_ports[1], "rx")]
+ port0_stats = self.get_stats(self.dut_ports[0])
+ gp0tx_pkts, gp0tx_bytes = [port0_stats['TX-packets'], port0_stats['TX-bytes']]
+ port1_stats = self.get_stats(self.dut_ports[1])
+ gp1rx_pkts, gp1rx_err, gp1rx_bytes = [port1_stats['RX-packets'], port1_stats['RX-errors'], port1_stats['RX-bytes']]
interface = self.tester.get_interface(
self.tester.get_local_port(self.dut_ports[1]))
@@ -438,10 +397,10 @@ class TestPmd(TestCase):
out = self.tester.scapy_execute()
time.sleep(.5)
- p0tx_pkts, _, p0tx_bytes = [int(_) for _ in self.get_stat(
- self.dut_ports[0], "tx")]
- p1rx_pkts, p1rx_err, p1rx_bytes = [int(
- _) for _ in self.get_stat(self.dut_ports[1], "rx")]
+ port0_stats = self.get_stats(self.dut_ports[0])
+ p0tx_pkts, p0tx_bytes = [port0_stats['TX-packets'], port0_stats['TX-bytes']]
+ port1_stats = self.get_stats(self.dut_ports[1])
+ p1rx_pkts, p1rx_err, p1rx_bytes = [port1_stats['RX-packets'], port1_stats['RX-errors'], port1_stats['RX-bytes']]
p0tx_pkts -= gp0tx_pkts
p0tx_bytes -= gp0tx_bytes
diff --git a/tests/TestSuite_pmd_bonded.py b/tests/TestSuite_pmd_bonded.py
index 3553a5f..77afe1d 100644
--- a/tests/TestSuite_pmd_bonded.py
+++ b/tests/TestSuite_pmd_bonded.py
@@ -1,36 +1,81 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
-
Test userland 10Gb PMD.
-
"""
import time
import re
import random
from socket import htons, htonl
-import pdb
+from functools import wraps
-import dcts
+import dts
from test_case import TestCase
-
-#
-#
-# Test class.
-#
+from exception import TimeoutException
+from settings import TIMEOUT
+from pmd_output import PmdOutput
+
+SOCKET_0 = 0
+SOCKET_1 = 1
+
+MODE_ROUND_ROBIN = 0
+MODE_ACTIVE_BACKUP = 1
+MODE_XOR_BALANCE = 2
+MODE_BROADCAST = 3
+MODE_LACP = 4
+MODE_TLB_BALANCE = 5
+MODE_ALB_BALANCE = 6
+
+FRAME_SIZE_64 = 64
+FRAME_SIZE_65 = 65
+FRAME_SIZE_128 = 128
+FRAME_SIZE_256 = 256
+FRAME_SIZE_512 = 512
+FRAME_SIZE_1024 = 1024
+FRAME_SIZE_1280 = 1280
+FRAME_SIZE_1518 = 1518
+
+S_MAC_IP_PORT = [('52:00:00:00:00:00', '10.239.129.65', 61),
+ ('52:00:00:00:00:01', '10.239.129.66', 62),
+ ('52:00:00:00:00:02', '10.239.129.67', 63)]
+
+D_MAC_IP_PORT = []
+LACP_MESSAGE_SIZE = 128
class TestPmdBonded(TestCase):
- #
- #
- # Utility methods and other non-test code.
- #
- # Insert or move non-test functions here.
-
def get_stats(self, portid, rx_tx):
"""
Get packets number from port statistic
@@ -50,9 +95,8 @@ class TestPmdBonded(TestCase):
return m.groups()
- def send_packet(self, port_id, frame_size=64, count=1, reverse_verify=False, **ether_ip):
+ def parse_ether_ip(self, dest_port, **ether_ip):
"""
- Send count packet to portid
ether_ip:
'ether':
{
@@ -74,124 +118,204 @@ class TestPmdBonded(TestCase):
'src_port':53
}
"""
+ ret_ether_ip = {}
+ ether = {}
+ dot1q = {}
+ ip = {}
+ udp = {}
- gp0rx_pkts, gp0rx_err, gp0rx_bytes = [int(_) for _ in self.get_stats(self.dut_ports[port_id], "rx")]
-
- itf = self.tester.get_interface(self.tester.get_local_port(self.dut_ports[port_id]))
+ try:
+ dut_dest_port = self.dut_ports[dest_port]
+ except Exception, e:
+ dut_dest_port = dest_port
if not ether_ip.get('ether'):
- dest_mac = self.dut.get_mac_address(self.dut_ports[port_id])
- src_mac = "52:00:00:00:00:00"
+ ether['dest_mac'] = self.dut.get_mac_address(dut_dest_port)
+ ether['src_mac'] = "52:00:00:00:00:00"
else:
if not ether_ip['ether'].get('dest_mac'):
- dest_mac = self.dut.get_mac_address(self.dut_ports[port_id])
+ ether['dest_mac'] = self.dut.get_mac_address(dut_dest_port)
else:
- dest_mac = ether_ip['ether']['dest_mac']
+ ether['dest_mac'] = ether_ip['ether']['dest_mac']
if not ether_ip['ether'].get('src_mac'):
- src_mac = "52:00:00:00:00:00"
+ ether['src_mac'] = "52:00:00:00:00:00"
else:
- src_mac = ether_ip["ether"]["src_mac"]
+ ether['src_mac'] = ether_ip["ether"]["src_mac"]
if not ether_ip.get('dot1q'):
pass
else:
if not ether_ip['dot1q'].get('vlan'):
- vlan = '1'
+ dot1q['vlan'] = '1'
else:
- vlan = ether_ip['dot1q']['vlan']
+ dot1q['vlan'] = ether_ip['dot1q']['vlan']
if not ether_ip.get('ip'):
- dest_ip = "10.239.129.88"
- src_ip = "10.239.129.65"
+ ip['dest_ip'] = "10.239.129.88"
+ ip['src_ip'] = "10.239.129.65"
else:
if not ether_ip['ip'].get('dest_ip'):
- dest_ip = "10.239.129.88"
+ ip['dest_ip'] = "10.239.129.88"
else:
- dest_ip = ether_ip['ip']['dest_ip']
+ ip['dest_ip'] = ether_ip['ip']['dest_ip']
if not ether_ip['ip'].get('src_ip'):
- src_ip = "10.239.129.65"
+ ip['src_ip'] = "10.239.129.65"
else:
- src_ip = ether_ip['ip']['src_ip']
+ ip['src_ip'] = ether_ip['ip']['src_ip']
if not ether_ip.get('udp'):
- dest_port = 53
- src_port = 53
+ udp['dest_port'] = 53
+ udp['src_port'] = 53
else:
if not ether_ip['udp'].get('dest_port'):
- dest_port = 53
+ udp['dest_port'] = 53
else:
- dest_port = ether_ip['udp']['dest_port']
+ udp['dest_port'] = ether_ip['udp']['dest_port']
if not ether_ip['udp'].get('src_port'):
- src_port = 53
+ udp['src_port'] = 53
else:
- src_port = ether_ip['udp']['src_port']
+ udp['src_port'] = ether_ip['udp']['src_port']
+
+ ret_ether_ip['ether'] = ether
+ ret_ether_ip['dot1q'] = dot1q
+ ret_ether_ip['ip'] = ip
+ ret_ether_ip['udp'] = udp
+
+ return ret_ether_ip
+
+ def send_packet(self,
+ dest_port,
+ src_port=False,
+ frame_size=FRAME_SIZE_64,
+ count=1,
+ invert_verify=False,
+ **ether_ip):
+ """
+ Send count packet to portid
+ count: 1 or 2 or 3 or ... or 'MANY'
+ if count is 'MANY', then set count=1000,
+ send packets during 5 seconds.
+ ether_ip:
+ 'ether':
+ {
+ 'dest_mac':False
+ 'src_mac':"52:00:00:00:00:00"
+ }
+ 'dot1q':
+ {
+ 'vlan':1
+ }
+ 'ip':
+ {
+ 'dest_ip':"10.239.129.88"
+ 'src_ip':"10.239.129.65"
+ }
+ 'udp':
+ {
+ 'dest_port':53
+ 'src_port':53
+ }
+ """
+ during = 0
+ loop = 0
+ try:
+ count = int(count)
+ except ValueError as e:
+ if count == 'MANY':
+ during = 5
+ count = 1000
+ else:
+ raise e
+
+ if not src_port:
+ gp0rx_pkts, gp0rx_err, gp0rx_bytes = [int(_) for _ in self.get_stats(self.dut_ports[dest_port], "rx")]
+ itf = self.tester.get_interface(self.tester.get_local_port(self.dut_ports[dest_port]))
+ else:
+ gp0rx_pkts, gp0rx_err, gp0rx_bytes = [int(_) for _ in self.get_stats(dest_port, "rx")]
+ itf = src_port
+
+ ret_ether_ip = self.parse_ether_ip(dest_port, **ether_ip)
pktlen = frame_size - 18
padding = pktlen - 20
- self.tester.scapy_foreground()
- self.tester.scapy_append('nutmac="%s"' % dest_mac)
- self.tester.scapy_append('srcmac="%s"' % src_mac)
-
- if ether_ip.get('dot1q'):
- self.tester.scapy_append('vlanvalue=%d' % vlan)
- self.tester.scapy_append('destip="%s"' % dest_ip)
- self.tester.scapy_append('srcip="%s"' % src_ip)
- self.tester.scapy_append('destport=%d' % dest_port)
- self.tester.scapy_append('srcport=%d' % src_port)
- if not ether_ip.get('dot1q'):
- self.tester.scapy_append('sendp([Ether(dst=nutmac, src=srcmac)/IP(dst=destip, src=srcip, len=%s)/\
+ start = time.time()
+ while True:
+ self.tester.scapy_foreground()
+ self.tester.scapy_append('nutmac="%s"' % ret_ether_ip['ether']['dest_mac'])
+ self.tester.scapy_append('srcmac="%s"' % ret_ether_ip['ether']['src_mac'])
+
+ if ether_ip.get('dot1q'):
+ self.tester.scapy_append('vlanvalue=%d' % ret_ether_ip['dot1q']['vlan'])
+ self.tester.scapy_append('destip="%s"' % ret_ether_ip['ip']['dest_ip'])
+ self.tester.scapy_append('srcip="%s"' % ret_ether_ip['ip']['src_ip'])
+ self.tester.scapy_append('destport=%d' % ret_ether_ip['udp']['dest_port'])
+ self.tester.scapy_append('srcport=%d' % ret_ether_ip['udp']['src_port'])
+ if not ret_ether_ip.get('dot1q'):
+ self.tester.scapy_append('sendp([Ether(dst=nutmac, src=srcmac)/IP(dst=destip, src=srcip, len=%s)/\
UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)' % (pktlen, padding, itf, count))
- else:
- self.tester.scapy_append('sendp([Ether(dst=nutmac, src=srcmac)/Dot1Q(vlan=vlanvalue)/IP(dst=destip, src=srcip, len=%s)/\
+ else:
+ self.tester.scapy_append('sendp([Ether(dst=nutmac, src=srcmac)/Dot1Q(vlan=vlanvalue)/IP(dst=destip, src=srcip, len=%s)/\
UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)' % (pktlen, padding, itf, count))
- out = self.tester.scapy_execute()
+ self.tester.scapy_execute()
+ loop += 1
+
+ now = time.time()
+ if (now - start) >= during:
+ break
time.sleep(.5)
- p0rx_pkts, p0rx_err, p0rx_bytes = [int(_) for _ in self.get_stats(self.dut_ports[port_id], "rx")]
+ if not src_port:
+ p0rx_pkts, p0rx_err, p0rx_bytes = [int(_) for _ in self.get_stats(self.dut_ports[dest_port], "rx")]
+ else:
+ p0rx_pkts, p0rx_err, p0rx_bytes = [int(_) for _ in self.get_stats(dest_port, "rx")]
p0rx_pkts -= gp0rx_pkts
+ p0rx_bytes -= gp0rx_bytes
- if not reverse_verify:
- self.verify(p0rx_pkts == count, "Data not received by port")
+ if not invert_verify:
+ self.verify(p0rx_pkts >= count * loop,
+ "Data not received by port")
else:
- self.verify(p0rx_pkts == 0, "Data received by port,should not received")
- return out
+ global LACP_MESSAGE_SIZE
+ self.verify(p0rx_pkts == 0 or
+ p0rx_bytes / p0rx_pkts == LACP_MESSAGE_SIZE,
+ "Data received by port, but should not.")
+ return count * loop
- #
- #
- #
- # Test cases.
- #
- def set_up_all(self):
+ def blank_enter(self):
"""
- Run before each test suite
+ Just enter blank for the prompt 'testpmd> '
"""
- self.verify('bsdapp' not in self.target, "Bonding not support freebsd")
- self.frame_sizes = [64, 65, 128, 256, 512, 1024, 1280, 1518]
-
- self.eth_head_size = 18
- self.ip_head_size = 20
- self.udp_header_size = 8
-
- self.dut_ports = self.dut.get_ports(self.nic)
-
- self.port_mask = dcts.create_mask(self.dut_ports)
+ time.sleep(2)
+ self.dut.send_expect(" ", "testpmd> ")
- self.verify(len(self.dut_ports) >= 4, "Insufficient ports")
-
- self.ports_socket = self.dut.get_numa_id(self.dut_ports[0])
-
- self.all_cores_mask = dcts.create_mask(self.dut.get_core_list("all"))
-
- def set_up(self):
+ def dummy_timeout(func):
"""
- Run before each test case.
+ There are multiple threads, so maybe you can`t wait for the 'testpmd>',
+ if raising TIMEOUT, we will try to expect one more time.
"""
- pass
+ @wraps(func)
+ def ack_timeout(*args, **kwargs):
+ pmd_bond_instance = args[0]
+ try:
+ return func(*args, **kwargs)
+ except TimeoutException:
+ return pmd_bond_instance.blank_enter()
+ return ack_timeout
+
+ @dummy_timeout
+ def __send_expect(self, cmds, expected, timeout=TIMEOUT, alt_session=False):
+ """
+ Encapsulate private expect function because multiple threads printing issue.
+ """
+ return self.dut.send_expect(cmds, expected, timeout, alt_session)
def get_value_from_str(self, key_str, regx_str, string):
+ """
+ Get some values from the given string by the regular expression.
+ """
pattern = r"(?<=%s)%s" % (key_str, regx_str)
s = re.compile(pattern)
res = s.search(string)
@@ -201,36 +325,64 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
return res.group(0)
def get_detail_from_port_info(self, key_str, regx_str, port):
+ """
+ Get the detail info from the output of pmd cmd 'show port info <port num>'.
+ """
out = self.dut.send_expect("show port info %d" % port, "testpmd> ")
find_value = self.get_value_from_str(key_str, regx_str, out)
return find_value
def get_port_mac(self, port_id):
+ """
+ Get the specified port MAC.
+ """
return self.get_detail_from_port_info("MAC address: ", "([0-9A-F]{2}:){5}[0-9A-F]{2}", port_id)
def get_port_connect_socket(self, port_id):
+ """
+ Get the socket id which the specified port is connectting with.
+ """
return self.get_detail_from_port_info("Connect to socket: ", "\d+", port_id)
def get_port_memory_socket(self, port_id):
+ """
+ Get the socket id which the specified port memory is allocated on.
+ """
return self.get_detail_from_port_info("memory allocation on the socket: ", "\d+", port_id)
def get_port_link_status(self, port_id):
+ """
+ Get the specified port link status now.
+ """
return self.get_detail_from_port_info("Link status: ", "\d+", port_id)
def get_port_link_speed(self, port_id):
+ """
+ Get the specified port link speed now.
+ """
return self.get_detail_from_port_info("Link speed: ", "\d+", port_id)
def get_port_link_duplex(self, port_id):
+ """
+ Get the specified port link mode, duplex or siplex.
+ """
return self.get_detail_from_port_info("Link duplex: ", "\S+", port_id)
def get_port_promiscuous_mode(self, port_id):
+ """
+ Get the promiscuous mode of port.
+ """
return self.get_detail_from_port_info("Promiscuous mode: ", "\S+", port_id)
def get_port_allmulticast_mode(self, port_id):
+ """
+ Get the allmulticast mode of port.
+ """
return self.get_detail_from_port_info("Allmulticast mode: ", "\S+", port_id)
def get_port_vlan_offload(self, port_id):
"""
+ Function: get the port vlan settting info.
return value:
'strip':'on'
'filter':'on'
@@ -243,245 +395,659 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
return vlan_info
def get_info_from_bond_config(self, key_str, regx_str, bond_port):
+ """
+ Get info by executing the command "show bonding config".
+ """
out = self.dut.send_expect("show bonding config %d" % bond_port, "testpmd> ")
find_value = self.get_value_from_str(key_str, regx_str, out)
return find_value
def get_bond_mode(self, bond_port):
+ """
+ Get the mode of the bonding device which you choose.
+ """
return self.get_info_from_bond_config("Bonding mode: ", "\d*", bond_port)
def get_bond_balance_policy(self, bond_port):
+ """
+ Get the balance transmit policy of bonding device.
+ """
return self.get_info_from_bond_config("Balance Xmit Policy: ", "\S+", bond_port)
def get_bond_slaves(self, bond_port):
+ """
+ Get all the slaves of the bonding device which you choose.
+ """
try:
return self.get_info_from_bond_config("Slaves \(\d\): \[", "\d*( \d*)*", bond_port)
except Exception as e:
return self.get_info_from_bond_config("Slaves: \[", "\d*( \d*)*", bond_port)
def get_bond_active_slaves(self, bond_port):
+ """
+ Get the active slaves of the bonding device which you choose.
+ """
try:
return self.get_info_from_bond_config("Active Slaves \(\d\): \[", "\d*( \d*)*", bond_port)
except Exception as e:
return self.get_info_from_bond_config("Acitve Slaves: \[", "\d*( \d*)*", bond_port)
def get_bond_primary(self, bond_port):
+ """
+ Get the primary slave of the bonding device which you choose.
+ """
return self.get_info_from_bond_config("Primary: \[", "\d*", bond_port)
- def launch_app(self, cmd_param="-c 0xf -n 4 -- -i"):
- app_path = "./%s/app/testpmd" % self.target
- self.dut.send_expect(app_path + ' ' + cmd_param, "testpmd> ", 120)
+ def launch_app(self, pmd_param=" "):
+ """
+ Launch the testpmd app with the command parameters.
+ """
+ self.pmdout.start_testpmd("all", param=pmd_param)
def create_bonded_device(self, mode=0, socket=0, verify_detail=False):
+ """
+ Create a bonding device with the parameters you specified.
+ """
out = self.dut.send_expect("create bonded device %d %d" % (mode, socket), "testpmd> ")
- self.verify("Created new bonded device" in out, "Create bonded device on mode [%d] socket [%d] failed" % (mode, socket))
- bond_port = self.get_value_from_str("Created new bonded device eth_bond_testpmd_[\d] on \(port ", "\d+", out)
+ self.verify("Created new bonded device" in out,
+ "Create bonded device on mode [%d] socket [%d] failed" % (mode, socket))
+ bond_port = self.get_value_from_str("Created new bonded device eth_bond_testpmd_[\d] on \(port ",
+ "\d+",
+ out)
bond_port = int(bond_port)
if verify_detail:
out = self.dut.send_expect("show bonding config %d" % bond_port, "testpmd> ")
- self.verify("Bonding mode: %d" % mode in out, "Bonding mode display error when create bonded device")
- self.verify("Slaves: []" in out, "Slaves display error when create bonded device")
- self.verify("Active Slaves: []" in out, "Active Slaves display error when create bonded device")
- self.verify("Primary: []" not in out, "Primary display error when create bonded device")
+ self.verify("Bonding mode: %d" % mode in out,
+ "Bonding mode display error when create bonded device")
+ self.verify("Slaves: []" in out,
+ "Slaves display error when create bonded device")
+ self.verify("Active Slaves: []" in out,
+ "Active Slaves display error when create bonded device")
+ self.verify("Primary: []" not in out,
+ "Primary display error when create bonded device")
out = self.dut.send_expect("show port info %d" % bond_port, "testpmd> ")
- self.verify("Connect to socket: %d" % socket in out, "Bonding port connect socket error")
- self.verify("Link status: down" in out, "Bonding port default link status error")
- self.verify("Link speed: 0 Mbps" in out, "Bonding port default link speed error")
+ self.verify("Connect to socket: %d" % socket in out,
+ "Bonding port connect socket error")
+ self.verify("Link status: down" in out,
+ "Bonding port default link status error")
+ self.verify("Link speed: 0 Mbps" in out,
+ "Bonding port default link speed error")
return bond_port
def start_all_ports(self):
- self.dut.send_expect("port start all", "testpmd> ")
- time.sleep(5)
+ """
+ Start all the ports which the testpmd can see.
+ """
+ self.start_port("all")
- def add_slave_to_bonding_device(self, bond_port, reverse_verify=False, *slave_port):
+ def start_port(self, port):
+ """
+ Start a port which the testpmd can see.
+ """
+ self.__send_expect("port start %s" % str(port), "testpmd> ")
+ time.sleep(3)
+
+ def add_slave_to_bonding_device(self, bond_port, invert_verify=False, *slave_port):
+ """
+ Add the ports into the bonding device as slaves.
+ """
if len(slave_port) <= 0:
- dcts.RED("No port exist when add slave to bonded device")
+ dts.RED("No port exist when add slave to bonded device")
for slave_id in slave_port:
- self.dut.send_expect("add bonding slave %d %d" % (slave_id, bond_port), "testpmd> ")
+ self.__send_expect("add bonding slave %d %d" % (slave_id, bond_port), "testpmd> ")
slaves = self.get_info_from_bond_config("Slaves \(\d\): \[", "\d*( \d*)*", bond_port)
- if not reverse_verify:
- self.verify(str(slave_id) in slaves, "Add port as bonding slave failed")
+ if not invert_verify:
+ self.verify(str(slave_id) in slaves,
+ "Add port as bonding slave failed")
else:
- self.verify(str(slave_id) not in slaves, "Add port as bonding slave successfully,should fail")
+ self.verify(str(slave_id) not in slaves,
+ "Add port as bonding slave successfully,should fail")
- def remove_slave_from_bonding_device(self, bond_port, reverse_verify=False, *slave_port):
+ def remove_slave_from_bonding_device(self, bond_port, invert_verify=False, *slave_port):
+ """
+ Remove the specified slave port from the bonding device.
+ """
if len(slave_port) <= 0:
- dcts.RED("No port exist when remove slave from bonded device")
+ dts.RED("No port exist when remove slave from bonded device")
for slave_id in slave_port:
- self.dut.send_expect("remove bonding slave %d %d" % (slave_id, bond_port), "testpmd> ")
+ self.dut.send_expect("remove bonding slave %d %d" % (int(slave_id), bond_port), "testpmd> ")
out = self.get_info_from_bond_config("Slaves: \[", "\d*( \d*)*", bond_port)
- if not reverse_verify:
- self.verify(str(slave_id) not in out, "Remove slave to fail from bonding device")
+ if not invert_verify:
+ self.verify(str(slave_id) not in out,
+ "Remove slave to fail from bonding device")
else:
- self.verify(str(slave_id) in out, "Remove slave successfully from bonding device,should be failed")
+ self.verify(str(slave_id) in out,
+ "Remove slave successfully from bonding device,should be failed")
+
+ def remove_all_slaves(self, bond_port):
+ """
+ Remove all slaves of specified bound device.
+ """
+ all_slaves = self.get_bond_slaves(bond_port)
+ all_slaves = all_slaves.split()
+ if len(all_slaves) == 0:
+ pass
+ else:
+ self.remove_slave_from_bonding_device(bond_port, False, *all_slaves)
- def set_primary_for_bonding_device(self, bond_port, slave_port, reverse_verify=False):
+ def set_primary_for_bonding_device(self, bond_port, slave_port, invert_verify=False):
+ """
+ Set the primary slave for the bonding device.
+ """
self.dut.send_expect("set bonding primary %d %d" % (slave_port, bond_port), "testpmd> ")
out = self.get_info_from_bond_config("Primary: \[", "\d*", bond_port)
- if not reverse_verify:
- self.verify(str(slave_port) in out, "Set bonding primary port failed")
+ if not invert_verify:
+ self.verify(str(slave_port) in out,
+ "Set bonding primary port failed")
else:
- self.verify(str(slave_port) not in out, "Set bonding primary port successfully,should not success")
+ self.verify(str(slave_port) not in out,
+ "Set bonding primary port successfully,should not success")
def set_mode_for_bonding_device(self, bond_port, mode):
+ """
+ Set the mode for the bonding device.
+ """
self.dut.send_expect("set bonding mode %d %d" % (mode, bond_port), "testpmd> ")
mode_value = self.get_bond_mode(bond_port)
self.verify(str(mode) in mode_value, "Set bonding mode failed")
def set_mac_for_bonding_device(self, bond_port, mac):
+ """
+ Set the MAC for the bonding device.
+ """
self.dut.send_expect("set bonding mac_addr %s %s" % (bond_port, mac), "testpmd> ")
new_mac = self.get_port_mac(bond_port)
self.verify(new_mac == mac, "Set bonding mac failed")
def set_balance_policy_for_bonding_device(self, bond_port, policy):
+ """
+ Set the balance transmit policy for the bonding device.
+ """
self.dut.send_expect("set bonding balance_xmit_policy %d %s" % (bond_port, policy), "testpmd> ")
new_policy = self.get_bond_balance_policy(bond_port)
policy = "BALANCE_XMIT_POLICY_LAYER" + policy.lstrip('l')
self.verify(new_policy == policy, "Set bonding balance policy failed")
- def test_create_bonded_devices_and_slaves(self):
+ def send_default_packet_to_slave(self, unbound_port, bond_port, pkt_count=100, **slaves):
"""
- Create bonded devices and slaves.
+ Send packets to the slaves and calculate the slave`s RX packets
+ and unbond port TX packets.
+ Parameters:
+ *** unbound_port: the unbonded port id
+ *** bond_port: the bonded device port id
+ *** slaves:
+ ******* 'active'=[]
+ ******* 'inactive'=[]
"""
- self.launch_app()
- bond_port_0 = self.create_bonded_device(1, 0, True)
+ pkt_orig = {}
+ pkt_now = {}
+ temp_count = 0
+ summary = 0
+
+ # send to slave ports
+ pkt_orig = self.get_all_stats(unbound_port, 'tx', bond_port, **slaves)
+ for slave in slaves['active']:
+ temp_count = self.send_packet(self.dut_ports[slave], False, FRAME_SIZE_64, pkt_count)
+ summary += temp_count
+ for slave in slaves['inactive']:
+ self.send_packet(self.dut_ports[slave], False, FRAME_SIZE_64, pkt_count, True)
+ pkt_now = self.get_all_stats(unbound_port, 'tx', bond_port, **slaves)
+
+ for key in pkt_now:
+ for num in [0, 1, 2]:
+ pkt_now[key][num] -= pkt_orig[key][num]
+
+ return pkt_now, summary
+
+ def send_customized_packet_to_slave(self, unbound_port, bond_port, *pkt_info, **slaves):
+ """
+ Send packets to the slaves and calculate the slave`s RX packets
+ and unbond port TX packets.
+ Parameters:
+ *** unbound_port: the unbonded port id
+ *** bond_port: the bonded device port id
+ *** pkt_info: the first is necessary which will describe the packet,
+ the second is optional which will describe the params of
+ the function send_packet
+ *** slaves:
+ ******* 'active'=[]
+ ******* 'inactive'=[]
+ """
+ pkt_orig = {}
+ pkt_now = {}
+ temp_count = 0
+ summary = 0
+
+ pkt_info_len = len(pkt_info)
+ if pkt_info_len < 1:
+ self.verify(False, "At least one members for pkt_info!")
+
+ ether_ip = pkt_info[0]
+ if pkt_info_len > 1:
+ pkt_size = pkt_info[1].get('frame_size', FRAME_SIZE_64)
+ pkt_count = pkt_info[1].get('pkt_count', 1)
+ invert_verify = pkt_info[1].get('verify', False)
+ else:
+ pkt_size = FRAME_SIZE_64
+ pkt_count = 1
+ invert_verify = False
+
+ # send to slave ports
+ pkt_orig = self.get_all_stats(unbound_port, 'tx', bond_port, **slaves)
+ for slave in slaves['active']:
+ temp_count = self.send_packet(self.dut_ports[slave], False, pkt_size, pkt_count, invert_verify, **ether_ip)
+ summary += temp_count
+ for slave in slaves['inactive']:
+ self.send_packet(self.dut_ports[slave], False, FRAME_SIZE_64, pkt_count, True)
+ pkt_now = self.get_all_stats(unbound_port, 'tx', bond_port, **slaves)
+
+ for key in pkt_now:
+ for num in [0, 1, 2]:
+ pkt_now[key][num] -= pkt_orig[key][num]
+
+ return pkt_now, summary
+
+ def send_customized_packet_to_bond_port(self, dut_unbound_port, dut_bond_port, tester_bond_port, pkt_count=100, **slaves):
+ pkt_orig = {}
+ pkt_now = {}
+ temp_count = 0
+ summary = 0
+
+ # send to bond_port
+ pkt_orig = self.get_all_stats(dut_unbound_port, 'tx', dut_bond_port, **slaves)
+
+ if len(slaves['active']) != 0:
+ invert_verify = False
+ else:
+ invert_verify = True
+
+ dest_mac = self.get_port_mac(dut_bond_port)
+
+ ether_ip = {}
+ ether = {}
+ ether['src_mac'] = ''
+ ether['dest_mac'] = dest_mac
+ ether_ip['ether'] = ether
+
+ global S_MAC_IP_PORT
+ source = S_MAC_IP_PORT
+
+ for src_mac, src_ip, src_port in source:
+ ether_ip['ether']['src_mac'] = src_mac
+ temp_count = self.send_packet(dut_bond_port, tester_bond_port, FRAME_SIZE_64, pkt_count, invert_verify, **ether_ip)
+ summary += temp_count
+ pkt_now = self.get_all_stats(dut_unbound_port, 'tx', dut_bond_port, **slaves)
+
+ for key in pkt_now:
+ for num in [0, 1, 2]:
+ pkt_now[key][num] -= pkt_orig[key][num]
+
+ return pkt_now, summary
+
+ def send_default_packet_to_unbound_port(self, unbound_port, bond_port, pkt_count=300, **slaves):
+ """
+ Send packets to the unbound port and calculate unbound port RX packets
+ and the slave`s TX packets.
+ Parameters:
+ *** unbound_port: the unbonded port id
+ *** bond_port: the bonded device port id
+ *** slaves:
+ ******* 'actvie':[]
+ ******* 'inactive':[]
+ """
+ pkt_orig = {}
+ pkt_now = {}
+ summary = 0
+
+ # send to unbonded device
+ pkt_orig = self.get_all_stats(unbound_port, 'rx', bond_port, **slaves)
+ summary = self.send_packet(unbound_port, False, FRAME_SIZE_64, pkt_count)
+ pkt_now = self.get_all_stats(unbound_port, 'rx', bond_port, **slaves)
+
+ for key in pkt_now:
+ for num in [0, 1, 2]:
+ pkt_now[key][num] -= pkt_orig[key][num]
+
+ return pkt_now, summary
+
+ def send_customized_packet_to_unbound_port(self, unbound_port, bond_port, policy, vlan_tag=False, pkt_count=100, **slaves):
+ """
+ Verify that transmitting the packets correctly in the XOR mode.
+ Parameters:
+ *** unbound_port: the unbonded port id
+ *** bond_port: the bonded device port id
+ *** policy:'L2' , 'L23' or 'L34'
+ *** vlan_tag:False or True
+ *** slaves:
+ ******* 'active'=[]
+ ******* 'inactive'=[]
+ """
+ pkt_orig = {}
+ pkt_now = {}
+ summary = 0
+ temp_count = 0
+
+ # send to unbound_port
+ pkt_orig = self.get_all_stats(unbound_port, 'rx', bond_port, **slaves)
+
+ dest_mac = self.dut.get_mac_address(self.dut_ports[unbound_port])
+ dest_ip = "10.239.129.88"
+ dest_port = 53
+
+ global D_MAC_IP_PORT
+ D_MAC_IP_PORT = [dest_mac, dest_ip, dest_port]
+
+ ether_ip = {}
+ ether = {}
+ ip = {}
+ udp = {}
+
+ ether['dest_mac'] = False
+ ip['dest_ip'] = dest_ip
+ udp['dest_port'] = 53
+ if vlan_tag:
+ dot1q = {}
+ dot1q['vlan'] = random.randint(1, 50)
+ ether_ip['dot1q'] = dot1q
+
+ ether_ip['ether'] = ether
+ ether_ip['ip'] = ip
+ ether_ip['udp'] = udp
+
+ global S_MAC_IP_PORT
+ source = S_MAC_IP_PORT
+
+ for src_mac, src_ip, src_port in source:
+ ether_ip['ether']['src_mac'] = src_mac
+ ether_ip['ip']['src_ip'] = src_ip
+ ether_ip['udp']['src_port'] = src_port
+ temp_count = self.send_packet(unbound_port, False, FRAME_SIZE_64, pkt_count, False, **ether_ip)
+ summary += temp_count
+ pkt_now = self.get_all_stats(unbound_port, 'rx', bond_port, **slaves)
+
+ for key in pkt_now:
+ for num in [0, 1, 2]:
+ pkt_now[key][num] -= pkt_orig[key][num]
+
+ return pkt_now, summary
+
+ #
+ # Test cases.
+ #
+ def set_up_all(self):
+ """
+ Run before each test suite
+ """
+ self.verify('bsdapp' not in self.target, "Bonding not support freebsd")
+ self.frame_sizes = [64, 65, 128, 256, 512, 1024, 1280, 1518]
+
+ self.eth_head_size = 18
+ self.ip_head_size = 20
+ self.udp_header_size = 8
+
+ self.dut_ports = self.dut.get_ports(self.nic)
+
+ self.port_mask = dts.create_mask(self.dut_ports)
+
+ self.verify(len(self.dut_ports) >= 4, "Insufficient ports")
+
+ self.ports_socket = self.dut.get_numa_id(self.dut_ports[0])
+
+ self.all_cores_mask = dts.create_mask(self.dut.get_core_list("all"))
+
+ self.pmdout = PmdOutput(self.dut)
+
+ self.tester_bond = "bond0"
+
+ def set_up(self):
+ """
+ Run before each test case.
+ """
+ if self.dut.want_func_tests:
+ self.launch_app()
+ elif self.dut.want_perf_tests:
+ pmd_param = "--burst=32 --rxfreet=32 --mbcache=250 --txpt=32 \
+--rxht=8 --rxwt=0 --txfreet=32 --txrst=32 --txqflags=0xf01"
+ self.launch_app(pmd_param)
+ else:
+ self.verify(False,
+ "Test type not etting," +
+ "please check framework to set test type to be function or performance.")
+
+ def verify_bound_basic_opt(self, mode_set):
+ """
+ Do some basic operations to bonded devices and slaves,
+ such as adding, removing, setting primary or setting mode.
+ """
+ bond_port_0 = self.create_bonded_device(mode_set, SOCKET_0, True)
self.add_slave_to_bonding_device(bond_port_0, False, self.dut_ports[1])
- self.start_all_ports()
+
mode_value = self.get_bond_mode(bond_port_0)
- self.verify('1' in mode_value, "Bonding mode show error")
- slaves = self.get_bond_slaves(bond_port_0)
- self.verify(str(self.dut_ports[1]) in slaves, "Bonding slaves show error")
- primary = self.get_bond_primary(bond_port_0)
- self.verify(str(self.dut_ports[1]) in primary, "Bonding primary show error")
+ self.verify('%d' % mode_set in mode_value,
+ "Setting bonding mode error")
- bond_port_1 = self.create_bonded_device(1, 0)
+ bond_port_1 = self.create_bonded_device(mode_set, SOCKET_0)
self.add_slave_to_bonding_device(bond_port_0, False, self.dut_ports[0])
self.add_slave_to_bonding_device(bond_port_1, True, self.dut_ports[0])
- self.set_mode_for_bonding_device(bond_port_0, 3)
+ OTHER_MODE = mode_set + 1 if not mode_set else mode_set - 1
+ self.set_mode_for_bonding_device(bond_port_0, OTHER_MODE)
+ self.set_mode_for_bonding_device(bond_port_0, mode_set)
+
self.add_slave_to_bonding_device(bond_port_0, False, self.dut_ports[2])
time.sleep(5)
self.set_primary_for_bonding_device(bond_port_0, self.dut_ports[2])
- self.remove_slave_from_bonding_device(bond_port_0, False, self.dut_ports[1])
- self.remove_slave_from_bonding_device(bond_port_0, False, self.dut_ports[0])
self.remove_slave_from_bonding_device(bond_port_0, False, self.dut_ports[2])
+ primary_now = self.get_bond_primary(bond_port_0)
+ self.verify(int(primary_now) == self.dut_ports[1],
+ "Reset primary slave failed after removing primary slave")
- def test_bonded_mac_address(self):
+ for bond_port in [bond_port_0, bond_port_1]:
+ self.remove_all_slaves(bond_port)
+
+ self.dut.send_expect("quit", "# ")
+ self.launch_app()
+
+ def verify_bound_mac_opt(self, mode_set):
"""
- Create bonded device, add one slave, verify bonded device MAC address is the slave's MAC.
+ Create bonded device, add one slave,
+ verify bonded device MAC action varies with the mode.
"""
- self.launch_app()
- bond_port = self.create_bonded_device(3, 1)
- self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[1])
mac_address_0_orig = self.get_port_mac(self.dut_ports[0])
mac_address_1_orig = self.get_port_mac(self.dut_ports[1])
mac_address_2_orig = self.get_port_mac(self.dut_ports[2])
mac_address_3_orig = self.get_port_mac(self.dut_ports[3])
+
+ bond_port = self.create_bonded_device(mode_set, SOCKET_1)
+ self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[1])
+
mac_address_bond_orig = self.get_port_mac(bond_port)
- self.verify(mac_address_1_orig == mac_address_bond_orig, "Bonded device MAC address not same with first slave MAC")
+ self.verify(mac_address_1_orig == mac_address_bond_orig,
+ "Bonded device MAC address not same with first slave MAC")
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[2])
mac_address_2_now = self.get_port_mac(self.dut_ports[2])
mac_address_bond_now = self.get_port_mac(bond_port)
- self.verify(mac_address_1_orig == mac_address_bond_now and mac_address_bond_now == mac_address_2_now,
- "NOT all slaves MAC address same with bonding device")
+ if mode_set in [MODE_ROUND_ROBIN, MODE_XOR_BALANCE, MODE_BROADCAST]:
+ self.verify(mac_address_1_orig == mac_address_bond_now and
+ mac_address_bond_now == mac_address_2_now,
+ "NOT all slaves MAC address same with bonding device in mode %d" % mode_set)
+ else:
+ self.verify(mac_address_1_orig == mac_address_bond_now and
+ mac_address_bond_now != mac_address_2_now,
+ "All slaves should not be the same in mode %d"
+ % mode_set)
new_mac = "00:11:22:00:33:44"
self.set_mac_for_bonding_device(bond_port, new_mac)
mac_address_1_now = self.get_port_mac(self.dut_ports[1])
mac_address_2_now = self.get_port_mac(self.dut_ports[2])
mac_address_bond_now = self.get_port_mac(bond_port)
- self.verify(mac_address_1_now == mac_address_2_now == mac_address_bond_now == new_mac,
- "Set mac failed for bonding device")
+ if mode_set in [MODE_ROUND_ROBIN, MODE_XOR_BALANCE, MODE_BROADCAST]:
+ self.verify(mac_address_1_now == mac_address_2_now == mac_address_bond_now == new_mac,
+ "Set mac failed for bonding device in mode %d" % mode_set)
+ elif mode_set == MODE_LACP:
+ self.verify(mac_address_bond_now == new_mac and
+ mac_address_1_now != new_mac and
+ mac_address_2_now != new_mac and
+ mac_address_1_now != mac_address_2_now,
+ "Set mac failed for bonding device in mode %d" % mode_set)
+ elif mode_set in [MODE_ACTIVE_BACKUP, MODE_TLB_BALANCE]:
+ self.verify(mac_address_bond_now == new_mac and
+ mac_address_1_now == new_mac and
+ mac_address_bond_now != mac_address_2_now,
+ "Set mac failed for bonding device in mode %d" % mode_set)
- self.dut.send_expect("port start %d" % bond_port, "testpmd> ")
- time.sleep(5)
self.set_primary_for_bonding_device(bond_port, self.dut_ports[2], False)
mac_address_1_now = self.get_port_mac(self.dut_ports[1])
mac_address_2_now = self.get_port_mac(self.dut_ports[2])
mac_address_bond_now = self.get_port_mac(bond_port)
- self.verify(mac_address_1_now == mac_address_2_now == mac_address_bond_now == new_mac,
+ self.verify(mac_address_bond_now == new_mac,
"Slave MAC changed when set primary slave")
+
+ mac_address_1_orig = mac_address_1_now
self.remove_slave_from_bonding_device(bond_port, False, self.dut_ports[2])
- primary_now = self.get_bond_primary(bond_port)
- self.verify(int(primary_now) == self.dut_ports[1], "Reset primary slave failed after removing primary slave")
mac_address_2_now = self.get_port_mac(self.dut_ports[2])
- self.verify(mac_address_2_now == mac_address_2_orig, "MAC not back to original after removing the port")
+ self.verify(mac_address_2_now == mac_address_2_orig,
+ "MAC not back to original after removing the port")
+
mac_address_1_now = self.get_port_mac(self.dut_ports[1])
mac_address_bond_now = self.get_port_mac(bond_port)
- self.verify(mac_address_1_now == mac_address_bond_now == new_mac,
- "Bonding device and slave MAC changed after removing the primary slave")
+ self.verify(mac_address_bond_now == new_mac and
+ mac_address_1_now == mac_address_1_orig,
+ "Bonding device or slave MAC changed after removing the primary slave")
- self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[3])
- self.remove_slave_from_bonding_device(bond_port, False, self.dut_ports[3])
- mac_address_3_now = self.get_port_mac(self.dut_ports[3])
- self.verify(mac_address_3_now == mac_address_3_orig, "Slave MAC not back to original after removing it")
-
- def test_device_promiscuous_mode(self):
+ self.remove_all_slaves(bond_port)
+ self.dut.send_expect("quit", "# ")
self.launch_app()
- bond_port = self.create_bonded_device(3, 0)
- self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
- port_enabled_num = 0
- for port_id in [0, 1, 2, 4]:
+
+ def verify_bound_promisc_opt(self, mode_set):
+ """
+ Set promiscuous mode on bonded device, verify bonded device and all slaves
+ have different actions by the different modes.
+ """
+ unbound_port = self.dut_ports[3]
+ bond_port = self.create_bonded_device(mode_set, SOCKET_0)
+ self.add_slave_to_bonding_device(bond_port,
+ False,
+ self.dut_ports[0],
+ self.dut_ports[1],
+ self.dut_ports[2])
+ self.dut.send_expect("set portlist %d,%d" % (unbound_port, bond_port), "testpmd> ")
+ self.start_port(bond_port)
+ self.dut.send_expect("start", "testpmd> ")
+
+ port_disabled_num = 0
+ testpmd_all_ports = self.dut_ports
+ testpmd_all_ports.append(bond_port)
+ for port_id in testpmd_all_ports:
value = self.get_detail_from_port_info("Promiscuous mode: ", "enabled", port_id)
- if value:
- port_enabled_num += 1
- self.verify(port_enabled_num == 4, "Not all slaves of bonded device changed to promiscuous mode.")
+ if not value:
+ port_disabled_num += 1
+ self.verify(port_disabled_num == 0,
+ "Not all slaves of bonded device turn promiscuous mode on by default.")
ether_ip = {}
ether = {}
ether['dest_mac'] = "00:11:22:33:44:55"
ether_ip['ether'] = ether
+ send_param = {}
pkt_count = 1
+ send_param['pkt_count'] = pkt_count
+ pkt_info = [ether_ip, send_param]
- self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
- self.start_all_ports()
- self.dut.send_expect("start", "testpmd> ")
- gp0rx_pkts, gp0rx_err, gp0rx_bytes = [int(_) for _ in self.get_stats(self.dut_ports[0], "rx")]
- gp4rx_pkts, gp4rx_err, gp4rx_bytes = [int(_) for _ in self.get_stats(bond_port, "rx")]
- self.send_packet(self.dut_ports[0], 64, pkt_count, False, **ether_ip)
- p0rx_pkts, p0rx_err, p0rx_bytes = [int(_) for _ in self.get_stats(self.dut_ports[0], "rx")]
- p4rx_pkts, p4rx_err, p4rx_bytes = [int(_) for _ in self.get_stats(bond_port, "rx")]
- p0rx_pkts -= gp0rx_pkts
- p4rx_pkts -= gp4rx_pkts
- self.verify(p0rx_pkts == pkt_count and p4rx_pkts == pkt_count, "Data not received by slave or bonding device when promiscuous state")
+ slaves = {}
+ slaves['active'] = [self.dut_ports[0]]
+ slaves['inactive'] = []
- self.dut.send_expect("set promisc 4 off", "testpmd> ")
+ pkt_now, summary = self.send_customized_packet_to_slave(unbound_port, bond_port, *pkt_info, **slaves)
+ if mode_set == MODE_LACP:
+ do_transmit = False
+ pkt_size = 0
+ if pkt_now[unbound_port][0]:
+ do_transmit = True
+ pkt_size = pkt_now[unbound_port][2] / pkt_now[unbound_port][0]
+ self.verify(do_transmit and pkt_size != LACP_MESSAGE_SIZE,
+ "Data not received by slave or bonding device when promiscuous enabled")
+ else:
+ self.verify(pkt_now[self.dut_ports[0]][0] == pkt_now[bond_port][0] and
+ pkt_now[bond_port][0] == pkt_count,
+ "Data not received by slave or bonding device when promiscuous enabled")
+
+ self.dut.send_expect("set promisc %s off" % bond_port, "testpmd> ")
port_disabled_num = 0
- for port_id in [0, 1, 2, 4]:
+ testpmd_all_ports = [self.dut_ports[0], self.dut_ports[1], self.dut_ports[2], bond_port]
+ for port_id in testpmd_all_ports:
value = self.get_detail_from_port_info('Promiscuous mode: ', 'disabled', port_id)
- if value:
+ if value == 'disabled':
port_disabled_num += 1
- self.verify(port_disabled_num == 4, "Not all slaves of bonded device make promiscuous mode disabled.")
+ if mode_set in [MODE_ROUND_ROBIN, MODE_XOR_BALANCE, MODE_BROADCAST]:
+ self.verify(port_disabled_num == 4,
+ "Not all slaves of bonded device turn promiscuous mode off in mode %d." % mode_set)
+ elif mode_set == MODE_LACP:
+ self.verify(port_disabled_num == 1,
+ "Not only turn bound device promiscuous mode off in mode %d" % mode_set)
+ else:
+ self.verify(port_disabled_num == 2,
+ "Not only the primary slave turn promiscous mode off in mode %d, " % mode_set +
+ " when bonded device promiscous disabled.")
+
+ if mode_set != MODE_LACP:
+ send_param['verify'] = True
+ pkt_now, summary = self.send_customized_packet_to_slave(unbound_port, bond_port, *pkt_info, **slaves)
+ if mode_set == MODE_LACP:
+ do_transmit = False
+ pkt_size = 0
+ if pkt_now[unbound_port][0]:
+ do_transmit = True
+ pkt_size = pkt_now[unbound_port][2] / pkt_now[unbound_port][0]
+ self.verify(not do_transmit or
+ pkt_size == LACP_MESSAGE_SIZE,
+ "Data received by slave or bonding device when promiscuous disabled")
+ else:
+ self.verify(pkt_now[self.dut_ports[0]][0] == 0 and
+ pkt_now[bond_port][0] == 0,
+ "Data received by slave or bonding device when promiscuous disabled")
+
+ pkt_now, summary = self.send_default_packet_to_slave(self.dut_ports[3], bond_port, pkt_count, **slaves)
+ if mode_set == MODE_LACP:
+ do_transmit = False
+ pkt_size = 0
+ if pkt_now[unbound_port][0]:
+ do_transmit = True
+ pkt_size = pkt_now[unbound_port][2] / pkt_now[unbound_port][0]
+ self.verify(not do_transmit or
+ pkt_size != LACP_MESSAGE_SIZE,
+ "RX or TX packet number not correct when promiscuous disabled")
+ else:
+ self.verify(pkt_now[self.dut_ports[0]][0] == pkt_now[bond_port][0] and
+ pkt_now[self.dut_ports[3]][0] == pkt_now[bond_port][0] and
+ pkt_now[bond_port][0] == pkt_count,
+ "RX or TX packet number not correct when promiscuous disabled")
- gp0rx_pkts, gp0rx_err, gp0rx_bytes = [int(_) for _ in self.get_stats(self.dut_ports[0], "rx")]
- gp4rx_pkts, gp4rx_err, gp4rx_bytes = [int(_) for _ in self.get_stats(bond_port, "rx")]
- self.send_packet(self.dut_ports[0], 64, pkt_count, True, **ether_ip)
- p0rx_pkts, p0rx_err, p0rx_bytes = [int(_) for _ in self.get_stats(self.dut_ports[0], "rx")]
- p4rx_pkts, p4rx_err, p4rx_bytes = [int(_) for _ in self.get_stats(bond_port, "rx")]
- p0rx_pkts -= gp0rx_pkts
- p4rx_pkts -= gp4rx_pkts
- self.verify(p0rx_pkts == 0 and p4rx_pkts == 0, "Data received by slave or bonding device when promiscuous disabled")
-
- gp0rx_pkts, gp0rx_err, gp0rx_bytes = [int(_) for _ in self.get_stats(self.dut_ports[0], "rx")]
- gp3tx_pkts, gp3tx_err, gp3tx_bytes = [int(_) for _ in self.get_stats(self.dut_ports[3], "tx")]
- gp4rx_pkts, gp4rx_err, gp4rx_bytes = [int(_) for _ in self.get_stats(bond_port, "rx")]
- self.send_packet(self.dut_ports[0], 64, pkt_count)
- p0rx_pkts, p0rx_err, p0rx_bytes = [int(_) for _ in self.get_stats(self.dut_ports[0], "rx")]
- p3tx_pkts, p3tx_err, p3tx_bytes = [int(_) for _ in self.get_stats(self.dut_ports[3], "tx")]
- p4rx_pkts, p4rx_err, p4rx_bytes = [int(_) for _ in self.get_stats(bond_port, "rx")]
- p0rx_pkts -= gp0rx_pkts
- p3tx_pkts -= gp3tx_pkts
- p4rx_pkts -= gp4rx_pkts
- self.verify(p0rx_pkts == p4rx_pkts == p3tx_pkts == pkt_count, "RX or TX packet number not correct when promiscuous disabled")
+ self.remove_all_slaves(bond_port)
+ self.dut.send_expect("quit", "# ")
+ self.launch_app()
+
+ def test_bound_basic_opt(self):
+ self.verify_bound_basic_opt(MODE_ACTIVE_BACKUP)
+
+ def test_bound_mac_opt(self):
+ self.verify_bound_mac_opt(MODE_BROADCAST)
+
+ def test_bound_promisc_opt(self):
+ self.verify_bound_promisc_opt(MODE_BROADCAST)
def admin_tester_port(self, local_port, status):
+ """
+ Do some operations to the network interface port, such as "up" or "down".
+ """
if self.tester.get_os_type() == 'freebsd':
self.tester.admin_ports(local_port, status)
else:
@@ -489,65 +1055,45 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
self.tester.admin_ports_linux(eth, status)
time.sleep(5)
- def verify_round_robin_rx_tx(self, unbond_port, bond_port, **slaves):
+ def verify_round_robin_rx(self, unbound_port, bond_port, **slaves):
"""
+ Verify the receiving packet are all correct in the round robin mode.
slaves:
'active' = []
'inactive' = []
"""
- pkt_count = 300
- tx_pkt_orig = {}
- tx_pkt_now = {}
-
- # send to unbonding port
- for slave in slaves['active']:
- tx_pkt_orig[slave] = [int(_) for _ in self.get_stats(slave, "tx")]
- for slave in slaves['inactive']:
- tx_pkt_orig[slave] = [int(_) for _ in self.get_stats(slave, "tx")]
- tx_pkt_orig[bond_port] = [int(_) for _ in self.get_stats(bond_port, "tx")]
+ pkt_count = 100
+ pkt_now = {}
+ pkt_now, summary = self.send_default_packet_to_slave(unbound_port, bond_port, pkt_count=pkt_count, **slaves)
- self.send_packet(unbond_port, 64, pkt_count)
+ self.verify(pkt_now[unbound_port][0] == pkt_count * slaves['active'].__len__(), "Unbonded port has error TX pkt count in mode 0")
+ self.verify(pkt_now[bond_port][0] == pkt_count * slaves['active'].__len__(), "Bonding port has error RX pkt count in mode 0")
- for slave in slaves['active']:
- tx_pkt_now[slave] = [int(_) for _ in self.get_stats(slave, "tx")]
- tx_pkt_now[slave][0] -= tx_pkt_orig[slave][0]
- for slave in slaves['inactive']:
- tx_pkt_now[slave] = [int(_) for _ in self.get_stats(slave, "tx")]
- tx_pkt_now[slave][0] -= tx_pkt_orig[slave][0]
- tx_pkt_now[bond_port] = [int(_) for _ in self.get_stats(bond_port, "tx")]
- tx_pkt_now[bond_port][0] -= tx_pkt_orig[bond_port][0]
+ def verify_round_robin_tx(self, unbound_port, bond_port, **slaves):
+ """
+ Verify the transmitting packet are all correct in the round robin mode.
+ slaves:
+ 'active' = []
+ 'inactive' = []
+ """
+ pkt_count = 300
+ pkt_now = {}
+ pkt_now, summary = self.send_default_packet_to_unbound_port(unbound_port, bond_port, pkt_count=pkt_count, **slaves)
if slaves['active'].__len__() == 0:
- self.verify(tx_pkt_now[bond_port][0] == 0, "Bonding port should not have TX pkt in mode 0 when all slaves down")
+ self.verify(pkt_now[bond_port][0] == 0, "Bonding port should not have TX pkt in mode 0 when all slaves down")
else:
- self.verify(tx_pkt_now[bond_port][0] == pkt_count, "Bonding port has error TX pkt count in mode 0")
+ self.verify(pkt_now[bond_port][0] == pkt_count, "Bonding port has error TX pkt count in mode 0")
for slave in slaves['active']:
- self.verify(tx_pkt_now[slave][0] == pkt_count / slaves['active'].__len__(), "Active slave has error TX pkt count in mode 0")
+ self.verify(pkt_now[slave][0] == pkt_count / slaves['active'].__len__(), "Active slave has error TX pkt count in mode 0")
for slave in slaves['inactive']:
- self.verify(tx_pkt_now[slave][0] == 0, "Inactive slave has error TX pkt count in mode 0")
-
- # send to bonding slaves
- pkt_orig = {}
- pkt_now = {}
- pkt_orig[unbond_port] = [int(_) for _ in self.get_stats(unbond_port, "tx")]
- pkt_orig[bond_port] = [int(_) for _ in self.get_stats(bond_port, "rx")]
-
- for slave in slaves['active']:
- self.send_packet(slave, 64, pkt_count)
- for slave in slaves['inactive']:
- self.send_packet(slave, 64, pkt_count, True)
-
- pkt_now[unbond_port] = [int(_) for _ in self.get_stats(unbond_port, "tx")]
- pkt_now[bond_port] = [int(_) for _ in self.get_stats(bond_port, "rx")]
- pkt_now[unbond_port][0] -= pkt_orig[unbond_port][0]
- pkt_now[bond_port][0] -= pkt_orig[bond_port][0]
-
- self.verify(pkt_now[unbond_port][0] == pkt_count * slaves['active'].__len__(), "Unbonded port has error TX pkt count in mode 0")
- self.verify(pkt_now[bond_port][0] == pkt_count * slaves['active'].__len__(), "Bonding port has error RX pkt count in mode 0")
+ self.verify(pkt_now[slave][0] == 0, "Inactive slave has error TX pkt count in mode 0")
def test_round_robin_rx_tx(self):
- self.launch_app()
- bond_port = self.create_bonded_device(0, 0)
+ """
+ Verify that receiving and transmitting the packets correctly in the round robin mode.
+ """
+ bond_port = self.create_bonded_device(MODE_ROUND_ROBIN, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -556,11 +1102,15 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
slaves = {}
slaves['active'] = [self.dut_ports[0], self.dut_ports[1], self.dut_ports[2]]
slaves['inactive'] = []
- self.verify_round_robin_rx_tx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_round_robin_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_round_robin_tx(self.dut_ports[3], bond_port, **slaves)
def test_round_robin_one_slave_down(self):
- self.launch_app()
- bond_port = self.create_bonded_device(0, 0)
+ """
+ Verify that receiving and transmitting the packets correctly in the round robin mode,
+ when bringing any one slave of the bonding device link down.
+ """
+ bond_port = self.create_bonded_device(MODE_ROUND_ROBIN, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -575,13 +1125,17 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
slaves = {}
slaves['active'] = [self.dut_ports[1], self.dut_ports[2]]
slaves['inactive'] = [self.dut_ports[0]]
- self.verify_round_robin_rx_tx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_round_robin_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_round_robin_tx(self.dut_ports[3], bond_port, **slaves)
finally:
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "up")
- def test_round_robin_all_slave_down(self):
- self.launch_app()
- bond_port = self.create_bonded_device(0, 0)
+ def test_round_robin_all_slaves_down(self):
+ """
+ Verify that receiving and transmitting the packets correctly in the round robin mode,
+ when bringing all slaves of the bonding device link down.
+ """
+ bond_port = self.create_bonded_device(MODE_ROUND_ROBIN, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -595,20 +1149,23 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
slaves = {}
slaves['active'] = []
slaves['inactive'] = [self.dut_ports[0], self.dut_ports[1], self.dut_ports[2]]
- self.verify_round_robin_rx_tx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_round_robin_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_round_robin_tx(self.dut_ports[3], bond_port, **slaves)
finally:
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "up")
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[1]), "up")
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[2]), "up")
- def get_all_stats(self, unbond_port, rx_tx, bond_port, **slaves):
+ def get_all_stats(self, unbound_port, rx_tx, bond_port, **slaves):
"""
- unbond_port: pmd port id
- rx_tx: 'rx' or 'tx'
- bond_port: bonding port
- slaves:
- 'active' = []
- 'inactive' = []
+ Get all the port stats which the testpmd can dicover.
+ Parameters:
+ *** unbound_port: pmd port id
+ *** rx_tx: unbond port stat 'rx' or 'tx'
+ *** bond_port: bonding port
+ *** slaves:
+ ******** 'active' = []
+ ******** 'inactive' = []
"""
pkt_now = {}
@@ -617,7 +1174,7 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
else:
bond_stat = 'rx'
- pkt_now[unbond_port] = [int(_) for _ in self.get_stats(unbond_port, rx_tx)]
+ pkt_now[unbound_port] = [int(_) for _ in self.get_stats(unbound_port, rx_tx)]
pkt_now[bond_port] = [int(_) for _ in self.get_stats(bond_port, bond_stat)]
for slave in slaves['active']:
pkt_now[slave] = [int(_) for _ in self.get_stats(slave, bond_stat)]
@@ -626,58 +1183,64 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
return pkt_now
- def verify_active_backup_rx_tx(self, unbond_port, bond_port, **slaves):
+ def verify_active_backup_rx(self, unbound_port, bond_port, **slaves):
"""
- slaves:
- 'active' = []
- 'inactive' = []
+ Verify the RX packets are all correct in the active-backup mode.
+ Parameters:
+ *** slaves:
+ ******* 'active' = []
+ ******* 'inactive' = []
"""
pkt_count = 100
- pkt_orig = {}
pkt_now = {}
- if slaves['active'].__len__() != 0:
- primary_port = slaves['active'][0]
+ slave_num = slaves['active'].__len__()
+ if slave_num != 0:
active_flag = 1
else:
- reverse_verify = True
active_flag = 0
- # send to unbond port
- pkt_orig = self.get_all_stats(unbond_port, 'rx', bond_port, **slaves)
- self.send_packet(unbond_port, 64, pkt_count)
- pkt_now = self.get_all_stats(unbond_port, 'rx', bond_port, **slaves)
-
- for key in pkt_now:
- for num in [0, 1, 2]:
- pkt_now[key][num] -= pkt_orig[key][num]
+ pkt_now, summary = self.send_default_packet_to_slave(unbound_port, bond_port, pkt_count=pkt_count, **slaves)
- if active_flag == 1:
- self.verify(pkt_now[primary_port][0] == pkt_count, "Active port not correct TX pkt in mode 1")
- self.verify(pkt_now[bond_port][0] == pkt_count * active_flag, "Bond port not correct TX pkt in mode 1")
+ self.verify(pkt_now[bond_port][0] == pkt_count * slave_num, "Not correct RX pkt on bond port in mode 1")
+ self.verify(pkt_now[unbound_port][0] == pkt_count * active_flag, "Not correct TX pkt on unbound port in mode 1")
for slave in slaves['inactive']:
- self.verify(pkt_now[slave][0] == 0, "Backup port not correct TX pkt in mode 1")
+ self.verify(pkt_now[slave][0] == 0, "Not correct RX pkt on inactive port in mode 1")
+ for slave in slaves['active']:
+ self.verify(pkt_now[slave][0] == pkt_count, "Not correct RX pkt on active port in mode 1")
- # send to primary slave
- if active_flag == 1:
- pkt_orig = self.get_all_stats(unbond_port, 'tx', bond_port, **slaves)
- self.send_packet(primary_port, 64, pkt_count)
- pkt_now = self.get_all_stats(unbond_port, 'tx', bond_port, **slaves)
+ def verify_active_backup_tx(self, unbound_port, bond_port, **slaves):
+ """
+ Verify the TX packets are all correct in the active-backup mode.
+ Parameters:
+ *** slaves:
+ ******* 'active' = []
+ ******* 'inactive' = []
+ """
+ pkt_count = 0
+ pkt_now = {}
+
+ if slaves['active'].__len__() != 0:
+ primary_port = slaves['active'][0]
+ active_flag = 1
+ else:
+ active_flag = 0
- pkt_now[bond_port][0] -= pkt_orig[bond_port][0]
- pkt_now[unbond_port][0] -= pkt_orig[bond_port][0]
- for key in pkt_now:
- for num in [0, 1, 2]:
- pkt_now[key][num] -= pkt_orig[key][num]
+ pkt_now, summary = self.send_default_packet_to_unbound_port(unbound_port, bond_port, pkt_count=pkt_count, **slaves)
- self.verify(pkt_now[bond_port][0] == pkt_count, "Bond port not correct RX pkt in mode 1")
- self.verify(pkt_now[unbond_port][0] == pkt_count, "Unbond port not correct TX pkt in mode 1")
- for slave in slaves['inactive']:
- self.verify(pkt_now[slave][0] == 0, "Backup port not correct RX pkt in mode 1")
+ self.verify(pkt_now[bond_port][0] == pkt_count * active_flag, "Not correct RX pkt on bond port in mode 1")
+ if active_flag == 1:
+ self.verify(pkt_now[primary_port][0] == pkt_count, "Not correct TX pkt on primary port in mode 1")
+ for slave in slaves['inactive']:
+ self.verify(pkt_now[slave][0] == 0, "Not correct TX pkt on inactive port in mode 1")
+ for slave in [slave for slave in slaves['active'] if slave != primary_port]:
+ self.verify(pkt_now[slave][0] == 0, "Not correct TX pkt on backup port in mode 1")
def test_active_backup_rx_tx(self):
- self.launch_app()
- bond_port = self.create_bonded_device(1, 0)
+ """
+ Verify receiving and transmitting the packets correctly in the active-backup mode.
+ """
+ bond_port = self.create_bonded_device(MODE_ACTIVE_BACKUP, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -685,13 +1248,17 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
time.sleep(5)
slaves = {}
- slaves['active'] = [self.dut_ports[0]]
- slaves['inactive'] = [self.dut_ports[1], self.dut_ports[2]]
- self.verify_active_backup_rx_tx(self.dut_ports[3], bond_port, **slaves)
+ slaves['active'] = [self.dut_ports[0], self.dut_ports[1], self.dut_ports[2]]
+ slaves['inactive'] = []
+ self.verify_active_backup_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_active_backup_tx(self.dut_ports[3], bond_port, **slaves)
def test_active_backup_change_primary(self):
- self.launch_app()
- bond_port = self.create_bonded_device(1, 0)
+ """
+ Verify that receiving and transmitting the packets correctly in the active-backup mode,
+ when you change the primary slave.
+ """
+ bond_port = self.create_bonded_device(MODE_ACTIVE_BACKUP, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -700,13 +1267,17 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
time.sleep(5)
slaves = {}
- slaves['active'] = [self.dut_ports[1]]
- slaves['inactive'] = [self.dut_ports[0], self.dut_ports[2]]
- self.verify_active_backup_rx_tx(self.dut_ports[3], bond_port, **slaves)
+ slaves['active'] = [self.dut_ports[1], self.dut_ports[0], self.dut_ports[2]]
+ slaves['inactive'] = []
+ self.verify_active_backup_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_active_backup_tx(self.dut_ports[3], bond_port, **slaves)
def test_active_backup_one_slave_down(self):
- self.launch_app()
- bond_port = self.create_bonded_device(1, 0)
+ """
+ Verify that receiving and transmitting the pcakets correctly in the active-backup mode,
+ when bringing any one slave of the bonding device link down.
+ """
+ bond_port = self.create_bonded_device(MODE_ACTIVE_BACKUP, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -716,16 +1287,22 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
try:
slaves = {}
+ active_slaves = [self.dut_ports[1], self.dut_ports[2]]
+ active_slaves.remove(primary_port)
slaves['active'] = [primary_port]
- slaves['inactive'] = [self.dut_ports[0], self.dut_ports[1], self.dut_ports[2]]
- slaves['inactive'].remove(primary_port)
- self.verify_active_backup_rx_tx(self.dut_ports[3], bond_port, **slaves)
+ slaves['active'].extend(active_slaves)
+ slaves['inactive'] = [self.dut_ports[0]]
+ self.verify_active_backup_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_active_backup_tx(self.dut_ports[3], bond_port, **slaves)
finally:
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "up")
- def test_active_backup_all_slave_down(self):
- self.launch_app()
- bond_port = self.create_bonded_device(1, 0)
+ def test_active_backup_all_slaves_down(self):
+ """
+ Verify that receiving and transmitting that packets correctly in the active-backup mode,
+ when bringing all slaves of the bonding device link down.
+ """
+ bond_port = self.create_bonded_device(MODE_ACTIVE_BACKUP, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -738,19 +1315,26 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
slaves = {}
slaves['active'] = []
slaves['inactive'] = [self.dut_ports[0], self.dut_ports[1], self.dut_ports[2]]
- self.verify_active_backup_rx_tx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_active_backup_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_active_backup_tx(self.dut_ports[3], bond_port, **slaves)
finally:
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "up")
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[1]), "up")
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[2]), "up")
def translate_mac_str_into_int(self, mac_str):
+ """
+ Translate the MAC type from the string into the int.
+ """
mac_hex = '0x'
for mac_part in mac_str.split(':'):
mac_hex += mac_part
return int(mac_hex, 16)
def mac_hash(self, dest_mac, src_mac):
+ """
+ Generate the hash value with the source and destination MAC.
+ """
dest_port_mac = self.translate_mac_str_into_int(dest_mac)
src_port_mac = self.translate_mac_str_into_int(src_mac)
src_xor_dest = dest_port_mac ^ src_port_mac
@@ -760,6 +1344,9 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
return htons(xor_value_1 ^ xor_value_2 ^ xor_value_3)
def translate_ip_str_into_int(self, ip_str):
+ """
+ Translate the IP type from the string into the int.
+ """
ip_part_list = ip_str.split('.')
ip_part_list.reverse()
num = 0
@@ -771,123 +1358,118 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
return ip_int
def ipv4_hash(self, dest_ip, src_ip):
+ """
+ Generate the hash value with the source and destination IP.
+ """
dest_ip_int = self.translate_ip_str_into_int(dest_ip)
src_ip_int = self.translate_ip_str_into_int(src_ip)
return htonl(dest_ip_int ^ src_ip_int)
def udp_hash(self, dest_port, src_port):
+ """
+ Generate the hash value with the source and destination port.
+ """
return htons(dest_port ^ src_port)
+ def policy_and_slave_hash(self, policy, **slaves):
+ """
+ Generate the hash value by the policy and active slave number.
+ *** policy:'L2' , 'L23' or 'L34'
+ *** slaves:
+ ******* 'active'=[]
+ ******* 'inactive'=[]
+ """
+ global S_MAC_IP_PORT
+ source = S_MAC_IP_PORT
+
+ global D_MAC_IP_PORT
+ dest_mac = D_MAC_IP_PORT[0]
+ dest_ip = D_MAC_IP_PORT[1]
+ dest_port = D_MAC_IP_PORT[2]
+
+ hash_values = []
+ if len(slaves['active']) != 0:
+ for src_mac, src_ip, src_port in source:
+ if policy == "L2":
+ hash_value = self.mac_hash(dest_mac, src_mac)
+ elif policy == "L23":
+ hash_value = self.mac_hash(dest_mac, src_mac) ^ self.ipv4_hash(dest_ip, src_ip)
+ else:
+ hash_value = self.ipv4_hash(dest_ip, src_ip) ^ self.udp_hash(dest_port, src_port)
+
+ if policy in ("L23", "L34"):
+ hash_value ^= hash_value >> 16
+ hash_value ^= hash_value >> 8
+ hash_value = hash_value % len(slaves['active'])
+ hash_values.append(hash_value)
+
+ return hash_values
+
def slave_map_hash(self, port, order_ports):
+ """
+ Find the hash value by the given slave port id.
+ """
if len(order_ports) == 0:
return None
else:
order_ports = order_ports.split()
return order_ports.index(str(port))
- def verify_xor_rx(self, unbond_port, bond_port, **slaves):
+ def verify_xor_rx(self, unbound_port, bond_port, **slaves):
"""
- slaves:
- 'active'=[]
- 'inactive'=[]
+ Verify receiving the pcakets correctly in the XOR mode.
+ Parameters:
+ *** unbound_port: the unbonded port id
+ *** bond_port: the bonded device port id
+ *** slaves:
+ ******* 'active'=[]
+ ******* 'inactive'=[]
"""
pkt_count = 100
- pkt_orig = {}
pkt_now = {}
- # send to slave ports
- pkt_orig = self.get_all_stats(unbond_port, 'tx', bond_port, **slaves)
- for slave in slaves['active']:
- self.send_packet(self.dut_ports[slave], 64, pkt_count)
- pkt_now = self.get_all_stats(unbond_port, 'tx', bond_port, **slaves)
-
- for key in pkt_now:
- for num in [0, 1, 2]:
- pkt_now[key][num] -= pkt_orig[key][num]
+ pkt_now, summary = self.send_default_packet_to_slave(unbound_port, bond_port, pkt_count=pkt_count, **slaves)
for slave in slaves['active']:
self.verify(pkt_now[slave][0] == pkt_count, "Slave have error RX packet in XOR")
for slave in slaves['inactive']:
self.verify(pkt_now[slave][0] == 0, "Slave have error RX packet in XOR")
- self.verify(pkt_now[unbond_port][0] == pkt_count * len(slaves['active']), "Unbonded device have error TX packet in XOR")
+ self.verify(pkt_now[unbound_port][0] == pkt_count * len(slaves['active']), "Unbonded device have error TX packet in XOR")
- def verify_xor_tx(self, unbond_port, bond_port, policy, vlan_tag=False, **slaves):
+ def verify_xor_tx(self, unbound_port, bond_port, policy, vlan_tag=False, **slaves):
"""
- vlan_tag:False or True
- policy:'L2' , 'L23' or 'L34'
- slaves:
- 'active'=[]
- 'inactive'=[]
+ Verify that transmitting the packets correctly in the XOR mode.
+ Parameters:
+ *** unbound_port: the unbonded port id
+ *** bond_port: the bonded device port id
+ *** policy:'L2' , 'L23' or 'L34'
+ *** vlan_tag:False or True
+ *** slaves:
+ ******* 'active'=[]
+ ******* 'inactive'=[]
"""
pkt_count = 100
- pkt_orig = {}
pkt_now = {}
- # send to unbond_port
- pkt_orig = self.get_all_stats(unbond_port, 'rx', bond_port, **slaves)
-
- dest_mac = self.dut.get_mac_address(self.dut_ports[unbond_port])
- dest_ip = "10.239.129.88"
- dest_port = 53
-
- ether_ip = {}
- ether = {}
- ip = {}
- udp = {}
-
- ether['dest_mac'] = False
- ip['dest_ip'] = dest_ip
- udp['dest_port'] = 53
- if vlan_tag:
- dot1q = {}
- dot1q['vlan'] = random.randint(1, 50)
- ether_ip['dot1q'] = dot1q
-
- ether_ip['ether'] = ether
- ether_ip['ip'] = ip
- ether_ip['udp'] = udp
-
- source = [('52:00:00:00:00:00', '10.239.129.65', 61),
- ('52:00:00:00:00:01', '10.239.129.66', 62),
- ('52:00:00:00:00:02', '10.239.129.67', 63)]
-
- for src_mac, src_ip, src_port in source:
- ether_ip['ether']['src_mac'] = src_mac
- ether_ip['ip']['src_ip'] = src_ip
- ether_ip['udp']['src_port'] = src_port
- self.send_packet(unbond_port, 64, pkt_count, False, **ether_ip)
- pkt_now = self.get_all_stats(unbond_port, 'rx', bond_port, **slaves)
-
- for key in pkt_now:
- for num in [0, 1, 2]:
- pkt_now[key][num] -= pkt_orig[key][num]
+ pkt_now, summary = self.send_customized_packet_to_unbound_port(unbound_port, bond_port, policy, vlan_tag=False, pkt_count=pkt_count, **slaves)
hash_values = []
- if len(slaves['active']) != 0:
- for src_mac, src_ip, src_port in source:
- if policy == "L2":
- hash_value = self.mac_hash(dest_mac, src_mac)
- elif policy == "L23":
- hash_value = self.mac_hash(dest_mac, src_mac) ^ self.ipv4_hash(dest_ip, src_ip)
- else:
- hash_value = self.ipv4_hash(dest_ip, src_ip) ^ self.udp_hash(dest_port, src_port)
-
- if policy in ("L23", "L34"):
- hash_value ^= hash_value >> 16
- hash_value ^= hash_value >> 8
- hash_value = hash_value % len(slaves['active'])
- hash_values.append(hash_value)
+ hash_values = self.policy_and_slave_hash(policy, **slaves)
order_ports = self.get_bond_active_slaves(bond_port)
for slave in slaves['active']:
slave_map_hash = self.slave_map_hash(slave, order_ports)
- self.verify(pkt_now[slave][0] == pkt_count * hash_values.count(slave_map_hash), "XOR load balance transmit error on the link up port")
+ self.verify(pkt_now[slave][0] == pkt_count * hash_values.count(slave_map_hash),
+ "XOR load balance transmit error on the link up port")
for slave in slaves['inactive']:
- self.verify(pkt_now[slave][0] == 0, "XOR load balance transmit error on the link down port")
+ self.verify(pkt_now[slave][0] == 0,
+ "XOR load balance transmit error on the link down port")
def test_xor_tx(self):
- self.launch_app()
- bond_port = self.create_bonded_device(2, 0)
+ """
+ Verify that transmitting packets correctly in the XOR mode.
+ """
+ bond_port = self.create_bonded_device(MODE_XOR_BALANCE, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -900,8 +1482,11 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
self.verify_xor_tx(self.dut_ports[3], bond_port, "L2", False, **slaves)
def test_xor_tx_one_slave_down(self):
- self.launch_app()
- bond_port = self.create_bonded_device(2, 0)
+ """
+ Verify that transmitting packets correctly in the XOR mode,
+ when bringing any one slave of the bonding device link down.
+ """
+ bond_port = self.create_bonded_device(MODE_XOR_BALANCE, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[2], self.dut_ports[1])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -917,9 +1502,12 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
finally:
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "up")
- def test_xor_tx_all_slave_down(self):
- self.launch_app()
- bond_port = self.create_bonded_device(2, 0)
+ def test_xor_tx_all_slaves_down(self):
+ """
+ Verify that transmitting packets correctly in the XOR mode,
+ when bringing all slaves of the bonding device link down.
+ """
+ bond_port = self.create_bonded_device(MODE_XOR_BALANCE, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -940,13 +1528,19 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[2]), "up")
def vlan_strip_and_filter(self, action='off', *ports):
+ """
+ Open or shutdown the vlan strip and filter option of specified port.
+ """
for port_id in ports:
self.dut.send_expect("vlan set strip %s %d" % (action, port_id), "testpmd> ")
self.dut.send_expect("vlan set filter %s %d" % (action, port_id), "testpmd> ")
def test_xor_l34_forward(self):
- self.launch_app()
- bond_port = self.create_bonded_device(2, 0)
+ """
+ Verify that transmitting packets correctly in the XOR mode,
+ when choosing the l34 as the load balance policy.
+ """
+ bond_port = self.create_bonded_device(MODE_XOR_BALANCE, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.set_balance_policy_for_bonding_device(bond_port, "l34")
@@ -962,8 +1556,10 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
self.verify_xor_tx(self.dut_ports[3], bond_port, "L34", True, **slaves)
def test_xor_rx(self):
- self.launch_app()
- bond_port = self.create_bonded_device(2, 0)
+ """
+ Verify that receiving packets correctly in the XOR mode.
+ """
+ bond_port = self.create_bonded_device(MODE_XOR_BALANCE, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -975,64 +1571,58 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
self.verify_xor_rx(self.dut_ports[3], bond_port, **slaves)
- def verify_broadcast_bonded_rx(self, unbond_port, bond_port, **slaves):
+ def verify_broadcast_rx(self, unbound_port, bond_port, **slaves):
"""
- slaves:
- 'active':[]
- 'inactive':[]
+ Verify that receiving packets correctly in the broadcast mode.
+ Parameters:
+ *** unbound_port: the unbonded port id
+ *** bond_port: the bonded device port id
+ *** slaves:
+ ******* 'active':[]
+ ******* 'inactive':[]
"""
pkt_count = 100
- pkt_orig = {}
pkt_now = {}
- pkt_orig = self.get_all_stats(unbond_port, 'tx', bond_port, **slaves)
- for slave in slaves['active']:
- self.send_packet(slave, 64, pkt_count)
- pkt_now = self.get_all_stats(unbond_port, 'tx', bond_port, **slaves)
-
- for key in pkt_now:
- for num in [0, 1, 2]:
- pkt_now[key][num] -= pkt_orig[key][num]
+ pkt_now, summary = self.send_default_packet_to_slave(unbound_port, bond_port, pkt_count=pkt_count, **slaves)
for slave in slaves['active']:
self.verify(pkt_now[slave][0] == pkt_count, "Slave RX packet not correct in mode 3")
for slave in slaves['inactive']:
self.verify(pkt_now[slave][0] == 0, "Slave RX packet not correct in mode 3")
- self.verify(pkt_now[unbond_port][0] == pkt_count * len(slaves['active']),
+ self.verify(pkt_now[unbound_port][0] == pkt_count * len(slaves['active']),
"Unbonded port TX packet not correct in mode 3")
self.verify(pkt_now[bond_port][0] == pkt_count * len(slaves['active']),
"Bonded device RX packet not correct in mode 3")
- def verify_broadcast_bonded_tx(self, unbond_port, bond_port, **slaves):
+ def verify_broadcast_tx(self, unbound_port, bond_port, **slaves):
"""
- slaves:
- 'actvie':[]
- 'inactive':[]
+ Verify that transmitting packets correctly in the broadcast mode.
+ Parameters:
+ *** unbound_port: the unbonded port id
+ *** bond_port: the bonded device port id
+ *** slaves:
+ ******* 'actvie':[]
+ ******* 'inactive':[]
"""
pkt_count = 100
- pkt_orig = {}
pkt_now = {}
- # send to unbonded device
- pkt_orig = self.get_all_stats(unbond_port, 'rx', bond_port, **slaves)
- self.send_packet(unbond_port, 64, pkt_count)
- pkt_now = self.get_all_stats(unbond_port, 'rx', bond_port, **slaves)
-
- for key in pkt_now:
- for num in [0, 1, 2]:
- pkt_now[key][num] -= pkt_orig[key][num]
+ pkt_now, summary = self.send_default_packet_to_unbound_port(unbound_port, bond_port, pkt_count=pkt_count, **slaves)
for slave in slaves['active']:
self.verify(pkt_now[slave][0] == pkt_count, "Slave TX packet not correct in mode 3")
for slave in slaves['inactive']:
self.verify(pkt_now[slave][0] == 0, "Slave TX packet not correct in mode 3")
- self.verify(pkt_now[unbond_port][0] == pkt_count, "Unbonded port RX packet not correct in mode 3")
+ self.verify(pkt_now[unbound_port][0] == pkt_count, "Unbonded port RX packet not correct in mode 3")
self.verify(pkt_now[bond_port][0] == pkt_count * len(slaves['active']),
"Bonded device TX packet not correct in mode 3")
def test_broadcast_rx_tx(self):
- self.launch_app()
- bond_port = self.create_bonded_device(3, 0)
+ """
+ Verify receiving and transmitting packets correctly in the broadcast mode.
+ """
+ bond_port = self.create_bonded_device(MODE_BROADCAST, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -1042,12 +1632,15 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
slaves['active'] = [self.dut_ports[0], self.dut_ports[1], self.dut_ports[2]]
slaves['inactive'] = []
- self.verify_broadcast_bonded_rx(self.dut_ports[3], bond_port, **slaves)
- self.verify_broadcast_bonded_tx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_broadcast_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_broadcast_tx(self.dut_ports[3], bond_port, **slaves)
def test_broadcast_tx_one_slave_down(self):
- self.launch_app()
- bond_port = self.create_bonded_device(3, 0)
+ """
+ Verify that transmitting packets correctly in the broadcast mode,
+ when bringing any one slave of the bonding device link down.
+ """
+ bond_port = self.create_bonded_device(MODE_BROADCAST, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -1059,13 +1652,16 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
slaves['active'] = [self.dut_ports[1], self.dut_ports[2]]
slaves['inactive'] = [self.dut_ports[0]]
- self.verify_broadcast_bonded_tx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_broadcast_tx(self.dut_ports[3], bond_port, **slaves)
finally:
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "up")
- def test_broadcast_tx_all_slave_down(self):
- self.launch_app()
- bond_port = self.create_bonded_device(3, 0)
+ def test_broadcast_tx_all_slaves_down(self):
+ """
+ Verify that transmitting packets correctly in the broadcast mode,
+ when bringing all slaves of the bonding device link down.
+ """
+ bond_port = self.create_bonded_device(MODE_BROADCAST, SOCKET_0)
self.add_slave_to_bonding_device(bond_port, False, self.dut_ports[0], self.dut_ports[1], self.dut_ports[2])
self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
self.start_all_ports()
@@ -1079,7 +1675,353 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
slaves['active'] = []
slaves['inactive'] = [self.dut_ports[0], self.dut_ports[1], self.dut_ports[2]]
- self.verify_broadcast_bonded_tx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_broadcast_tx(self.dut_ports[3], bond_port, **slaves)
+ finally:
+ self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "up")
+ self.admin_tester_port(self.tester.get_local_port(self.dut_ports[1]), "up")
+ self.admin_tester_port(self.tester.get_local_port(self.dut_ports[2]), "up")
+
+ def verify_lacp_rx(self, unbound_port, bond_port, **slaves):
+ """
+ Verify that receiving packets correctly in the mode 4.
+ Parameters:
+ *** unbound_port: the unbonded port id
+ *** bond_port: the bonded device port id
+ *** slaves:
+ ******* 'active':[]
+ ******* 'inactive':[]
+ """
+ pkt_count = 100
+ pkt_now = {}
+ summary = 0
+
+ if len(slaves['active']):
+ active_flag = 1
+ else:
+ active_flag = 0
+
+ pkt_now, summary = self.send_customized_packet_to_bond_port(unbound_port, bond_port, self.tester_bond, pkt_count, **slaves)
+
+ active_summary = 0
+ for slave in slaves['active']:
+ active_summary += pkt_now[slave][0]
+ self.verify(active_summary >= summary * active_flag,
+ "Active slave have incorrect RX packet number in LACP")
+ for slave in slaves['inactive']:
+ self.verify(pkt_now[slave][0] == 0,
+ "Inactive slave have incorrect RX packet number in LACP")
+ self.dut.send_expect("show port info %d" % self.dut_ports[3], "testpmd> ")
+ self.verify(pkt_now[unbound_port][0] == summary * active_flag,
+ "Unbonded device has incorrect TX packet number in LACP")
+
+ def verify_lacp_tx(self, unbound_port, bond_port, policy, vlan_tag=False, **slaves):
+ """
+ Verify that transmitting the packets correctly in the XOR mode.
+ Parameters:
+ *** unbound_port: the unbonded port id
+ *** bond_port: the bonded device port id
+ *** policy:'L2' , 'L23' or 'L34'
+ *** vlan_tag:False or True
+ *** slaves:
+ ******* 'active'=[]
+ ******* 'inactive'=[]
+ """
+ pkt_count = 100
+ pkt_now = {}
+
+ pkt_now, summary = self.send_customized_packet_to_unbound_port(unbound_port, bond_port, policy, vlan_tag=False, pkt_count=pkt_count, **slaves)
+
+ hash_values = []
+ hash_values = self.policy_and_slave_hash(policy, **slaves)
+
+ order_ports = self.get_bond_active_slaves(bond_port)
+ for slave in slaves['active']:
+ slave_map_hash = self.slave_map_hash(slave, order_ports)
+ self.verify(pkt_now[slave][0] >= pkt_count * hash_values.count(slave_map_hash),
+ "LACP load balance transmit incorrectly on the link up port")
+ for slave in slaves['inactive']:
+ self.verify(pkt_now[slave][0] == 0,
+ "LACP load balance transmit incorrectly on the link down port")
+ self.verify(pkt_now[unbound_port][0] == summary,
+ "LACP load balance receive incorrectly on the unbound port")
+
+ def add_linux_bond_device(self, bond_mode, bond_name='bond0', *tester_local_ports):
+ if self.tester.get_os_type() == "linux":
+ self.tester.send_expect("modprobe bonding mode=%d miimon=100" %
+ int(bond_mode), "# ")
+
+ tester_bond_intfs = [self.tester.get_interface(port) for port in tester_local_ports]
+ for intf in tester_bond_intfs:
+ self.tester.send_expect("ifenslave -f %s %s" %
+ (bond_name, intf), "# ")
+ if not self.slave_is_here_linux(bond_name, intf):
+ self.verify(False, "Add linux bond device failed")
+ for port in tester_local_ports:
+ self.admin_tester_port(port, "up")
+ else:
+ self.verify(False,
+ "Not support to verify LACP on OS %s" % self.tester.get_os_type())
+
+ def detach_linux_bond_device(self, bond_name='bond0', *tester_local_ports):
+ tester_bond_intf = [self.tester.get_interface(port) for port in tester_local_ports]
+ if self.tester.get_os_type() == "linux":
+ for intf in tester_bond_intf:
+ if self.slave_is_here_linux(bond_name, intf):
+ self.tester.send_expect("ifenslave -d %s %s" % (bond_name, intf),
+ "# ")
+ if self.slave_is_here_linux(bond_name, intf):
+ self.verify(False, "Delete linux bond device failed")
+ for port in tester_local_ports:
+ self.admin_tester_port(port, "up")
+ else:
+ self.verify(False,
+ "Not support to verify LACP on OS %s" % self.tester.get_os_type())
+
+ def slave_is_here_linux(self, bond_name="bond0", *interfaces):
+ out = self.tester.send_expect("cat /proc/net/bonding/%s" % bond_name,
+ "# ")
+ for intf in interfaces:
+ if re.search(intf, out):
+ return True
+ else:
+ return False
+
+ def setup_and_clear_lacp(func):
+ """
+ Setting lacp test environment on tester.
+ """
+ @wraps(func)
+ def test_env(*args, **kwargs):
+ pmd_bond_instance = args[0]
+ try:
+ dut_ports = [pmd_bond_instance.dut_ports[port] for port in [0, 1, 2]]
+ tester = pmd_bond_instance.tester
+ tester_local_ports = [tester.get_local_port(port) for port in dut_ports]
+
+ pmd_bond_instance.add_linux_bond_device(MODE_LACP,
+ pmd_bond_instance.tester_bond,
+ *tester_local_ports)
+
+ func(*args, **kwargs)
+ finally:
+ pmd_bond_instance.detach_linux_bond_device(pmd_bond_instance.tester_bond,
+ *tester_local_ports)
+
+ return test_env
+
+ def just_clear_lacp(func):
+ """
+
+ """
+ @wraps(func)
+ def clear_env(*args, **kwargs):
+ pmd_bond_instance = args[0]
+ try:
+ dut_ports = [pmd_bond_instance.dut_ports[port] for port in [0, 1, 2]]
+ tester = pmd_bond_instance.tester
+ tester_local_ports = [tester.get_local_port(port) for port in dut_ports]
+
+ func(*args, **kwargs)
+ finally:
+ pmd_bond_instance.detach_linux_bond_device(pmd_bond_instance.tester_bond,
+ *tester_local_ports)
+ return clear_env
+
+ @setup_and_clear_lacp
+ def test_lacp_basic(self):
+ self.verify_bound_basic_opt(MODE_LACP)
+ self.verify_bound_mac_opt(MODE_LACP)
+ self.verify_bound_promisc_opt(MODE_LACP)
+
+ @setup_and_clear_lacp
+ def test_lacp_rx_tx(self):
+ slaves = {}
+ slaves['active'] = [self.dut_ports[0], self.dut_ports[1], self.dut_ports[2]]
+ slaves['inactive'] = []
+
+ bond_port = self.create_bonded_device(MODE_LACP, SOCKET_0)
+ self.add_slave_to_bonding_device(bond_port, False,
+ self.dut_ports[0],
+ self.dut_ports[1],
+ self.dut_ports[2])
+ self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
+ self.start_port(bond_port)
+ self.start_all_ports()
+ self.dut.send_expect("start", "testpmd> ")
+ time.sleep(5)
+
+ self.verify_lacp_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_lacp_tx(self.dut_ports[3], bond_port, 'L2', **slaves)
+
+ @setup_and_clear_lacp
+ def test_lacp_one_slave_down(self):
+ self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "down")
+
+ slaves = {}
+ slaves['active'] = [self.dut_ports[1], self.dut_ports[2]]
+ slaves['inactive'] = [self.dut_ports[0]]
+
+ bond_port = self.create_bonded_device(MODE_LACP, SOCKET_0)
+ self.add_slave_to_bonding_device(bond_port, False,
+ self.dut_ports[0],
+ self.dut_ports[1],
+ self.dut_ports[2])
+ self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
+ self.start_port(bond_port)
+ self.start_all_ports()
+ self.dut.send_expect("start", "testpmd> ")
+
+ self.verify_lacp_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_lacp_tx(self.dut_ports[3], bond_port, 'L2', **slaves)
+
+ @setup_and_clear_lacp
+ def test_lacp_all_slaves_down(self):
+ self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "down")
+ self.admin_tester_port(self.tester.get_local_port(self.dut_ports[1]), "down")
+ self.admin_tester_port(self.tester.get_local_port(self.dut_ports[2]), "down")
+
+ slaves = {}
+ slaves['active'] = []
+ slaves['inactive'] = [self.dut_ports[0], self.dut_ports[1], self.dut_ports[2]]
+
+ bond_port = self.create_bonded_device(MODE_LACP, SOCKET_0)
+ self.add_slave_to_bonding_device(bond_port, False,
+ self.dut_ports[0],
+ self.dut_ports[1],
+ self.dut_ports[2])
+ self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
+ self.start_port(bond_port)
+ self.start_all_ports()
+ self.dut.send_expect("start", "testpmd> ")
+
+ self.verify_lacp_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_lacp_tx(self.dut_ports[3], bond_port, 'L2', **slaves)
+
+ def verify_tlb_rx(self, unbound_port, bond_port, **slaves):
+ """
+ Verify that receiving packets correctly in the mode 4.
+ Parameters:
+ *** unbound_port: the unbonded port id
+ *** bond_port: the bonded device port id
+ *** slaves:
+ ******* 'active':[]
+ ******* 'inactive':[]
+ """
+ pkt_count = 100
+ pkt_now = {}
+
+ slave_num = slaves['active'].__len__()
+ if slave_num != 0:
+ active_flag = 1
+ else:
+ active_flag = 0
+
+ pkt_now, summary = self.send_default_packet_to_slave(unbound_port, bond_port, pkt_count=pkt_count, **slaves)
+
+ self.verify(pkt_now[unbound_port][0] == pkt_count * active_flag, "Unbonded device has error TX packet in TLB")
+ self.verify(pkt_now[bond_port][0] == pkt_count * slave_num, "Bounded device has error RX packet in TLB")
+ for slave in slaves['inactive']:
+ self.verify(pkt_now[slave][0] == 0, "Inactive slave has error RX packet in TLB")
+ for slave in slaves['active']:
+ self.verify(pkt_now[slave][0] == pkt_count, "Active slave has error RX packet in TLB")
+
+ def verify_tlb_tx(self, unbound_port, bond_port, **slaves):
+ """
+ Verify that transmitting packets correctly in the broadcast mode.
+ Parameters:
+ *** unbound_port: the unbonded port id
+ *** bond_port: the bonded device port id
+ *** slaves:
+ ******* 'actvie':[]
+ ******* 'inactive':[]
+ """
+ pkt_count = 'MANY'
+ pkt_now = {}
+
+ # send to unbonded device
+ pkt_now, summary = self.send_default_packet_to_unbound_port(unbound_port, bond_port, pkt_count=pkt_count, **slaves)
+
+ active_slaves = len(slaves['active'])
+ if active_slaves:
+ mean = float(summary) / float(active_slaves)
+ active_flag = 1
+ else:
+ active_flag = 0
+
+ for slave in slaves['active']:
+ self.verify(pkt_now[slave][0] > mean * 0.9 and
+ pkt_now[slave][0] < mean * 1.1,
+ "Slave TX packet not correct in mode 5")
+ for slave in slaves['inactive']:
+ self.verify(pkt_now[slave][0] == 0, "Slave TX packet not correct in mode 5")
+ self.verify(pkt_now[unbound_port][0] == summary,
+ "Unbonded port RX packet not correct in TLB")
+ self.verify(pkt_now[bond_port][0] == summary * active_flag,
+ "Bonded device TX packet not correct in TLB")
+
+ def test_tlb_basic(self):
+ self.verify_bound_basic_opt(MODE_TLB_BALANCE)
+ self.verify_bound_mac_opt(MODE_TLB_BALANCE)
+ self.verify_bound_promisc_opt(MODE_TLB_BALANCE)
+
+ def test_tlb_rx_tx(self):
+ bond_port = self.create_bonded_device(MODE_TLB_BALANCE, SOCKET_0)
+ self.add_slave_to_bonding_device(bond_port, False,
+ self.dut_ports[0],
+ self.dut_ports[1],
+ self.dut_ports[2])
+ self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
+ self.start_all_ports()
+ self.dut.send_expect("start", "testpmd> ")
+
+ slaves = {}
+ slaves['active'] = [self.dut_ports[0], self.dut_ports[1], self.dut_ports[2]]
+ slaves['inactive'] = []
+
+ self.verify_tlb_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_tlb_tx(self.dut_ports[3], bond_port, **slaves)
+
+ def test_tlb_one_slave_dwon(self):
+ bond_port = self.create_bonded_device(MODE_TLB_BALANCE, SOCKET_0)
+ self.add_slave_to_bonding_device(bond_port, False,
+ self.dut_ports[0],
+ self.dut_ports[1],
+ self.dut_ports[2])
+ self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
+ self.start_all_ports()
+ self.dut.send_expect("start", "testpmd> ")
+ self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "down")
+
+ try:
+ slaves = {}
+ slaves['active'] = [self.dut_ports[1], self.dut_ports[2]]
+ slaves['inactive'] = [self.dut_ports[0]]
+
+ self.verify_tlb_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_tlb_tx(self.dut_ports[3], bond_port, **slaves)
+ finally:
+ self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "up")
+
+ def test_tlb_all_slaves_down(self):
+ bond_port = self.create_bonded_device(MODE_TLB_BALANCE, SOCKET_0)
+ self.add_slave_to_bonding_device(bond_port, False,
+ self.dut_ports[0],
+ self.dut_ports[1],
+ self.dut_ports[2])
+ self.dut.send_expect("set portlist %d,%d" % (self.dut_ports[3], bond_port), "testpmd> ")
+ self.start_all_ports()
+ self.dut.send_expect("start", "testpmd> ")
+ self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "down")
+ self.admin_tester_port(self.tester.get_local_port(self.dut_ports[1]), "down")
+ self.admin_tester_port(self.tester.get_local_port(self.dut_ports[2]), "down")
+
+ try:
+ slaves = {}
+ slaves['active'] = []
+ slaves['inactive'] = [self.dut_ports[0], self.dut_ports[1], self.dut_ports[2]]
+
+ self.verify_tlb_rx(self.dut_ports[3], bond_port, **slaves)
+ self.verify_tlb_tx(self.dut_ports[3], bond_port, **slaves)
finally:
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[0]), "up")
self.admin_tester_port(self.tester.get_local_port(self.dut_ports[1]), "up")
@@ -1091,6 +2033,7 @@ UDP(sport=srcport, dport=destport)/Raw(load="\x50"*%s)], iface="%s", count=%d)'
"""
self.dut.send_expect("quit", "# ")
+ @just_clear_lacp
def tear_down_all(self):
"""
Run after each test suite.
diff --git a/tests/TestSuite_timer.py b/tests/TestSuite_timer.py
index f144bea..7b88d56 100644
--- a/tests/TestSuite_timer.py
+++ b/tests/TestSuite_timer.py
@@ -1,33 +1,49 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Test Timer.
-
"""
-import dcts
+import dts
import re
import time
from test_case import TestCase
-#
-#
-# Test class.
-#
-
class TestTimer(TestCase):
- #
- #
- #
- # Test cases.
- #
-
def set_up_all(self):
"""
Run at the start of each test suite.
@@ -53,7 +69,7 @@ class TestTimer(TestCase):
# get the mask for the first core
cores = self.dut.get_core_list('1S/1C/1T')
- coreMask = dcts.create_mask(cores)
+ coreMask = dts.create_mask(cores)
# run timer on the background
cmdline = "./examples/timer/build/app/timer -n 1 -c " + coreMask + " &"
@@ -63,7 +79,7 @@ class TestTimer(TestCase):
out = self.dut.send_expect("killall timer", "# ", 5)
# verify timer0
- dcts.regexp(out, r'timer0_cb\(\) on lcore (\d+)')
+ dts.regexp(out, r'timer0_cb\(\) on lcore (\d+)')
pat = re.compile(r'timer0_cb\(\) on lcore (\d+)')
match = pat.findall(out)
self.verify(match or match[0] == 0, "timer0 error")
diff --git a/tests/TestSuite_vlan.py b/tests/TestSuite_vlan.py
index 11ef94f..e9813f3 100644
--- a/tests/TestSuite_vlan.py
+++ b/tests/TestSuite_vlan.py
@@ -1,32 +1,49 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Test the support of VLAN Offload Features by Poll Mode Drivers.
-
"""
-import dcts
+import dts
import time
from test_case import TestCase
-
-#
-#
-# Test class.
-#
+from pmd_output import PmdOutput
class TestVlan(TestCase):
- #
- #
- #
- # Test cases.
- #
-
def set_up_all(self):
"""
Run at the start of each test suite.
@@ -41,19 +58,15 @@ class TestVlan(TestCase):
# Verify that enough ports are available
self.verify(len(ports) >= 2, "Insufficient ports")
- cores = self.dut.get_core_list('1S/2C/2T')
- coreMask = dcts.create_mask(cores)
-
ports = self.dut.get_ports(self.nic)
global valports
valports = [_ for _ in ports if self.tester.get_local_port(_) != -1]
- portMask = dcts.create_mask(valports[:2])
+ portMask = dts.create_mask(valports[:2])
- cmd = "./%s/build/app/test-pmd/testpmd -c %s -n 3 -- -i --burst=1 \
- --mbcache=250 --portmask=%s" % (self.target, coreMask, portMask)
+ self.pmdout = PmdOutput(self.dut)
+ self.pmdout.start_testpmd("all", "--portmask=%s" % portMask)
- self.dut.send_expect("%s" % cmd, "testpmd> ", 120)
self.dut.send_expect("set verbose 1", "testpmd> ")
out = self.dut.send_expect("set fwd mac", "testpmd> ")
self.dut.send_expect("vlan set strip off %s" % valports[0], "testpmd> ")
@@ -118,6 +131,9 @@ class TestVlan(TestCase):
out = self.dut.send_expect("stop", "testpmd> ")
def test_vlan_strip_config_on(self):
+ """
+ Set vlan strip on
+ """
self.dut.send_expect("vlan set strip on %s" % valports[0], "testpmd> ", 20)
self.dut.send_expect("set promisc all off", "testpmd> ", 20)
out = self.dut.send_expect("vlan set strip on %s" % valports[0], "testpmd> ", 20)
@@ -130,6 +146,10 @@ class TestVlan(TestCase):
out = self.dut.send_expect("quit", "#", 120)
def test_vlan_strip_config_off(self):
+ """
+ Set vlan strip off
+ """
+
self.dut.send_expect("vlan set strip off %s" % valports[0], "testpmd> ", 20)
out = self.dut.send_expect("show port info %s" % valports[0], "testpmd> ", 20)
self.verify("strip off" in out, "Wrong strip:" + out)
diff --git a/tests/TestSuite_whitelist.py b/tests/TestSuite_whitelist.py
index 3ef1756..a32251d 100644
--- a/tests/TestSuite_whitelist.py
+++ b/tests/TestSuite_whitelist.py
@@ -1,32 +1,49 @@
-# <COPYRIGHT_TAG>
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
DPDK Test suite.
-
Test the support of Whitelist Features by Poll Mode Drivers
-
"""
-import dcts
+import dts
import time
from test_case import TestCase
-
-#
-#
-# Test class.
-#
+from pmd_output import PmdOutput
class TestWhitelist(TestCase):
- #
- #
- #
- # Test cases.
- #
-
def set_up_all(self):
"""
Run at the start of each test suite.
@@ -43,14 +60,10 @@ class TestWhitelist(TestCase):
# Verify that enough ports are available
self.verify(len(self.dutPorts) >= 1, "Insufficient ports")
- cores = self.dut.get_core_list('1S/2C/1T')
- coreMask = dcts.create_mask(cores)
-
- portMask = dcts.create_mask(self.dutPorts[:2])
+ portMask = dts.create_mask(self.dutPorts[:2])
- cmd = "./%s/build/app/test-pmd/testpmd -c %s -n 3 -- -i --burst=1 --rxpt=0 \
- --rxht=0 --rxwt=0 --txpt=36 --txht=0 --txwt=0 --txrst=32 --txfreet=32 --rxfreet=64 --mbcache=250 --portmask=%s" % (self.target, coreMask, portMask)
- self.dut.send_expect("%s" % cmd, "testpmd> ", 120)
+ self.pmdout = PmdOutput(self.dut)
+ self.pmdout.start_testpmd("1S/2C/1T", "--portmask=%s" % portMask)
self.dut.send_expect("set verbose 1", "testpmd> ")
# get dest address from self.target port
@@ -59,11 +72,11 @@ class TestWhitelist(TestCase):
self.dest = self.dut.get_mac_address(self.dutPorts[0])
mac_scanner = r"MAC address: (([\dA-F]{2}:){5}[\dA-F]{2})"
- ret = dcts.regexp(out, mac_scanner)
+ ret = dts.regexp(out, mac_scanner)
self.verify(ret is not None, "MAC address not found")
self.verify(cmp(ret.lower(), self.dest) == 0, "MAC address wrong")
- self.max_mac_addr = dcts.regexp(out, "Maximum number of MAC addresses: ([0-9]+)")
+ self.max_mac_addr = dts.regexp(out, "Maximum number of MAC addresses: ([0-9]+)")
def set_up(self):
"""
@@ -98,12 +111,12 @@ class TestWhitelist(TestCase):
self.dut.send_expect("set promisc %d off" % portid, "testpmd> ")
out = self.dut.send_expect("show port stats %d" % portid, "testpmd> ")
- pre_rxpkt = dcts.regexp(out, "RX-packets: ([0-9]+)")
+ pre_rxpkt = dts.regexp(out, "RX-packets: ([0-9]+)")
# send one packet with the portid MAC address
self.whitelist_send_packet(portid, self.dest)
out = self.dut.send_expect("show port stats %d" % portid, "testpmd> ")
- cur_rxpkt = dcts.regexp(out, "RX-packets: ([0-9]+)")
+ cur_rxpkt = dts.regexp(out, "RX-packets: ([0-9]+)")
# check the packet increase
self.verify(int(cur_rxpkt) == int(pre_rxpkt) + self.frames_to_send,
"Packet has not been received on default address")
@@ -113,7 +126,7 @@ class TestWhitelist(TestCase):
pre_rxpkt = cur_rxpkt
out = self.dut.send_expect("show port stats %d" % portid, "testpmd> ")
- cur_rxpkt = dcts.regexp(out, "RX-packets: ([0-9]+)")
+ cur_rxpkt = dts.regexp(out, "RX-packets: ([0-9]+)")
# check the packet DO NOT increase
self.verify(int(cur_rxpkt) == int(pre_rxpkt),
@@ -126,7 +139,7 @@ class TestWhitelist(TestCase):
pre_rxpkt = cur_rxpkt
out = self.dut.send_expect("show port stats %d" % portid, "testpmd> ")
- cur_rxpkt = dcts.regexp(out, "RX-packets: ([0-9]+)")
+ cur_rxpkt = dts.regexp(out, "RX-packets: ([0-9]+)")
# check the packet increase
self.verify(int(cur_rxpkt) == int(pre_rxpkt) + self.frames_to_send,
@@ -140,7 +153,7 @@ class TestWhitelist(TestCase):
pre_rxpkt = cur_rxpkt
out = self.dut.send_expect("show port stats %d" % portid, "testpmd> ")
- cur_rxpkt = dcts.regexp(out, "RX-packets: ([0-9]+)")
+ cur_rxpkt = dts.regexp(out, "RX-packets: ([0-9]+)")
# check the packet increase
self.verify(int(cur_rxpkt) == int(pre_rxpkt),