#!/usr/bin/env python3 -u r""" Generic utility functions. """ import imp import random import string import subprocess from robot.libraries.BuiltIn import BuiltIn from robot.utils import DotDict def random_mac(): r""" Return random mac address in the following format. Example: 00:01:6C:80:02:78 """ return ":".join( map( lambda x: "%02x" % x, (random.randint(0x00, 0xFF) for _ in range(6)), ) ) def random_ip(): r""" Return random ip address in the following format. Example: 9.3.128.100 """ return ".".join(map(str, (random.randint(0, 255) for _ in range(4)))) def get_sensor(module_name, value): r""" Return sensor matched ID name. """ m = imp.load_source("module.name", module_name) for i in m.ID_LOOKUP["SENSOR"]: if m.ID_LOOKUP["SENSOR"][i] == value: return i return 0xFF def get_inventory_sensor(module_name, value): r""" Return sensor matched ID name from inventory. """ m = imp.load_source("module.name", module_name) value = string.replace(value, m.INVENTORY_ROOT, "") for i in m.ID_LOOKUP["SENSOR"]: if m.ID_LOOKUP["SENSOR"][i] == value: return i return 0xFF ################################################################ # This will return the URI's of the FRU type # # i.e. get_inventory_list('../data/Palmetto.py') # # [/org/openbmc/inventory/system/chassis/motherboard/cpu0/core0, # /org/openbmc/inventory/system/chassis/motherboard/dimm0] ################################################################ def get_inventory_list(module_name): r""" Return all FRU URI(s) list available from inventory. """ inventory_list = [] m = imp.load_source("module.name", module_name) for i in m.ID_LOOKUP["FRU"]: s = m.ID_LOOKUP["FRU"][i] s = s.replace("", m.INVENTORY_ROOT) inventory_list.append(s) return inventory_list ################################################################ # This will return the URI's of the FRU type # # i.e. get_inventory_fru_type_list('../data/Witherspoon.py', 'CPU') # # [/org/openbmc/inventory/system/chassis/motherboard/cpu0, # /org/openbmc/inventory/system/chassis/motherboard/cpu1] ################################################################ def get_inventory_fru_type_list(module_name, fru): r""" Return FRU URI(s) list of a given type from inventory. """ inventory_list = [] m = imp.load_source("module.name", module_name) for i in m.FRU_INSTANCES.keys(): if m.FRU_INSTANCES[i]["fru_type"] == fru: s = i.replace("", m.INVENTORY_ROOT) inventory_list.append(s) return inventory_list ################################################################ # This will return the URI's of the FRU type that contain VPD # # i.e. get_vpd_inventory_list('../data/Palmetto.py', 'DIMM') # # [/org/openbmc/inventory/system/chassis/motherboard/dimm0, # /org/openbmc/inventory/system/chassis/motherboard/dimm1] ################################################################ def get_vpd_inventory_list(module_name, fru): r""" Return VPD URI(s) list of a FRU type from inventory. """ inventory_list = [] m = imp.load_source("module.name", module_name) for i in m.ID_LOOKUP["FRU_STR"]: x = m.ID_LOOKUP["FRU_STR"][i] if m.FRU_INSTANCES[x]["fru_type"] == fru: s = x.replace("", m.INVENTORY_ROOT) inventory_list.append(s) return inventory_list def call_keyword(keyword): r""" Return result of the execute robot keyword. """ return BuiltIn().run_keyword(keyword) def main(): r""" Python main func call. """ print(get_vpd_inventory_list("../data/Palmetto.py", "DIMM")) if __name__ == "__main__": main() def get_mtr_report(host=""): r""" Get an mtr report and return it as a dictionary of dictionaries. The key for the top level dictionary will be the host DNS name. The key for the next level dictionary will be the field of a given row of the report. Example result: report: report[host_dummy-dnsname.com]: report[host_dummy-dnsname.com][row_num]: 1 report[host_dummy-dnsname.com][host]: host_dummy-dnsname.com report[host_dummy-dnsname.com][loss]: 0.0 report[host_dummy-dnsname.com][snt]: 10 report[host_dummy-dnsname.com][last]: 0.2 report[host_dummy-dnsname.com][avg]: 3.5 report[host_dummy-dnsname.com][best]: 0.2 report[host_dummy-dnsname.com][wrst]: 32.5 report[host_dummy-dnsname.com][stdev]: 10.2 report[bmc-dummy-dnsname.com]: report[bmc-dummy-dnsname.com][row_num]: 2 report[bmc-dummy-dnsname.com][host]: bmc-dummy-dnsname.com report[bmc-dummy-dnsname.com][loss]: 0.0 report[bmc-dummy-dnsname.com][snt]: 10 report[bmc-dummy-dnsname.com][last]: 0.5 report[bmc-dummy-dnsname.com][avg]: 0.5 report[bmc-dummy-dnsname.com][best]: 0.5 report[bmc-dummy-dnsname.com][wrst]: 0.5 report[bmc-dummy-dnsname.com][stdev]: 0.0 Description of arguments: host The DNS name or IP address to be passed to the mtr command. """ # Run the mtr command. Exclude the header line. Trim leading space from # each line. Change all multiple spaces delims to single space delims. cmd_buf = ( "mtr --report " + host + " | tail -n +2 | sed -r -e 's/^[ ]+//g' -e 's/[ ]+/ /g'" ) sub_proc = subprocess.Popen( cmd_buf, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) out_buf, err_buf = sub_proc.communicate() shell_rc = sub_proc.returncode out_buf = out_buf.decode("utf-8") # Split the output by line. rows = out_buf.rstrip("\n").split("\n") # Initialize report dictionary. report = DotDict() for row in rows: # Process each row of mtr output. # Create a list of fields by splitting on space delimiter. row_list = row.split(" ") # Create dictionary for the row. row = DotDict() row["row_num"] = row_list[0].rstrip(".") row["host"] = row_list[1] row["loss"] = row_list[2].rstrip("%") row["snt"] = row_list[3] row["last"] = row_list[4] row["avg"] = row_list[5] row["best"] = row_list[6] row["wrst"] = row_list[7] row["stdev"] = row_list[8] report[row["host"]] = row # Return the full report as dictionary of dictionaries. return report def get_mtr_row(host=""): r""" Run an mtr report and get a specified row and return it as a dictionary. Example result: row: row[row_num]: 2 row[host]: bmc-dummy-dnsname.com row[loss]: 0.0 row[snt]: 10 row[last]: 0.5 row[avg]: 0.5 row[best]: 0.4 row[wrst]: 0.7 row[stdev]: 0.1 Description of arguments: host The DNS name or IP address to be passed to the mtr command as well as the indicating which row of the report to return. """ report = get_mtr_report(host) # The max length of host in output is 28 chars. row = [value for key, value in report.items() if host[0:28] in key][0] return row def list_to_set(fru_list=""): r""" Pack the list into a set tuple and return. It may seem that this function is rather trivial. However, it simplifies the code and improves robot program readability and achieve the result required. Example result: set(['Version', 'PartNumber', 'SerialNumber', 'FieldReplaceable', 'BuildDate', 'Present', 'Manufacturer', 'PrettyName', 'Cached', 'Model']) # Description of arguments. fru_list List of FRU's elements. """ return set(fru_list) def min_list_value(value_list): r""" Returns the element from the list with minimum value. """ return min(value_list) def convert_lsb_to_msb(string): r""" Reverse given string (From LSB first to MSB first) and converts to HEX. Input string 0a 00 Return string 0a """ datalist = string.split(" ") new_list = datalist[::-1] new_string = "".join([str(element) for element in new_list]) return int(new_string, 16) def add_prefix_to_string(string, prefix): r""" Add given prefix to the string and return string. Input string 0a 01 Return string 0x0a 0x01 """ prefix_string = "" data_list = string.strip().split(" ") for item in data_list: prefix_string += prefix + item + " " return prefix_string.strip() def get_value_from_nested_dict(key, nested_dict): r""" Returns the key value from the nested dictionary. key Key value of the dictionary to look up. nested_dict Dictionary data. """ result = [] for k, v in nested_dict.items(): if k == key: result.append(v) elif isinstance(v, dict) and k != key: result += get_value_from_nested_dict(key, v) return result