From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3974243349; Thu, 16 Nov 2023 22:51:57 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AA7554027D; Thu, 16 Nov 2023 22:51:56 +0100 (CET) Received: from mail-lj1-f182.google.com (mail-lj1-f182.google.com [209.85.208.182]) by mails.dpdk.org (Postfix) with ESMTP id EBA2F40150 for ; Thu, 16 Nov 2023 22:51:54 +0100 (CET) Received: by mail-lj1-f182.google.com with SMTP id 38308e7fff4ca-2c503dbe50dso18030861fa.1 for ; Thu, 16 Nov 2023 13:51:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; t=1700171514; x=1700776314; darn=dpdk.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=yJChYd6isRs4J9tilzPzCeO8paV4wfhdf+Y94AGDCv8=; b=GgqR40XErD3t+cSzaD9GOTCPJLkmCTOddV7DMnSq4xsgyyLOdNFcluEHfhe3DXt4sr HSDBZsBog8fnLenqFAuYHkavU0942ChdsiYcUMZdzh3WpO34qj/h+4iBqPqdyJ/t8JAN DomGePuCc154g+zXlPyN2m8TsG2KsQMCEfoT0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700171514; x=1700776314; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=yJChYd6isRs4J9tilzPzCeO8paV4wfhdf+Y94AGDCv8=; b=wjtHVVsFiShzUkp2tF7ploSG8Ajgyh+l5FHoLhqN3C19LBs0j07deOnpC+E3ZM98Z2 9Se0lM+Y0KtmlJIaWbB2f2jgSBkUwz1F+YhX4ugWsGm7/pMtghY3HKas9WH0DSvAU+Kg 1k6mrq6+w5lMbRtnhaOZbhQ6A98rzhE/2V38Dc+SYfMMCT8oUtEc84H6wdqgpTp4hU58 XND2zpnKNimbp/a6dvg6EEs9rxHcFicBP/lMIUwIcLsHpVsez+2zawZLBE2NslqXJRT6 phH7drNiCIgCB7ON+Hmg10I7FLlCUM8PI802DWorfQCgvwAi8W2qfTv9Z93oFOrA3hKX xp7g== X-Gm-Message-State: AOJu0YytuYLtN6EZRPZ+Srf8I0385NZWCxGGnvOY4AX/3XwPlp0/EouV NTZylT4GL6hiRSRGZ4O2LNu7yfko2vKKdDeqxg5+8g== X-Google-Smtp-Source: AGHT+IHqwu14+UtuekEfVl70IWtHYR5qU8qbfRH9/qYjBcYDdteQIW0U++gzylpkCL5qyNjHHb3Mi2/Z+XDFzb82gVU= X-Received: by 2002:a2e:91cc:0:b0:2ba:6519:c50f with SMTP id u12-20020a2e91cc000000b002ba6519c50fmr8837239ljg.52.1700171514200; Thu, 16 Nov 2023 13:51:54 -0800 (PST) MIME-Version: 1.0 References: <20231108125324.191005-23-juraj.linkes@pantheon.tech> <20231115130959.39420-1-juraj.linkes@pantheon.tech> <20231115130959.39420-8-juraj.linkes@pantheon.tech> In-Reply-To: <20231115130959.39420-8-juraj.linkes@pantheon.tech> From: Jeremy Spewock Date: Thu, 16 Nov 2023 16:51:42 -0500 Message-ID: Subject: Re: [PATCH v7 07/21] dts: dts runner and main docstring update To: =?UTF-8?Q?Juraj_Linke=C5=A1?= Cc: thomas@monjalon.net, Honnappa.Nagarahalli@arm.com, probb@iol.unh.edu, paul.szczepanek@arm.com, yoan.picchi@foss.arm.com, dev@dpdk.org Content-Type: multipart/alternative; boundary="000000000000295a53060a4c0726" X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --000000000000295a53060a4c0726 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Wed, Nov 15, 2023 at 8:11=E2=80=AFAM Juraj Linke=C5=A1 wrote: > Format according to the Google format and PEP257, with slight > deviations. > > Signed-off-by: Juraj Linke=C5=A1 > --- > dts/framework/dts.py | 128 ++++++++++++++++++++++++++++++++++++------- > dts/main.py | 8 ++- > 2 files changed, 112 insertions(+), 24 deletions(-) > > diff --git a/dts/framework/dts.py b/dts/framework/dts.py > index 4c7fb0c40a..331fed7dc4 100644 > --- a/dts/framework/dts.py > +++ b/dts/framework/dts.py > @@ -3,6 +3,33 @@ > # Copyright(c) 2022-2023 PANTHEON.tech s.r.o. > # Copyright(c) 2022-2023 University of New Hampshire > > +r"""Test suite runner module. > + > +A DTS run is split into stages: > + > + #. Execution stage, > + #. Build target stage, > + #. Test suite stage, > + #. Test case stage. > + > +The module is responsible for running tests on testbeds defined in the > test run configuration. > +Each setup or teardown of each stage is recorded in a > :class:`~framework.test_result.DTSResult` or > +one of its subclasses. The test case results are also recorded. > + > +If an error occurs, the current stage is aborted, the error is recorded > and the run continues in > +the next iteration of the same stage. The return code is the highest > `severity` of all > +:class:`~.framework.exception.DTSError`\s. > + > +Example: > + An error occurs in a build target setup. The current build target is > aborted and the run > + continues with the next build target. If the errored build target wa= s > the last one in the given > + execution, the next execution begins. > + > +Attributes: > + dts_logger: The logger instance used in this module. > + result: The top level result used in the module. > +""" > + > import sys > > from .config import ( > @@ -23,9 +50,38 @@ > > > def run_all() -> None: > - """ > - The main process of DTS. Runs all build targets in all executions > from the main > - config file. > + """Run all build targets in all executions from the test run > configuration. > + > + Before running test suites, executions and build targets are first > set up. > + The executions and build targets defined in the test run > configuration are iterated over. > + The executions define which tests to run and where to run them and > build targets define > + the DPDK build setup. > + > + The tests suites are set up for each execution/build target tuple an= d > each scheduled > + test case within the test suite is set up, executed and torn down. > After all test cases > + have been executed, the test suite is torn down and the next build > target will be tested. > + > + All the nested steps look like this: > + > + #. Execution setup > + > + #. Build target setup > + > + #. Test suite setup > + > + #. Test case setup > + #. Test case logic > + #. Test case teardown > + > + #. Test suite teardown > + > + #. Build target teardown > + > + #. Execution teardown > + > + The test cases are filtered according to the specification in the > test run configuration and > + the :option:`--test-cases` command line argument or > + the :envvar:`DTS_TESTCASES` environment variable. > """ > global dts_logger > global result > @@ -87,6 +143,8 @@ def run_all() -> None: > > > def _check_dts_python_version() -> None: > + """Check the required Python version - v3.10.""" > + > def RED(text: str) -> str: > return f"\u001B[31;1m{str(text)}\u001B[0m" > > @@ -111,9 +169,16 @@ def _run_execution( > execution: ExecutionConfiguration, > result: DTSResult, > ) -> None: > - """ > - Run the given execution. This involves running the execution setup a= s > well as > - running all build targets in the given execution. > + """Run the given execution. > + > + This involves running the execution setup as well as running all > build targets > + in the given execution. After that, execution teardown is run. > + > + Args: > + sut_node: The execution's SUT node. > + tg_node: The execution's TG node. > + execution: An execution's test run configuration. > + result: The top level result object. > """ > dts_logger.info( > f"Running execution with SUT '{ > execution.system_under_test_node.name}'." > @@ -150,8 +215,18 @@ def _run_build_target( > execution: ExecutionConfiguration, > execution_result: ExecutionResult, > ) -> None: > - """ > - Run the given build target. > + """Run the given build target. > + > + This involves running the build target setup as well as running all > test suites > + in the given execution the build target is defined in. > + After that, build target teardown is run. > + > + Args: > + sut_node: The execution's SUT node. > + tg_node: The execution's TG node. > + build_target: A build target's test run configuration. > + execution: The build target's execution's test run configuration= . > + execution_result: The execution level result object associated > with the execution. > """ > dts_logger.info(f"Running build target '{build_target.name}'.") > build_target_result =3D execution_result.add_build_target(build_targ= et) > @@ -183,10 +258,17 @@ def _run_all_suites( > execution: ExecutionConfiguration, > build_target_result: BuildTargetResult, > ) -> None: > - """ > - Use the given build_target to run execution's test suites > - with possibly only a subset of test cases. > - If no subset is specified, run all test cases. > + """Run the execution's (possibly a subset) test suites using the > current build_target. > + > + The function assumes the build target we're testing has already been > built on the SUT node. > + The current build target thus corresponds to the current DPDK build > present on the SUT node. > + > + Args: > + sut_node: The execution's SUT node. > + tg_node: The execution's TG node. > + execution: The execution's test run configuration associated wit= h > the current build target. > + build_target_result: The build target level result object > associated > + with the current build target. > """ > Is it worth mentioning in this method or the _run_build_target method that when a blocking suite fails that no more suites will be run on that build target? > end_build_target =3D False > if not execution.skip_smoke_tests: > @@ -215,16 +297,22 @@ def _run_single_suite( > build_target_result: BuildTargetResult, > test_suite_config: TestSuiteConfig, > ) -> None: > - """Runs a single test suite. > + """Run all test suite in a single test suite module. > + > + The function assumes the build target we're testing has already been > built on the SUT node. > + The current build target thus corresponds to the current DPDK build > present on the SUT node. > > Args: > - sut_node: Node to run tests on. > - execution: Execution the test case belongs to. > - build_target_result: Build target configuration test case is run > on > - test_suite_config: Test suite configuration > + sut_node: The execution's SUT node. > + tg_node: The execution's TG node. > + execution: The execution's test run configuration associated wit= h > the current build target. > + build_target_result: The build target level result object > associated > + with the current build target. > + test_suite_config: Test suite test run configuration specifying > the test suite module > + and possibly a subset of test cases of test suites in that > module. > > Raises: > - BlockingTestSuiteError: If a test suite that was marked as > blocking fails. > + BlockingTestSuiteError: If a blocking test suite fails. > """ > try: > full_suite_path =3D > f"tests.TestSuite_{test_suite_config.test_suite}" > @@ -248,9 +336,7 @@ def _run_single_suite( > > > def _exit_dts() -> None: > - """ > - Process all errors and exit with the proper exit code. > - """ > + """Process all errors and exit with the proper exit code.""" > result.process() > > if dts_logger: > diff --git a/dts/main.py b/dts/main.py > index 5d4714b0c3..f703615d11 100755 > --- a/dts/main.py > +++ b/dts/main.py > @@ -4,9 +4,7 @@ > # Copyright(c) 2022 PANTHEON.tech s.r.o. > # Copyright(c) 2022 University of New Hampshire > > -""" > -A test framework for testing DPDK. > -""" > +"""The DTS executable.""" > > import logging > > @@ -17,6 +15,10 @@ def main() -> None: > """Set DTS settings, then run DTS. > > The DTS settings are taken from the command line arguments and the > environment variables. > + The settings object is stored in the module-level variable > settings.SETTINGS which the entire > + framework uses. After importing the module (or the variable), any > changes to the variable are > + not going to be reflected without a re-import. This means that the > SETTINGS variable must > + be modified before the settings module is imported anywhere else in > the framework. > """ > settings.SETTINGS =3D settings.get_settings() > from framework import dts > -- > 2.34.1 > > --000000000000295a53060a4c0726 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


