<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Fri, Jul 11, 2025 at 1:25 PM Dean Marx <<a href="mailto:dmarx@iol.unh.edu">dmarx@iol.unh.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The Framework Coding Guidelines section includes outdated information<br>
about DTS and how to write a test suite. Updated these points to include<br>
the new test case decorators and setup/teardown hooks.<br>
<br>
Signed-off-by: Dean Marx <<a href="mailto:dmarx@iol.unh.edu" target="_blank">dmarx@iol.unh.edu</a>><br>
---<br>
 doc/guides/tools/dts.rst | 181 ++++++++++++++++++---------------------<br>
 1 file changed, 84 insertions(+), 97 deletions(-)<br>
<br>
diff --git a/doc/guides/tools/dts.rst b/doc/guides/tools/dts.rst<br>
index 7f6f7c1db5..6af9f8b75c 100644<br>
--- a/doc/guides/tools/dts.rst<br>
+++ b/doc/guides/tools/dts.rst<br>
@@ -348,122 +348,109 @@ Adding test cases may require adding code to the framework as well.<br>
 Framework Coding Guidelines<br>
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~<br>
<br>
-When adding code to the DTS framework, pay attention to the rest of the code<br>
-and try not to divert much from it.<br>
-The :ref:`DTS developer tools <dts_dev_tools>` will issue warnings<br>
-when some of the basics are not met.<br>
-You should also build the :ref:`API documentation <building_api_docs>`<br>
-to address any issues found during the build.<br>
-<br>
-The API documentation, which is a helpful reference when developing, may be accessed<br>
-in the code directly or generated with the :ref:`API docs build steps <building_api_docs>`.<br>
-When adding new files or modifying the directory structure,<br>
-the corresponding changes must be made to DTS API doc sources in ``doc/api/dts``.<br>
-<br>
-Speaking of which, the code must be properly documented with docstrings.<br>
-The style must conform to the `Google style<br>
-<<a href="https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings" rel="noreferrer" target="_blank">https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings</a>>`_.<br>
-See an example of the style `here<br>
-<<a href="https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html" rel="noreferrer" target="_blank">https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html</a>>`_.<br>
-For cases which are not covered by the Google style, refer to `PEP 257<br>
-<<a href="https://peps.python.org/pep-0257/" rel="noreferrer" target="_blank">https://peps.python.org/pep-0257/</a>>`_.<br>
-There are some cases which are not covered by the two style guides,<br>
-where we deviate or where some additional clarification is helpful:<br>
-<br>
-   * The ``__init__()`` methods of classes are documented separately<br>
-     from the docstring of the class itself.<br>
-   * The docstrings of implemented abstract methods should refer to the superclass's definition<br>
-     if there's no deviation.<br>
-   * Instance variables/attributes should be documented in the docstring of the class<br>
-     in the ``Attributes:`` section.<br>
-   * The ``dataclass.dataclass`` decorator changes how the attributes are processed.<br>
-     The dataclass attributes which result in instance variables/attributes<br>
-     should also be recorded in the ``Attributes:`` section.<br>
-   * Class variables/attributes and Pydantic model fields, on the other hand,<br>
-     should be documented with ``#:`` above the type annotated line.<br>
-     The description may be omitted if the meaning is obvious.<br>
-   * The ``Enum`` and ``TypedDict`` also process the attributes in particular ways<br>
-     and should be documented with ``#:`` as well.<br>
-     This is mainly so that the autogenerated documentation contains the assigned value.<br>
-   * When referencing a parameter of a function or a method in their docstring,<br>
-     don't use any articles and put the parameter into single backticks.<br>
-     This mimics the style of `Python's documentation <<a href="https://docs.python.org/3/index.html" rel="noreferrer" target="_blank">https://docs.python.org/3/index.html</a>>`_.<br>
-   * When specifying a value, use double backticks::<br>
-<br>
-        def foo(greet: bool) -> None:<br>
-            """Demonstration of single and double backticks.<br>
-<br>
-            `greet` controls whether ``Hello World`` is printed.<br>
-<br>
-            Args:<br>
-               greet: Whether to print the ``Hello World`` message.<br>
-            """<br>
-            if greet:<br>
-               print(f"Hello World")<br>
-<br>
-   * The docstring maximum line length is the same as the code maximum line length.<br>
+When contributing code to the DTS framework, follow existing conventions to ensure consistency.<br>
+The :ref:`DTS developer tools <dts_dev_tools>` will flag basic issues.<br>
+Also, be sure to :ref:`build the API documentation <building_api_docs>` to catch any problems during the build.<br>
+<br>
+The API documentation is a helpful reference during development.<br>
+It can be viewed in the code directly or generated using the :ref:`API docs build steps <building_api_docs>`.<br>
+If you add new files or change the directory structure, update the corresponding sources in ``doc/api/dts``.<br>
+<br>
+Code must be documented with docstrings that follow the<br>
+`Google style <<a href="https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings" rel="noreferrer" target="_blank">https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings</a>>`_.<br>
+Additional references:<br>
+<br>
+* `Sphinx Google style example <<a href="https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html" rel="noreferrer" target="_blank">https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html</a>>`_<br>
+* `PEP 257 <<a href="https://peps.python.org/pep-0257/" rel="noreferrer" target="_blank">https://peps.python.org/pep-0257/</a>>`_<br>
+<br>
+Docstring and Attribute Guidelines<br>
+<br>
+* Document ``__init__()`` separately from the class docstring.<br>
+* If an abstract method simply implements a superclass definition without changes, refer to that superclass in the docstring.<br>
+* Document instance variables in the class docstring under an ``Attributes:`` section.<br>
+* For ``@dataclass`` classes, document instance-level attributes in ``Attributes:``, as they are generated from the class fields.<br>
+* Document class variables and Pydantic fields using ``#:``,<br>
+   placed above the type-annotated line. Descriptions may be omitted if the meaning is clear.<br>
+* Apply ``#:`` to ``Enum`` and ``TypedDict`` fields as well, so that autogenerated documentation includes their values.<br>
+* When referring to a parameter in a docstring, omit articles and enclose the parameter in single backticks (e.g., `` `param` ``),<br>
+   consistent with the `Python documentation style <<a href="https://docs.python.org/3/index.html" rel="noreferrer" target="_blank">https://docs.python.org/3/index.html</a>>`_.<br>
+* Use double backticks (````value````) for literal values.<br>
+<br>
+Example::<br>
+<br>
+   def foo(greet: bool) -> None:<br>
+       """Demonstrates single vs. double backticks.<br></blockquote><div><br></div><div>single AND double</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+       `greet` controls whether ``Hello World`` is printed.<br>
+<br>
+       Args:<br>
+           greet: Whether to print the ``Hello World`` message.<br>
+       """<br>
+       if greet:<br>
+           print("Hello World")<br>
+<br>
+The maximum line length for docstrings must match that of the code.<br>
<br>
<br>
 How To Write a Test Suite<br>
 -------------------------<br>
