blob: 1ec3b71daf87336541d7bf6c98fdbc8750545e83 [file] [log] [blame]
George Keishinge7e91712021-09-03 11:28:44 -05001#!/usr/bin/env python3 -u
George Keishingd9b3e162022-08-18 23:28:35 -05002
3r"""
4Generic utility functions.
5"""
Chris Austenb29d2e82016-06-07 12:25:35 -05006import imp
George Keishinge635ddc2022-12-08 07:38:02 -06007import random
Patrick Williams20f38712022-12-08 06:18:26 -06008import string
Michael Walsh8b270ec2017-01-31 12:07:08 -06009import subprocess
Patrick Williams20f38712022-12-08 06:18:26 -060010
George Keishingd9b3e162022-08-18 23:28:35 -050011from robot.libraries.BuiltIn import BuiltIn
Michael Walsh8b270ec2017-01-31 12:07:08 -060012from robot.utils import DotDict
13
Chris Austenb29d2e82016-06-07 12:25:35 -050014
Rahul Maheshwari757d80c2016-10-17 01:09:55 -050015def random_mac():
16 r"""
17 Return random mac address in the following format.
18 Example: 00:01:6C:80:02:78
19 """
Patrick Williams20f38712022-12-08 06:18:26 -060020 return ":".join(
21 map(
22 lambda x: "%02x" % x,
23 (random.randint(0x00, 0xFF) for _ in range(6)),
24 )
25 )
Gunnar Mills096cd562018-03-26 10:19:12 -050026
Rahul Maheshwari757d80c2016-10-17 01:09:55 -050027
28def random_ip():
29 r"""
30 Return random ip address in the following format.
31 Example: 9.3.128.100
32 """
Patrick Williams20f38712022-12-08 06:18:26 -060033 return ".".join(map(str, (random.randint(0, 255) for _ in range(4))))
Gunnar Mills096cd562018-03-26 10:19:12 -050034
Chris Austenb29d2e82016-06-07 12:25:35 -050035
36def get_sensor(module_name, value):
George Keishingd9b3e162022-08-18 23:28:35 -050037 r"""
38 Return sensor matched ID name.
39 """
Patrick Williams20f38712022-12-08 06:18:26 -060040 m = imp.load_source("module.name", module_name)
Chris Austenb29d2e82016-06-07 12:25:35 -050041
Patrick Williams20f38712022-12-08 06:18:26 -060042 for i in m.ID_LOOKUP["SENSOR"]:
43 if m.ID_LOOKUP["SENSOR"][i] == value:
Gunnar Millsbb398ac2016-11-14 11:50:22 -060044 return i
Chris Austenb29d2e82016-06-07 12:25:35 -050045
Gunnar Millsbb398ac2016-11-14 11:50:22 -060046 return 0xFF
47
Chris Austenb29d2e82016-06-07 12:25:35 -050048
Gunnar Mills096cd562018-03-26 10:19:12 -050049def get_inventory_sensor(module_name, value):
George Keishingd9b3e162022-08-18 23:28:35 -050050 r"""
51 Return sensor matched ID name from inventory.
52 """
Patrick Williams20f38712022-12-08 06:18:26 -060053 m = imp.load_source("module.name", module_name)
Chris Austenb29d2e82016-06-07 12:25:35 -050054
Patrick Williams20f38712022-12-08 06:18:26 -060055 value = string.replace(value, m.INVENTORY_ROOT, "<inventory_root>")
Chris Austenb29d2e82016-06-07 12:25:35 -050056
Patrick Williams20f38712022-12-08 06:18:26 -060057 for i in m.ID_LOOKUP["SENSOR"]:
58 if m.ID_LOOKUP["SENSOR"][i] == value:
Gunnar Millsbb398ac2016-11-14 11:50:22 -060059 return i
Chris Austenb29d2e82016-06-07 12:25:35 -050060
Gunnar Millsbb398ac2016-11-14 11:50:22 -060061 return 0xFF
Chris Austenb29d2e82016-06-07 12:25:35 -050062
63
64################################################################
Gunnar Millsbb398ac2016-11-14 11:50:22 -060065# This will return the URI's of the FRU type
Chris Austenb29d2e82016-06-07 12:25:35 -050066#
67# i.e. get_inventory_list('../data/Palmetto.py')
68#
George Keishingd9b3e162022-08-18 23:28:35 -050069# [/org/openbmc/inventory/system/chassis/motherboard/cpu0/core0,
Chris Austenb29d2e82016-06-07 12:25:35 -050070# /org/openbmc/inventory/system/chassis/motherboard/dimm0]
71################################################################
72def get_inventory_list(module_name):
George Keishingd9b3e162022-08-18 23:28:35 -050073 r"""
74 Return all FRU URI(s) list available from inventory.
75 """
Chris Austenb29d2e82016-06-07 12:25:35 -050076
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050077 inventory_list = []
Patrick Williams20f38712022-12-08 06:18:26 -060078 m = imp.load_source("module.name", module_name)
Chris Austenb29d2e82016-06-07 12:25:35 -050079
Patrick Williams20f38712022-12-08 06:18:26 -060080 for i in m.ID_LOOKUP["FRU"]:
81 s = m.ID_LOOKUP["FRU"][i]
82 s = s.replace("<inventory_root>", m.INVENTORY_ROOT)
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050083 inventory_list.append(s)
Gunnar Millsbb398ac2016-11-14 11:50:22 -060084
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050085 return inventory_list
Chris Austenb29d2e82016-06-07 12:25:35 -050086
87
88################################################################
Gunnar Millsbb398ac2016-11-14 11:50:22 -060089# This will return the URI's of the FRU type
Chris Austenb29d2e82016-06-07 12:25:35 -050090#
George Keishingbe3cdfd2018-08-28 00:00:06 -050091# i.e. get_inventory_fru_type_list('../data/Witherspoon.py', 'CPU')
Chris Austenb29d2e82016-06-07 12:25:35 -050092#
George Keishingd9b3e162022-08-18 23:28:35 -050093# [/org/openbmc/inventory/system/chassis/motherboard/cpu0,
94# /org/openbmc/inventory/system/chassis/motherboard/cpu1]
Chris Austenb29d2e82016-06-07 12:25:35 -050095################################################################
Gunnar Mills096cd562018-03-26 10:19:12 -050096def get_inventory_fru_type_list(module_name, fru):
George Keishingd9b3e162022-08-18 23:28:35 -050097 r"""
98 Return FRU URI(s) list of a given type from inventory.
99 """
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500100 inventory_list = []
Patrick Williams20f38712022-12-08 06:18:26 -0600101 m = imp.load_source("module.name", module_name)
Chris Austenb29d2e82016-06-07 12:25:35 -0500102
Gunnar Millsbb398ac2016-11-14 11:50:22 -0600103 for i in m.FRU_INSTANCES.keys():
Patrick Williams20f38712022-12-08 06:18:26 -0600104 if m.FRU_INSTANCES[i]["fru_type"] == fru:
105 s = i.replace("<inventory_root>", m.INVENTORY_ROOT)
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500106 inventory_list.append(s)
Gunnar Millsbb398ac2016-11-14 11:50:22 -0600107
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500108 return inventory_list
Chris Austenb29d2e82016-06-07 12:25:35 -0500109
110
111################################################################
112# This will return the URI's of the FRU type that contain VPD
113#
114# i.e. get_vpd_inventory_list('../data/Palmetto.py', 'DIMM')
115#
116# [/org/openbmc/inventory/system/chassis/motherboard/dimm0,
117# /org/openbmc/inventory/system/chassis/motherboard/dimm1]
118################################################################
Gunnar Mills096cd562018-03-26 10:19:12 -0500119def get_vpd_inventory_list(module_name, fru):
George Keishingd9b3e162022-08-18 23:28:35 -0500120 r"""
121 Return VPD URI(s) list of a FRU type from inventory.
122 """
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500123 inventory_list = []
Patrick Williams20f38712022-12-08 06:18:26 -0600124 m = imp.load_source("module.name", module_name)
Chris Austenb29d2e82016-06-07 12:25:35 -0500125
Patrick Williams20f38712022-12-08 06:18:26 -0600126 for i in m.ID_LOOKUP["FRU_STR"]:
127 x = m.ID_LOOKUP["FRU_STR"][i]
Chris Austenb29d2e82016-06-07 12:25:35 -0500128
Patrick Williams20f38712022-12-08 06:18:26 -0600129 if m.FRU_INSTANCES[x]["fru_type"] == fru:
130 s = x.replace("<inventory_root>", m.INVENTORY_ROOT)
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500131 inventory_list.append(s)
Gunnar Millsbb398ac2016-11-14 11:50:22 -0600132
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500133 return inventory_list
Chris Austenb29d2e82016-06-07 12:25:35 -0500134
135
136def call_keyword(keyword):
George Keishingd9b3e162022-08-18 23:28:35 -0500137 r"""
138 Return result of the execute robot keyword.
139 """
Chris Austenb29d2e82016-06-07 12:25:35 -0500140 return BuiltIn().run_keyword(keyword)
141
142
143def main():
George Keishingd9b3e162022-08-18 23:28:35 -0500144 r"""
145 Python main func call.
146 """
Patrick Williams20f38712022-12-08 06:18:26 -0600147 print(get_vpd_inventory_list("../data/Palmetto.py", "DIMM"))
Chris Austenb29d2e82016-06-07 12:25:35 -0500148
149
150if __name__ == "__main__":
Gunnar Mills096cd562018-03-26 10:19:12 -0500151 main()
Michael Walsh8b270ec2017-01-31 12:07:08 -0600152
153
Michael Walsh8b270ec2017-01-31 12:07:08 -0600154def get_mtr_report(host=""):
Michael Walsh8b270ec2017-01-31 12:07:08 -0600155 r"""
156 Get an mtr report and return it as a dictionary of dictionaries.
157
158 The key for the top level dictionary will be the host DNS name. The key
159 for the next level dictionary will be the field of a given row of the
160 report.
161
162 Example result:
163
164 report:
George Keishingfb4b1252017-06-15 00:05:45 -0500165 report[host_dummy-dnsname.com]:
166 report[host_dummy-dnsname.com][row_num]: 1
167 report[host_dummy-dnsname.com][host]: host_dummy-dnsname.com
168 report[host_dummy-dnsname.com][loss]: 0.0
169 report[host_dummy-dnsname.com][snt]: 10
170 report[host_dummy-dnsname.com][last]: 0.2
171 report[host_dummy-dnsname.com][avg]: 3.5
172 report[host_dummy-dnsname.com][best]: 0.2
173 report[host_dummy-dnsname.com][wrst]: 32.5
174 report[host_dummy-dnsname.com][stdev]: 10.2
175 report[bmc-dummy-dnsname.com]:
176 report[bmc-dummy-dnsname.com][row_num]: 2
177 report[bmc-dummy-dnsname.com][host]: bmc-dummy-dnsname.com
178 report[bmc-dummy-dnsname.com][loss]: 0.0
179 report[bmc-dummy-dnsname.com][snt]: 10
180 report[bmc-dummy-dnsname.com][last]: 0.5
181 report[bmc-dummy-dnsname.com][avg]: 0.5
182 report[bmc-dummy-dnsname.com][best]: 0.5
183 report[bmc-dummy-dnsname.com][wrst]: 0.5
184 report[bmc-dummy-dnsname.com][stdev]: 0.0
Michael Walsh8b270ec2017-01-31 12:07:08 -0600185
186 Description of arguments:
187 host The DNS name or IP address to be passed to the mtr command.
188 """
189
Gunnar Millsacc7c562019-08-20 13:12:46 -0500190 # Run the mtr command. Exclude the header line. Trim leading space from
Michael Walsh8b270ec2017-01-31 12:07:08 -0600191 # each line. Change all multiple spaces delims to single space delims.
Patrick Williams20f38712022-12-08 06:18:26 -0600192 cmd_buf = (
193 "mtr --report "
194 + host
195 + " | tail -n +2 | sed -r -e 's/^[ ]+//g' -e 's/[ ]+/ /g'"
196 )
197 sub_proc = subprocess.Popen(
198 cmd_buf, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
199 )
Michael Walsh8b270ec2017-01-31 12:07:08 -0600200 out_buf, err_buf = sub_proc.communicate()
201 shell_rc = sub_proc.returncode
manimozhik6abea652023-11-09 07:05:16 +0000202 out_buf = out_buf.decode("utf-8")
Michael Walsh8b270ec2017-01-31 12:07:08 -0600203
204 # Split the output by line.
Patrick Williams20f38712022-12-08 06:18:26 -0600205 rows = out_buf.rstrip("\n").split("\n")
Michael Walsh8b270ec2017-01-31 12:07:08 -0600206
207 # Initialize report dictionary.
208 report = DotDict()
209 for row in rows:
210 # Process each row of mtr output.
211 # Create a list of fields by splitting on space delimiter.
212 row_list = row.split(" ")
213 # Create dictionary for the row.
214 row = DotDict()
Patrick Williams20f38712022-12-08 06:18:26 -0600215 row["row_num"] = row_list[0].rstrip(".")
216 row["host"] = row_list[1]
217 row["loss"] = row_list[2].rstrip("%")
218 row["snt"] = row_list[3]
219 row["last"] = row_list[4]
220 row["avg"] = row_list[5]
221 row["best"] = row_list[6]
222 row["wrst"] = row_list[7]
223 row["stdev"] = row_list[8]
224 report[row["host"]] = row
Michael Walsh8b270ec2017-01-31 12:07:08 -0600225
226 # Return the full report as dictionary of dictionaries.
227 return report
228
Michael Walsh8b270ec2017-01-31 12:07:08 -0600229
Michael Walsh8b270ec2017-01-31 12:07:08 -0600230def get_mtr_row(host=""):
Michael Walsh8b270ec2017-01-31 12:07:08 -0600231 r"""
232 Run an mtr report and get a specified row and return it as a dictionary.
233
234 Example result:
235
236 row:
237 row[row_num]: 2
George Keishingfb4b1252017-06-15 00:05:45 -0500238 row[host]: bmc-dummy-dnsname.com
Michael Walsh8b270ec2017-01-31 12:07:08 -0600239 row[loss]: 0.0
240 row[snt]: 10
241 row[last]: 0.5
242 row[avg]: 0.5
243 row[best]: 0.4
244 row[wrst]: 0.7
245 row[stdev]: 0.1
246
247 Description of arguments:
248 host The DNS name or IP address to be passed to the mtr command as
249 well as the indicating which row of the report to return.
250 """
251
252 report = get_mtr_report(host)
253
254 # The max length of host in output is 28 chars.
255 row = [value for key, value in report.items() if host[0:28] in key][0]
256
257 return row
258
George Keishingefa97352017-03-13 07:13:03 -0500259
George Keishingefa97352017-03-13 07:13:03 -0500260def list_to_set(fru_list=""):
261 r"""
262 Pack the list into a set tuple and return.
263
264 It may seem that this function is rather trivial. However, it simplifies
265 the code and improves robot program readability and achieve the result
266 required.
267
268 Example result:
269
270 set(['Version', 'PartNumber', 'SerialNumber', 'FieldReplaceable',
271 'BuildDate', 'Present', 'Manufacturer', 'PrettyName', 'Cached', 'Model'])
272
273 # Description of arguments.
274 fru_list List of FRU's elements.
275 """
276 return set(fru_list)
277
George Keishing81ae45b2017-09-28 14:05:04 -0500278
279def min_list_value(value_list):
280 r"""
281 Returns the element from the list with minimum value.
282 """
283 return min(value_list)
nagarjunb2287138e62022-04-19 16:49:16 +0530284
285
286def convert_lsb_to_msb(string):
287 r"""
288 Reverse given string (From LSB first to MSB first) and converts to HEX.
289
George Keishing86d85f42022-08-18 23:02:22 -0500290 Input string 0a 00
nagarjunb2287138e62022-04-19 16:49:16 +0530291 Return string 0a
292 """
293 datalist = string.split(" ")
294 new_list = datalist[::-1]
295 new_string = "".join([str(element) for element in new_list])
296 return int(new_string, 16)
297
298
299def add_prefix_to_string(string, prefix):
300 r"""
301 Add given prefix to the string and return string.
302
303 Input string 0a 01
304 Return string 0x0a 0x01
305 """
Patrick Williams20f38712022-12-08 06:18:26 -0600306 prefix_string = ""
nagarjunb2287138e62022-04-19 16:49:16 +0530307 data_list = string.strip().split(" ")
308 for item in data_list:
Patrick Williams20f38712022-12-08 06:18:26 -0600309 prefix_string += prefix + item + " "
nagarjunb2287138e62022-04-19 16:49:16 +0530310 return prefix_string.strip()
George Keishing8ef9e722023-01-18 10:21:31 +0530311
312
313def get_value_from_nested_dict(key, nested_dict):
314 r"""
315 Returns the key value from the nested dictionary.
316
317 key Key value of the dictionary to look up.
318 nested_dict Dictionary data.
319 """
320 result = []
321 for k, v in nested_dict.items():
322 if k == key:
323 result.append(v)
324 elif isinstance(v, dict) and k != key:
325 result += get_value_from_nested_dict(key, v)
326
327 return result