<= div dir=3D"ltr" class=3D"gmail_attr">On Wed, Nov 15, 2023 at 8:11=E2=80=AFA= M Juraj Linke=C5=A1 <juraj.linkes@pantheon.tech> wrote:
Format according to the Googl= e format and PEP257, with slight
deviations.

Signed-off-by: Juraj Linke=C5=A1 <juraj.linkes@pantheon.tech>
---
=C2=A0dts/framework/dts.py | 128 ++++++++++++++++++++++++++++++++++++------= -
=C2=A0dts/main.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A08 ++-
=C2=A02 files changed, 112 insertions(+), 24 deletions(-)

diff --git a/dts/framework/dts.py b/dts/framework/dts.py
index 4c7fb0c40a..331fed7dc4 100644
--- a/dts/framework/dts.py
+++ b/dts/framework/dts.py
@@ -3,6 +3,33 @@
=C2=A0# Copyright(c) 2022-2023 PANTHEON.tech s.r.o.
=C2=A0# Copyright(c) 2022-2023 University of New Hampshire

+r"""Test suite runner module.
+
+A DTS run is split into stages:
+
+=C2=A0 =C2=A0 #. Execution stage,
+=C2=A0 =C2=A0 #. Build target stage,
+=C2=A0 =C2=A0 #. Test suite stage,
+=C2=A0 =C2=A0 #. Test case stage.
+
+The module is responsible for running tests on testbeds defined in the tes= t run configuration.
+Each setup or teardown of each stage is recorded in a :class:`~framework.t= est_result.DTSResult` or
+one of its subclasses. The test case results are also recorded.
+
+If an error occurs, the current stage is aborted, the error is recorded an= d the run continues in
+the next iteration of the same stage. The return code is the highest `seve= rity` of all
+:class:`~.framework.exception.DTSError`\s.
+
+Example:
+=C2=A0 =C2=A0 An error occurs in a build target setup. The current build t= arget is aborted and the run
+=C2=A0 =C2=A0 continues with the next build target. If the errored build t= arget was the last one in the given
+=C2=A0 =C2=A0 execution, the next execution begins.
+
+Attributes:
+=C2=A0 =C2=A0 dts_logger: The logger instance used in this module.
+=C2=A0 =C2=A0 result: The top level result used in the module.
+"""
+
=C2=A0import sys