<br>
-All test suites inherit from ``TestSuite`` defined in ``dts/framework/test_suite.py``.<br>
-There are four types of methods that comprise a test suite:<br>
+All test suites are classes that inherit from TestSuite, defined in dts/framework/test_suite.py. A typical suite contains:<br>
+<br>
+Test Cases<br>
+<br>
+   Test cases are defined as methods and must be decorated appropriately.<br>
+   Use the @func_test and/or @perf_test decorators from TestSuite above each test case method.<br>
+   For example: @func_test followed by def test_basic_link(self):<br></blockquote><div><br></div><div>I think you should either not attempt to provide a literal example, or, if you are going to do so, then show it in normal syntax i.e.:</div><div><br></div><div>@func_test</div><div>def test_basic_link(self):</div><div>   """your testcase docstring here"""</div><div>   #your testcase code here</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+   Functional test cases should use the @func_test decorator, and performance test cases should use @perf_test.<br>
+   A test suite may include any number of functional and/or performance test cases.<br>
+   Each suite should focus on testing a single feature (one feature = one test suite).<br>
+   If a feature requires extensive testing scenarios, it's better to split the test cases across multiple test suites to reduce execution time.<br></blockquote><div><br></div><div>Can you remove this last line about execution time? It doesn't sound true to me (the execution time will be the same).</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+Setup and Teardown Hooks<br>
+<br>
+   Setup and teardown methods can be defined at both the suite and test case levels.<br>
+<br>
+   Suite-level:<br>
+<br>
+   * set_up_suite() — runs once before any test cases in the suite<br>
+<br>
+   * tear_down_suite() — runs once after all test cases have completed<br>
<br>
-#. **Test cases**<br>
+   Case-level:<br>
<br>
-   | Test cases are methods that start with a particular prefix.<br>
-   | Functional test cases start with ``test_``, e.g. ``test_hello_world_single_core``.<br>
-   | Performance test cases start with ``test_perf_``, e.g. ``test_perf_nic_single_core``.<br>
-   | A test suite may have any number of functional and/or performance test cases.<br>
-     However, these test cases must test the same feature,<br>
-     following the rule of one feature = one test suite.<br>
-     Test cases for one feature don't need to be grouped in just one test suite, though.<br>
-     If the feature requires many testing scenarios to cover,<br>
-     the test cases would be better off spread over multiple test suites<br>
-     so that each test suite doesn't take too long to execute.<br>
+   * set_up_test_case() — runs before each individual test case<br>
<br>
-#. **Setup and Teardown methods**<br>
+   * tear_down_test_case() — runs after each individual test case<br>
<br>
-   | There are setup and teardown methods for the whole test suite and each individual test case.<br>
-   | Methods ``set_up_suite`` and ``tear_down_suite`` will be executed<br>
-     before any and after all test cases have been executed, respectively.<br>
-   | Methods ``set_up_test_case`` and ``tear_down_test_case`` will be executed<br>
-     before and after each test case, respectively.<br>
-   | These methods don't need to be implemented if there's no need for them in a test suite.<br>
-     In that case, nothing will happen when they are executed.<br>
+   These methods are optional. If not implemented, the framework will simply skip them.<br>
<br>
-#. **Configuration, traffic and other logic**<br>
+Configuration, Traffic, and Other Logic<br></blockquote><div><br></div><div>Your section below does not say anything about configuration, so remove configuration from the header above. Also, it's unclear (to people who dont write/read lots of DTS) that "Traffic" is encompassed by the TestSuite class methods (like send_packet_and_capture).</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
-   The ``TestSuite`` class contains a variety of methods for anything that<br>
-   a test suite setup, a teardown, or a test case may need to do.<br>
+   The TestSuite class provides a variety of methods for setup, teardown, and test logic.<br>
+   Test suites often use DPDK applications (e.g., testpmd) in interactive mode and interact with them via shell instances.<br>
<br>
-   The test suites also frequently use a DPDK app, such as testpmd, in interactive mode<br>
-   and use the interactive shell instances directly.<br>
+Framework logic should be used in one of two ways:<br></blockquote><div><br></div><div>I think what this section is trying to say is that there is an API surface for the testsuite writer, and that is the TestSuite classes and DPDK apps.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
-   These are the two main ways to call the framework logic in test suites.<br>
-   If there's any functionality or logic missing from the framework,<br>
-   it should be implemented so that the test suites can use one of these two ways.<br>
+* Using built-in methods provided by TestSuite or its base classes<br>
<br>
-   Test suites may also be configured individually using a file provided at the command line.<br>
-   The file is a simple mapping of test suite names to their corresponding configurations.<br>
+* Interacting directly with tools or shell interfaces<br>
<br>
-   Any test suite can be designed to require custom configuration attributes or optional ones.<br>
-   Any optional attributes should supply a default value for the test suite to use.<br>
+If any required functionality is missing, it should be implemented in a way that supports one of these two approaches.<br>
<br></blockquote><div><br></div><div>Should this be indented since it is under the section "Framework logic should be used in one of two ways:" (although that section name should be renamed per the earlier comment).</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
-#. **Test case verification**<br>
+Test Case Verification<br>
<br>
-   Test case verification should be done with the ``verify`` method, which records the result.<br>
-   The method should be called at the end of each test case.<br>
+   Use the verify method to assert conditions and record test results.<br>
+   This should typically be called at the end of each test case.<br>
+   Example: self.verify(link_up, "Link should be up after configuration.")<br>
<br>
-#. **Other methods**<br>
+Other Methods<br>
<br>
-   Of course, all test suite code should adhere to coding standards.<br>
-   Only the above methods will be treated specially and any other methods may be defined<br>
-   (which should be mostly private methods needed by each particular test suite).<br>
-   Any specific features (such as NIC configuration) required by a test suite<br>
-   should be implemented in the ``SutNode`` class (and the underlying classes that ``SutNode`` uses)<br>
-   and used by the test suite via the ``sut_node`` field.<br>
+   All test suite code should follow the project's coding standards.<br>
+   Only test cases, setup/teardown hooks, and verification methods are treated specially by the framework.<br>
+   Additional methods may be defined as needed (ideally private).<br>
+   Any specific features (such as NIC configuration) should be implemented in the SutNode class or its supporting classes, and accessed using the sut_node field.<br></blockquote><div><br></div><div>There's no such class as SutNode anymore.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
 .. _dts_dev_tools:<br>
-- <br>
2.49.0<br>
<br></blockquote><div><br></div><div>Also, this series should adjust the poetry section to explain that "poetry shell" is deprecated now and one must use "poetry run" instead. </div><div><br></div><div>Reviewed-by: Patrick Robb <<a href="mailto:probb@iol.unh.edu">probb@iol.unh.edu</a>></div></div></div>