1#!/usr/bin/env python3 -u 2 3r""" 4Generic utility functions. 5""" 6import imp 7import string 8import random 9import subprocess 10from robot.libraries.BuiltIn import BuiltIn 11from robot.utils import DotDict 12 13 14def random_mac(): 15 r""" 16 Return random mac address in the following format. 17 Example: 00:01:6C:80:02:78 18 """ 19 return ":".join(map(lambda x: "%02x" % x, (random.randint(0x00, 0xff) 20 for _ in range(6)))) 21 22 23def random_ip(): 24 r""" 25 Return random ip address in the following format. 26 Example: 9.3.128.100 27 """ 28 return ".".join(map(str, (random.randint(0, 255) 29 for _ in range(4)))) 30 31 32def get_sensor(module_name, value): 33 r""" 34 Return sensor matched ID name. 35 """ 36 m = imp.load_source('module.name', module_name) 37 38 for i in m.ID_LOOKUP['SENSOR']: 39 40 if m.ID_LOOKUP['SENSOR'][i] == value: 41 return i 42 43 return 0xFF 44 45 46def get_inventory_sensor(module_name, value): 47 r""" 48 Return sensor matched ID name from inventory. 49 """ 50 m = imp.load_source('module.name', module_name) 51 52 value = string.replace(value, m.INVENTORY_ROOT, '<inventory_root>') 53 54 for i in m.ID_LOOKUP['SENSOR']: 55 56 if m.ID_LOOKUP['SENSOR'][i] == value: 57 return i 58 59 return 0xFF 60 61 62################################################################ 63# This will return the URI's of the FRU type 64# 65# i.e. get_inventory_list('../data/Palmetto.py') 66# 67# [/org/openbmc/inventory/system/chassis/motherboard/cpu0/core0, 68# /org/openbmc/inventory/system/chassis/motherboard/dimm0] 69################################################################ 70def get_inventory_list(module_name): 71 r""" 72 Return all FRU URI(s) list available from inventory. 73 """ 74 75 inventory_list = [] 76 m = imp.load_source('module.name', module_name) 77 78 for i in m.ID_LOOKUP['FRU']: 79 s = m.ID_LOOKUP['FRU'][i] 80 s = s.replace('<inventory_root>', m.INVENTORY_ROOT) 81 inventory_list.append(s) 82 83 return inventory_list 84 85 86################################################################ 87# This will return the URI's of the FRU type 88# 89# i.e. get_inventory_fru_type_list('../data/Witherspoon.py', 'CPU') 90# 91# [/org/openbmc/inventory/system/chassis/motherboard/cpu0, 92# /org/openbmc/inventory/system/chassis/motherboard/cpu1] 93################################################################ 94def get_inventory_fru_type_list(module_name, fru): 95 r""" 96 Return FRU URI(s) list of a given type from inventory. 97 """ 98 inventory_list = [] 99 m = imp.load_source('module.name', module_name) 100 101 for i in m.FRU_INSTANCES.keys(): 102 if m.FRU_INSTANCES[i]['fru_type'] == fru: 103 s = i.replace('<inventory_root>', m.INVENTORY_ROOT) 104 inventory_list.append(s) 105 106 return inventory_list 107 108 109################################################################ 110# This will return the URI's of the FRU type that contain VPD 111# 112# i.e. get_vpd_inventory_list('../data/Palmetto.py', 'DIMM') 113# 114# [/org/openbmc/inventory/system/chassis/motherboard/dimm0, 115# /org/openbmc/inventory/system/chassis/motherboard/dimm1] 116################################################################ 117def get_vpd_inventory_list(module_name, fru): 118 r""" 119 Return VPD URI(s) list of a FRU type from inventory. 120 """ 121 inventory_list = [] 122 m = imp.load_source('module.name', module_name) 123 124 for i in m.ID_LOOKUP['FRU_STR']: 125 x = m.ID_LOOKUP['FRU_STR'][i] 126 127 if m.FRU_INSTANCES[x]['fru_type'] == fru: 128 s = x.replace('<inventory_root>', m.INVENTORY_ROOT) 129 inventory_list.append(s) 130 131 return inventory_list 132 133 134def call_keyword(keyword): 135 r""" 136 Return result of the execute robot keyword. 137 """ 138 return BuiltIn().run_keyword(keyword) 139 140 141def main(): 142 r""" 143 Python main func call. 144 """ 145 print(get_vpd_inventory_list('../data/Palmetto.py', 'DIMM')) 146 147 148if __name__ == "__main__": 149 main() 150 151 152def get_mtr_report(host=""): 153 r""" 154 Get an mtr report and return it as a dictionary of dictionaries. 155 156 The key for the top level dictionary will be the host DNS name. The key 157 for the next level dictionary will be the field of a given row of the 158 report. 159 160 Example result: 161 162 report: 163 report[host_dummy-dnsname.com]: 164 report[host_dummy-dnsname.com][row_num]: 1 165 report[host_dummy-dnsname.com][host]: host_dummy-dnsname.com 166 report[host_dummy-dnsname.com][loss]: 0.0 167 report[host_dummy-dnsname.com][snt]: 10 168 report[host_dummy-dnsname.com][last]: 0.2 169 report[host_dummy-dnsname.com][avg]: 3.5 170 report[host_dummy-dnsname.com][best]: 0.2 171 report[host_dummy-dnsname.com][wrst]: 32.5 172 report[host_dummy-dnsname.com][stdev]: 10.2 173 report[bmc-dummy-dnsname.com]: 174 report[bmc-dummy-dnsname.com][row_num]: 2 175 report[bmc-dummy-dnsname.com][host]: bmc-dummy-dnsname.com 176 report[bmc-dummy-dnsname.com][loss]: 0.0 177 report[bmc-dummy-dnsname.com][snt]: 10 178 report[bmc-dummy-dnsname.com][last]: 0.5 179 report[bmc-dummy-dnsname.com][avg]: 0.5 180 report[bmc-dummy-dnsname.com][best]: 0.5 181 report[bmc-dummy-dnsname.com][wrst]: 0.5 182 report[bmc-dummy-dnsname.com][stdev]: 0.0 183 184 Description of arguments: 185 host The DNS name or IP address to be passed to the mtr command. 186 """ 187 188 # Run the mtr command. Exclude the header line. Trim leading space from 189 # each line. Change all multiple spaces delims to single space delims. 190 cmd_buf = "mtr --report " + host +\ 191 " | tail -n +2 | sed -r -e 's/^[ ]+//g' -e 's/[ ]+/ /g'" 192 sub_proc = subprocess.Popen(cmd_buf, shell=True, stdout=subprocess.PIPE, 193 stderr=subprocess.STDOUT) 194 out_buf, err_buf = sub_proc.communicate() 195 shell_rc = sub_proc.returncode 196 197 # Split the output by line. 198 rows = out_buf.rstrip('\n').split("\n") 199 200 # Initialize report dictionary. 201 report = DotDict() 202 for row in rows: 203 # Process each row of mtr output. 204 # Create a list of fields by splitting on space delimiter. 205 row_list = row.split(" ") 206 # Create dictionary for the row. 207 row = DotDict() 208 row['row_num'] = row_list[0].rstrip('.') 209 row['host'] = row_list[1] 210 row['loss'] = row_list[2].rstrip('%') 211 row['snt'] = row_list[3] 212 row['last'] = row_list[4] 213 row['avg'] = row_list[5] 214 row['best'] = row_list[6] 215 row['wrst'] = row_list[7] 216 row['stdev'] = row_list[8] 217 report[row['host']] = row 218 219 # Return the full report as dictionary of dictionaries. 220 return report 221 222 223def get_mtr_row(host=""): 224 r""" 225 Run an mtr report and get a specified row and return it as a dictionary. 226 227 Example result: 228 229 row: 230 row[row_num]: 2 231 row[host]: bmc-dummy-dnsname.com 232 row[loss]: 0.0 233 row[snt]: 10 234 row[last]: 0.5 235 row[avg]: 0.5 236 row[best]: 0.4 237 row[wrst]: 0.7 238 row[stdev]: 0.1 239 240 Description of arguments: 241 host The DNS name or IP address to be passed to the mtr command as 242 well as the indicating which row of the report to return. 243 """ 244 245 report = get_mtr_report(host) 246 247 # The max length of host in output is 28 chars. 248 row = [value for key, value in report.items() if host[0:28] in key][0] 249 250 return row 251 252 253def list_to_set(fru_list=""): 254 r""" 255 Pack the list into a set tuple and return. 256 257 It may seem that this function is rather trivial. However, it simplifies 258 the code and improves robot program readability and achieve the result 259 required. 260 261 Example result: 262 263 set(['Version', 'PartNumber', 'SerialNumber', 'FieldReplaceable', 264 'BuildDate', 'Present', 'Manufacturer', 'PrettyName', 'Cached', 'Model']) 265 266 # Description of arguments. 267 fru_list List of FRU's elements. 268 """ 269 return set(fru_list) 270 271 272def min_list_value(value_list): 273 r""" 274 Returns the element from the list with minimum value. 275 """ 276 return min(value_list) 277 278 279def convert_lsb_to_msb(string): 280 r""" 281 Reverse given string (From LSB first to MSB first) and converts to HEX. 282 283 Input string 0a 00 284 Return string 0a 285 """ 286 datalist = string.split(" ") 287 new_list = datalist[::-1] 288 new_string = "".join([str(element) for element in new_list]) 289 return int(new_string, 16) 290 291 292def add_prefix_to_string(string, prefix): 293 r""" 294 Add given prefix to the string and return string. 295 296 Input string 0a 01 297 Return string 0x0a 0x01 298 """ 299 prefix_string = '' 300 data_list = string.strip().split(" ") 301 for item in data_list: 302 prefix_string += prefix + item + ' ' 303 return prefix_string.strip() 304