Skip to content

Commit 2285b7d

Browse files
dmarxIOLPatrickRobbIOL
authored andcommitted
doc: revise coding guidelines section
The Framework Coding Guidelines section includes outdated information about DTS and how to write a test suite. Updated these points to include the new test case decorators and setup/teardown hooks. Signed-off-by: Dean Marx <dmarx@iol.unh.edu> Reviewed-by: Patrick Robb <probb@iol.unh.edu>
1 parent 0268ce5 commit 2285b7d

File tree

1 file changed

+97
-104
lines changed

1 file changed

+97
-104
lines changed

doc/guides/tools/dts.rst

Lines changed: 97 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,15 @@ Setting up DTS environment
7878
To install Poetry, visit their `doc pages <https://python-poetry.org/docs/>`_.
7979
The recommended Poetry version is at least 1.8.2.
8080

81-
#. **Getting a Poetry shell**
81+
#. **Running DTS with Poetry**
8282

8383
Once you have Poetry along with the proper Python version all set up, it's just a matter
84-
of installing dependencies via Poetry and using the virtual environment Poetry provides:
84+
of installing dependencies via Poetry and running main.py:
8585

8686
.. code-block:: console
8787
8888
poetry install
89-
poetry shell
89+
poetry run ./main.py
9090
9191
#. **SSH Connection**
9292

@@ -263,7 +263,7 @@ which don't require password authentication.
263263
DTS Execution
264264
~~~~~~~~~~~~~
265265

266-
DTS is run with ``main.py`` located in the ``dts`` directory after entering Poetry shell:
266+
DTS is run with ``main.py`` located in the ``dts`` directory using the ``poetry run`` command:
267267

268268
.. code-block:: console
269269
@@ -348,122 +348,118 @@ Adding test cases may require adding code to the framework as well.
348348
Framework Coding Guidelines
349349
~~~~~~~~~~~~~~~~~~~~~~~~~~~
350350

