1.. SPDX-License-Identifier: BSD-3-Clause 2 Copyright(c) 2022-2023 PANTHEON.tech s.r.o. 3 Copyright(c) 2024 Arm Limited 4 5DPDK Test Suite 6=============== 7 8The DPDK Test Suite, abbreviated DTS, is a Python test framework with test suites 9implementing functional and performance tests used to test DPDK. 10 11 12DTS Terminology 13--------------- 14 15DTS node 16 A generic description of any host/server DTS connects to. 17 18DTS runtime environment 19 An environment containing Python with packages needed to run DTS. 20 21DTS runtime environment node 22 A node where at least one DTS runtime environment is present. 23 This is the node where we run DTS and from which DTS connects to other nodes. 24 25System under test 26 An SUT is the combination of DPDK and the hardware we're testing 27 in conjunction with DPDK (NICs, crypto and other devices). 28 29System under test node 30 A node where at least one SUT is present. 31 32Traffic generator 33 A TG is either software or hardware capable of sending packets. 34 35Traffic generator node 36 A node where at least one TG is present. 37 In case of hardware traffic generators, the TG and the node are literally the same. 38 39 40In most cases, interchangeably referring to a runtime environment, SUT, TG or the node 41they're running on (e.g. using SUT and SUT node interchangeably) doesn't cause confusion. 42There could theoretically be more than of these running on the same node and in that case 43it's useful to have stricter definitions. 44An example would be two different traffic generators (such as Trex and Scapy) 45running on the same node. 46A different example would be a node containing both a DTS runtime environment 47and a traffic generator, in which case it's both a DTS runtime environment node and a TG node. 48 49 50DTS Environment 51--------------- 52 53DTS is written entirely in Python using a variety of dependencies. 54DTS uses Poetry as its Python dependency management. 55Python build/development and runtime environments are the same and DTS development environment, 56DTS runtime environment or just plain DTS environment are used interchangeably. 57 58.. _dts_deps: 59 60Setting up DTS environment 61~~~~~~~~~~~~~~~~~~~~~~~~~~ 62 63#. **Python Version** 64 65 The Python Version required by DTS is specified in ``dts/pyproject.toml`` in the 66 **[tool.poetry.dependencies]** section: 67 68 .. literalinclude:: ../../../dts/pyproject.toml 69 :language: cfg 70 :start-at: [tool.poetry.dependencies] 71 :end-at: python 72 73 The Python dependency manager DTS uses, Poetry, doesn't install Python, so you may need 74 to satisfy this requirement by other means if your Python is not up-to-date. 75 A tool such as `Pyenv <https://github.com/pyenv/pyenv>`_ is a good way to get Python, 76 though not the only one. 77 78#. **Poetry** 79 80 The typical style of python dependency management, pip with ``requirements.txt``, 81 has a few issues. 82 The advantages of Poetry include specifying what Python version is required and forcing you 83 to specify versions, enforced by a lockfile, both of which help prevent broken dependencies. 84 Another benefit is the usage of ``pyproject.toml``, which has become the standard config file 85 for python projects, improving project organization. 86 To install Poetry, visit their `doc pages <https://python-poetry.org/docs/>`_. 87 The recommended Poetry version is at least 1.8.2. 88 89#. **Getting a Poetry shell** 90 91 Once you have Poetry along with the proper Python version all set up, it's just a matter 92 of installing dependencies via Poetry and using the virtual environment Poetry provides: 93 94 .. code-block:: console 95 96 poetry install 97 poetry shell 98 99#. **SSH Connection** 100 101 DTS uses the Fabric Python library for SSH connections between DTS environment 102 and the other hosts. 103 The authentication method used is pubkey authentication. 104 Fabric tries to use a passed key/certificate, 105 then any key it can with through an SSH agent, 106 then any "id_rsa", "id_dsa" or "id_ecdsa" key discoverable in ``~/.ssh/`` 107 (with any matching OpenSSH-style certificates). 108 DTS doesn't pass any keys, so Fabric tries to use the other two methods. 109 110 111Setting up System Under Test 112---------------------------- 113 114There are two areas that need to be set up on a System Under Test: 115 116#. **DPDK dependencies** 117 118 DPDK will be built and run on the SUT. 119 Consult the Getting Started guides for the list of dependencies for each distribution. 120 121#. **Hardware dependencies** 122 123 Any hardware DPDK uses needs a proper driver 124 and most OS distributions provide those, but the version may not be satisfactory. 125 It's up to each user to install the driver they're interested in testing. 126 The hardware also may also need firmware upgrades, which is also left at user discretion. 127 128#. **Hugepages** 129 130 There are two ways to configure hugepages: 131 132 * DTS configuration 133 134 You may specify the optional hugepage configuration in the DTS config file. 135 If you do, DTS will take care of configuring hugepages, 136 overwriting your current SUT hugepage configuration. 137 Configuration of hugepages via DTS allows only for allocation of 2MB hugepages, 138 as doing so prevents accidental/over allocation of hugepage sizes 139 not recommended during runtime due to contiguous memory space requirements. 140 Thus, if you require hugepage sizes not equal to 2MB, 141 then this configuration must be done outside of the DTS framework. 142 143 * System under test configuration 144 145 It's possible to use the hugepage configuration already present on the SUT. 146 If you wish to do so, don't specify the hugepage configuration in the DTS config file. 147 148#. **User with administrator privileges** 149 150.. _sut_admin_user: 151 152 DTS needs administrator privileges to run DPDK applications (such as testpmd) on the SUT. 153 The SUT user must be able run commands in privileged mode without asking for password. 154 On most Linux distributions, it's a matter of setting up passwordless sudo: 155 156 #. Run ``sudo visudo`` and check that it contains ``%sudo ALL=(ALL:ALL) NOPASSWD:ALL``. 157 158 #. Add the SUT user to the sudo group with: 159 160 .. code-block:: console 161 162 sudo usermod -aG sudo <sut_user> 163 164 165Setting up Traffic Generator Node 166--------------------------------- 167 168These need to be set up on a Traffic Generator Node: 169 170#. **Traffic generator dependencies** 171 172 The traffic generator running on the traffic generator node must be installed beforehand. 173 For Scapy traffic generator, only a few Python libraries need to be installed: 174 175 .. code-block:: console 176 177 sudo apt install python3-pip 178 sudo pip install --upgrade pip 179 sudo pip install scapy==2.5.0 180 181#. **Hardware dependencies** 182 183 The traffic generators, like DPDK, need a proper driver and firmware. 184 The Scapy traffic generator doesn't have strict requirements - the drivers that come 185 with most OS distributions will be satisfactory. 186 187 188#. **User with administrator privileges** 189 190 Similarly to the System Under Test, traffic generators need administrator privileges 191 to be able to use the devices. 192 Refer to the `System Under Test section <sut_admin_user>` for details. 193 194 195Running DTS 196----------- 197 198DTS needs to know which nodes to connect to and what hardware to use on those nodes. 199Once that's configured, either a DPDK source code tarball or tree folder 200need to be supplied whether these are on your DTS host machine or the SUT node. 201DTS can accept a pre-compiled build placed in a subdirectory, 202or it will compile DPDK on the SUT node, 203and then run the tests with the newly built binaries. 204 205 206Configuring DTS 207~~~~~~~~~~~~~~~ 208 209DTS configuration is split into nodes and test runs, 210and must respect the model definitions 211as documented in the DTS API docs under the ``config`` page. 212The root of the configuration is represented by the ``Configuration`` model. 213By default, DTS will try to use the ``dts/conf.yaml`` :ref:`config file <configuration_example>`, 214which is a template that illustrates what can be configured in DTS. 215 216The user must have :ref:`administrator privileges <sut_admin_user>` 217which don't require password authentication. 218 219 220DTS Execution 221~~~~~~~~~~~~~ 222 223DTS is run with ``main.py`` located in the ``dts`` directory after entering Poetry shell: 224 225.. code-block:: console 226 227 (dts-py3.10) $ ./main.py --help 228 usage: main.py [-h] [--config-file FILE_PATH] [--output-dir DIR_PATH] [-t SECONDS] [-v] [--dpdk-tree DIR_PATH | --tarball FILE_PATH] [--remote-source] 229 [--precompiled-build-dir DIR_NAME] [--compile-timeout SECONDS] [--test-suite TEST_SUITE [TEST_CASES ...]] [--re-run N_TIMES] 230 [--random-seed NUMBER] 231 232 Run DPDK test suites. All options may be specified with the environment variables provided in brackets. Command line arguments have higher priority. 233 234 options: 235 -h, --help show this help message and exit 236 --config-file FILE_PATH 237 [DTS_CFG_FILE] The configuration file that describes the test cases, SUTs and DPDK build configs. (default: conf.yaml) 238 --output-dir DIR_PATH, --output DIR_PATH 239 [DTS_OUTPUT_DIR] Output directory where DTS logs and results are saved. (default: output) 240 -t SECONDS, --timeout SECONDS 241 [DTS_TIMEOUT] The default timeout for all DTS operations except for compiling DPDK. (default: 15) 242 -v, --verbose [DTS_VERBOSE] Specify to enable verbose output, logging all messages to the console. (default: False) 243 --compile-timeout SECONDS 244 [DTS_COMPILE_TIMEOUT] The timeout for compiling DPDK. (default: 1200) 245 --test-suite TEST_SUITE [TEST_CASES ...] 246 [DTS_TEST_SUITES] A list containing a test suite with test cases. The first parameter is the test suite name, and the rest are 247 test case names, which are optional. May be specified multiple times. To specify multiple test suites in the environment 248 variable, join the lists with a comma. Examples: --test-suite suite case case --test-suite suite case ... | 249 DTS_TEST_SUITES='suite case case, suite case, ...' | --test-suite suite --test-suite suite case ... | DTS_TEST_SUITES='suite, 250 suite case, ...' (default: []) 251 --re-run N_TIMES, --re_run N_TIMES 252 [DTS_RERUN] Re-run each test case the specified number of times if a test failure occurs. (default: 0) 253 --random-seed NUMBER [DTS_RANDOM_SEED] The seed to use with the pseudo-random generator. If not specified, the configuration value is used instead. 254 If that's also not specified, a random seed is generated. (default: None) 255 256 DPDK Build Options: 257 Arguments in this group (and subgroup) will be applied to a DPDKLocation when the DPDK tree, tarball or revision will be provided, other arguments 258 like remote source and build dir are optional. A DPDKLocation from settings are used instead of from config if construct successful. 259 260 --dpdk-tree DIR_PATH [DTS_DPDK_TREE] The path to the DPDK source tree directory to test. Cannot be used in conjunction with --tarball. (default: 261 None) 262 --tarball FILE_PATH, --snapshot FILE_PATH 263 [DTS_DPDK_TARBALL] The path to the DPDK source tarball to test. DPDK must be contained in a folder with the same name as the 264 tarball file. Cannot be used in conjunction with --dpdk-tree. (default: None) 265 --remote-source [DTS_REMOTE_SOURCE] Set this option if either the DPDK source tree or tarball to be used are located on the SUT node. Can only 266 be used with --dpdk-tree or --tarball. (default: False) 267 --precompiled-build-dir DIR_NAME 268 [DTS_PRECOMPILED_BUILD_DIR] Define the subdirectory under the DPDK tree root directory where the pre-compiled binaries are 269 located. If set, DTS will build DPDK under the `build` directory instead. Can only be used with --dpdk-tree or --tarball. 270 (default: None) 271 272 273The brackets contain the names of environment variables that set the same thing. 274The minimum DTS needs is a config file and a pre-built DPDK 275or DPDK sources location which can be specified in said config file 276or on the command line or environment variables. 277 278 279DTS Results 280~~~~~~~~~~~ 281 282Results are stored in the output dir by default 283which be changed with the ``--output-dir`` command line argument. 284The results contain basic statistics of passed/failed test cases and DPDK version. 285 286 287Contributing to DTS 288------------------- 289 290There are two areas of contribution: The DTS framework and DTS test suites. 291 292The framework contains the logic needed to run test cases, such as connecting to nodes, 293running DPDK applications and collecting results. 294 295The test cases call APIs from the framework to test their scenarios. 296Adding test cases may require adding code to the framework as well. 297 298 299Framework Coding Guidelines 300~~~~~~~~~~~~~~~~~~~~~~~~~~~ 301 302When adding code to the DTS framework, pay attention to the rest of the code 303and try not to divert much from it. 304The :ref:`DTS developer tools <dts_dev_tools>` will issue warnings 305when some of the basics are not met. 306You should also build the :ref:`API documentation <building_api_docs>` 307to address any issues found during the build. 308 309The API documentation, which is a helpful reference when developing, may be accessed 310in the code directly or generated with the :ref:`API docs build steps <building_api_docs>`. 311When adding new files or modifying the directory structure, 312the corresponding changes must be made to DTS API doc sources in ``doc/api/dts``. 313 314Speaking of which, the code must be properly documented with docstrings. 315The style must conform to the `Google style 316<https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings>`_. 317See an example of the style `here 318<https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html>`_. 319For cases which are not covered by the Google style, refer to `PEP 257 320<https://peps.python.org/pep-0257/>`_. 321There are some cases which are not covered by the two style guides, 322where we deviate or where some additional clarification is helpful: 323 324 * The ``__init__()`` methods of classes are documented separately 325 from the docstring of the class itself. 326 * The docstrings of implemented abstract methods should refer to the superclass's definition 327 if there's no deviation. 328 * Instance variables/attributes should be documented in the docstring of the class 329 in the ``Attributes:`` section. 330 * The ``dataclass.dataclass`` decorator changes how the attributes are processed. 331 The dataclass attributes which result in instance variables/attributes 332 should also be recorded in the ``Attributes:`` section. 333 * Class variables/attributes and Pydantic model fields, on the other hand, 334 should be documented with ``#:`` above the type annotated line. 335 The description may be omitted if the meaning is obvious. 336 * The ``Enum`` and ``TypedDict`` also process the attributes in particular ways 337 and should be documented with ``#:`` as well. 338 This is mainly so that the autogenerated documentation contains the assigned value. 339 * When referencing a parameter of a function or a method in their docstring, 340 don't use any articles and put the parameter into single backticks. 341 This mimics the style of `Python's documentation <https://docs.python.org/3/index.html>`_. 342 * When specifying a value, use double backticks:: 343 344 def foo(greet: bool) -> None: 345 """Demonstration of single and double backticks. 346 347 `greet` controls whether ``Hello World`` is printed. 348 349 Args: 350 greet: Whether to print the ``Hello World`` message. 351 """ 352 if greet: 353 print(f"Hello World") 354 355 * The docstring maximum line length is the same as the code maximum line length. 356 357 358How To Write a Test Suite 359------------------------- 360 361All test suites inherit from ``TestSuite`` defined in ``dts/framework/test_suite.py``. 362There are four types of methods that comprise a test suite: 363 364#. **Test cases** 365 366 | Test cases are methods that start with a particular prefix. 367 | Functional test cases start with ``test_``, e.g. ``test_hello_world_single_core``. 368 | Performance test cases start with ``test_perf_``, e.g. ``test_perf_nic_single_core``. 369 | A test suite may have any number of functional and/or performance test cases. 370 However, these test cases must test the same feature, 371 following the rule of one feature = one test suite. 372 Test cases for one feature don't need to be grouped in just one test suite, though. 373 If the feature requires many testing scenarios to cover, 374 the test cases would be better off spread over multiple test suites 375 so that each test suite doesn't take too long to execute. 376 377#. **Setup and Teardown methods** 378 379 | There are setup and teardown methods for the whole test suite and each individual test case. 380 | Methods ``set_up_suite`` and ``tear_down_suite`` will be executed 381 before any and after all test cases have been executed, respectively. 382 | Methods ``set_up_test_case`` and ``tear_down_test_case`` will be executed 383 before and after each test case, respectively. 384 | These methods don't need to be implemented if there's no need for them in a test suite. 385 In that case, nothing will happen when they are executed. 386 387#. **Configuration, traffic and other logic** 388 389 The ``TestSuite`` class contains a variety of methods for anything that 390 a test suite setup, a teardown, or a test case may need to do. 391 392 The test suites also frequently use a DPDK app, such as testpmd, in interactive mode 393 and use the interactive shell instances directly. 394 395 These are the two main ways to call the framework logic in test suites. 396 If there's any functionality or logic missing from the framework, 397 it should be implemented so that the test suites can use one of these two ways. 398 399#. **Test case verification** 400 401 Test case verification should be done with the ``verify`` method, which records the result. 402 The method should be called at the end of each test case. 403 404#. **Other methods** 405 406 Of course, all test suite code should adhere to coding standards. 407 Only the above methods will be treated specially and any other methods may be defined 408 (which should be mostly private methods needed by each particular test suite). 409 Any specific features (such as NIC configuration) required by a test suite 410 should be implemented in the ``SutNode`` class (and the underlying classes that ``SutNode`` uses) 411 and used by the test suite via the ``sut_node`` field. 412 413 414.. _dts_dev_tools: 415 416DTS Developer Tools 417------------------- 418 419There are three tools used in DTS to help with code checking, style and formatting: 420 421* `isort <https://pycqa.github.io/isort/>`_ 422 423 Alphabetically sorts python imports within blocks. 424 425* `black <https://github.com/psf/black>`_ 426 427 Does most of the actual formatting (whitespaces, comments, line length etc.) 428 and works similarly to clang-format. 429 430* `pylama <https://github.com/klen/pylama>`_ 431 432 Runs a collection of python linters and aggregates output. 433 It will run these tools over the repository: 434 435 .. literalinclude:: ../../../dts/pyproject.toml 436 :language: cfg 437 :start-after: [tool.pylama] 438 :end-at: linters 439 440* `mypy <https://github.com/python/mypy>`_ 441 442 Enables static typing for Python, exploiting the type hints in the source code. 443 444These three tools are all used in ``devtools/dts-check-format.sh``, 445the DTS code check and format script. 446Refer to the script for usage: ``devtools/dts-check-format.sh -h``. 447 448 449.. _building_api_docs: 450 451Building DTS API docs 452--------------------- 453 454The documentation is built using the standard DPDK build system. 455See :doc:`../linux_gsg/build_dpdk` for more details on compiling DPDK with meson. 456 457The :ref:`doc build dependencies <doc_dependencies>` may be installed with Poetry: 458 459.. code-block:: console 460 461 poetry install --only docs 462 poetry install --with docs # an alternative that will also install DTS dependencies 463 poetry shell 464 465After executing the meson command, build the documentation with: 466 467.. code-block:: console 468 469 ninja -C build doc 470 471The output is generated in ``build/doc/api/dts/html``. 472 473.. note:: 474 475 Make sure to fix any Sphinx warnings when adding or updating docstrings. 476 477.. _configuration_example: 478 479Configuration Example 480--------------------- 481 482The following example (which can be found in ``dts/conf.yaml``) sets up two nodes: 483 484* ``SUT1`` which is already setup with the DPDK build requirements and any other 485 required for execution; 486* ``TG1`` which already has Scapy installed in the system. 487 488And they both have two network ports which are physically connected to each other. 489 490.. note:: 491 This example assumes that you have setup SSH keys in both the system under test 492 and traffic generator nodes. 493 494.. literalinclude:: ../../../dts/conf.yaml 495 :language: yaml 496 :start-at: test_runs: 497