diff --git a/framework/src/act/act.py b/framework/src/act/act.py index de7d4e0cec..05fd8c8af9 100644 --- a/framework/src/act/act.py +++ b/framework/src/act/act.py @@ -100,6 +100,7 @@ def run_act( config_names: list[str] = [] tasks: list[BuildTask] = [] + excluded_extensions = {ext.strip() for ext in exclude.split(",") if ext.strip()} for config_file in config_files: # Load configuration config = load_config(config_file) @@ -113,7 +114,11 @@ def run_act( # Select tests for config selected_tests = select_tests( - full_test_dict, implemented_extensions, config_params, include_priv_tests=config.include_priv_tests + full_test_dict, + implemented_extensions, + config_params, + include_priv_tests=config.include_priv_tests, + excluded_extensions=excluded_extensions, ) mxlen = config_params["MXLEN"] if not isinstance(mxlen, int): diff --git a/framework/src/act/select_tests.py b/framework/src/act/select_tests.py index 9cf8105ca3..934d9ee24b 100644 --- a/framework/src/act/select_tests.py +++ b/framework/src/act/select_tests.py @@ -6,9 +6,8 @@ # # Select tests to run based on UDB config and test list ################################## - from __future__ import annotations - +import sys import re from act.parse_test_constraints import TestMetadata @@ -67,6 +66,7 @@ def select_tests( config_params: dict[str, ConfigParamValue], *, include_priv_tests: bool = True, + excluded_extensions: set[str] | None = None, ) -> dict[str, TestMetadata]: """Select tests that match the UDB configuration.""" selected_tests: dict[str, TestMetadata] = {} @@ -80,4 +80,43 @@ def select_tests( test_params = test_metadata.params if check_test_params(test_params, config_params): selected_tests[test_name] = test_metadata + # Warn about implemented extensions with no tests + untested_extensions = get_untested_implemented_extensions( + selected_tests, + implemented_extensions, + include_priv_tests=include_priv_tests, + excluded_extensions=excluded_extensions, + ) + + if untested_extensions: + print( + "Warning: no applicable tests selected for implemented extension(s): " + + ", ".join(untested_extensions), + file=sys.stderr, + ) + return selected_tests + +def _is_excluded_extension(ext: str, excluded_extensions: set[str]) -> bool: + return any(ext.startswith(ex) for ex in excluded_extensions) + +def get_untested_implemented_extensions( + selected_tests: dict[str, TestMetadata], + implemented_extensions: set[str], + *, + include_priv_tests: bool = True, + excluded_extensions: set[str] | None = None, +) -> list[str]: + """Return implemented extensions that have no selected tests.""" + covered_extensions = { + extension for test_metadata in selected_tests.values() for extension in test_metadata.required_extensions + } + untested_extensions = implemented_extensions - covered_extensions + if not include_priv_tests: + untested_extensions -= PRIV_EXTENSIONS + if excluded_extensions: + untested_extensions = { + ext for ext in untested_extensions + if not _is_excluded_extension(ext, excluded_extensions) + } + return sorted(untested_extensions)