Skip to content

Commit 7edbd42

Browse files
Updated metadata.py changes as suggested in the PR comments review
1 parent 425a88b commit 7edbd42

File tree

1 file changed

+123
-37
lines changed

1 file changed

+123
-37
lines changed

scripts/tests/py/metadata.py

+123-37
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
# Copyright (c) 2023 Project CHIP Authors
1+
#!/usr/local/bin/python3
2+
# Copyright (c) 2022 Project CHIP Authors
23
#
34
# Licensed under the Apache License, Version 2.0 (the "License");
45
# you may not use this file except in compliance with the License.
@@ -17,7 +18,9 @@
1718
import re
1819
import yaml
1920
from typing import Optional
20-
21+
from typing import Dict
22+
from typing import List
23+
from typing import Union
2124

2225
@dataclass
2326
class Metadata:
@@ -38,27 +41,67 @@ class Metadata:
3841

3942

4043
class Metadata_Reader:
41-
# This class will be initialized with
42-
# the name of the script folder and the environment
43-
# file name
44+
"""
45+
A class to parse run arguments from the test scripts and
46+
resolve them to environment specific values.
47+
48+
Attributes:
49+
50+
env: str
51+
A dictionary that reprsents a environment configuration in
52+
YAML format.
53+
"""
4454

45-
def __init__(self, script_folder, env_file_name):
46-
print(env_file_name)
47-
self.script_folder = script_folder
55+
def __init__(self, env_file_name: str):
56+
"""
57+
Constructs the environment object
58+
59+
Parameters:
60+
61+
env_file_name: str
62+
Path to the environment file that contains the YAML configuration.
63+
"""
4864
self.env = self.__build_env_object__(env_file_name)
65+
4966

50-
# builds the environment object
51-
def __build_env_object__(self, env_file_name):
67+
68+
def __build_env_object__(self, env_yaml_file_path: str) -> Dict[str, Union[str, int, Dict]]:
69+
"""
70+
Reads a YAML file and converts it into a dictionary
71+
72+
Parameters:
73+
74+
env_yaml_file_path: str
75+
path to the YAML file that contains environment configuration
76+
77+
Returns:
78+
Dict - a Python Dictionary representation of the environment YAML file
5279
53-
with open(env_file_name) as stream:
80+
"""
81+
with open(env_yaml_file_path) as stream:
5482
return yaml.safe_load(stream)
5583

56-
# resolves the run arguments associated with the environment
57-
def __resolve_env_vals__(self, metadata_dict):
84+
85+
def __resolve_env_vals__(self, metadata_dict: Dict[str, str]) -> None:
86+
"""
87+
Resolves the argument defined in the test script to environment values.
88+
For example, if a test script defines "all_clusters" as the value for app
89+
name, we will check the environment configuration to see what raw value is
90+
assocaited with the "all_cluster" variable and set the value for "app" option
91+
to this raw value.
92+
93+
Parameter:
94+
95+
metadata_dict: Dict[str, str]
96+
Dictionary where each key represent a particular argument and its value represent
97+
the value for that argument defined in the test script.
5898
59-
for run_arg in metadata_dict:
99+
Return:
60100
61-
run_arg_val = metadata_dict[run_arg]
101+
None
102+
"""
103+
104+
for run_arg,run_arg_val in metadata_dict.items():
62105

63106
if not type(run_arg_val)==str or run_arg=="run":
64107
metadata_dict[run_arg]=run_arg_val
@@ -68,6 +111,15 @@ def __resolve_env_vals__(self, metadata_dict):
68111
continue
69112

70113
sub_args = run_arg_val.split('/')
114+
115+
if len(sub_args) not in [1,2]:
116+
err = """The argument is not in the correct format.
117+
The argument must follow the format of arg1 or arg1/arg2.
118+
For example, arg1 represents the argument type and optionally arg2
119+
represents a specific variable defined in the environment file whose
120+
value should be used as the argument value. If arg2 is not specified,
121+
we will just use the first value associated with arg1 in the environment file."""
122+
raise Exception(err)
71123

