Skip to content

Commit de20c30

Browse files
feature: added env_test file and code to get default args from env file.
1 parent 58c6789 commit de20c30

File tree

2 files changed

+63
-86
lines changed

2 files changed

+63
-86
lines changed

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

+58-71
Original file line numberDiff line numberDiff line change
@@ -48,32 +48,32 @@ def extract_runs_args(py_script_path: str) -> Dict[str, Dict[str, str]]:
4848
runs_arg_lines: Dict[str, Dict[str, str]] = {}
4949

5050
ci_args_section_lines = []
51+
5152
with open(py_script_path, 'r', encoding='utf8') as py_script:
52-
for line_idx, line in enumerate(py_script.readlines()):
53+
for line in py_script.readlines():
5354
line = line.strip()
55+
ci_args_section_lines.append("") # Preserve line numbers for YAML parsing
5456

55-
# Append empty line to the line capture, so during YAML parsing
56-
# line numbers will match the original file.
57-
ci_args_section_lines.append("")
58-
59-
# Detect the single CI args section, to skip the lines otherwise.
6057
if line.startswith("# === BEGIN CI TEST ARGUMENTS ==="):
6158
found_ci_args_section = True
6259
continue
6360
if line.startswith("# === END CI TEST ARGUMENTS ==="):
6461
break
6562

6663
if found_ci_args_section:
67-
# Update the last line in the line capture.
6864
ci_args_section_lines[-1] = " " + line.lstrip("#")
6965

70-
if not runs_arg_lines:
66+
if ci_args_section_lines:
7167
try:
7268
runs = yaml.safe_load(NamedStringIO("\n".join(ci_args_section_lines), py_script_path))
7369
for run, args in runs.get("test-runner-runs", {}).items():
74-
runs_arg_lines[run] = {}
75-
runs_arg_lines[run]['run'] = run
76-
runs_arg_lines[run].update(args)
70+
runs_arg_lines[run] = args
71+
72+
# Capture skip-default-flags (if defined)
73+
skip_flags = runs.get("skip-default-flags", [])
74+
for run in runs_arg_lines:
75+
runs_arg_lines[run]["skip-default-flags"] = skip_flags
76+
7777
except yaml.YAMLError as e:
7878
logging.error(f"Failed to parse CI arguments YAML: {e}")
7979

@@ -82,77 +82,64 @@ def extract_runs_args(py_script_path: str) -> Dict[str, Dict[str, str]]:
8282

8383
class MetadataReader:
8484
"""
85-
A class to parse run arguments from the test scripts and
86-
resolve them to environment specific values.
85+
Parses test script arguments and merges them with defaults from env_test.yaml.
8786
"""
8887

8988
def __init__(self, env_yaml_file_path: str):
90-
"""
91-
Reads the YAML file and Constructs the environment object
92-
93-
Parameters:
89+
"""Loads default arguments from env_test.yaml."""
90+
with open(env_yaml_file_path, 'r', encoding='utf8') as stream:
91+
env_yaml = yaml.safe_load(stream) or {}
9492

95-
env_yaml_file_path:
96-
Path to the environment file that contains the YAML configuration.
97-
"""
98-
with open(env_yaml_file_path) as stream:
99-
self.env: Dict[str, str] = yaml.safe_load(stream)
93+
self.default_args = env_yaml.get("default-arguments", {})
10094

10195
def __resolve_env_vals__(self, metadata_dict: Dict[str, str]) -> None:
102-
"""
103-
Resolves the argument defined in the test script to environment values.
104-
For example, if a test script defines "all_clusters" as the value for app
105-
name, we will check the environment configuration to see what raw value is
106-
associated with the "all_cluster" variable and set the value for "app" option
107-
to this raw value.
108-
109-
Parameter:
110-
111-
metadata_dict:
112-
Dictionary where each key represent a particular argument and its value represent
113-
the value for that argument defined in the test script.
114-
"""
96+
"""Resolves ${VAR} placeholders using default arguments."""
11597
for arg, arg_val in metadata_dict.items():
116-
if not isinstance(arg_val, str):
117-
continue
118-
# We do not expect to recurse (like ${FOO_${BAR}}) so just expand once
119-
for name, value in self.env.items():
120-
arg_val = arg_val.replace(f'${{{name}}}', value)
121-
metadata_dict[arg] = arg_val.strip()
98+
if isinstance(arg_val, str):
99+
for name, value in self.default_args.items():
100+
arg_val = arg_val.replace(f'${{{name}}}', value)
101+
metadata_dict[arg] = arg_val.strip()
122102

