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 E1C8445C9D; Wed, 6 Nov 2024 19:11:59 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1F32942EB2; Wed, 6 Nov 2024 19:11:12 +0100 (CET) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mails.dpdk.org (Postfix) with ESMTP id B4AD442E9C for ; Wed, 6 Nov 2024 19:11:08 +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 EEE7C1063; Wed, 6 Nov 2024 10:11:37 -0800 (PST) Received: from localhost.localdomain (JR4XG4HTQC.cambridge.arm.com [10.1.30.24]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 75AC93F66E; Wed, 6 Nov 2024 10:11:07 -0800 (PST) From: Luca Vizzarro To: dev@dpdk.org Cc: Paul Szczepanek , Patrick Robb , Luca Vizzarro , Nicholas Pratte Subject: [PATCH v5 8/8] dts: use TestSuiteSpec class imports Date: Wed, 6 Nov 2024 18:09:20 +0000 Message-ID: <20241106180921.4038458-9-luca.vizzarro@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241106180921.4038458-1-luca.vizzarro@arm.com> References: <20240822163941.1390326-1-luca.vizzarro@arm.com> <20241106180921.4038458-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 --- 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