blob: 3c544417bbd9c4bf3e82c7a86769262f0a1e76be [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"""
Brian Ma139f1da2024-10-18 13:34:14 +08006import importlib.util
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
Brian Ma139f1da2024-10-18 13:34:14 +080015def load_source(name, module_path):
16 r"""
17 import util to replace deprecated imp.load_source
18 """
19 spec = importlib.util.spec_from_file_location(name, module_path)
20 module = importlib.util.module_from_spec(spec)
21 spec.loader.exec_module(module)
22 return module
23
24
Rahul Maheshwari757d80c2016-10-17 01:09:55 -050025def random_mac():
26 r"""
27 Return random mac address in the following format.
28 Example: 00:01:6C:80:02:78
29 """
Patrick Williams20f38712022-12-08 06:18:26 -060030 return ":".join(
31 map(
32 lambda x: "%02x" % x,
33 (random.randint(0x00, 0xFF) for _ in range(6)),
34 )
35 )
Gunnar Mills096cd562018-03-26 10:19:12 -050036
Rahul Maheshwari757d80c2016-10-17 01:09:55 -050037
38def random_ip():
39 r"""
40 Return random ip address in the following format.
41 Example: 9.3.128.100
42 """
Patrick Williams20f38712022-12-08 06:18:26 -060043 return ".".join(map(str, (random.randint(0, 255) for _ in range(4))))
Gunnar Mills096cd562018-03-26 10:19:12 -050044
Chris Austenb29d2e82016-06-07 12:25:35 -050045
46def get_sensor(module_name, value):
George Keishingd9b3e162022-08-18 23:28:35 -050047 r"""
48 Return sensor matched ID name.
49 """
Brian Ma139f1da2024-10-18 13:34:14 +080050 m = load_source("module.name", module_name)
Chris Austenb29d2e82016-06-07 12:25:35 -050051
Patrick Williams20f38712022-12-08 06:18:26 -060052 for i in m.ID_LOOKUP["SENSOR"]:
53 if m.ID_LOOKUP["SENSOR"][i] == value:
Gunnar Millsbb398ac2016-11-14 11:50:22 -060054 return i
Chris Austenb29d2e82016-06-07 12:25:35 -050055
Gunnar Millsbb398ac2016-11-14 11:50:22 -060056 return 0xFF
57
Chris Austenb29d2e82016-06-07 12:25:35 -050058
Gunnar Mills096cd562018-03-26 10:19:12 -050059def get_inventory_sensor(module_name, value):
George Keishingd9b3e162022-08-18 23:28:35 -050060 r"""
61 Return sensor matched ID name from inventory.
62 """
Brian Ma139f1da2024-10-18 13:34:14 +080063 m = load_source("module.name", module_name)
Chris Austenb29d2e82016-06-07 12:25:35 -050064
Patrick Williams20f38712022-12-08 06:18:26 -060065 value = string.replace(value, m.INVENTORY_ROOT, "<inventory_root>")
Chris Austenb29d2e82016-06-07 12:25:35 -050066
Patrick Williams20f38712022-12-08 06:18:26 -060067 for i in m.ID_LOOKUP["SENSOR"]:
68 if m.ID_LOOKUP["SENSOR"][i] == value:
Gunnar Millsbb398ac2016-11-14 11:50:22 -060069 return i
Chris Austenb29d2e82016-06-07 12:25:35 -050070
Gunnar Millsbb398ac2016-11-14 11:50:22 -060071 return 0xFF
Chris Austenb29d2e82016-06-07 12:25:35 -050072
73
74################################################################
Gunnar Millsbb398ac2016-11-14 11:50:22 -060075# This will return the URI's of the FRU type
Chris Austenb29d2e82016-06-07 12:25:35 -050076#
77# i.e. get_inventory_list('../data/Palmetto.py')
78#
George Keishingd9b3e162022-08-18 23:28:35 -050079# [/org/openbmc/inventory/system/chassis/motherboard/cpu0/core0,
Chris Austenb29d2e82016-06-07 12:25:35 -050080# /org/openbmc/inventory/system/chassis/motherboard/dimm0]
81################################################################
82def get_inventory_list(module_name):
George Keishingd9b3e162022-08-18 23:28:35 -050083 r"""
84 Return all FRU URI(s) list available from inventory.
85 """
Chris Austenb29d2e82016-06-07 12:25:35 -050086
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050087 inventory_list = []
Brian Ma139f1da2024-10-18 13:34:14 +080088 m = load_source("module.name", module_name)
Chris Austenb29d2e82016-06-07 12:25:35 -050089
Patrick Williams20f38712022-12-08 06:18:26 -060090 for i in m.ID_LOOKUP["FRU"]:
91 s = m.ID_LOOKUP["FRU"][i]
92 s = s.replace("<inventory_root>", m.INVENTORY_ROOT)
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050093 inventory_list.append(s)
Gunnar Millsbb398ac2016-11-14 11:50:22 -060094
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050095 return inventory_list
Chris Austenb29d2e82016-06-07 12:25:35 -050096
97
98################################################################
Gunnar Millsbb398ac2016-11-14 11:50:22 -060099# This will return the URI's of the FRU type
Chris Austenb29d2e82016-06-07 12:25:35 -0500100#
George Keishingbe3cdfd2018-08-28 00:00:06 -0500101# i.e. get_inventory_fru_type_list('../data/Witherspoon.py', 'CPU')
Chris Austenb29d2e82016-06-07 12:25:35 -0500102#
George Keishingd9b3e162022-08-18 23:28:35 -0500103# [/org/openbmc/inventory/system/chassis/motherboard/cpu0,
104# /org/openbmc/inventory/system/chassis/motherboard/cpu1]
Chris Austenb29d2e82016-06-07 12:25:35 -0500105################################################################
Gunnar Mills096cd562018-03-26 10:19:12 -0500106def get_inventory_fru_type_list(module_name, fru):
George Keishingd9b3e162022-08-18 23:28:35 -0500107 r"""
108 Return FRU URI(s) list of a given type from inventory.
109 """
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500110 inventory_list = []
Brian Ma139f1da2024-10-18 13:34:14 +0800111 m = load_source("module.name", module_name)
Chris Austenb29d2e82016-06-07 12:25:35 -0500112
Gunnar Millsbb398ac2016-11-14 11:50:22 -0600113 for i in m.FRU_INSTANCES.keys():
Patrick Williams20f38712022-12-08 06:18:26 -0600114 if m.FRU_INSTANCES[i]["fru_type"] == fru:
115 s = i.replace("<inventory_root>", m.INVENTORY_ROOT)
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500116 inventory_list.append(s)
Gunnar Millsbb398ac2016-11-14 11:50:22 -0600117
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500118 return inventory_list
Chris Austenb29d2e82016-06-07 12:25:35 -0500119
120
121################################################################
122# This will return the URI's of the FRU type that contain VPD
123#
124# i.e. get_vpd_inventory_list('../data/Palmetto.py', 'DIMM')
125#
126# [/org/openbmc/inventory/system/chassis/motherboard/dimm0,
127# /org/openbmc/inventory/system/chassis/motherboard/dimm1]
128################################################################
Gunnar Mills096cd562018-03-26 10:19:12 -0500129def get_vpd_inventory_list(module_name, fru):
George Keishingd9b3e162022-08-18 23:28:35 -0500130 r"""
131 Return VPD URI(s) list of a FRU type from inventory.
132 """
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500133 inventory_list = []
Brian Ma139f1da2024-10-18 13:34:14 +0800134 m = load_source("module.name", module_name)
Chris Austenb29d2e82016-06-07 12:25:35 -0500135
Patrick Williams20f38712022-12-08 06:18:26 -0600136 for i in m.ID_LOOKUP["FRU_STR"]:
137 x = m.ID_LOOKUP["FRU_STR"][i]
Chris Austenb29d2e82016-06-07 12:25:35 -0500138
Patrick Williams20f38712022-12-08 06:18:26 -0600139 if m.FRU_INSTANCES[x]["fru_type"] == fru:
140 s = x.replace("<inventory_root>", m.INVENTORY_ROOT)
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500141 inventory_list.append(s)
Gunnar Millsbb398ac2016-11-14 11:50:22 -0600142
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500143 return inventory_list
Chris Austenb29d2e82016-06-07 12:25:35 -0500144
145
146def call_keyword(keyword):
George Keishingd9b3e162022-08-18 23:28:35 -0500147 r"""
148 Return result of the execute robot keyword.
149 """
Chris Austenb29d2e82016-06-07 12:25:35 -0500150 return BuiltIn().run_keyword(keyword)
151
152
153def main():
George Keishingd9b3e162022-08-18 23:28:35 -0500154 r"""
155 Python main func call.
156 """
Patrick Williams20f38712022-12-08 06:18:26 -0600157 print(get_vpd_inventory_list("../data/Palmetto.py", "DIMM"))
Chris Austenb29d2e82016-06-07 12:25:35 -0500158
159
160if __name__ == "__main__":
Gunnar Mills096cd562018-03-26 10:19:12 -0500161 main()
Michael Walsh8b270ec2017-01-31 12:07:08 -0600162
163
Michael Walsh8b270ec2017-01-31 12:07:08 -0600164def get_mtr_report(host=""):
Michael Walsh8b270ec2017-01-31 12:07:08 -0600165 r"""
166 Get an mtr report and return it as a dictionary of dictionaries.
167
168 The key for the top level dictionary will be the host DNS name. The key
169 for the next level dictionary will be the field of a given row of the
170 report.
171
172 Example result:
173
174 report:
George Keishingfb4b1252017-06-15 00:05:45 -0500175 report[host_dummy-dnsname.com]:
176 report[host_dummy-dnsname.com][row_num]: 1
177 report[host_dummy-dnsname.com][host]: host_dummy-dnsname.com
178 report[host_dummy-dnsname.com][loss]: 0.0
179 report[host_dummy-dnsname.com][snt]: 10
180 report[host_dummy-dnsname.com][last]: 0.2
181 report[host_dummy-dnsname.com][avg]: 3.5
182 report[host_dummy-dnsname.com][best]: 0.2
183 report[host_dummy-dnsname.com][wrst]: 32.5
184 report[host_dummy-dnsname.com][stdev]: 10.2
185 report[bmc-dummy-dnsname.com]:
186 report[bmc-dummy-dnsname.com][row_num]: 2
187 report[bmc-dummy-dnsname.com][host]: bmc-dummy-dnsname.com
188 report[bmc-dummy-dnsname.com][loss]: 0.0
189 report[bmc-dummy-dnsname.com][snt]: 10
190 report[bmc-dummy-dnsname.com][last]: 0.5
191 report[bmc-dummy-dnsname.com][avg]: 0.5
192 report[bmc-dummy-dnsname.com][best]: 0.5
193 report[bmc-dummy-dnsname.com][wrst]: 0.5
194 report[bmc-dummy-dnsname.com][stdev]: 0.0
Michael Walsh8b270ec2017-01-31 12:07:08 -0600195
196 Description of arguments:
197 host The DNS name or IP address to be passed to the mtr command.
198 """
199
Gunnar Millsacc7c562019-08-20 13:12:46 -0500200 # Run the mtr command. Exclude the header line. Trim leading space from
Michael Walsh8b270ec2017-01-31 12:07:08 -0600201 # each line. Change all multiple spaces delims to single space delims.
Patrick Williams20f38712022-12-08 06:18:26 -0600202 cmd_buf = (
203 "mtr --report "
204 + host
205 + " | tail -n +2 | sed -r -e 's/^[ ]+//g' -e 's/[ ]+/ /g'"
206 )
207 sub_proc = subprocess.Popen(
208 cmd_buf, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
209 )
Michael Walsh8b270ec2017-01-31 12:07:08 -0600210 out_buf, err_buf = sub_proc.communicate()
211 shell_rc = sub_proc.returncode
manimozhik6abea652023-11-09 07:05:16 +0000212 out_buf = out_buf.decode("utf-8")
Michael Walsh8b270ec2017-01-31 12:07:08 -0600213
214 # Split the output by line.
Patrick Williams20f38712022-12-08 06:18:26 -0600215 rows = out_buf.rstrip("\n").split("\n")
Michael Walsh8b270ec2017-01-31 12:07:08 -0600216
217 # Initialize report dictionary.
218 report = DotDict()
219 for row in rows:
220 # Process each row of mtr output.
221 # Create a list of fields by splitting on space delimiter.
222 row_list = row.split(" ")
223 # Create dictionary for the row.
224 row = DotDict()
Patrick Williams20f38712022-12-08 06:18:26 -0600225 row["row_num"] = row_list[0].rstrip(".")
226 row["host"] = row_list[1]
227 row["loss"] = row_list[2].rstrip("%")
228 row["snt"] = row_list[3]
229 row["last"] = row_list[4]
230 row["avg"] = row_list[5]
231 row["best"] = row_list[6]
232 row["wrst"] = row_list[7]
233 row["stdev"] = row_list[8]
234 report[row["host"]] = row
Michael Walsh8b270ec2017-01-31 12:07:08 -0600235
236 # Return the full report as dictionary of dictionaries.
237 return report
238
Michael Walsh8b270ec2017-01-31 12:07:08 -0600239
Michael Walsh8b270ec2017-01-31 12:07:08 -0600240def get_mtr_row(host=""):
Michael Walsh8b270ec2017-01-31 12:07:08 -0600241 r"""
242 Run an mtr report and get a specified row and return it as a dictionary.
243
244 Example result:
245
246 row:
247 row[row_num]: 2
George Keishingfb4b1252017-06-15 00:05:45 -0500248 row[host]: bmc-dummy-dnsname.com
Michael Walsh8b270ec2017-01-31 12:07:08 -0600249 row[loss]: 0.0
250 row[snt]: 10
251 row[last]: 0.5
252 row[avg]: 0.5
253 row[best]: 0.4
254 row[wrst]: 0.7
255 row[stdev]: 0.1
256
257 Description of arguments:
258 host The DNS name or IP address to be passed to the mtr command as
259 well as the indicating which row of the report to return.
260 """
261
262 report = get_mtr_report(host)
263
264 # The max length of host in output is 28 chars.
265 row = [value for key, value in report.items() if host[0:28] in key][0]
266
267 return row
268
George Keishingefa97352017-03-13 07:13:03 -0500269
George Keishingefa97352017-03-13 07:13:03 -0500270def list_to_set(fru_list=""):
271 r"""
272 Pack the list into a set tuple and return.
273
274 It may seem that this function is rather trivial. However, it simplifies
275 the code and improves robot program readability and achieve the result
276 required.
277
278 Example result:
279
280 set(['Version', 'PartNumber', 'SerialNumber', 'FieldReplaceable',
281 'BuildDate', 'Present', 'Manufacturer', 'PrettyName', 'Cached', 'Model'])
282
283 # Description of arguments.
284 fru_list List of FRU's elements.
285 """
286 return set(fru_list)
287
George Keishing81ae45b2017-09-28 14:05:04 -0500288
289def min_list_value(value_list):
290 r"""
291 Returns the element from the list with minimum value.
292 """
293 return min(value_list)
nagarjunb2287138e62022-04-19 16:49:16 +0530294
295
296def convert_lsb_to_msb(string):
297 r"""
298 Reverse given string (From LSB first to MSB first) and converts to HEX.
299
George Keishing86d85f42022-08-18 23:02:22 -0500300 Input string 0a 00
nagarjunb2287138e62022-04-19 16:49:16 +0530301 Return string 0a
302 """
303 datalist = string.split(" ")
304 new_list = datalist[::-1]
305 new_string = "".join([str(element) for element in new_list])
306 return int(new_string, 16)
307
308
309def add_prefix_to_string(string, prefix):
310 r"""
311 Add given prefix to the string and return string.
312
313 Input string 0a 01
314 Return string 0x0a 0x01
315 """
Patrick Williams20f38712022-12-08 06:18:26 -0600316 prefix_string = ""
nagarjunb2287138e62022-04-19 16:49:16 +0530317 data_list = string.strip().split(" ")
318 for item in data_list:
Patrick Williams20f38712022-12-08 06:18:26 -0600319 prefix_string += prefix + item + " "
nagarjunb2287138e62022-04-19 16:49:16 +0530320 return prefix_string.strip()
George Keishing8ef9e722023-01-18 10:21:31 +0530321
322
323def get_value_from_nested_dict(key, nested_dict):
324 r"""
325 Returns the key value from the nested dictionary.
326
327 key Key value of the dictionary to look up.
328 nested_dict Dictionary data.
329 """
330 result = []
331 for k, v in nested_dict.items():
332 if k == key:
333 result.append(v)
334 elif isinstance(v, dict) and k != key:
335 result += get_value_from_nested_dict(key, v)
336
337 return result