From a0b6bf79f478c5413ad96f9bfaecc80f18d963d8 Mon Sep 17 00:00:00 2001 From: Romulo Quidute Filho Date: Tue, 14 Oct 2025 14:05:55 +0000 Subject: [PATCH 1/5] Fix python script listing --- .../matter/sdk_tests/python_tests_ignore.txt | 4 + .../list_python_tests_classes.py | 34 +++- .../test_list_python_tests_classes.py | 177 ++++++++++++++++-- 3 files changed, 197 insertions(+), 18 deletions(-) create mode 100644 test_collections/matter/sdk_tests/python_tests_ignore.txt diff --git a/test_collections/matter/sdk_tests/python_tests_ignore.txt b/test_collections/matter/sdk_tests/python_tests_ignore.txt new file mode 100644 index 00000000..1597118d --- /dev/null +++ b/test_collections/matter/sdk_tests/python_tests_ignore.txt @@ -0,0 +1,4 @@ +# Files to be ignored +TC_TestAttrAvail.py +TC_COLORCONTROL.py +TC_AVSM_StreamReuseRangeParams.py \ No newline at end of file diff --git a/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py b/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py index d5063d22..aa4b80c7 100644 --- a/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py +++ b/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py @@ -34,8 +34,10 @@ GET_TEST_INFO_ARGUMENT = "--get-test-info" TEST_INFO_JSON_FILENAME = "test_info.json" -# Pattern to match TC____....py format -TC_FILENAME_PATTERN = r"^TC_[A-Z_]{2,20}_\d+_\d+(_\d+)*(-custom)?\.py$" +# Pattern to match TC_*.py format +# TC_ followed by at least one character/digit, then .py +TC_FILENAME_PATTERN = r"^TC_.+\.py$" + SDK_TESTS_PATH = Path(__file__).parent.parent.parent PYTHON_TESTING_PATH = SDK_TESTS_PATH / "sdk_checkout/python_testing" JSON_OUTPUT_FILE_PATH = PYTHON_TESTING_PATH / TEST_INFO_JSON_FILENAME @@ -50,6 +52,7 @@ PYTHON_TESTS_PARSED_FILE = SDK_TESTS_PATH / "python_tests_info.json" CUSTOM_PYTHON_TESTS_PARSED_FILE = SDK_TESTS_PATH / "custom_python_tests_info.json" +PYTHON_TESTS_IGNORE_FILE = SDK_TESTS_PATH / "python_tests_ignore.txt" CONTAINER_TH_CLIENT_EXEC = "python3 /root/python_testing/scripts/sdk/matter_testing_infrastructure/chip/testing/test_harness_client.py" # noqa @@ -87,6 +90,23 @@ def __get_error_message_from_result(result: ExecResultExtended) -> str: return error_message +def load_ignore_list() -> set[str]: + """Load the list of Python test files to ignore. + + Returns: + set[str]: Set of filenames to ignore (e.g., {'TC_TEST_1_1.py'}) + """ + ignore_list = set() + if PYTHON_TESTS_IGNORE_FILE.exists(): + with open(PYTHON_TESTS_IGNORE_FILE, "r") as f: + for line in f: + # Strip whitespace and skip empty lines or comments + filename = line.strip() + if filename and not filename.startswith("#"): + ignore_list.add(filename) + return ignore_list + + def base_test_classes(module: ast.Module) -> list[ast.ClassDef]: """Find classes that inherit from MatterBaseTest. @@ -162,11 +182,19 @@ def get_command_list(test_folder: SDKTestFolder) -> list: # Use the constant pattern for TC filename validation tc_pattern = re.compile(TC_FILENAME_PATTERN) + # Load ignore list + ignore_list = load_ignore_list() + for python_test_file in python_test_files: - # Check if the file follows the TC___.py pattern + # Check if the file follows the TC_*.py pattern if not tc_pattern.match(python_test_file.name): continue + # Check if the file is in the ignore list + if python_test_file.name in ignore_list: + print(f"Skipping {python_test_file.name} (in ignore list)") + continue + parent_folder = python_test_file.parent.name try: with open(python_test_file, "r") as python_file: diff --git a/test_collections/matter/sdk_tests/support/tests/python_tests/test_list_python_tests_classes.py b/test_collections/matter/sdk_tests/support/tests/python_tests/test_list_python_tests_classes.py index b508016d..c78409ca 100644 --- a/test_collections/matter/sdk_tests/support/tests/python_tests/test_list_python_tests_classes.py +++ b/test_collections/matter/sdk_tests/support/tests/python_tests/test_list_python_tests_classes.py @@ -25,6 +25,7 @@ from ...python_testing.list_python_tests_classes import ( TC_FILENAME_PATTERN, get_command_list, + load_ignore_list, ) @@ -45,27 +46,27 @@ ("TC_MCORE_FS_1_4.py", True), # underscore in cluster name ("TC_ACE_1_1-custom.py", True), # with -custom suffix at end ("TC_MCORE_FS_1_4-custom.py", True), # underscore + custom suffix at end + ("TC_A_0_0.py", True), # cluster name too short (1 letter) + ("TC_test.py", True), + ("TC_ACE_1.py", True), + ("TC_ACE_a_b.py", True), + ("TC_C4_1_1.py", True), + ("TC_ACE_1_2_extra.py", True), # extra content after numbers + ("TC_ACE_.py", True), # missing second number + ("TC_ACE_1_.py", True), # missing second number + ("TC_ACE__2.py", True), # missing first number + ("TC_ANOTHERVERYLONGCLUSTERNAME_99_99.py", True), # cluster name > 20 chars + ("TC_ACE_1_1-Custom.py", True), # with -Custom suffix at end + ("TC_ACE_1_1-CUSTOM.py", True), # with -CUSTOM suffix at end + ("TC_ace_1_2.py", True), # cluster name with lowercase letters + ("TC_1test_1_2.py", True), # cluster name starts with number # Negative test cases - should NOT match pattern - ("TC_A_0_0.py", False), # cluster name too short (1 letter) - ("TC_test.py", False), - ("TC_ACE_1.py", False), - ("TC_ACE_a_b.py", False), ("helper.py", False), - ("TC_C4_1_1.py", False), ("TC_.py", False), ("test_helper.py", False), - ("TC_ACE_1_2_extra.py", False), # extra content after numbers - ("TC_ACE_.py", False), # missing second number - ("TC_ACE_1_.py", False), # missing second number - ("TC_ACE__2.py", False), # missing first number ("XTC_ACE_1_2.py", False), # wrong prefix ("TC_ACE_1_2", False), # missing .py extension ("TC_ACE_1_2.txt", False), # wrong extension - ("TC_1test_1_2.py", False), # cluster name starts with number - ("TC_ANOTHERVERYLONGCLUSTERNAME_99_99.py", False), # cluster name > 20 chars - ("TC_ACE_1_1-Custom.py", False), # with -Custom suffix at end - ("TC_ACE_1_1-CUSTOM.py", False), # with -CUSTOM suffix at end - ("TC_ace_1_2.py", False), # cluster name with lowercase letters ], ) def test_filename_pattern_validation(filename: str, should_match: bool) -> None: @@ -90,7 +91,7 @@ def test_get_command_list_with_valid_and_invalid_files() -> None: valid_files = ["TC_ACE_1_2.py", "TC_CNET_4_12.py", "TC_DA_1_7.py"] # Create invalid test files - invalid_files = ["TC_test.py", "helper.py", "TC_ACE_1.py"] + invalid_files = ["test_TC.py", "helper.py", "TC_.py"] # Simple test file content test_content = """ @@ -146,3 +147,149 @@ def test_empty_folder_scenario() -> None: except ImportError: pytest.skip("Skipping integration test due to import dependencies") + + +def test_load_ignore_list_file_exists() -> None: + """Test load_ignore_list when ignore file exists with valid content.""" + with tempfile.TemporaryDirectory() as temp_dir: + ignore_file = Path(temp_dir) / "python_tests_ignore.txt" + ignore_content = """# Comment line +TC_PAVST_2_6.py +TC_PAVST_2_7.py + +# Another comment +TC_WEBRTCR_2_5.py +""" + ignore_file.write_text(ignore_content) + + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.PYTHON_TESTS_IGNORE_FILE", + ignore_file, + ): + result = load_ignore_list() + + assert result == {"TC_PAVST_2_6.py", "TC_PAVST_2_7.py", "TC_WEBRTCR_2_5.py"} + + +def test_load_ignore_list_file_not_exists() -> None: + """Test load_ignore_list when ignore file does not exist.""" + with tempfile.TemporaryDirectory() as temp_dir: + non_existent_file = Path(temp_dir) / "non_existent.txt" + + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.PYTHON_TESTS_IGNORE_FILE", + non_existent_file, + ): + result = load_ignore_list() + + assert result == set() + + +def test_load_ignore_list_empty_file() -> None: + """Test load_ignore_list with empty file.""" + with tempfile.TemporaryDirectory() as temp_dir: + ignore_file = Path(temp_dir) / "python_tests_ignore.txt" + ignore_file.write_text("") + + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.PYTHON_TESTS_IGNORE_FILE", + ignore_file, + ): + result = load_ignore_list() + + assert result == set() + + +def test_load_ignore_list_only_comments() -> None: + """Test load_ignore_list with file containing only comments.""" + with tempfile.TemporaryDirectory() as temp_dir: + ignore_file = Path(temp_dir) / "python_tests_ignore.txt" + ignore_content = """# Only comments here +# No actual files to ignore +""" + ignore_file.write_text(ignore_content) + + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.PYTHON_TESTS_IGNORE_FILE", + ignore_file, + ): + result = load_ignore_list() + + assert result == set() + + +def test_load_ignore_list_with_whitespace() -> None: + """Test load_ignore_list handles whitespace correctly.""" + with tempfile.TemporaryDirectory() as temp_dir: + ignore_file = Path(temp_dir) / "python_tests_ignore.txt" + ignore_content = """ TC_TEST_1_1.py +TC_TEST_2_2.py + + TC_TEST_3_3.py +""" + ignore_file.write_text(ignore_content) + + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.PYTHON_TESTS_IGNORE_FILE", + ignore_file, + ): + result = load_ignore_list() + + assert result == {"TC_TEST_1_1.py", "TC_TEST_2_2.py", "TC_TEST_3_3.py"} + + +def test_get_command_list_with_ignore_file() -> None: + """Test get_command_list respects ignore file.""" + with tempfile.TemporaryDirectory() as temp_dir: + temp_path = Path(temp_dir) + + # Create test files + all_files = ["TC_ACE_1_2.py", "TC_CNET_4_12.py", "TC_DA_1_7.py"] + files_to_ignore = ["TC_CNET_4_12.py"] + + test_content = """ +from matter_testing_support import MatterBaseTest + +class TestClass(MatterBaseTest): + def test_TC_example_1_1(self): + pass +""" + + for filename in all_files: + (temp_path / filename).write_text(test_content) + + test_folder = SDKTestFolder(path=temp_path, filename_pattern="*") + + # Mock the load_ignore_list function to return our test data + mock_path = ( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.load_ignore_list" + ) + with mock.patch(mock_path, return_value=set(files_to_ignore)): + with mock.patch("ast.parse") as mock_parse: + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.base_test_classes" + ) as mock_base_classes: + mock_parse.return_value = mock.MagicMock() + mock_class = mock.MagicMock() + mock_class.name = "TestClass" + mock_base_classes.return_value = [mock_class] + + commands = get_command_list(test_folder) + + # Should only process 2 files (3 total - 1 ignored) + assert len(commands) == 2 + + # Verify ignored file is not included + file_stems = [cmd[0].split("/")[-1] for cmd in commands] + assert "TC_CNET_4_12" not in file_stems + + # Verify non-ignored files are included + assert "TC_ACE_1_2" in file_stems + assert "TC_DA_1_7" in file_stems From 6e7e25f35841f8537d5ff6a712b44ed21ed0ae00 Mon Sep 17 00:00:00 2001 From: Romulo Quidute Filho Date: Tue, 14 Oct 2025 14:29:02 +0000 Subject: [PATCH 2/5] Added feature to files that should be included despite regex --- .../matter/sdk_tests/python_tests_include.txt | 2 + .../list_python_tests_classes.py | 26 ++- .../test_list_python_tests_classes.py | 198 ++++++++++++++++++ 3 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 test_collections/matter/sdk_tests/python_tests_include.txt diff --git a/test_collections/matter/sdk_tests/python_tests_include.txt b/test_collections/matter/sdk_tests/python_tests_include.txt new file mode 100644 index 00000000..6229a663 --- /dev/null +++ b/test_collections/matter/sdk_tests/python_tests_include.txt @@ -0,0 +1,2 @@ +# Files to be considered +TCP_Tests \ No newline at end of file diff --git a/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py b/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py index aa4b80c7..c15656c6 100644 --- a/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py +++ b/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py @@ -53,6 +53,7 @@ PYTHON_TESTS_PARSED_FILE = SDK_TESTS_PATH / "python_tests_info.json" CUSTOM_PYTHON_TESTS_PARSED_FILE = SDK_TESTS_PATH / "custom_python_tests_info.json" PYTHON_TESTS_IGNORE_FILE = SDK_TESTS_PATH / "python_tests_ignore.txt" +PYTHON_TESTS_INCLUDE_FILE = SDK_TESTS_PATH / "python_tests_include.txt" CONTAINER_TH_CLIENT_EXEC = "python3 /root/python_testing/scripts/sdk/matter_testing_infrastructure/chip/testing/test_harness_client.py" # noqa @@ -107,6 +108,23 @@ def load_ignore_list() -> set[str]: return ignore_list +def load_include_list() -> set[str]: + """Load the list of Python test files to always include (bypass regex check). + + Returns: + set[str]: Set of filenames to always include (e.g., {'TCP_Tests.py'}) + """ + include_list = set() + if PYTHON_TESTS_INCLUDE_FILE.exists(): + with open(PYTHON_TESTS_INCLUDE_FILE, "r") as f: + for line in f: + # Strip whitespace and skip empty lines or comments + filename = line.strip() + if filename and not filename.startswith("#"): + include_list.add(filename) + return include_list + + def base_test_classes(module: ast.Module) -> list[ast.ClassDef]: """Find classes that inherit from MatterBaseTest. @@ -182,12 +200,16 @@ def get_command_list(test_folder: SDKTestFolder) -> list: # Use the constant pattern for TC filename validation tc_pattern = re.compile(TC_FILENAME_PATTERN) - # Load ignore list + # Load ignore and include lists ignore_list = load_ignore_list() + include_list = load_include_list() for python_test_file in python_test_files: + # Check if file is in include list (bypass regex check) + if python_test_file.name in include_list: + print(f"Including {python_test_file.name} (in include list)") # Check if the file follows the TC_*.py pattern - if not tc_pattern.match(python_test_file.name): + elif not tc_pattern.match(python_test_file.name): continue # Check if the file is in the ignore list diff --git a/test_collections/matter/sdk_tests/support/tests/python_tests/test_list_python_tests_classes.py b/test_collections/matter/sdk_tests/support/tests/python_tests/test_list_python_tests_classes.py index c78409ca..427af880 100644 --- a/test_collections/matter/sdk_tests/support/tests/python_tests/test_list_python_tests_classes.py +++ b/test_collections/matter/sdk_tests/support/tests/python_tests/test_list_python_tests_classes.py @@ -26,6 +26,7 @@ TC_FILENAME_PATTERN, get_command_list, load_ignore_list, + load_include_list, ) @@ -293,3 +294,200 @@ def test_TC_example_1_1(self): # Verify non-ignored files are included assert "TC_ACE_1_2" in file_stems assert "TC_DA_1_7" in file_stems + + +def test_load_include_list_file_exists() -> None: + """Test load_include_list when include file exists with valid content.""" + with tempfile.TemporaryDirectory() as temp_dir: + include_file = Path(temp_dir) / "python_tests_include.txt" + include_content = """# Special test files +TCP_Tests.py +CUSTOM_Test.py + +# Another special file +SPECIAL_CASE.py +""" + include_file.write_text(include_content) + + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.PYTHON_TESTS_INCLUDE_FILE", + include_file, + ): + result = load_include_list() + + assert result == {"TCP_Tests.py", "CUSTOM_Test.py", "SPECIAL_CASE.py"} + + +def test_load_include_list_file_not_exists() -> None: + """Test load_include_list when include file does not exist.""" + with tempfile.TemporaryDirectory() as temp_dir: + non_existent_file = Path(temp_dir) / "non_existent.txt" + + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.PYTHON_TESTS_INCLUDE_FILE", + non_existent_file, + ): + result = load_include_list() + + assert result == set() + + +def test_load_include_list_empty_file() -> None: + """Test load_include_list with empty file.""" + with tempfile.TemporaryDirectory() as temp_dir: + include_file = Path(temp_dir) / "python_tests_include.txt" + include_file.write_text("") + + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.PYTHON_TESTS_INCLUDE_FILE", + include_file, + ): + result = load_include_list() + + assert result == set() + + +def test_load_include_list_only_comments() -> None: + """Test load_include_list with file containing only comments.""" + with tempfile.TemporaryDirectory() as temp_dir: + include_file = Path(temp_dir) / "python_tests_include.txt" + include_content = """# Only comments here +# No actual files to include +""" + include_file.write_text(include_content) + + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.PYTHON_TESTS_INCLUDE_FILE", + include_file, + ): + result = load_include_list() + + assert result == set() + + +def test_load_include_list_with_whitespace() -> None: + """Test load_include_list handles whitespace correctly.""" + with tempfile.TemporaryDirectory() as temp_dir: + include_file = Path(temp_dir) / "python_tests_include.txt" + include_content = """ TCP_Tests.py +CUSTOM_Test.py + + SPECIAL_CASE.py +""" + include_file.write_text(include_content) + + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.PYTHON_TESTS_INCLUDE_FILE", + include_file, + ): + result = load_include_list() + + assert result == {"TCP_Tests.py", "CUSTOM_Test.py", "SPECIAL_CASE.py"} + + +def test_get_command_list_with_include_file() -> None: + """Test get_command_list includes files from include list regardless of pattern.""" + with tempfile.TemporaryDirectory() as temp_dir: + temp_path = Path(temp_dir) + + # Create test files - mix of matching and non-matching patterns + all_files = ["TC_ACE_1_2.py", "TCP_Tests.py", "CUSTOM_Test.py"] + + test_content = """ +from matter_testing_support import MatterBaseTest + +class TestClass(MatterBaseTest): + def test_TC_example_1_1(self): + pass +""" + + for filename in all_files: + (temp_path / filename).write_text(test_content) + + test_folder = SDKTestFolder(path=temp_path, filename_pattern="*") + + # Mock load_include_list to return files that don't match pattern + files_to_include = ["TCP_Tests.py", "CUSTOM_Test.py"] + + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.load_include_list", + return_value=set(files_to_include), + ): + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.load_ignore_list", + return_value=set(), + ): + with mock.patch("ast.parse") as mock_parse: + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.base_test_classes" + ) as mock_base_classes: + mock_parse.return_value = mock.MagicMock() + mock_class = mock.MagicMock() + mock_class.name = "TestClass" + mock_base_classes.return_value = [mock_class] + + commands = get_command_list(test_folder) + + # Should process all 3 files (1 matching pattern + 2 in include list) + assert len(commands) == 3 + + # Verify all files are included + file_stems = [cmd[0].split("/")[-1] for cmd in commands] + assert "TC_ACE_1_2" in file_stems + assert "TCP_Tests" in file_stems + assert "CUSTOM_Test" in file_stems + + +def test_get_command_list_include_overrides_pattern() -> None: + """Test that include list bypasses pattern matching.""" + with tempfile.TemporaryDirectory() as temp_dir: + temp_path = Path(temp_dir) + + # File that doesn't match TC_ pattern but is in include list + special_file = "TCP_Special.py" + + test_content = """ +from matter_testing_support import MatterBaseTest + +class TestClass(MatterBaseTest): + def test_TC_example_1_1(self): + pass +""" + + (temp_path / special_file).write_text(test_content) + + test_folder = SDKTestFolder(path=temp_path, filename_pattern="*") + + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.load_include_list", + return_value={special_file}, + ): + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.load_ignore_list", + return_value=set(), + ): + with mock.patch("ast.parse") as mock_parse: + with mock.patch( + "test_collections.matter.sdk_tests.support.python_testing." + "list_python_tests_classes.base_test_classes" + ) as mock_base_classes: + mock_parse.return_value = mock.MagicMock() + mock_class = mock.MagicMock() + mock_class.name = "TestClass" + mock_base_classes.return_value = [mock_class] + + commands = get_command_list(test_folder) + + # Should include the file even though it doesn't match TC_ pattern + assert len(commands) == 1 + assert "TCP_Special" in commands[0][0] From eef2b37d159b4b359ee18d574343925ad60e481e Mon Sep 17 00:00:00 2001 From: Romulo Quidute Filho Date: Tue, 14 Oct 2025 16:03:01 +0000 Subject: [PATCH 3/5] Code review --- .../matter/sdk_tests/python_tests_include.txt | 2 +- .../list_python_tests_classes.py | 40 ++++++++++++------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/test_collections/matter/sdk_tests/python_tests_include.txt b/test_collections/matter/sdk_tests/python_tests_include.txt index 6229a663..476ceeef 100644 --- a/test_collections/matter/sdk_tests/python_tests_include.txt +++ b/test_collections/matter/sdk_tests/python_tests_include.txt @@ -1,2 +1,2 @@ # Files to be considered -TCP_Tests \ No newline at end of file +TCP_Tests.py \ No newline at end of file diff --git a/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py b/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py index c15656c6..035282e8 100644 --- a/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py +++ b/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py @@ -21,6 +21,8 @@ from pathlib import Path from typing import Optional +from loguru import logger + from test_collections.matter.config import matter_settings from test_collections.matter.sdk_tests.support.exec_run_in_container import ( ExecResultExtended, @@ -207,14 +209,14 @@ def get_command_list(test_folder: SDKTestFolder) -> list: for python_test_file in python_test_files: # Check if file is in include list (bypass regex check) if python_test_file.name in include_list: - print(f"Including {python_test_file.name} (in include list)") + logger.warning(f"Including {python_test_file.name} (in include list)") # Check if the file follows the TC_*.py pattern elif not tc_pattern.match(python_test_file.name): continue # Check if the file is in the ignore list if python_test_file.name in ignore_list: - print(f"Skipping {python_test_file.name} (in ignore list)") + logger.warning(f"Skipping {python_test_file.name} (in ignore list)") continue parent_folder = python_test_file.parent.name @@ -223,7 +225,9 @@ def get_command_list(test_folder: SDKTestFolder) -> list: parsed_python_file = ast.parse(python_file.read()) except SyntaxError: # Skip files with syntax errors (e.g., unterminated strings) - print(f"Warning: Skipping {python_test_file.name} due to syntax error") + logger.warning( + f"Warning: Skipping {python_test_file.name} due to syntax error" + ) continue test_classes = base_test_classes(parsed_python_file) @@ -372,7 +376,7 @@ async def __process_individual_commands( invalid_test_function_count: int = 0 total_commands = len(commands) for index, command in enumerate(commands): - print(f"Progress {index+1}/{total_commands}...") + logger.info(f"Progress {index+1}/{total_commands}...") command_string = " ".join(command + [GET_TEST_INFO_ARGUMENT]) result = sdk_container.send_command( command_string, @@ -422,25 +426,33 @@ def __print_report( warnings_found: list[str], errors_found: list[str], ) -> None: - print("###########################################################################") - print("############################### REPORT ################################") - print("###########################################################################") - print(f">>>>>>>> Output JSON file: {json_output_file}") - print(f">>>>>>>> Total of test functions: {test_function_count}") - print( + logger.info( + "###########################################################################" + ) + logger.info( + "############################### REPORT ################################" + ) + logger.info( + "###########################################################################" + ) + logger.info(f">>>>>>>> Output JSON file: {json_output_file}") + logger.info(f">>>>>>>> Total of test functions: {test_function_count}") + logger.info( ( ">>>>>>>> Total of invalid test functions (don't start with 'test_TC_'): " f"{invalid_test_function_count}" ) ) if len(warnings_found) > 0: - print(*warnings_found, sep="\n") + logger.info(*warnings_found, sep="\n") error_count = len(errors_found) - print(f">>>>>>>> Total of scripts with error: {error_count}") + logger.info(f">>>>>>>> Total of scripts with error: {error_count}") if error_count > 0: for i, error in enumerate(errors_found): - print(f"Error {i+1}: {error}") - print("###########################################################################") + logger.info(f"Error {i+1}: {error}") + logger.info( + "###########################################################################" + ) async def generate_python_test_json_file( From b552a5ea4b6fb1bdd0efaeaf4c604b14dd3e2418 Mon Sep 17 00:00:00 2001 From: Romulo Quidute Filho Date: Tue, 14 Oct 2025 16:03:50 +0000 Subject: [PATCH 4/5] Code review --- test_collections/matter/sdk_tests/python_tests_ignore.txt | 2 +- test_collections/matter/sdk_tests/python_tests_include.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test_collections/matter/sdk_tests/python_tests_ignore.txt b/test_collections/matter/sdk_tests/python_tests_ignore.txt index 1597118d..73a52c71 100644 --- a/test_collections/matter/sdk_tests/python_tests_ignore.txt +++ b/test_collections/matter/sdk_tests/python_tests_ignore.txt @@ -1,4 +1,4 @@ # Files to be ignored TC_TestAttrAvail.py TC_COLORCONTROL.py -TC_AVSM_StreamReuseRangeParams.py \ No newline at end of file +TC_AVSM_StreamReuseRangeParams.py diff --git a/test_collections/matter/sdk_tests/python_tests_include.txt b/test_collections/matter/sdk_tests/python_tests_include.txt index 476ceeef..d2c1ad98 100644 --- a/test_collections/matter/sdk_tests/python_tests_include.txt +++ b/test_collections/matter/sdk_tests/python_tests_include.txt @@ -1,2 +1,2 @@ # Files to be considered -TCP_Tests.py \ No newline at end of file +TCP_Tests.py From 41d6b280757c6571822076b4c586785311d8f17c Mon Sep 17 00:00:00 2001 From: Romulo Quidute Filho Date: Tue, 14 Oct 2025 18:01:28 +0000 Subject: [PATCH 5/5] Refactoring method to read ignore and include file --- .../list_python_tests_classes.py | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py b/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py index 035282e8..b91f8b07 100644 --- a/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py +++ b/test_collections/matter/sdk_tests/support/python_testing/list_python_tests_classes.py @@ -93,21 +93,33 @@ def __get_error_message_from_result(result: ExecResultExtended) -> str: return error_message -def load_ignore_list() -> set[str]: - """Load the list of Python test files to ignore. +def __load_file_list(file_path: Path) -> set[str]: + """Load a list of filenames from a text file. + + Args: + file_path: Path to the file containing the list Returns: - set[str]: Set of filenames to ignore (e.g., {'TC_TEST_1_1.py'}) + set[str]: Set of filenames from the file """ - ignore_list = set() - if PYTHON_TESTS_IGNORE_FILE.exists(): - with open(PYTHON_TESTS_IGNORE_FILE, "r") as f: + file_list = set() + if file_path.exists(): + with open(file_path, "r") as f: for line in f: # Strip whitespace and skip empty lines or comments filename = line.strip() if filename and not filename.startswith("#"): - ignore_list.add(filename) - return ignore_list + file_list.add(filename) + return file_list + + +def load_ignore_list() -> set[str]: + """Load the list of Python test files to ignore. + + Returns: + set[str]: Set of filenames to ignore (e.g., {'TC_TEST_1_1.py'}) + """ + return __load_file_list(PYTHON_TESTS_IGNORE_FILE) def load_include_list() -> set[str]: @@ -116,15 +128,7 @@ def load_include_list() -> set[str]: Returns: set[str]: Set of filenames to always include (e.g., {'TCP_Tests.py'}) """ - include_list = set() - if PYTHON_TESTS_INCLUDE_FILE.exists(): - with open(PYTHON_TESTS_INCLUDE_FILE, "r") as f: - for line in f: - # Strip whitespace and skip empty lines or comments - filename = line.strip() - if filename and not filename.startswith("#"): - include_list.add(filename) - return include_list + return __load_file_list(PYTHON_TESTS_INCLUDE_FILE) def base_test_classes(module: ast.Module) -> list[ast.ClassDef]: