1#!/usr/bin/env python3 2 3r""" 4Check for stop conditions. Return code of 2 if stop conditions are found. 5""" 6 7import argparse 8import os 9import re 10import subprocess 11import sys 12 13from gen_arg import * 14from gen_call_robot import * 15from gen_cmd import * 16from gen_misc import * 17from gen_plug_in_utils import * 18from gen_print import * 19from gen_valid import * 20 21# Set exit_on_error for gen_valid functions. 22set_exit_on_error(True) 23 24# Initialize default plug-in parms.. 25STOP_REST_FAIL = 0 26STOP_COMMAND = "" 27stop_test_rc = 2 28STOP_VERIFY_HARDWARE_FAIL = 0 29 30 31# Create parser object to process command line parameters and args. 32parser = argparse.ArgumentParser( 33 usage="%(prog)s [OPTIONS]", 34 description='If the "Stop" plug-in is selected by the user, %(prog)s' 35 + " is called by OBMC Boot Test after each boot test. If %(prog)s returns" 36 + " " 37 + str(stop_test_rc) 38 + ", then OBMC Boot Test will stop. The user" 39 + " may set environment variable STOP_COMMAND to contain any valid bash" 40 + " command or program. %(prog)s will run this stop command. If the stop" 41 + " command returns non-zero, then %(prog)s will return " 42 + str(stop_test_rc) 43 + ". %(prog)s recognizes some special values for" 44 + ' STOP_COMMAND: 1) "FAIL" means that OBMC Boot Test should stop' 45 + ' whenever a boot test fails. 2) "ALL" means that OBMC Boot Test' 46 + " should stop after any boot test. If environment variable" 47 + " STOP_REST_FAIL is set, OBMC Boot Test will stop if REST commands are" 48 + " no longer working.", 49 formatter_class=argparse.ArgumentDefaultsHelpFormatter, 50 prefix_chars="-+", 51) 52 53# The stock_list will be passed to gen_get_options. We populate it with the names of stock parm options we 54# want. These stock parms are pre-defined by gen_get_options. 55stock_list = [ 56 ("test_mode", get_plug_default("test_mode", 0)), 57 ("quiet", get_plug_default("quiet", 0)), 58 ("debug", get_plug_default("debug", 0)), 59] 60 61 62def exit_function(signal_number=0, frame=None): 63 r""" 64 Execute whenever the program ends normally or with the signals that we catch (i.e. TERM, INT). 65 66 This function will be called by gen_exit_function(). 67 """ 68 69 process_robot_output_files() 70 71 72def validate_parms(): 73 r""" 74 Validate program parameters, etc. 75 76 This function will be called by gen_setup(). 77 """ 78 79 get_plug_vars() 80 81 82def stop_check(): 83 r""" 84 Stop this program with the stop check return code. 85 """ 86 87 if MASTER_PID != PROGRAM_PID: 88 save_plug_in_value(stop_check_rc=stop_test_rc) 89 exit(stop_test_rc) 90 91 92def rest_fail(): 93 r""" 94 If STOP_REST_FAIL, then this function will determine whether REST commands to the target are working. If 95 not, this function will stop the program by returning stop_test_rc. 96 """ 97 98 if not STOP_REST_FAIL: 99 return 100 101 REDFISH_SUPPORT_TRANS_STATE = int( 102 os.environ.get("REDFISH_SUPPORT_TRANS_STATE", 0) 103 ) or int(os.environ.get("AUTOBOOT_REDFISH_SUPPORT_TRANS_STATE", 0)) 104 105 if REDFISH_SUPPORT_TRANS_STATE: 106 interface = "redfish" 107 else: 108 interface = "rest" 109 110 print_timen("Checking to see whether %s commands are working." % interface) 111 init_robot_out_parms(get_plug_in_package_name() + "." + pgm_name + ".") 112 lib_file_path = ( 113 init_robot_file_path("lib/utils.robot") 114 + ":" 115 + init_robot_file_path("lib/gen_robot_print.py") 116 ) 117 set_mod_global(lib_file_path) 118 timeout = "0 seconds" 119 interval = "1 second" 120 keyword_string = ( 121 "${match_state}= Create Dictionary %s=1 ;" % interface 122 + " ${state}= Wait State ${match_state} " 123 + timeout 124 + " " 125 + interval 126 + " quiet=${1} ; Rpvar state" 127 ) 128 set_mod_global(keyword_string) 129 cmd_buf = create_robot_cmd_string( 130 "extended/run_keyword.robot", 131 OPENBMC_HOST, 132 SSH_PORT, 133 HTTPS_PORT, 134 REST_USERNAME, 135 REST_PASSWORD, 136 OPENBMC_USERNAME, 137 OPENBMC_PASSWORD, 138 REDFISH_SUPPORT_TRANS_STATE, 139 keyword_string, 140 lib_file_path, 141 quiet, 142 test_mode, 143 debug, 144 outputdir, 145 output, 146 log, 147 report, 148 loglevel, 149 ) 150 if not robot_cmd_fnc(cmd_buf): 151 print_timen( 152 "The caller wishes to stop test execution if %s commands are" 153 " failing." % interface 154 ) 155 stop_check() 156 print_timen( 157 "%s commands are working so no reason as of yet to stop the test." 158 % interface 159 ) 160 161 162def esel_stop_check(): 163 r""" 164 Run the esel_stop_check program to determine whether any eSEL entries found warrant stopping the test 165 run. See esel_stop_check help text for details. 166 """ 167 168 if STOP_ESEL_STOP_FILE_PATH == "": 169 return 170 171 cmd_buf = ( 172 "esel_stop_check --esel_stop_file_path=" + STOP_ESEL_STOP_FILE_PATH 173 ) 174 shell_rc, out_buf = shell_cmd(cmd_buf, show_err=0) 175 if shell_rc == stop_test_rc: 176 print_timen( 177 "The caller wishes to stop test execution based on the presence of" 178 " certain esel entries." 179 ) 180 stop_check() 181 182 183def pel_stop_check(): 184 r""" 185 Determine whether any PEL entries found warrant stopping the test 186 run. 187 """ 188 189 if STOP_PEL_STOP_FILE_PATH == "": 190 return 191 192 pel_txt_file_path = ( 193 os.environ.get("AUTOBOOT_FFDC_DIR_PATH", "") 194 + os.environ.get("AUTOBOOT_FFDC_PREFIX", "") 195 + "PEL_logs_list.json" 196 ) 197 198 if not os.path.isfile(pel_txt_file_path): 199 qprint_timen( 200 "The following file was not present so no further" 201 + " action will be taken." 202 ) 203 qprint_var(pel_txt_file_path) 204 return 205 206 default_stop_dir_path = "/afs/rchland.ibm.com/projects/esw/dvt/" 207 208 # If pel_stop_file_path is unqualified and cannot be found, pre-pend 209 # default_stop_dir_path for the user. 210 pel_stop_file_path = os.environ.get("STOP_PEL_STOP_FILE_PATH", "") 211 if not os.path.isfile(pel_stop_file_path) and os.path.isfile( 212 default_stop_dir_path + pel_stop_file_path 213 ): 214 pel_stop_file_path = default_stop_dir_path + pel_stop_file_path 215 qprint_timen("Using default stop file path.") 216 qprint_var(pel_stop_file_path) 217 218 # First, read the file in and convert it to a list. 219 pel_stop_list = file_to_list(pel_stop_file_path, newlines=0, comments=0) 220 221 if len(pel_stop_list) == 0: 222 print_timen( 223 "There are no records to process in " + pel_stop_file_path + "." 224 ) 225 return 226 227 pel_all_list = file_to_list(pel_txt_file_path, newlines=0, comments=0) 228 229 if len(pel_all_list) == 0: 230 print_timen( 231 "There are no records to process in " + pel_txt_file_path + "." 232 ) 233 return 234 235 for stop_pel in pel_stop_list: 236 for pel_all in pel_all_list: 237 pel_match = re.search(".*SRC.*" + stop_pel + ".*", pel_all) 238 if pel_match: 239 print_timen( 240 "The caller wishes to stop test execution based on " 241 + "the presence of certain PEL entries." 242 ) 243 stop_check() 244 245 246def main(): 247 gen_setup() 248 249 print_plug_in_header() 250 251 if STOP_COMMAND.upper() == "FAIL": 252 if AUTOBOOT_BOOT_SUCCESS == "0": 253 print_timen("The caller wishes to stop after each boot failure.") 254 stop_check() 255 elif STOP_COMMAND.upper() == "ALL": 256 print_timen("The caller wishes to stop after each boot test.") 257 stop_check() 258 elif len(STOP_COMMAND) > 0: 259 shell_rc, out_buf = shell_cmd(STOP_COMMAND, quiet=quiet, show_err=0) 260 if shell_rc != 0: 261 print_timen("The caller wishes to stop test execution.") 262 stop_check() 263 264 rest_fail() 265 266 esel_stop_check() 267 268 pel_stop_check() 269 270 if STOP_VERIFY_HARDWARE_FAIL: 271 hardware_error_found = restore_plug_in_value(0, "Verify_hardware") 272 if hardware_error_found: 273 print_timen( 274 "The caller wishes to stop test execution when the" 275 " Verify_hardware plug-in detects a" 276 + " hardware error." 277 ) 278 stop_check() 279 280 qprint_timen("The caller does not wish to stop the test run.") 281 282 283main() 284