351-
When adding code to the DTS framework, pay attention to the rest of the code
352-
and try not to divert much from it.
353-
The :ref:`DTS developer tools <dts_dev_tools>` will issue warnings
354-
when some of the basics are not met.
355-
You should also build the :ref:`API documentation <building_api_docs>`
356-
to address any issues found during the build.
357-
358-
The API documentation, which is a helpful reference when developing, may be accessed
359-
in the code directly or generated with the :ref:`API docs build steps <building_api_docs>`.
360-
When adding new files or modifying the directory structure,
361-
the corresponding changes must be made to DTS API doc sources in ``doc/api/dts``.
362-
363-
Speaking of which, the code must be properly documented with docstrings.
364-
The style must conform to the `Google style
365-
<https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings>`_.
366-
See an example of the style `here
367-
<https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html>`_.
368-
For cases which are not covered by the Google style, refer to `PEP 257
369-
<https://peps.python.org/pep-0257/>`_.
370-
There are some cases which are not covered by the two style guides,
371-
where we deviate or where some additional clarification is helpful:
372-
373-
* The ``__init__()`` methods of classes are documented separately
374-
from the docstring of the class itself.
375-
* The docstrings of implemented abstract methods should refer to the superclass's definition
376-
if there's no deviation.
377-
* Instance variables/attributes should be documented in the docstring of the class
378-
in the ``Attributes:`` section.
379-
* The ``dataclass.dataclass`` decorator changes how the attributes are processed.
380-
The dataclass attributes which result in instance variables/attributes
381-
should also be recorded in the ``Attributes:`` section.
382-
* Class variables/attributes and Pydantic model fields, on the other hand,
383-
should be documented with ``#:`` above the type annotated line.
384-
The description may be omitted if the meaning is obvious.
385-
* The ``Enum`` and ``TypedDict`` also process the attributes in particular ways
386-
and should be documented with ``#:`` as well.
387-
This is mainly so that the autogenerated documentation contains the assigned value.
388-
* When referencing a parameter of a function or a method in their docstring,
389-
don't use any articles and put the parameter into single backticks.
390-
This mimics the style of `Python's documentation <https://docs.python.org/3/index.html>`_.
391-
* When specifying a value, use double backticks::
392-
393-
def foo(greet: bool) -> None:
394-
"""Demonstration of single and double backticks.
395-
396-
`greet` controls whether ``Hello World`` is printed.
397-
398-
Args:
399-
greet: Whether to print the ``Hello World`` message.
400-
"""
401-
if greet:
402-
print(f"Hello World")
403-
404-
* The docstring maximum line length is the same as the code maximum line length.
351+
When contributing code to the DTS framework, follow existing conventions to ensure consistency.
352+
The :ref:`DTS developer tools <dts_dev_tools>` will flag basic issues.
353+
Also, be sure to :ref:`build the API documentation <building_api_docs>` to catch any problems during the build.
354+
355+
The API documentation is a helpful reference during development.
356+
It can be viewed in the code directly or generated using the :ref:`API docs build steps <building_api_docs>`.
357+
If you add new files or change the directory structure, update the corresponding sources in ``doc/api/dts``.
358+
359+
Code must be documented with docstrings that follow the
360+
`Google style <https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings>`_.
361+
Additional references:
362+
363+
* `Sphinx Google style example <https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html>`_
364+
* `PEP 257 <https://peps.python.org/pep-0257/>`_
365+
366+
Docstring and Attribute Guidelines
367+
368+
* Document ``__init__()`` separately from the class docstring.
369+
* If an abstract method simply implements a superclass definition without changes, refer to that superclass in the docstring.
370+
* Document instance variables in the class docstring under an ``Attributes:`` section.
371+
* For ``@dataclass`` classes, document instance-level attributes in ``Attributes:``, as they are generated from the class fields.
372+
* Document class variables and Pydantic fields using ``#:``,
373+
placed above the type-annotated line. Descriptions may be omitted if the meaning is clear.
374+
* Apply ``#:`` to ``Enum`` and ``TypedDict`` fields as well, so that autogenerated documentation includes their values.
375+
* When referring to a parameter in a docstring, omit articles and enclose the parameter in single backticks (e.g., `param`),
376+
consistent with the `Python documentation style <https://docs.python.org/3/index.html>`_.
377+
* Use double backticks (````value````) for literal values.
378+
379+
Example::
380+
381+
def foo(greet: bool) -> None:
382+
"""Demonstrates single and double backticks.
383+
384+
`greet` controls whether ``Hello World`` is printed.
385+
386+
Args:
387+
greet: Whether to print the ``Hello World`` message.
388+
"""
389+
if greet:
390+
print("Hello World")
391+
392+
The maximum line length for docstrings must match that of the code.
405393

406394

407395
How To Write a Test Suite
408396
-------------------------
409397

410-
All test suites inherit from ``TestSuite`` defined in ``dts/framework/test_suite.py``.
411-
There are four types of methods that comprise a test suite:
398+
All test suites are classes that inherit from TestSuite, defined in dts/framework/test_suite.py. A typical suite contains:
399+
400+
Test Cases
401+
402+
Test cases are defined as methods and must be decorated appropriately.
403+
Use the @func_test and/or @perf_test decorators from TestSuite above each test case method.
404+
For example:
405+
406+
@func_test
407+
def test_basic_link(self):
408+
"""your testcase docstring here"""
409+
#your testcase code here
412410

413-
#. **Test cases**
411+
Functional test cases should use the @func_test decorator, and performance test cases should use @perf_test.
412+
A test suite may include any number of functional and/or performance test cases.
413+
Each suite should focus on testing a single feature (one feature = one test suite).
414414

415-
| Test cases are methods that start with a particular prefix.
416-
| Functional test cases start with ``test_``, e.g. ``test_hello_world_single_core``.
417-
| Performance test cases start with ``test_perf_``, e.g. ``test_perf_nic_single_core``.
418-
| A test suite may have any number of functional and/or performance test cases.
419-
However, these test cases must test the same feature,
420-
following the rule of one feature = one test suite.
421-
Test cases for one feature don't need to be grouped in just one test suite, though.
422-
If the feature requires many testing scenarios to cover,
423-
the test cases would be better off spread over multiple test suites
424-
so that each test suite doesn't take too long to execute.
415+
Setup and Teardown Hooks
425416

426-
#. **Setup and Teardown methods**
417+
Setup and teardown methods can be defined at both the suite and test case levels.
427418

