blob: 403164b57ef446cc258adf52afe84889bd9120f0 [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
202
203 # Split the output by line.
Patrick Williams20f38712022-12-08 06:18:26 -0600204 rows = out_buf.rstrip("\n").split("\n")
Michael Walsh8b270ec2017-01-31 12:07:08 -0600205
206 # Initialize report dictionary.
207 report = DotDict()
208 for row in rows:
209 # Process each row of mtr output.
210 # Create a list of fields by splitting on space delimiter.
211 row_list = row.split(" ")
212 # Create dictionary for the row.
213 row = DotDict()
Patrick Williams20f38712022-12-08 06:18:26 -0600214 row["row_num"] = row_list[0].rstrip(".")
215 row["host"] = row_list[1]
216 row["loss"] = row_list[2].rstrip("%")
217 row["snt"] = row_list[3]
218 row["last"] = row_list[4]
219 row["avg"] = row_list[5]
220 row["best"] = row_list[6]
221 row["wrst"] = row_list[7]
222 row["stdev"] = row_list[8]
223 report[row["host"]] = row
Michael Walsh8b270ec2017-01-31 12:07:08 -0600224
225 # Return the full report as dictionary of dictionaries.
226 return report
227
Michael Walsh8b270ec2017-01-31 12:07:08 -0600228
Michael Walsh8b270ec2017-01-31 12:07:08 -0600229def get_mtr_row(host=""):
Michael Walsh8b270ec2017-01-31 12:07:08 -0600230 r"""
231 Run an mtr report and get a specified row and return it as a dictionary.
232
233 Example result:
234
235 row:
236 row[row_num]: 2
George Keishingfb4b1252017-06-15 00:05:45 -0500237 row[host]: bmc-dummy-dnsname.com
Michael Walsh8b270ec2017-01-31 12:07:08 -0600238 row[loss]: 0.0
239 row[snt]: 10
240 row[last]: 0.5
241 row[avg]: 0.5
242 row[best]: 0.4
243 row[wrst]: 0.7
244 row[stdev]: 0.1
245
246 Description of arguments:
247 host The DNS name or IP address to be passed to the mtr command as
248 well as the indicating which row of the report to return.
249 """
250
251 report = get_mtr_report(host)
252
253 # The max length of host in output is 28 chars.
254 row = [value for key, value in report.items() if host[0:28] in key][0]
255
256 return row
257
George Keishingefa97352017-03-13 07:13:03 -0500258
George Keishingefa97352017-03-13 07:13:03 -0500259def list_to_set(fru_list=""):
260 r"""
261 Pack the list into a set tuple and return.
262
263 It may seem that this function is rather trivial. However, it simplifies
264 the code and improves robot program readability and achieve the result
265 required.
266
267 Example result:
268
269 set(['Version', 'PartNumber', 'SerialNumber', 'FieldReplaceable',
270 'BuildDate', 'Present', 'Manufacturer', 'PrettyName', 'Cached', 'Model'])
271
272 # Description of arguments.
273 fru_list List of FRU's elements.
274 """
275 return set(fru_list)
276
George Keishing81ae45b2017-09-28 14:05:04 -0500277
278def min_list_value(value_list):
279 r"""
280 Returns the element from the list with minimum value.
281 """
282 return min(value_list)
nagarjunb2287138e62022-04-19 16:49:16 +0530283
284
285def convert_lsb_to_msb(string):
286 r"""
287 Reverse given string (From LSB first to MSB first) and converts to HEX.
288
George Keishing86d85f42022-08-18 23:02:22 -0500289 Input string 0a 00
nagarjunb2287138e62022-04-19 16:49:16 +0530290 Return string 0a
291 """
292 datalist = string.split(" ")
293 new_list = datalist[::-1]
294 new_string = "".join([str(element) for element in new_list])
295 return int(new_string, 16)
296
297
298def add_prefix_to_string(string, prefix):
299 r"""
300 Add given prefix to the string and return string.
301
302 Input string 0a 01
303 Return string 0x0a 0x01
304 """
Patrick Williams20f38712022-12-08 06:18:26 -0600305 prefix_string = ""
nagarjunb2287138e62022-04-19 16:49:16 +0530306 data_list = string.strip().split(" ")
307 for item in data_list:
Patrick Williams20f38712022-12-08 06:18:26 -0600308 prefix_string += prefix + item + " "
nagarjunb2287138e62022-04-19 16:49:16 +0530309 return prefix_string.strip()
George Keishing8ef9e722023-01-18 10:21:31 +0530310
311
312def get_value_from_nested_dict(key, nested_dict):
313 r"""
314 Returns the key value from the nested dictionary.
315
316 key Key value of the dictionary to look up.
317 nested_dict Dictionary data.
318 """
319 result = []
320 for k, v in nested_dict.items():
321 if k == key:
322 result.append(v)
323 elif isinstance(v, dict) and k != key:
324 result += get_value_from_nested_dict(key, v)
325
326 return result