123103
def parse_script(self, py_script_path: str) -> List[Metadata]:
124104
"""
125-
Parses a script and returns a list of metadata object where
126-
each element of that list representing run arguments associated
127-
with a particular run.
128-
129-
Parameter:
130-
131-
py_script_path:
132-
path to the python test script
133-
134-
Return:
135-
136-
List[Metadata]
137-
List of Metadata object where each Metadata element represents
138-
the run arguments associated with a particular run defined in
139-
the script file.
105+
Parses a test script and merges run arguments with defaults.
106+
107+
- Uses defaults from env_test.yaml.
108+
- Applies script overrides.
109+
- Respects skip-default-flags.
110+
111+
Returns:
112+
List[Metadata]: List of parsed metadata objects.
140113
"""
141114
runs_metadata: List[Metadata] = []
142-
runs_args = extract_runs_args(py_script_path)
143-
144-
for run, attr in runs_args.items():
145-
self.__resolve_env_vals__(attr)
146-
runs_metadata.append(Metadata(
147-
py_script_path=py_script_path,
148-
run=run,
149-
app=attr.get("app", ""),
150-
app_args=attr.get("app-args"),
151-
app_ready_pattern=attr.get("app-ready-pattern"),
152-
app_stdin_pipe=attr.get("app-stdin-pipe"),
153-
script_args=attr.get("script-args"),
154-
factory_reset=attr.get("factory-reset", False),
155-
quiet=attr.get("quiet", True),
156-
))
115+
script_args = extract_runs_args(py_script_path)
116+
117+
for run, script_run_args in script_args.items():
118+
# Extract skip-default-flags (if present)
119+
skip_default_flags = script_run_args.pop("skip-default-flags", [])
120+
121+
# Start with defaults
122+
combined_args = {k: v.copy() if isinstance(v, dict) else v for k, v in self.default_args.items()}
123+
124+
# Apply script args, respecting skip-default-flags
125+
for key, value in script_run_args.items():
126+
if key in skip_default_flags:
127+
combined_args[key] = value # Take from script YAML block only
128+
else:
129+
combined_args.setdefault(key, value) # Keep default if not overridden
130+
131+
self.__resolve_env_vals__(combined_args) # Resolve ${VAR} placeholders
132+
133+
runs_metadata.append(Metadata(
134+
py_script_path=py_script_path,
135+
run=run,
136+
app=combined_args.get("app", ""),
137+
app_args=combined_args.get("app-args"),
138+
app_ready_pattern=combined_args.get("app-ready-pattern"),
139+
app_stdin_pipe=combined_args.get("app-stdin-pipe"),
140+
script_args=combined_args.get("script-args"),
141+
factory_reset=combined_args.get("factory-reset", False),
142+
quiet=combined_args.get("quiet", True),
143+
))
157144

158145
return runs_metadata

src/python_testing/matter_testing_infrastructure/env_test.yaml

+5-15
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,10 @@
1313
# limitations under the License.
1414

1515
# test environment argument definitions for metadata parser
16-
discriminator: 1234
17-
KVS: kvs1
18-
trace-to-appjson: json:out/trace_data/app-{SCRIPT_BASE_NAME}.json
19-
enable-key: 000102030405060708090a0b0c0d0e0f
16+
default-arguments:
2017

21-
storage-path: admin_storage.json
22-
commissioning-method: on-network
23-
passcode: 20202021
24-
endpoint: 1
25-
trace-to-testjson: json:out/trace_data/test-{SCRIPT_BASE_NAME}.json
26-
trace-to-testperfetto: perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto
27-
manual-code: 10054912339
28-
PICS: src/app/tests/suites/certification/ci-pics-values
18+
app-args:
19+
discriminator: "1234"
2920

30-
app:
31-
all-clusters: out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app
32-
lock: out/linux-x64-lock-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-lock-app
21+
script-args:
22+
discriminator: "1234"

0 commit comments

Comments
 (0)