428-
| There are setup and teardown methods for the whole test suite and each individual test case.
429-
| Methods ``set_up_suite`` and ``tear_down_suite`` will be executed
430-
before any and after all test cases have been executed, respectively.
431-
| Methods ``set_up_test_case`` and ``tear_down_test_case`` will be executed
432-
before and after each test case, respectively.
433-
| These methods don't need to be implemented if there's no need for them in a test suite.
434-
In that case, nothing will happen when they are executed.
419+
Suite-level:
435420

436-
#. **Configuration, traffic and other logic**
421+
* set_up_suite() — runs once before any test cases in the suite
437422

438-
The ``TestSuite`` class contains a variety of methods for anything that
439-
a test suite setup, a teardown, or a test case may need to do.
423+
* tear_down_suite() — runs once after all test cases have completed
440424

441-
The test suites also frequently use a DPDK app, such as testpmd, in interactive mode
442-
and use the interactive shell instances directly.
425+
Case-level:
443426

444-
These are the two main ways to call the framework logic in test suites.
445-
If there's any functionality or logic missing from the framework,
446-
it should be implemented so that the test suites can use one of these two ways.
427+
* set_up_test_case() — runs before each individual test case
447428

448-
Test suites may also be configured individually using a file provided at the command line.
449-
The file is a simple mapping of test suite names to their corresponding configurations.
429+
* tear_down_test_case() — runs after each individual test case
450430

451-
Any test suite can be designed to require custom configuration attributes or optional ones.
452-
Any optional attributes should supply a default value for the test suite to use.
431+
These methods are optional. If not implemented, the framework will simply skip them.
453432

454-
#. **Test case verification**
433+
The TestSuite class provides a variety of methods for setup, teardown, and test logic.
434+
Test suites often use DPDK applications (e.g., testpmd) in interactive mode and interact with them via shell instances.
455435

456-
Test case verification should be done with the ``verify`` method, which records the result.
457-
The method should be called at the end of each test case.
436+
Leveraging the DTS framework in writing testsuites:
458437

459-
#. **Other methods**
438+
One should avoid directly importing DTS framework code to their
439+
testsuites where possible. Instead, for performing common processes
440+
required in testsuites, one should use (or add to) the list of methods
441+
provided in the Testsuite class (the base class of all testsuites). For
442+
instance, for sending a list of packets, one should work through the packet
443+
transmitting function already made available in the TestSuite class,
444+
instead of directly importing the DTS traffic generator class and using
445+
that class in one's testsuite implementation. It is also acceptable to
446+
import and instantiate classes for various DPDK applications. For instance,
447+
writing a testsuite for a simple packet forwarding operation would involve
448+
importing the DTS TestPmdShell class, instantiating TestPmdShell, calling
449+
TestPmdShell's start() method, and then sending traffic via one of the
450+
traffic transmitting functions exposed in the Testsuite class.
460451

461-
Of course, all test suite code should adhere to coding standards.
462-
Only the above methods will be treated specially and any other methods may be defined
463-
(which should be mostly private methods needed by each particular test suite).
464-
Any specific features (such as NIC configuration) required by a test suite
465-
should be implemented in the ``SutNode`` class (and the underlying classes that ``SutNode`` uses)
466-
and used by the test suite via the ``sut_node`` field.
452+
Test Case Verification
453+
454+
Use the verify method to assert conditions and record test results.
455+
This should typically be called at the end of each test case.
456+
Example: self.verify(link_up, "Link should be up after configuration.")
457+
458+
Other Methods
459+
460+
All test suite code should follow the project's coding standards.
461+
Only test cases, setup/teardown hooks, and verification methods are treated specially by the framework.
462+
Additional private methods may be added as needed in your testsuite implementation.
467463

468464

469465
.. _dts_dev_tools:
@@ -493,13 +489,10 @@ Building DTS API docs
493489
The documentation is built using the standard DPDK build system.
494490
See :doc:`../linux_gsg/build_dpdk` for more details on compiling DPDK with meson.
495491

496-
The :ref:`doc build dependencies <doc_dependencies>` may be installed with Poetry:
497-
498492
.. code-block:: console
499493
500494
poetry install --only docs
501495
poetry install --with docs # an alternative that will also install DTS dependencies
502-
poetry shell
503496
504497
After executing the meson command, build the documentation with:
505498

0 commit comments

Comments
 (0)