blob: 4e4b8cfc28c54e6202a0a8dcf000d4de1445ac0e [file] [log] [blame]
George Keishinge7e91712021-09-03 11:28:44 -05001#!/usr/bin/env python3
Rahul Maheshwari4d488572019-12-10 23:53:05 -06002
3r"""
4PLDM functions.
5"""
6
Sridevi Ramesh961050b2020-11-12 11:04:30 -06007import json
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -05008import random
Patrick Williams20f38712022-12-08 06:18:26 -06009import re
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -050010import string
Patrick Williams20f38712022-12-08 06:18:26 -060011
12import bmc_ssh_utils as bsu
13import func_args as fa
14import var_funcs as vf
Anusha Dathatriba3cb8c2021-05-25 21:22:02 -050015from robot.api import logger
Rahul Maheshwari4d488572019-12-10 23:53:05 -060016
17
Sridevi Ramesh961050b2020-11-12 11:04:30 -060018def pldmtool(option_string, **bsu_options):
Rahul Maheshwari4d488572019-12-10 23:53:05 -060019 r"""
20 Run pldmtool on the BMC with the caller's option string and return the result.
21
22 Example:
23
24 ${pldm_results}= Pldmtool base GetPLDMTypes
25 Rprint Vars pldm_results
26
27 pldm_results:
Sridevi Ramesh961050b2020-11-12 11:04:30 -060028 pldmtool base GetPLDMVersion -t 0
29 {
30 "Response": "1.0.0"
31 }
32
Rahul Maheshwari4d488572019-12-10 23:53:05 -060033 Description of argument(s):
George Keishingb9080fc2023-02-17 12:31:31 -060034 option_string A string of options which are to be processed by the
35 pldmtool command.
36 parse_results Parse the pldmtool results and return a dictionary
37 rather than the raw
38 pldmtool output.
39 bsu_options Options to be passed directly to bmc_execute_command.
40 See its prolog for details.
Rahul Maheshwari4d488572019-12-10 23:53:05 -060041 """
42
George Keishingb9080fc2023-02-17 12:31:31 -060043 # This allows callers to specify arguments in python style
44 # (e.g. print_out=1 vs. print_out=${1}).
Rahul Maheshwari4d488572019-12-10 23:53:05 -060045 bsu_options = fa.args_to_objects(bsu_options)
46
Patrick Williams20f38712022-12-08 06:18:26 -060047 stdout, stderr, rc = bsu.bmc_execute_command(
Sridevi Ramesha4ab9f32023-12-13 02:58:53 -060048 "pldmtool " + option_string, **bsu_options, ignore_err=1
Patrick Williams20f38712022-12-08 06:18:26 -060049 )
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -050050 if stderr:
51 return stderr
52 try:
53 return json.loads(stdout)
54 except ValueError:
55 return stdout
Sridevi Ramesh57537452021-01-18 03:25:05 -060056
57
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -050058def GetBIOSEnumAttributeOptionalValues(attr_val_table_data):
Sridevi Ramesh57537452021-01-18 03:25:05 -060059 """
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -050060 From pldmtool GetBIOSTable of type AttributeValueTable get the dict of
61 attribute handle and its optional values for BIOS Enumeration type.
Sridevi Ramesh57537452021-01-18 03:25:05 -060062
63 Description of argument(s):
64 attr_val_table_data pldmtool output from GetBIOSTable table type AttributeValueTable
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -050065 e.g.
Sridevi Ramesh57537452021-01-18 03:25:05 -060066 [{
67 "AttributeHandle": 20,
68 "AttributeNameHandle": "23(pvm-pcie-error-inject)",
69 "AttributeType": "BIOSEnumeration",
70 "NumberOfPossibleValues": 2,
71 "PossibleValueStringHandle[0]": "3(Disabled)",
72 "PossibleValueStringHandle[1]": "4(Enabled)",
73 "NumberOfDefaultValues": 1,
74 "DefaultValueStringHandleIndex[0]": 1,
75 "StringHandle": "4(Enabled)"
Sridevi Ramesh57537452021-01-18 03:25:05 -060076 }]
Sridevi Ramesh57537452021-01-18 03:25:05 -060077 @return Dictionary of BIOS attribute and its value.
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -050078 e.g. {'pvm_pcie_error_inject': ['Disabled', 'Enabled']}
Sridevi Ramesh57537452021-01-18 03:25:05 -060079 """
80
81 attr_val_data_dict = {}
82 for item in attr_val_table_data:
83 for attr in item:
Patrick Williams20f38712022-12-08 06:18:26 -060084 if attr == "NumberOfPossibleValues":
Sridevi Ramesh57537452021-01-18 03:25:05 -060085 value_list = []
86 for i in range(0, int(item[attr])):
Patrick Williams20f38712022-12-08 06:18:26 -060087 attr_values = item[
88 "PossibleValueStringHandle[" + str(i) + "]"
89 ]
90 value = re.search(r"\((.*?)\)", attr_values).group(1)
Sridevi Ramesh57537452021-01-18 03:25:05 -060091 if value:
Sridevi Ramesh57537452021-01-18 03:25:05 -060092 value_list.append(value)
93 else:
Patrick Williams20f38712022-12-08 06:18:26 -060094 value_list.append("")
Sridevi Ramesh57537452021-01-18 03:25:05 -060095
Patrick Williams20f38712022-12-08 06:18:26 -060096 attr_handle = re.findall(
97 r"\(.*?\)", item["AttributeNameHandle"]
98 )
Sridevi Ramesh57537452021-01-18 03:25:05 -060099 attr_val_data_dict[attr_handle[0][1:-1]] = value_list
100 return attr_val_data_dict
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500101
102
103def GetBIOSStrAndIntAttributeHandles(attr_type, attr_val_table_data):
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500104 """
105 From pldmtool GetBIOSTable of type AttributeValueTable get the dict of
106 attribute handle and its values based on the attribute type.
107
108 Description of argument(s):
109 attr_type "BIOSInteger" or "BIOSString".
110 attr_val_table_data pldmtool output from GetBIOSTable table type AttributeValueTable.
111
112 @return Dict of BIOS attribute and its value based on attribute type.
113
114 """
115 attr_val_int_dict = {}
116 attr_val_str_dict = {}
117 for item in attr_val_table_data:
118 value_dict = {}
Patrick Williams20f38712022-12-08 06:18:26 -0600119 attr_handle = re.findall(r"\(.*?\)", item["AttributeNameHandle"])
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500120 # Example:
121 # {'vmi_if0_ipv4_prefix_length': {'UpperBound': 32, 'LowerBound': 0}
Patrick Williams20f38712022-12-08 06:18:26 -0600122 if item["AttributeType"] == "BIOSInteger":
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500123 value_dict["LowerBound"] = item["LowerBound"]
124 value_dict["UpperBound"] = item["UpperBound"]
125 attr_val_int_dict[attr_handle[0][1:-1]] = value_dict
126 # Example:
127 # {'vmi_if1_ipv4_ipaddr': {'MaximumStringLength': 15, 'MinimumStringLength': 7}}
Patrick Williams20f38712022-12-08 06:18:26 -0600128 elif item["AttributeType"] == "BIOSString":
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500129 value_dict["MinimumStringLength"] = item["MinimumStringLength"]
130 value_dict["MaximumStringLength"] = item["MaximumStringLength"]
131 attr_val_str_dict[attr_handle[0][1:-1]] = value_dict
132
Patrick Williams20f38712022-12-08 06:18:26 -0600133 if attr_type == "BIOSInteger":
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500134 return attr_val_int_dict
George Keishingb9080fc2023-02-17 12:31:31 -0600135 if attr_type == "BIOSString":
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500136 return attr_val_str_dict
137
George Keishingb9080fc2023-02-17 12:31:31 -0600138 return None
139
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500140
141def GetRandomBIOSIntAndStrValues(attr_name, count):
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500142 """
143 Get random integer or string values for BIOS attribute values based on the count.
144
145 Description of argument(s):
146 attr_name Attribute name of BIOS attribute type Integer or string.
147 count Max length for BIOS attribute type Integer or string.
148
149 @return Random attribute value based on BIOS attribute type Integer
150 or string.
151
152 """
Patrick Williams20f38712022-12-08 06:18:26 -0600153 attr_random_value = ""
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500154
155 # Example
156 # 12.13.14.15
Patrick Williams20f38712022-12-08 06:18:26 -0600157 if "gateway" in attr_name:
158 attr_random_value = ".".join(
159 map(str, (random.randint(0, 255) for _ in range(4)))
160 )
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500161 # Example
162 # 11.11.11.11
Patrick Williams20f38712022-12-08 06:18:26 -0600163 elif "ipaddr" in attr_name:
164 attr_random_value = ".".join(
165 map(str, (random.randint(0, 255) for _ in range(4)))
166 )
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500167 # Example
168 # E5YWEDWJJ
Patrick Williams20f38712022-12-08 06:18:26 -0600169 elif "name" in attr_name:
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500170 data = string.ascii_uppercase + string.digits
Patrick Williams20f38712022-12-08 06:18:26 -0600171 attr_random_value = "".join(
172 random.choice(data) for _ in range(int(count))
173 )
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500174
Patrick Williams20f38712022-12-08 06:18:26 -0600175 elif "mfg_flags" in attr_name:
Sridevi Ramesh74291d42021-04-28 07:52:35 -0500176 data = string.ascii_uppercase + string.digits
Patrick Williams20f38712022-12-08 06:18:26 -0600177 attr_random_value = "".join(
178 random.choice(data) for _ in range(int(count))
179 )
Sridevi Ramesh74291d42021-04-28 07:52:35 -0500180
Patrick Williams20f38712022-12-08 06:18:26 -0600181 elif "hb_lid_ids" in attr_name:
Sridevi Ramesh48615cd2021-06-15 07:21:22 -0500182 attr_random_value = str(random.randint(0, int(count)))
183
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500184 else:
185 attr_random_value = random.randint(0, int(count))
186 return attr_random_value
187
188
189def GetBIOSAttrOriginalValues(attr_val_table_data):
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500190 """
191 From pldmtool GetBIOSTable of type AttributeValueTable get the dict of
192 attribute handle and its values.
193
194 Description of argument(s):
195 attr_val_table_data pldmtool output from GetBIOSTable table type AttributeValueTable.
196
197 @return Dict of BIOS attribute and its value.
198
199 """
200 attr_val_data_dict = {}
201 for item in attr_val_table_data:
Patrick Williams20f38712022-12-08 06:18:26 -0600202 attr_handle = re.findall(r"\(.*?\)", item["AttributeNameHandle"])
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500203 attr_name = attr_handle[0][1:-1]
204
Sridevi Ramesha4ab9f32023-12-13 02:58:53 -0600205 # Exclude BIOS attribute which are ReadOnly.
206 if "ReadOnly" not in item["AttributeType"]:
207 command = (
208 "bios GetBIOSAttributeCurrentValueByHandle -a " + attr_name
209 )
210 value = pldmtool(command)
211 if "error" in value:
212 print("Ignore BIOS attribute which throws error...")
213 pass
214 elif not value["CurrentValue"]:
215 if "name" in attr_name:
216 attr_val_data_dict[attr_name] = '""'
217 elif "hb_lid_ids" in attr_name:
218 attr_val_data_dict[attr_name] = '""'
219 else:
220 attr_val_data_dict[attr_name] = value["CurrentValue"]
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500221
222 return attr_val_data_dict
223
224
225def GetBIOSAttrDefaultValues(attr_val_table_data):
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500226 """
227 From pldmtool GetBIOSTable of type AttributeValueTable get the dict of
228 attribute handle and its default attribute values.
229
230 Description of argument(s):
231 attr_val_table_data pldmtool output from GetBIOSTable table type AttributeValueTable.
232
233 @return Dict of BIOS attribute and its default attribute value.
234
235 """
236 attr_val_data_dict = {}
237 for item in attr_val_table_data:
Patrick Williams20f38712022-12-08 06:18:26 -0600238 attr_handle = re.findall(r"\(.*?\)", item["AttributeNameHandle"])
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500239 attr_name = attr_handle[0][1:-1]
240
241 if "DefaultString" in item:
242 attr_val_data_dict[attr_name] = item["DefaultString"]
243 if not item["DefaultString"]:
Patrick Williams20f38712022-12-08 06:18:26 -0600244 if "name" in attr_name:
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500245 attr_val_data_dict[attr_name] = '""'
Patrick Williams20f38712022-12-08 06:18:26 -0600246 elif "hb_lid_ids" in attr_name:
Sridevi Ramesh48615cd2021-06-15 07:21:22 -0500247 attr_val_data_dict[attr_name] = '""'
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500248 elif "DefaultValue" in item:
249 attr_val_data_dict[attr_name] = item["DefaultValue"]
250 elif "StringHandle" in item:
Patrick Williams20f38712022-12-08 06:18:26 -0600251 attr_default_value = re.findall(r"\(.*?\)", item["StringHandle"])
Sridevi Ramesh2ab3d382021-03-29 04:16:01 -0500252 attr_val_data_dict[attr_name] = attr_default_value[0][1:-1]
253
254 return attr_val_data_dict
Anusha Dathatriba3cb8c2021-05-25 21:22:02 -0500255
256
257def GetNewValuesForAllBIOSAttrs(attr_table_data):
Anusha Dathatriba3cb8c2021-05-25 21:22:02 -0500258 """
259 Get a new set of values for all attributes in Attribute Table.
260
261 Description of argument(s):
262 attr_table_data pldmtool output from GetBIOSTable table type AttributeValueTable.
263
264 @return Dict of BIOS attribute and new attribute value.
265
266 """
267 existing_data = GetBIOSAttrOriginalValues(attr_table_data)
268 logger.info(existing_data)
Patrick Williams20f38712022-12-08 06:18:26 -0600269 string_attr_data = GetBIOSStrAndIntAttributeHandles(
270 "BIOSString", attr_table_data
271 )
Anusha Dathatriba3cb8c2021-05-25 21:22:02 -0500272 logger.info(string_attr_data)
Patrick Williams20f38712022-12-08 06:18:26 -0600273 int_attr_data = GetBIOSStrAndIntAttributeHandles(
274 "BIOSInteger", attr_table_data
275 )
Anusha Dathatriba3cb8c2021-05-25 21:22:02 -0500276 logger.info(int_attr_data)
277 enum_attr_data = GetBIOSEnumAttributeOptionalValues(attr_table_data)
278 logger.info(enum_attr_data)
279
280 attr_random_data = {}
281 temp_list = enum_attr_data.copy()
282 for attr in enum_attr_data:
283 try:
284 temp_list[attr].remove(existing_data[attr])
285 except ValueError:
286 try:
287 # The data values have a double quote in them.
Anusha Dathatriba3cb8c2021-05-25 21:22:02 -0500288 data = '"' + str(existing_data[attr]) + '"'
289 temp_list[attr].remove(data)
290 except ValueError:
Patrick Williams20f38712022-12-08 06:18:26 -0600291 logger.info(
292 "Unable to remove the existing value "
293 + str(data)
294 + " from list "
295 + str(temp_list[attr])
296 )
Anusha Dathatriba3cb8c2021-05-25 21:22:02 -0500297 valid_values = temp_list[attr][:]
298 value = random.choice(valid_values)
299 attr_random_data[attr] = value.strip('"')
300 logger.info("Values generated for enumeration type attributes")
301
302 for attr in string_attr_data:
303 # Iterating to make sure we have a different value
304 # other than the existing value.
305 for iter in range(5):
Patrick Williams20f38712022-12-08 06:18:26 -0600306 random_val = GetRandomBIOSIntAndStrValues(
307 attr, string_attr_data[attr]["MaximumStringLength"]
308 )
Anusha Dathatriba3cb8c2021-05-25 21:22:02 -0500309 if random_val != existing_data[attr]:
310 break
Sridevi Ramesha4ab9f32023-12-13 02:58:53 -0600311 if isinstance(random_val, str):
312 attr_random_data[attr] = random_val.strip('"')
Anusha Dathatriba3cb8c2021-05-25 21:22:02 -0500313 logger.info("Values generated for string type attributes")
314
315 for attr in int_attr_data:
316 for iter in range(5):
Patrick Williams20f38712022-12-08 06:18:26 -0600317 random_val = GetRandomBIOSIntAndStrValues(
318 attr, int_attr_data[attr]["UpperBound"]
319 )
Anusha Dathatriba3cb8c2021-05-25 21:22:02 -0500320 if random_val != existing_data[attr]:
321 break
322 attr_random_data[attr] = random_val
323 logger.info("Values generated for integer type attributes")
324
325 return attr_random_data