72124
if len(sub_args)==1:
73125
run_arg_val=self.env.get(sub_args[0])
@@ -83,13 +135,57 @@ def __resolve_env_vals__(self, metadata_dict):
83135

84136
metadata_dict[run_arg] = run_arg_val
85137

138+
139+
140+
def __read_args__(self,run_args_lines: List[str],metadata_dict: Dict[str, str]) -> None:
141+
"""
142+
Goes these each raw line in argument header of a test script and extracts argument
143+
values from it.
144+
145+
Parameters:
146+
147+
run_args_lines: List[str]
148+
Raw lines in argument header
86149
87-
# reads the test script file and parses out the run arguments defined in the file
88-
def __parse_script__(self, py_script_path, runs_metadata):
150+
metadata_dict: Dict[str, str]
151+
Dictionary where the extracted arguments will be stored.
152+
This represents the side effect of this function.
153+
154+
Return:
155+
None
156+
157+
"""
158+
for run_line in run_args_lines:
159+
for run_arg_word in run_line.strip().split():
160+
run_arg=run_arg_word.split('/',1)[0]
161+
if run_arg in metadata_dict:
162+
metadata_dict[run_arg] = run_arg_word
163+
164+
165+
def parse_script(self, py_script_path: str) -> List[Metadata]:
166+
"""
167+
Parses a script and returns a list of metadata object where
168+
each element of that list representing run arguments associated
169+
with a particular run.
170+
171+
Parameter:
172+
173+
py_script_path: str
174+
path to the python test script
175+
176+
Return:
177+
178+
List[Metadata]
179+
List of Metadata object where each Metadata element represents
180+
the run arguments associated with a particular run defined in
181+
the script file.
182+
"""
183+
89184
runs_def_ptrn=re.compile(r'^\s*#\s*test-runner-runs:\s*(.*)$')
90-
args_def_ptrn=re.compile(r'^\s*#\s*test-runner-run/([a-zA-Z0-9_]+)/(script|app):\s*(.*)$')
185+
args_def_ptrn=re.compile(r'^\s*#\s*test-runner-run/([a-zA-Z0-9_]+):\s*(.*)$')
91186

92187
runs_arg_lines = {}
188+
runs_metadata = []
93189

94190

95191
with open(py_script_path, 'r', encoding='utf8') as py_script:
@@ -103,34 +199,24 @@ def __parse_script__(self, py_script_path, runs_metadata):
103199
runs_arg_lines[run]=[]
104200

105201
elif args_match:
106-
runs_arg_lines[args_match.group(1)].append(args_match.group(3))
202+
runs_arg_lines[args_match.group(1)].append(args_match.group(2))
107203

108204
for run in runs_arg_lines:
109205
metadata = Metadata()
110206
metadata_dict = vars(metadata)
207+
self.__read_args__(runs_arg_lines[run], metadata_dict)
208+
self.__resolve_env_vals__(metadata_dict)
209+
210+
# store the run value and script location in the
211+
# metadata object
111212
metadata_dict['py_script_path'] = str(py_script_path)
112213
metadata_dict['run'] = str(run)
113-
self.read_args(runs_arg_lines[run], metadata_dict)
114-
self.__resolve_env_vals__(metadata_dict)
115-
runs_metadata[str(metadata.py_script_path)+"+"+str(metadata.run)] = metadata
214+
215+
runs_metadata.append(metadata)
116216

217+
return runs_metadata
117218

118-
# gets the run metadata associated with all the test scripts in a particular folder
119-
def get_runs_metadata(self):
120-
runs_metadata = {}
121-
for path in Path(self.script_folder).glob('*.py'):
122-
self.__parse_script__(path, runs_metadata)
123219

124-
return runs_metadata
125-
126-
127-
# goes through run argument definition and extracts run arguments from it
128-
def read_args(self,run_args_lines,metadata_dict):
129-
for run_line in run_args_lines:
130-
for run_arg_word in run_line.strip().split():
131-
run_arg=run_arg_word.split('/',1)[0]
132-
if run_arg in metadata_dict:
133-
metadata_dict[run_arg] = run_arg_word
134220

135221

136222

0 commit comments

Comments
 (0)