=C2=A0from .config import (
@@ -23,9 +50,38 @@


=C2=A0def run_all() -> None:
-=C2=A0 =C2=A0 """
-=C2=A0 =C2=A0 The main process of DTS. Runs all build targets in all execu= tions from the main
-=C2=A0 =C2=A0 config file.
+=C2=A0 =C2=A0 """Run all build targets in all executions fr= om the test run configuration.
+
+=C2=A0 =C2=A0 Before running test suites, executions and build targets are= first set up.
+=C2=A0 =C2=A0 The executions and build targets defined in the test run con= figuration are iterated over.
+=C2=A0 =C2=A0 The executions define which tests to run and where to run th= em and build targets define
+=C2=A0 =C2=A0 the DPDK build setup.
+
+=C2=A0 =C2=A0 The tests suites are set up for each execution/build target = tuple and each scheduled
+=C2=A0 =C2=A0 test case within the test suite is set up, executed and torn= down. After all test cases
+=C2=A0 =C2=A0 have been executed, the test suite is torn down and the next= build target will be tested.
+
+=C2=A0 =C2=A0 All the nested steps look like this:
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 #. Execution setup
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #. Build target setup
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #. Test suite setu= p
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #. T= est case setup
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #. T= est case logic
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #. T= est case teardown
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #. Test suite tear= down
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #. Build target teardown
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 #. Execution teardown
+
+=C2=A0 =C2=A0 The test cases are filtered according to the specification i= n the test run configuration and
+=C2=A0 =C2=A0 the :option:`--test-cases` command line argument or
+=C2=A0 =C2=A0 the :envvar:`DTS_TESTCASES` environment variable.
=C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0global dts_logger
=C2=A0 =C2=A0 =C2=A0global result
@@ -87,6 +143,8 @@ def run_all() -> None:


=C2=A0def _check_dts_python_version() -> None:
+=C2=A0 =C2=A0 """Check the required Python version - v3.10.= """
+
=C2=A0 =C2=A0 =C2=A0def RED(text: str) -> str:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return f"\u001B[31;1m{str(text)}\u00= 1B[0m"

@@ -111,9 +169,16 @@ def _run_execution(
=C2=A0 =C2=A0 =C2=A0execution: ExecutionConfiguration,
=C2=A0 =C2=A0 =C2=A0result: DTSResult,
=C2=A0) -> None:
-=C2=A0 =C2=A0 """
-=C2=A0 =C2=A0 Run the given execution. This involves running the execution= setup as well as
-=C2=A0 =C2=A0 running all build targets in the given execution.
+=C2=A0 =C2=A0 """Run the given execution.
+
+=C2=A0 =C2=A0 This involves running the execution setup as well as running= all build targets
+=C2=A0 =C2=A0 in the given execution. After that, execution teardown is ru= n.
+
+=C2=A0 =C2=A0 Args:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 sut_node: The execution's SUT node.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 tg_node: The execution's TG node.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 execution: An execution's test run configu= ration.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 result: The top level result object.
=C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0dts_logger.info(
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f"Running execution with SUT '{<= a href=3D"http://execution.system_under_test_node.name" rel=3D"noreferrer" = target=3D"_blank">execution.system_under_test_node.name}'." @@ -150,8 +215,18 @@ def _run_build_target(
=C2=A0 =C2=A0 =C2=A0execution: ExecutionConfiguration,
=C2=A0 =C2=A0 =C2=A0execution_result: ExecutionResult,
=C2=A0) -> None:
-=C2=A0 =C2=A0 """
-=C2=A0 =C2=A0 Run the given build target.
+=C2=A0 =C2=A0 """Run the given build target.
+
+=C2=A0 =C2=A0 This involves running the build target setup as well as runn= ing all test suites
+=C2=A0 =C2=A0 in the given execution the build target is defined in.
+=C2=A0 =C2=A0 After that, build target teardown is run.
+
+=C2=A0 =C2=A0 Args:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 sut_node: The execution's SUT node.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 tg_node: The execution's TG node.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 build_target: A build target's test run co= nfiguration.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 execution: The build target's execution= 9;s test run configuration.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 execution_result: The execution level result o= bject associated with the execution.
=C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0dts_logger.info(f"Running build target '{build= _target.name}'.")
=C2=A0 =C2=A0 =C2=A0build_target_result =3D execution_result.add_build_targ= et(build_target)
@@ -183,10 +258,17 @@ def _run_all_suites(
=C2=A0 =C2=A0 =C2=A0execution: ExecutionConfiguration,
=C2=A0 =C2=A0 =C2=A0build_target_result: BuildTargetResult,
=C2=A0) -> None:
-=C2=A0 =C2=A0 """
-=C2=A0 =C2=A0 Use the given build_target to run execution's test suite= s
-=C2=A0 =C2=A0 with possibly only a subset of test cases.
-=C2=A0 =C2=A0 If no subset is specified, run all test cases.
+=C2=A0 =C2=A0 """Run the execution's (possibly a subset= ) test suites using the current build_target.
+
+=C2=A0 =C2=A0 The function assumes the build target we're testing has = already been built on the SUT node.
+=C2=A0 =C2=A0 The current build target thus corresponds to the current DPD= K build present on the SUT node.
+
+=C2=A0 =C2=A0 Args:
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 sut_node: The execution's SUT node.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 tg_node: The execution's TG node.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 execution: The execution's test run config= uration associated with the current build target.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 build_target_result: The build target level re= sult object associated
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 with the current build target. =C2=A0 =C2=A0 =C2=A0"""

=
Is it w= orth mentioning in this method or the _run_build_target method that when a = blocking suite fails that no more suites will be run on that build target?<= br>
=C2=A0
=C2=A0 =C2=A0 =C2=A0end_build_target =3D False
=C2=A0 =C2=A0 =C2=A0if not execution.skip_smoke_tests:
@@ -215,16 +297,22 @@ def _run_single_suite(
=C2=A0 =C2=A0 =C2=A0build_target_result: BuildTargetResult,
=C2=A0 =C2=A0 =C2=A0test_suite_config: TestSuiteConfig,
=C2=A0) -> None:
-=C2=A0 =C2=A0 """Runs a single test suite.
+=C2=A0 =C2=A0 """Run all test suite in a single test suite = module.
+
+=C2=A0 =C2=A0 The function assumes the build target we're testing has = already been built on the SUT node.
+=C2=A0 =C2=A0 The current build target thus corresponds to the current DPD= K build present on the SUT node.

=C2=A0 =C2=A0 =C2=A0Args:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 sut_node: Node to run tests on.
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 execution: Execution the test case belongs to.=
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 build_target_result: Build target configuratio= n test case is run on
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 test_suite_config: Test suite configuration +=C2=A0 =C2=A0 =C2=A0 =C2=A0 sut_node: The execution's SUT node.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 tg_node: The execution's TG node.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 execution: The execution's test run config= uration associated with the current build target.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 build_target_result: The build target level re= sult object associated
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 with the current build target. +=C2=A0 =C2=A0 =C2=A0 =C2=A0 test_suite_config: Test suite test run configu= ration specifying the test suite module
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 and possibly a subset of test ca= ses of test suites in that module.

=C2=A0 =C2=A0 =C2=A0Raises:
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 BlockingTestSuiteError: If a test suite that w= as marked as blocking fails.
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 BlockingTestSuiteError: If a blocking test sui= te fails.
=C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0try:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0full_suite_path =3D f"tests.TestSuit= e_{test_suite_config.test_suite}"
@@ -248,9 +336,7 @@ def _run_single_suite(


=C2=A0def _exit_dts() -> None:
-=C2=A0 =C2=A0 """
-=C2=A0 =C2=A0 Process all errors and exit with the proper exit code.
-=C2=A0 =C2=A0 """
+=C2=A0 =C2=A0 """Process all errors and exit with the prope= r exit code."""
=C2=A0 =C2=A0 =C2=A0result.process()

=C2=A0 =C2=A0 =C2=A0if dts_logger:
diff --git a/dts/main.py b/dts/main.py
index 5d4714b0c3..f703615d11 100755
--- a/dts/main.py
+++ b/dts/main.py
@@ -4,9 +4,7 @@
=C2=A0# Copyright(c) 2022 PANTHEON.tech s.r.o.
=C2=A0# Copyright(c) 2022 University of New Hampshire

-"""
-A test framework for testing DPDK.
-"""
+"""The DTS executable."""

=C2=A0import logging

@@ -17,6 +15,10 @@ def main() -> None:
=C2=A0 =C2=A0 =C2=A0"""Set DTS settings, then run DTS.

=C2=A0 =C2=A0 =C2=A0The DTS settings are taken from the command line argume= nts and the environment variables.
+=C2=A0 =C2=A0 The settings object is stored in the module-level variable s= ettings.SETTINGS which the entire
+=C2=A0 =C2=A0 framework uses. After importing the module (or the variable)= , any changes to the variable are
+=C2=A0 =C2=A0 not going to be reflected without a re-import. This means th= at the SETTINGS variable must
+=C2=A0 =C2=A0 be modified before the settings module is imported anywhere = else in the framework.
=C2=A0 =C2=A0 =C2=A0"""
=C2=A0 =C2=A0 =C2=A0settings.SETTINGS =3D settings.get_settings()
=C2=A0 =C2=A0 =C2=A0from framework import dts
--
2.34.1

--000000000000295a53060a4c0726--