Skip to content

Commit 62a4a97

Browse files
authored
Update python tests to maintain the test metadata as a local file (project-chip#36359)
* Add metadata that is shared for python tests * More updates * Fix typo * More metadata updates
1 parent 1efa8ae commit 62a4a97

File tree

4 files changed

+134
-123
lines changed

4 files changed

+134
-123
lines changed

scripts/tests/local.py

+25-85
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import click
3434
import coloredlogs
3535
import tabulate
36+
import yaml
3637

3738
# We compile for the local architecture. Figure out what platform we need
3839

@@ -43,12 +44,12 @@ def _get_native_machine_target():
4344
"""
4445
current_system_info = platform.uname()
4546
arch = current_system_info.machine
46-
if arch == 'x86_64':
47-
arch = 'x64'
48-
elif arch == 'i386' or arch == 'i686':
49-
arch = 'x86'
50-
elif arch in ('aarch64', 'aarch64_be', 'armv8b', 'armv8l'):
51-
arch = 'arm64'
47+
if arch == "x86_64":
48+
arch = "x64"
49+
elif arch == "i386" or arch == "i686":
50+
arch = "x86"
51+
elif arch in ("aarch64", "aarch64_be", "armv8b", "armv8l"):
52+
arch = "arm64"
5253

5354
return f"{current_system_info.system.lower()}-{arch}"
5455

@@ -165,14 +166,17 @@ def _do_build_apps():
165166
f"{target_prefix}-all-clusters-no-ble-clang-boringssl",
166167
f"{target_prefix}-bridge-no-ble-clang-boringssl",
167168
f"{target_prefix}-energy-management-no-ble-clang-boringssl",
169+
f"{target_prefix}-fabric-admin-rpc-ipv6only-clang-boringssl",
170+
f"{target_prefix}-fabric-bridge-rpc-ipv6only-clang-boringssl",
171+
f"{target_prefix}-light-data-model-no-unique-id-ipv6only-no-ble-no-wifi-clang",
168172
f"{target_prefix}-lit-icd-no-ble-clang-boringssl",
169173
f"{target_prefix}-lock-no-ble-clang-boringssl",
170174
f"{target_prefix}-microwave-oven-no-ble-clang-boringssl",
175+
f"{target_prefix}-network-manager-ipv6only-no-ble-clang-boringssl",
171176
f"{target_prefix}-ota-provider-no-ble-clang-boringssl",
172177
f"{target_prefix}-ota-requestor-no-ble-clang-boringssl",
173178
f"{target_prefix}-rvc-no-ble-clang-boringssl",
174179
f"{target_prefix}-tv-app-no-ble-clang-boringssl",
175-
f"{target_prefix}-network-manager-ipv6only-no-ble-clang-boringssl",
176180
]
177181

178182
cmd = ["./scripts/build/build_examples.py"]
@@ -354,6 +358,11 @@ def as_runner(path):
354358
CHIP_RVC_APP: {as_runner(f'out/{target_prefix}-rvc-no-ble-clang-boringssl/chip-rvc-app')}
355359
NETWORK_MANAGEMENT_APP: {
356360
as_runner(f'out/{target_prefix}-network-manager-ipv6only-no-ble-clang-boringssl/matter-network-manager-app')}
361+
FABRIC_ADMIN_APP: {
362+
as_runner(f'out/{target_prefix}-fabric-admin-rpc-ipv6only-clang-boringssl/fabric-admin')}
363+
FABRIC_BRIDGE_APP: {
364+
as_runner(f'out/{target_prefix}-fabric-bridge-rpc-ipv6only-clang-boringssl/fabric-bridge-app')}
365+
LIGHTING_APP_NO_UNIQUE_ID: {as_runner(f'out/{target_prefix}-light-data-model-no-unique-id-ipv6only-no-ble-no-wifi-clang/chip-lighting-app')}
357366
TRACE_APP: out/trace_data/app-{{SCRIPT_BASE_NAME}}
358367
TRACE_TEST_JSON: out/trace_data/test-{{SCRIPT_BASE_NAME}}
359368
TRACE_TEST_PERFETTO: out/trace_data/test-{{SCRIPT_BASE_NAME}}
@@ -382,58 +391,11 @@ def as_runner(path):
382391
if not os.path.exists("out/trace_data"):
383392
os.mkdir("out/trace_data")
384393

385-
# IGNORES are taken out of `src/python_testing/execute_python_tests.py` in the SDK
386-
excluded_patterns = {
387-
"MinimalRepresentation.py",
388-
"TC_CNET_4_4.py",
389-
"TC_CCTRL_2_1.py",
390-
"TC_CCTRL_2_2.py",
391-
"TC_CCTRL_2_3.py",
392-
"TC_DGGEN_3_2.py",
393-
"TC_EEVSE_Utils.py",
394-
"TC_ECOINFO_2_1.py",
395-
"TC_ECOINFO_2_2.py",
396-
"TC_EWATERHTRBase.py",
397-
"TC_EWATERHTR_2_1.py",
398-
"TC_EWATERHTR_2_2.py",
399-
"TC_EWATERHTR_2_3.py",
400-
"TC_EnergyReporting_Utils.py",
401-
"TC_OpstateCommon.py",
402-
"TC_pics_checker.py",
403-
"TC_TMP_2_1.py",
404-
"TC_MCORE_FS_1_1.py",
405-
"TC_MCORE_FS_1_2.py",
406-
"TC_MCORE_FS_1_3.py",
407-
"TC_MCORE_FS_1_4.py",
408-
"TC_MCORE_FS_1_5.py",
409-
"TC_OCC_3_1.py",
410-
"TC_OCC_3_2.py",
411-
"TC_BRBINFO_4_1.py",
412-
"TestCommissioningTimeSync.py",
413-
"TestConformanceSupport.py",
414-
"TestChoiceConformanceSupport.py",
415-
"TC_DEMTestBase.py",
416-
"choice_conformance_support.py",
417-
"TestConformanceTest.py", # Unit test of the conformance test (TC_DeviceConformance) - does not run against an app.
418-
"TestIdChecks.py",
419-
"TestSpecParsingDeviceType.py",
420-
"TestMatterTestingSupport.py",
421-
"TestSpecParsingSupport.py",
422-
"TestTimeSyncTrustedTimeSource.py",
423-
"basic_composition_support.py",
424-
"conformance_support.py",
425-
"drlk_2_x_common.py",
426-
"execute_python_tests.py",
427-
"global_attribute_ids.py",
428-
"hello_external_runner.py",
429-
"hello_test.py",
430-
"matter_testing_support.py",
431-
"pics_support.py",
432-
"spec_parsing_support.py",
433-
"taglist_and_topology_test_support.py",
434-
"test_plan_support.py",
435-
"test_plan_table_generator.py",
436-
}
394+
metadata = yaml.full_load(open("src/python_testing/test_metadata.yaml"))
395+
excluded_patterns = set([item["name"] for item in metadata["not_automated"]])
396+
397+
# NOTE: for slow tests. we add logs to not get impatient
398+
slow_test_duration = dict([(item["name"], item["duration"]) for item in metadata["slow_tests"]])
437399

438400
if not os.path.isdir("src/python_testing"):
439401
raise Exception(
@@ -448,31 +410,6 @@ def as_runner(path):
448410
test_scripts.append("src/controller/python/test/test_scripts/mobile-device-test.py")
449411
test_scripts.sort() # order consistent
450412

451-
# NOTE: VERY slow tests. we add logs to not get impatient
452-
slow_test_duration = {
453-
"mobile-device-test.py": "3 minutes",
454-
"TC_AccessChecker.py": "1.5 minutes",
455-
"TC_CADMIN_1_9.py": "40 seconds",
456-
"TC_CC_2_2.py": "1.5 minutes",
457-
"TC_DEM_2_10.py": "40 seconds",
458-
"TC_DeviceBasicComposition.py": "25 seconds",
459-
"TC_DRLK_2_12.py": "30 seconds",
460-
"TC_DRLK_2_3.py": "30 seconds",
461-
"TC_EEVSE_2_6.py": "30 seconds",
462-
"TC_FAN_3_1.py": "15 seconds",
463-
"TC_OPSTATE_2_5.py": "1.25 minutes",
464-
"TC_OPSTATE_2_6.py": "35 seconds",
465-
"TC_PS_2_3.py": "30 seconds",
466-
"TC_RR_1_1.py": "25 seconds",
467-
"TC_SWTCH.py": "1 minute",
468-
"TC_TIMESYNC_2_10.py": "20 seconds",
469-
"TC_TIMESYNC_2_11.py": "30 seconds",
470-
"TC_TIMESYNC_2_12.py": "20 seconds",
471-
"TC_TIMESYNC_2_7.py": "20 seconds",
472-
"TC_TIMESYNC_2_8.py": "1.5 minutes",
473-
"TC_ICDM_5_1.py": "TODO",
474-
}
475-
476413
execution_times = []
477414
try:
478415
to_run = []
@@ -698,7 +635,10 @@ def chip_tool_tests(target, target_glob, include_tags, expected_failures, runner
698635

699636
target_prefix = _get_native_machine_target()
700637
cmd.extend(
701-
["--chip-tool", f"./out/{target_prefix}-chip-tool-no-ble-clang-boringssl/chip-tool"]
638+
[
639+
"--chip-tool",
640+
f"./out/{target_prefix}-chip-tool-no-ble-clang-boringssl/chip-tool",
641+
]
702642
)
703643

704644
if target is not None:

src/python_testing/execute_python_tests.py

+6-37
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import os
2121
import subprocess
2222

23+
import yaml
24+
2325
# Function to load --app argument environment variables from a file
2426

2527

@@ -36,11 +38,8 @@ def load_env_from_yaml(file_path):
3638
Args:
3739
file_path (str): The path to the YAML file containing the environment variables.
3840
"""
39-
with open(file_path, 'r') as file:
40-
for line in file:
41-
if line.strip(): # Skip empty lines
42-
key, value = line.strip().split(': ', 1)
43-
os.environ[key] = value
41+
for key, value in yaml.full_load(open(file_path, 'r')).items():
42+
os.environ[key] = value
4443

4544

4645
def main(search_directory, env_file):
@@ -53,38 +52,8 @@ def main(search_directory, env_file):
5352
# Define the base command to run tests
5453
base_command = os.path.join(chip_root, "scripts/tests/run_python_test.py")
5554

56-
# Define the test python script files and patterns to exclude
57-
excluded_patterns = {
58-
"MinimalRepresentation.py", # Code/Test not being used or not shared code for any other tests
59-
"TC_CNET_4_4.py", # It has no CI execution block, is not executed in CI
60-
"TC_DGGEN_3_2.py", # src/python_testing/test_testing/test_TC_DGGEN_3_2.py is the Unit test of this test
61-
"TC_EEVSE_Utils.py", # Shared code for TC_EEVSE, not a standalone test
62-
"TC_EWATERHTRBase.py", # Shared code for TC_EWATERHTR, not a standalone test
63-
"TC_EnergyReporting_Utils.py", # Shared code for TC_EEM and TC_EPM, not a standalone test
64-
"TC_OpstateCommon.py", # Shared code for TC_OPSTATE, not a standalone test
65-
"TC_pics_checker.py", # Currently isn't enabled because we don't have any examples with conformant PICS
66-
"TC_TMP_2_1.py", # src/python_testing/test_testing/test_TC_TMP_2_1.py is the Unit test of this test
67-
"TC_OCC_3_1.py", # There are CI issues for the test cases that implements manually controlling sensor device for the occupancy state ON/OFF change
68-
"TC_OCC_3_2.py", # There are CI issues for the test cases that implements manually controlling sensor device for the occupancy state ON/OFF change
69-
"TestCommissioningTimeSync.py", # Code/Test not being used or not shared code for any other tests
70-
"TestConformanceSupport.py", # Unit test - does not run against an app
71-
"TestChoiceConformanceSupport.py", # Unit test - does not run against an app
72-
"TC_DEMTestBase.py", # Shared code for TC_DEM, not a standalone test
73-
"TestConformanceTest.py", # Unit test of the conformance test (TC_DeviceConformance) - does not run against an app
74-
"TestIdChecks.py", # Unit test - does not run against an app
75-
"TestSpecParsingDeviceType.py", # Unit test - does not run against an app
76-
"TestConformanceTest.py", # Unit test - does not run against an app
77-
"TestMatterTestingSupport.py", # Unit test - does not run against an app
78-
"TestSpecParsingSupport.py", # Unit test - does not run against an app
79-
"TestTimeSyncTrustedTimeSource.py", # Unit test and shared code for scripts/tests/TestTimeSyncTrustedTimeSourceRunner.py
80-
"drlk_2_x_common.py", # Shared code for TC_DRLK, not a standalone test
81-
# Python code that runs all the python tests from src/python_testing (This code itself run via tests.yaml)
82-
"execute_python_tests.py",
83-
"hello_external_runner.py", # Code/Test not being used or not shared code for any other tests
84-
"hello_test.py", # Is a template for tests
85-
"test_plan_support.py", # Shared code for TC_*, not a standalone test
86-
"test_plan_table_generator.py", # Code/Test not being used or not shared code for any other tests
87-
}
55+
metadata = yaml.full_load(open(os.path.join(chip_root, "src/python_testing/test_metadata.yaml")))
56+
excluded_patterns = set([item["name"] for item in metadata["not_automated"]])
8857

8958
# Get all .py files in the directory
9059
all_python_files = glob.glob(os.path.join(search_directory, "*.py"))

src/python_testing/matter_testing_infrastructure/chip/testing/tasks.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def start(self,
123123
# hang on the join call in our thread entry point in case of
124124
# Python process termination (not-caught exception).
125125
self.p.terminate()
126-
raise TimeoutError("Expected output not found")
126+
raise TimeoutError("Expected output '%r' not found within %s seconds" % (expected_output, timeout))
127127
self.expected_output = None
128128

129129
def send(self, message: str, end: str = "\n",

src/python_testing/test_metadata.yaml

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Tests that are NOT executed in CI, along with the reason on
2+
# why they are not.
3+
not_automated:
4+
- name: MinimalRepresentation.py
5+
reason: Code/Test not being used or not shared code for any other tests
6+
- name: TC_CNET_4_4.py
7+
reason: It has no CI execution block, is not executed in CI
8+
- name: TC_DGGEN_3_2.py
9+
reason:
10+
src/python_testing/test_testing/test_TC_DGGEN_3_2.py is the Unit test
11+
of this test
12+
- name: TC_EEVSE_Utils.py
13+
reason: Shared code for TC_EEVSE, not a standalone test
14+
- name: TC_EWATERHTRBase.py
15+
reason: Shared code for TC_EWATERHTR, not a standalone test
16+
- name: TC_EnergyReporting_Utils.py
17+
reason: Shared code for TC_EEM and TC_EPM, not a standalone test
18+
- name: TC_OpstateCommon.py
19+
reason: Shared code for TC_OPSTATE, not a standalone test
20+
- name: TC_pics_checker.py
21+
reason:
22+
Currently isn't enabled because we don't have any examples with
23+
conformant PICS
24+
- name: TC_TMP_2_1.py
25+
reason:
26+
src/python_testing/test_testing/test_TC_TMP_2_1.py is the Unit test of
27+
this test
28+
- name: TC_OCC_3_1.py
29+
reason:
30+
There are CI issues for the test cases that implements manually
31+
controlling sensor device for the occupancy state ON/OFF change
32+
- name: TC_OCC_3_2.py
33+
reason:
34+
There are CI issues for the test cases that implements manually
35+
controlling sensor device for the occupancy state ON/OFF change
36+
- name: TestCommissioningTimeSync.py
37+
reason: Code/Test not being used or not shared code for any other tests
38+
- name: TestConformanceSupport.py
39+
reason: Unit test - does not run against an app
40+
- name: TestChoiceConformanceSupport.py
41+
reason: Unit test - does not run against an app
42+
- name: TC_DEMTestBase.py
43+
reason: Shared code for TC_DEM, not a standalone test
44+
- name: TestConformanceTest.py
45+
reason:
46+
Unit test of the conformance test (TC_DeviceConformance) - does not
47+
run against an app
48+
- name: TestIdChecks.py
49+
reason: Unit test - does not run against an app
50+
- name: TestSpecParsingDeviceType.py
51+
reason: Unit test - does not run against an app
52+
- name: TestConformanceTest.py
53+
reason: Unit test - does not run against an app
54+
- name: TestMatterTestingSupport.py
55+
reason: Unit test - does not run against an app
56+
- name: TestSpecParsingSupport.py
57+
reason: Unit test - does not run against an app
58+
- name: TestTimeSyncTrustedTimeSource.py
59+
reason:
60+
Unit test and shared code for
61+
scripts/tests/TestTimeSyncTrustedTimeSourceRunner.py
62+
- name: drlk_2_x_common.py
63+
reason: Shared code for TC_DRLK, not a standalone test
64+
- name: execute_python_tests.py
65+
reason:
66+
Python code that runs all the python tests from src/python_testing
67+
(This code itself run via tests.yaml)
68+
- name: hello_external_runner.py
69+
reason: Code/Test not being used or not shared code for any other tests
70+
- name: hello_test.py
71+
reason: Is a template for tests
72+
- name: test_plan_support.py
73+
reason: Shared code for TC_*, not a standalone test
74+
- name: test_plan_table_generator.py
75+
reason: Code/Test not being used or not shared code for any other tests
76+
77+
# This is a list of slow tests (just arbitrarely picked around 20 seconds)
78+
# used in some script reporting for "be patient" messages as well as potentially
79+
# to consider improving. May not be exhaustive
80+
slow_tests:
81+
- { name: mobile-device-test.py, duration: 3 minutes }
82+
- { name: TC_AccessChecker.py, duration: 1.5 minutes }
83+
- { name: TC_BRBINFO_4_1.py, duration: 2 minutes }
84+
- { name: TC_CADMIN_1_9.py, duration: 40 seconds }
85+
- { name: TC_CC_2_2.py, duration: 1.5 minutes }
86+
- { name: TC_DEM_2_10.py, duration: 40 seconds }
87+
- { name: TC_DeviceBasicComposition.py, duration: 25 seconds }
88+
- { name: TC_DRLK_2_12.py, duration: 30 seconds }
89+
- { name: TC_DRLK_2_3.py, duration: 30 seconds }
90+
- { name: TC_EEVSE_2_6.py, duration: 30 seconds }
91+
- { name: TC_FAN_3_1.py, duration: 15 seconds }
92+
- { name: TC_MCORE_FS_1_4.py, duration: 20 seconds }
93+
- { name: TC_OPSTATE_2_5.py, duration: 1.25 minutes }
94+
- { name: TC_OPSTATE_2_6.py, duration: 35 seconds }
95+
- { name: TC_PS_2_3.py, duration: 30 seconds }
96+
- { name: TC_RR_1_1.py, duration: 25 seconds }
97+
- { name: TC_SWTCH.py, duration: 1 minute }
98+
- { name: TC_TIMESYNC_2_10.py, duration: 20 seconds }
99+
- { name: TC_TIMESYNC_2_11.py, duration: 30 seconds }
100+
- { name: TC_TIMESYNC_2_12.py, duration: 20 seconds }
101+
- { name: TC_TIMESYNC_2_7.py, duration: 20 seconds }
102+
- { name: TC_TIMESYNC_2_8.py, duration: 1.5 minutes }

0 commit comments

Comments
 (0)