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 C41F945CA6; Fri, 8 Nov 2024 12:41:22 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A99FE433AD; Fri, 8 Nov 2024 12:40:27 +0100 (CET) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mails.dpdk.org (Postfix) with ESMTP id 079254339A for ; Fri, 8 Nov 2024 12:40:25 +0100 (CET) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7011E339; Fri, 8 Nov 2024 03:40:54 -0800 (PST) Received: from localhost.localdomain (unknown [10.57.59.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 979EA3F66E; Fri, 8 Nov 2024 03:40:23 -0800 (PST) From: Luca Vizzarro To: dev@dpdk.org Cc: Paul Szczepanek , Patrick Robb , Luca Vizzarro , Nicholas Pratte Subject: [PATCH v6 9/9] dts: use TestSuiteSpec class imports Date: Fri, 8 Nov 2024 11:40:05 +0000 Message-ID: <20241108114006.64595-10-luca.vizzarro@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241108114006.64595-1-luca.vizzarro@arm.com> References: <20240822163941.1390326-1-luca.vizzarro@arm.com> <20241108114006.64595-1-luca.vizzarro@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 The introduction of TestSuiteSpec adds auto-discovery of test suites, which are also automatically imported. This causes double imports as the runner loads the test suites. This changes the behaviour of the runner to load the imported classes from TestSuiteSpec instead of importing them again. Signed-off-by: Luca Vizzarro Reviewed-by: Paul Szczepanek Reviewed-by: Nicholas Pratte Reviewed-by: Patrick Robb --- dts/framework/runner.py | 84 ++++------------------------------------- 1 file changed, 7 insertions(+), 77 deletions(-) diff --git a/dts/framework/runner.py b/dts/framework/runner.py index c3d9a27a8c..5f5837a132 100644 --- a/dts/framework/runner.py +++ b/dts/framework/runner.py @@ -2,6 +2,7 @@ # Copyright(c) 2010-2019 Intel Corporation # Copyright(c) 2022-2023 PANTHEON.tech s.r.o. # Copyright(c) 2022-2023 University of New Hampshire +# Copyright(c) 2024 Arm Limited """Test suite runner module. @@ -17,8 +18,6 @@ and the test case stage runs test cases individually. """ -import importlib -import inspect import os import random import sys @@ -39,12 +38,7 @@ TGNodeConfiguration, load_config, ) -from .exception import ( - BlockingTestSuiteError, - ConfigurationError, - SSHTimeoutError, - TestCaseVerifyError, -) +from .exception import BlockingTestSuiteError, SSHTimeoutError, TestCaseVerifyError from .logger import DTSLogger, DtsStage, get_dts_logger from .settings import SETTINGS from .test_result import ( @@ -215,11 +209,10 @@ def _get_test_suites_with_cases( func: bool, perf: bool, ) -> list[TestSuiteWithCases]: - """Test suites with test cases discovery. + """Get test suites with selected cases. - The test suites with test cases defined in the user configuration are discovered - and stored for future use so that we don't import the modules twice and so that - the list of test suites with test cases is available for recording right away. + The test suites with test cases defined in the user configuration are selected + and the corresponding functions and classes are gathered. Args: test_suite_configs: Test suite configurations. @@ -227,12 +220,12 @@ def _get_test_suites_with_cases( perf: Whether to include performance test cases in the final list. Returns: - The discovered test suites, each with test cases. + The test suites, each with test cases. """ test_suites_with_cases = [] for test_suite_config in test_suite_configs: - test_suite_class = self._get_test_suite_class(test_suite_config.test_suite_name) + test_suite_class = test_suite_config.test_suite_spec.class_obj test_cases: list[type[TestCase]] = [] func_test_cases, perf_test_cases = test_suite_class.filter_test_cases( test_suite_config.test_cases_names @@ -245,71 +238,8 @@ def _get_test_suites_with_cases( test_suites_with_cases.append( TestSuiteWithCases(test_suite_class=test_suite_class, test_cases=test_cases) ) - return test_suites_with_cases - def _get_test_suite_class(self, module_name: str) -> type[TestSuite]: - """Find the :class:`TestSuite` class in `module_name`. - - The full module name is `module_name` prefixed with `self._test_suite_module_prefix`. - The module name is a standard filename with words separated with underscores. - Search the `module_name` for a :class:`TestSuite` class which starts - with `self._test_suite_class_prefix`, continuing with CamelCase `module_name`. - The first matching class is returned. - - The CamelCase convention applies to abbreviations, acronyms, initialisms and so on:: - - OS -> Os - TCP -> Tcp - - Args: - module_name: The module name without prefix where to search for the test suite. - - Returns: - The found test suite class. - - Raises: - ConfigurationError: If the corresponding module is not found or - a valid :class:`TestSuite` is not found in the module. - """ - - def is_test_suite(object) -> bool: - """Check whether `object` is a :class:`TestSuite`. - - The `object` is a subclass of :class:`TestSuite`, but not :class:`TestSuite` itself. - - Args: - object: The object to be checked. - - Returns: - :data:`True` if `object` is a subclass of `TestSuite`. - """ - try: - if issubclass(object, TestSuite) and object is not TestSuite: - return True - except TypeError: - return False - return False - - testsuite_module_path = f"{self._test_suite_module_prefix}{module_name}" - try: - test_suite_module = importlib.import_module(testsuite_module_path) - except ModuleNotFoundError as e: - raise ConfigurationError( - f"Test suite module '{testsuite_module_path}' not found." - ) from e - - camel_case_suite_name = "".join( - [suite_word.capitalize() for suite_word in module_name.split("_")] - ) - full_suite_name_to_find = f"{self._test_suite_class_prefix}{camel_case_suite_name}" - for class_name, class_obj in inspect.getmembers(test_suite_module, is_test_suite): - if class_name == full_suite_name_to_find: - return class_obj - raise ConfigurationError( - f"Couldn't find any valid test suites in {test_suite_module.__name__}." - ) - def _connect_nodes_and_run_test_run( self, sut_nodes: dict[str, SutNode], -- 2.43.0