1#!/usr/bin/env python3 2 3r""" 4PEL functions. 5""" 6 7import func_args as fa 8import bmc_ssh_utils as bsu 9import json 10import os 11import sys 12from robot.libraries.BuiltIn import BuiltIn 13 14base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 15sys.path.append(base_path + "/data/") 16 17import pel_variables 18 19 20class peltool_exception(Exception): 21 r""" 22 Base class for peltool related exceptions. 23 """ 24 25 def __init__(self, message): 26 self.message = message 27 super().__init__(self.message) 28 29 30def peltool(option_string, parse_json=True, **bsu_options): 31 r""" 32 Run peltool on the BMC with the caller's option string and return the result. 33 34 Example: 35 36 ${pel_results}= Peltool -l 37 Rprint Vars pel_results 38 39 pel_results: 40 [0x50000031]: 41 [CompID]: 0x1000 42 [PLID]: 0x50000031 43 [Subsystem]: BMC Firmware 44 [Message]: An application had an internal failure 45 [SRC]: BD8D1002 46 [Commit Time]: 02/25/2020 04:51:31 47 [Sev]: Unrecoverable Error 48 [CreatorID]: BMC 49 50 Description of argument(s): 51 option_string A string of options which are to be processed by the peltool command. 52 parse_json Indicates that the raw JSON data should parsed into a list of 53 dictionaries. 54 bsu_options Options to be passed directly to bmc_execute_command. See its prolog for 55 details. 56 """ 57 58 bsu_options = fa.args_to_objects(bsu_options) 59 out_buf, stderr, rc = bsu.bmc_execute_command('peltool ' + option_string, **bsu_options) 60 if parse_json: 61 try: 62 return json.loads(out_buf) 63 except ValueError: 64 return {} 65 return out_buf 66 67 68def get_pel_data_from_bmc(include_hidden_pels=False, 69 include_informational_pels=False): 70 r""" 71 Returns PEL data from BMC else throws exception. 72 73 Description of arguments: 74 include_hidden_pels True/False (default: False). 75 Set True to get hidden PELs else False. 76 include_informational_pels True/False (default: False). 77 Set True to get informational PELs else False. 78 """ 79 try: 80 pel_cmd = " -l" 81 if include_hidden_pels: 82 pel_cmd = pel_cmd + " -h" 83 if include_informational_pels: 84 pel_cmd = pel_cmd + " -f" 85 pel_data = peltool(pel_cmd) 86 if not pel_data: 87 print("No PEL data present in BMC ...") 88 except Exception as e: 89 raise peltool_exception("Failed to get PEL data from BMC : " + str(e)) 90 return pel_data 91 92 93def fetch_all_pel_ids_for_src(src_id, severity, include_hidden_pels=False): 94 r""" 95 Fetch all PEL IDs for the input SRC ID based on the severity type 96 in the list format. 97 98 Description of arguments: 99 src_id SRC ID (e.g. BCXXYYYY). 100 severity PEL severity (e.g. "Predictive Error" 101 "Recovered Error"). 102 include_hidden_pels True/False (default: False). 103 Set True to get hidden PELs else False. 104 """ 105 106 try: 107 src_pel_ids = [] 108 pel_data = get_pel_data_from_bmc(include_hidden_pels) 109 pel_id_list = pel_data.keys() 110 for pel_id in pel_id_list: 111 # Check if required SRC ID with severity is present 112 if ((pel_data[pel_id]["SRC"] == src_id) and (pel_data[pel_id]["Sev"] == severity)): 113 src_pel_ids.append(pel_id) 114 115 if not src_pel_ids: 116 raise peltool_exception(src_id + " with severity " + severity + " not present") 117 except Exception as e: 118 raise peltool_exception("Failed to fetch PEL ID for required SRC : " + str(e)) 119 return src_pel_ids 120 121 122def verify_src_signature_and_threshold(pel_id, attn_type, signature_desc, th_limit): 123 r""" 124 Verifies SRC details for the given PEL ID based on the required 125 attention type, signature description, threshold limits. 126 127 Description of arguments: 128 pel_id PEL ID for the required SRC details to verify. 129 attn_type Attention type (e.g. RE, CS, UNIT_CS). 130 signature_desc Signature description of the error inject. 131 th_limit Threshold limit (e.g. 1, 5, 32). 132 """ 133 134 try: 135 pel_cmd = " -i " + pel_id 136 src_data = peltool(pel_cmd) 137 src_dict = src_data["Primary SRC"]["SRC Details"] 138 usr_data = src_data["User Data 1"] 139 140 # Example for signature in recoverable error 141 # 142 # "SRC Details": { 143 # "Attention Type": "RECOVERABLE", 144 # "Node": 0, 145 # "Target Type": "TYPE_OMIC", 146 # "Target Instance": 0, 147 # "Signature": "MC_OMI_DL_FIR[1]: OMI-DL0 UE on data flit" 148 # } 149 if (attn_type == "RE"): 150 if (src_dict["Attention Type"] != "RECOVERABLE"): 151 raise peltool_exception("Required Attention type " + attn_type + " not found") 152 153 # Example for signature in system checkstop error 154 # 155 # "SRC Details": { 156 # "Primary Attention": "system checkstop", 157 # "Signature Description": { 158 # "Chip Desc": "node 0 proc 0 (P10 2.0)", 159 # "Signature": "EQ_L2_FIR(0)[7] L2 directory read UE", 160 # "Attn Type": "checkstop" 161 # } 162 163 elif (attn_type == "CS"): 164 if (src_dict["Primary Attention"] != "system checkstop"): 165 raise peltool_exception("Required Attention type " + attn_type + " not found") 166 167 elif (attn_type == "UNIT_CS"): 168 if (src_dict["Attention Type"] != "UNIT_CS"): 169 raise peltool_exception("Required Attention type " + attn_type + " not found") 170 else: 171 raise peltool_exception("Required Attention type " + attn_type + " not found") 172 173 if signature_desc not in src_dict["Signature"]: 174 raise peltool_exception("Required Signature " + signature_desc + " not found") 175 176 if (int(th_limit) != usr_data["Error Count"]): 177 raise peltool_exception("Required Threshold limit " + th_limit + " not found") 178 179 except Exception as e: 180 raise peltool_exception("Failed to verify SRC details : " + str(e)) 181 return True 182 183 184def fetch_all_src(include_hidden_pels=False): 185 r""" 186 Fetch all SRC IDs from peltool in the list format. 187 188 include_hidden_pels True/False (default: False). 189 Set True to get hidden PELs else False. 190 """ 191 try: 192 src_id = [] 193 pel_data = get_pel_data_from_bmc(include_hidden_pels) 194 if pel_data: 195 pel_id_list = pel_data.keys() 196 for pel_id in pel_id_list: 197 src_id.append(pel_data[pel_id]["SRC"]) 198 print("SRC IDs: " + str(src_id)) 199 except Exception as e: 200 raise peltool_exception("Failed to fetch all SRCs : " + str(e)) 201 return src_id 202 203 204def check_for_unexpected_src(unexpected_src_list=[], include_hidden_pels=False): 205 r""" 206 From the given unexpected SRC list, check if any unexpected SRC created 207 on the BMC. Returns 0 if no SRC found else throws exception. 208 209 Description of arguments: 210 unexpected_src_list Give unexpected SRCs in the list format. 211 e.g.: ["BBXXYYYY", "AAXXYYYY"]. 212 213 include_hidden_pels True/False (default: False). 214 Set True to get hidden PELs else False. 215 """ 216 try: 217 unexpected_src_count = 0 218 if not unexpected_src_list: 219 print("Unexpected SRC list is empty.") 220 src_data = fetch_all_src(include_hidden_pels) 221 for src in unexpected_src_list: 222 if src in src_data: 223 print("Found an unexpected SRC : " + src) 224 unexpected_src_count = unexpected_src_count + 1 225 if (unexpected_src_count >= 1): 226 raise peltool_exception("Unexpected SRC found.") 227 228 except Exception as e: 229 raise peltool_exception("Failed to verify unexpected SRC list : " + str(e)) 230 return unexpected_src_count 231 232 233def filter_unexpected_srcs(expected_srcs=None): 234 r""" 235 Return list of SRCs found in BMC after filtering expected SRCs. 236 If expected_srcs is None then all SRCs found in system are returned. 237 238 Description of arguments: 239 expected_srcs List of expected SRCs. E.g. ["BBXXYYYY", "AAXXYYYY"]. 240 """ 241 242 srcs_found = fetch_all_src() 243 if not expected_srcs: 244 expected_srcs = [] 245 print(expected_srcs) 246 return list(set(srcs_found) - set(expected_srcs)) 247 248 249def get_bmc_event_log_id_for_pel(pel_id): 250 r""" 251 Return BMC event log ID for the given PEL ID. 252 253 Description of arguments: 254 pel_id PEL ID. E.g. 0x50000021. 255 """ 256 257 pel_data = peltool("-i " + pel_id) 258 print(pel_data) 259 bmc_id_for_pel = pel_data["Private Header"]["BMC Event Log Id"] 260 return bmc_id_for_pel 261