10bbd860fSMichael Walsh#!/usr/bin/env python 20bbd860fSMichael Walsh 30bbd860fSMichael Walshr""" 40bbd860fSMichael WalshThis module is the python counterpart to obmc_boot_test. 50bbd860fSMichael Walsh""" 60bbd860fSMichael Walsh 70b93fbf8SMichael Walshimport os 80b93fbf8SMichael Walshimport imp 90b93fbf8SMichael Walshimport time 100b93fbf8SMichael Walshimport glob 110b93fbf8SMichael Walshimport random 120ad0f7f8SMichael Walshimport re 13f566fb1fSMichael Walshimport signal 14d54bbc22SGeorge Keishingtry: 150b93fbf8SMichael Walsh import cPickle as pickle 16d54bbc22SGeorge Keishingexcept ImportError: 17d54bbc22SGeorge Keishing import pickle 18dc80d67dSMichael Walshimport socket 190b93fbf8SMichael Walsh 200b93fbf8SMichael Walshfrom robot.utils import DotDict 210b93fbf8SMichael Walshfrom robot.libraries.BuiltIn import BuiltIn 220b93fbf8SMichael Walsh 236741f740SMichael Walshfrom boot_data import * 24c9116811SMichael Walshimport gen_print as gp 2555302295SMichael Walshimport gen_robot_plug_in as grpi 26f75d4354SMichael Walshimport gen_arg as ga 2744cef258SMichael Walshimport gen_valid as gv 286741f740SMichael Walshimport gen_misc as gm 296741f740SMichael Walshimport gen_cmd as gc 30b5839d00SMichael Walshimport gen_robot_keyword as grk 3155302295SMichael Walshimport state as st 32ff340006SMichael Walshimport var_stack as vs 33c9bd2e87SMichael Walshimport gen_plug_in_utils as gpu 341a67b08aSMichael Sheposimport pel_utils as pel 350e5f1137SMichael Sheposimport logging_utils as log 360bbd860fSMichael Walsh 370b93fbf8SMichael Walshbase_path = os.path.dirname(os.path.dirname( 380b93fbf8SMichael Walsh imp.find_module("gen_robot_print")[1])) +\ 390b93fbf8SMichael Walsh os.sep 400b93fbf8SMichael Walshsys.path.append(base_path + "extended/") 410b93fbf8SMichael Walshimport run_keyword as rk 420bbd860fSMichael Walsh 43e1e26448SMichael Walsh# Setting master_pid correctly influences the behavior of plug-ins like 44e1e26448SMichael Walsh# DB_Logging 45e1e26448SMichael Walshprogram_pid = os.getpid() 46e1e26448SMichael Walshmaster_pid = os.environ.get('AUTOBOOT_MASTER_PID', program_pid) 47004ad3c9SJoy Onyerikwupgm_name = re.sub('\\.py$', '', os.path.basename(__file__)) 48e1e26448SMichael Walsh 49b5839d00SMichael Walsh# Set up boot data structures. 50986d8aeeSMichael Walshos_host = BuiltIn().get_variable_value("${OS_HOST}", default="") 510b93fbf8SMichael Walsh 526741f740SMichael Walshboot_lists = read_boot_lists() 53986d8aeeSMichael Walsh 54986d8aeeSMichael Walsh# The maximum number of entries that can be in the boot_history global variable. 55815b1d5bSMichael Walshmax_boot_history = 10 56986d8aeeSMichael Walshboot_history = [] 576741f740SMichael Walsh 587dc885b6SMichael Walshstate = st.return_state_constant('default_state') 596741f740SMichael Walshcp_setup_called = 0 606741f740SMichael Walshnext_boot = "" 616741f740SMichael Walshbase_tool_dir_path = os.path.normpath(os.environ.get( 626741f740SMichael Walsh 'AUTOBOOT_BASE_TOOL_DIR_PATH', "/tmp")) + os.sep 63b5839d00SMichael Walsh 646741f740SMichael Walshffdc_dir_path = os.path.normpath(os.environ.get('FFDC_DIR_PATH', '')) + os.sep 656741f740SMichael Walshboot_success = 0 666741f740SMichael Walshstatus_dir_path = os.environ.get('STATUS_DIR_PATH', "") 676741f740SMichael Walshif status_dir_path != "": 686741f740SMichael Walsh status_dir_path = os.path.normpath(status_dir_path) + os.sep 6934c7956cSMichael Sheposredfish_support_trans_state = int(os.environ.get('REDFISH_SUPPORT_TRANS_STATE', 0)) or \ 7034c7956cSMichael Shepos int(BuiltIn().get_variable_value("${REDFISH_SUPPORT_TRANS_STATE}", default=0)) 71e58df1c8SMichael Walshredfish_supported = BuiltIn().get_variable_value("${REDFISH_SUPPORTED}", default=False) 72eb1fe352SGeorge Keishingredfish_rest_supported = BuiltIn().get_variable_value("${REDFISH_REST_SUPPORTED}", default=False) 73d86e45c6SGeorge Keishingredfish_delete_sessions = int(BuiltIn().get_variable_value("${REDFISH_DELETE_SESSIONS}", default=1)) 74e58df1c8SMichael Walshif redfish_supported: 7589537a85SGeorge Keishing redfish = BuiltIn().get_library_instance('redfish') 76e58df1c8SMichael Walsh default_power_on = "Redfish Power On" 77e58df1c8SMichael Walsh default_power_off = "Redfish Power Off" 78870999aaSGeorge Keishing if not redfish_support_trans_state: 79cc490b41SMichael Shepos delete_errlogs_cmd = "Delete Error Logs ${quiet}=${1}" 8092a54bf5SMichael Shepos delete_bmcdump_cmd = "Delete All BMC Dump" 81763902a1SGeorge Keishing default_set_power_policy = "Set BMC Power Policy ALWAYS_POWER_OFF" 82e58df1c8SMichael Walsh else: 83eb1fe352SGeorge Keishing delete_errlogs_cmd = "Redfish Purge Event Log" 8492a54bf5SMichael Shepos delete_bmcdump_cmd = "Redfish Delete All BMC Dumps" 852ef6a7dbSGeorge Keishing delete_sysdump_cmd = "Redfish Delete All System Dumps" 86eb1fe352SGeorge Keishing default_set_power_policy = "Redfish Set Power Restore Policy AlwaysOff" 87eb1fe352SGeorge Keishingelse: 880b93fbf8SMichael Walsh default_power_on = "REST Power On" 890b93fbf8SMichael Walsh default_power_off = "REST Power Off" 90cc490b41SMichael Shepos delete_errlogs_cmd = "Delete Error Logs ${quiet}=${1}" 9192a54bf5SMichael Shepos delete_bmcdump_cmd = "Delete All BMC Dump" 92a54e06f5SGeorge Keishing default_set_power_policy = "Set BMC Power Policy ALWAYS_POWER_OFF" 936741f740SMichael Walshboot_count = 0 940bbd860fSMichael Walsh 9585678948SMichael WalshLOG_LEVEL = BuiltIn().get_variable_value("${LOG_LEVEL}") 96986d8aeeSMichael WalshAUTOBOOT_FFDC_PREFIX = os.environ.get('AUTOBOOT_FFDC_PREFIX', '') 97986d8aeeSMichael Walshffdc_prefix = AUTOBOOT_FFDC_PREFIX 98325eb548SSunil Mboot_start_time = "" 99325eb548SSunil Mboot_end_time = "" 100ff340006SMichael Walshsave_stack = vs.var_stack('save_stack') 101ff340006SMichael Walshmain_func_parm_list = ['boot_stack', 'stack_mode', 'quiet'] 10285678948SMichael Walsh 10385678948SMichael Walsh 10489de14a4SMichael Walshdef dump_ffdc_rc(): 10589de14a4SMichael Walsh r""" 10689de14a4SMichael Walsh Return the constant dump ffdc test return code value. 10789de14a4SMichael Walsh 10889de14a4SMichael Walsh When a plug-in call point program returns this value, it indicates that 10989de14a4SMichael Walsh this program should collect FFDC. 11089de14a4SMichael Walsh """ 11189de14a4SMichael Walsh 11289de14a4SMichael Walsh return 0x00000200 11389de14a4SMichael Walsh 11489de14a4SMichael Walsh 11589de14a4SMichael Walshdef stop_test_rc(): 11689de14a4SMichael Walsh r""" 11789de14a4SMichael Walsh Return the constant stop test return code value. 11889de14a4SMichael Walsh 11989de14a4SMichael Walsh When a plug-in call point program returns this value, it indicates that 12089de14a4SMichael Walsh this program should stop running. 12189de14a4SMichael Walsh """ 12289de14a4SMichael Walsh 12389de14a4SMichael Walsh return 0x00000200 12489de14a4SMichael Walsh 12589de14a4SMichael Walsh 1260ad0f7f8SMichael Walshdef process_host(host, 1270ad0f7f8SMichael Walsh host_var_name=""): 1280ad0f7f8SMichael Walsh r""" 1290ad0f7f8SMichael Walsh Process a host by getting the associated host name and IP address and 1300ad0f7f8SMichael Walsh setting them in global variables. 1310ad0f7f8SMichael Walsh 1320ad0f7f8SMichael Walsh If the caller does not pass the host_var_name, this function will try to 1330ad0f7f8SMichael Walsh figure out the name of the variable used by the caller for the host parm. 1340ad0f7f8SMichael Walsh Callers are advised to explicitly specify the host_var_name when calling 1350ad0f7f8SMichael Walsh with an exec command. In such cases, the get_arg_name cannot figure out 1360ad0f7f8SMichael Walsh the host variable name. 1370ad0f7f8SMichael Walsh 1380ad0f7f8SMichael Walsh This function will then create similar global variable names by 1390ad0f7f8SMichael Walsh removing "_host" and appending "_host_name" or "_ip" to the host variable 1400ad0f7f8SMichael Walsh name. 1410ad0f7f8SMichael Walsh 1420ad0f7f8SMichael Walsh Example: 1430ad0f7f8SMichael Walsh 1440ad0f7f8SMichael Walsh If a call is made like this: 1450ad0f7f8SMichael Walsh process_host(openbmc_host) 1460ad0f7f8SMichael Walsh 1470ad0f7f8SMichael Walsh Global variables openbmc_host_name and openbmc_ip will be set. 1480ad0f7f8SMichael Walsh 1490ad0f7f8SMichael Walsh Description of argument(s): 1500ad0f7f8SMichael Walsh host A host name or IP. The name of the variable used should 1510ad0f7f8SMichael Walsh have a suffix of "_host". 1520ad0f7f8SMichael Walsh host_var_name The name of the variable being used as the host parm. 1530ad0f7f8SMichael Walsh """ 1540ad0f7f8SMichael Walsh 1550ad0f7f8SMichael Walsh if host_var_name == "": 1560ad0f7f8SMichael Walsh host_var_name = gp.get_arg_name(0, 1, stack_frame_ix=2) 1570ad0f7f8SMichael Walsh 1580ad0f7f8SMichael Walsh host_name_var_name = re.sub("host", "host_name", host_var_name) 1590ad0f7f8SMichael Walsh ip_var_name = re.sub("host", "ip", host_var_name) 1600ad0f7f8SMichael Walsh cmd_buf = "global " + host_name_var_name + ", " + ip_var_name + " ; " +\ 1610ad0f7f8SMichael Walsh host_name_var_name + ", " + ip_var_name + " = gm.get_host_name_ip('" +\ 1620ad0f7f8SMichael Walsh host + "')" 1630ad0f7f8SMichael Walsh exec(cmd_buf) 1640ad0f7f8SMichael Walsh 1650ad0f7f8SMichael Walsh 166b5839d00SMichael Walshdef process_pgm_parms(): 167b5839d00SMichael Walsh r""" 168b5839d00SMichael Walsh Process the program parameters by assigning them all to corresponding 169b5839d00SMichael Walsh globals. Also, set some global values that depend on program parameters. 170b5839d00SMichael Walsh """ 171b5839d00SMichael Walsh 172b5839d00SMichael Walsh # Program parameter processing. 173b5839d00SMichael Walsh # Assign all program parms to python variables which are global to this 174b5839d00SMichael Walsh # module. 175b5839d00SMichael Walsh 176b5839d00SMichael Walsh global parm_list 177b5839d00SMichael Walsh parm_list = BuiltIn().get_variable_value("${parm_list}") 178b5839d00SMichael Walsh # The following subset of parms should be processed as integers. 179b5839d00SMichael Walsh int_list = ['max_num_tests', 'boot_pass', 'boot_fail', 'ffdc_only', 18089de14a4SMichael Walsh 'boot_fail_threshold', 'delete_errlogs', 181986d8aeeSMichael Walsh 'call_post_stack_plug', 'do_pre_boot_plug_in_setup', 'quiet', 182986d8aeeSMichael Walsh 'test_mode', 'debug'] 183b5839d00SMichael Walsh for parm in parm_list: 184b5839d00SMichael Walsh if parm in int_list: 185b5839d00SMichael Walsh sub_cmd = "int(BuiltIn().get_variable_value(\"${" + parm +\ 186b5839d00SMichael Walsh "}\", \"0\"))" 187b5839d00SMichael Walsh else: 188b5839d00SMichael Walsh sub_cmd = "BuiltIn().get_variable_value(\"${" + parm + "}\")" 189b5839d00SMichael Walsh cmd_buf = "global " + parm + " ; " + parm + " = " + sub_cmd 190ff340006SMichael Walsh gp.dpissuing(cmd_buf) 191b5839d00SMichael Walsh exec(cmd_buf) 1920ad0f7f8SMichael Walsh if re.match(r".*_host$", parm): 1930ad0f7f8SMichael Walsh cmd_buf = "process_host(" + parm + ", '" + parm + "')" 1940ad0f7f8SMichael Walsh exec(cmd_buf) 1950ad0f7f8SMichael Walsh if re.match(r".*_password$", parm): 1960ad0f7f8SMichael Walsh # Register the value of any parm whose name ends in _password. 1970ad0f7f8SMichael Walsh # This will cause the print functions to replace passwords with 1980ad0f7f8SMichael Walsh # asterisks in the output. 1990ad0f7f8SMichael Walsh cmd_buf = "gp.register_passwords(" + parm + ")" 2000ad0f7f8SMichael Walsh exec(cmd_buf) 201b5839d00SMichael Walsh 202b5839d00SMichael Walsh global ffdc_dir_path_style 203b5839d00SMichael Walsh global boot_list 204b5839d00SMichael Walsh global boot_stack 205b5839d00SMichael Walsh global boot_results_file_path 206b5839d00SMichael Walsh global boot_results 207986d8aeeSMichael Walsh global boot_history 208b5839d00SMichael Walsh global ffdc_list_file_path 209e0cf8d70SMichael Walsh global ffdc_report_list_path 210600876daSMichael Walsh global ffdc_summary_list_path 211a3e7b222SMichael Walsh global boot_table 212a3e7b222SMichael Walsh global valid_boot_types 213b5839d00SMichael Walsh 214b5839d00SMichael Walsh if ffdc_dir_path_style == "": 215b5839d00SMichael Walsh ffdc_dir_path_style = int(os.environ.get('FFDC_DIR_PATH_STYLE', '0')) 216b5839d00SMichael Walsh 217b5839d00SMichael Walsh # Convert these program parms to lists for easier processing.. 21836efbc04SGeorge Keishing boot_list = list(filter(None, boot_list.split(":"))) 21936efbc04SGeorge Keishing boot_stack = list(filter(None, boot_stack.split(":"))) 220b5839d00SMichael Walsh 221a3e7b222SMichael Walsh boot_table = create_boot_table(boot_table_path, os_host=os_host) 222a3e7b222SMichael Walsh valid_boot_types = create_valid_boot_list(boot_table) 223a3e7b222SMichael Walsh 224903e0b20SMichael Walsh cleanup_boot_results_file() 225903e0b20SMichael Walsh boot_results_file_path = create_boot_results_file_path(pgm_name, 226903e0b20SMichael Walsh openbmc_nickname, 227903e0b20SMichael Walsh master_pid) 228b5839d00SMichael Walsh 229b5839d00SMichael Walsh if os.path.isfile(boot_results_file_path): 230b5839d00SMichael Walsh # We've been called before in this run so we'll load the saved 231986d8aeeSMichael Walsh # boot_results and boot_history objects. 232986d8aeeSMichael Walsh boot_results, boot_history =\ 2336c64574bSMichael Walsh pickle.load(open(boot_results_file_path, 'rb')) 234b5839d00SMichael Walsh else: 235b5839d00SMichael Walsh boot_results = boot_results(boot_table, boot_pass, boot_fail) 236b5839d00SMichael Walsh 237b5839d00SMichael Walsh ffdc_list_file_path = base_tool_dir_path + openbmc_nickname +\ 238b5839d00SMichael Walsh "/FFDC_FILE_LIST" 239e0cf8d70SMichael Walsh ffdc_report_list_path = base_tool_dir_path + openbmc_nickname +\ 240e0cf8d70SMichael Walsh "/FFDC_REPORT_FILE_LIST" 241b5839d00SMichael Walsh 242600876daSMichael Walsh ffdc_summary_list_path = base_tool_dir_path + openbmc_nickname +\ 243600876daSMichael Walsh "/FFDC_SUMMARY_FILE_LIST" 244600876daSMichael Walsh 245b5839d00SMichael Walsh 24685678948SMichael Walshdef initial_plug_in_setup(): 24785678948SMichael Walsh r""" 24885678948SMichael Walsh Initialize all plug-in environment variables which do not change for the 24985678948SMichael Walsh duration of the program. 25085678948SMichael Walsh 25185678948SMichael Walsh """ 25285678948SMichael Walsh 25385678948SMichael Walsh global LOG_LEVEL 25485678948SMichael Walsh BuiltIn().set_log_level("NONE") 25585678948SMichael Walsh 25685678948SMichael Walsh BuiltIn().set_global_variable("${master_pid}", master_pid) 25785678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path) 25885678948SMichael Walsh BuiltIn().set_global_variable("${STATUS_DIR_PATH}", status_dir_path) 25985678948SMichael Walsh BuiltIn().set_global_variable("${BASE_TOOL_DIR_PATH}", base_tool_dir_path) 26085678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_LIST_FILE_PATH}", 26185678948SMichael Walsh ffdc_list_file_path) 262e0cf8d70SMichael Walsh BuiltIn().set_global_variable("${FFDC_REPORT_LIST_PATH}", 263e0cf8d70SMichael Walsh ffdc_report_list_path) 264600876daSMichael Walsh BuiltIn().set_global_variable("${FFDC_SUMMARY_LIST_PATH}", 265600876daSMichael Walsh ffdc_summary_list_path) 26685678948SMichael Walsh 26785678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_DIR_PATH_STYLE}", 26885678948SMichael Walsh ffdc_dir_path_style) 26985678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_CHECK}", 27085678948SMichael Walsh ffdc_check) 27185678948SMichael Walsh 27285678948SMichael Walsh # For each program parameter, set the corresponding AUTOBOOT_ environment 27385678948SMichael Walsh # variable value. Also, set an AUTOBOOT_ environment variable for every 27485678948SMichael Walsh # element in additional_values. 27585678948SMichael Walsh additional_values = ["program_pid", "master_pid", "ffdc_dir_path", 27685678948SMichael Walsh "status_dir_path", "base_tool_dir_path", 277600876daSMichael Walsh "ffdc_list_file_path", "ffdc_report_list_path", 2787fe83b32SMichael Shepos "ffdc_summary_list_path", "execdir", "redfish_supported", 27934c7956cSMichael Shepos "redfish_rest_supported", "redfish_support_trans_state"] 28085678948SMichael Walsh 28185678948SMichael Walsh plug_in_vars = parm_list + additional_values 28285678948SMichael Walsh 28385678948SMichael Walsh for var_name in plug_in_vars: 28485678948SMichael Walsh var_value = BuiltIn().get_variable_value("${" + var_name + "}") 28585678948SMichael Walsh var_name = var_name.upper() 28685678948SMichael Walsh if var_value is None: 28785678948SMichael Walsh var_value = "" 28885678948SMichael Walsh os.environ["AUTOBOOT_" + var_name] = str(var_value) 28985678948SMichael Walsh 29085678948SMichael Walsh BuiltIn().set_log_level(LOG_LEVEL) 29185678948SMichael Walsh 29268a61162SMichael Walsh # Make sure the ffdc list directory exists. 29368a61162SMichael Walsh ffdc_list_dir_path = os.path.dirname(ffdc_list_file_path) + os.sep 29468a61162SMichael Walsh if not os.path.exists(ffdc_list_dir_path): 29568a61162SMichael Walsh os.makedirs(ffdc_list_dir_path) 29685678948SMichael Walsh 29785678948SMichael Walsh 2980bbd860fSMichael Walshdef plug_in_setup(): 2990bbd860fSMichael Walsh r""" 30085678948SMichael Walsh Initialize all changing plug-in environment variables for use by the 30185678948SMichael Walsh plug-in programs. 3020bbd860fSMichael Walsh """ 3030bbd860fSMichael Walsh 30485678948SMichael Walsh global LOG_LEVEL 30585678948SMichael Walsh global test_really_running 30685678948SMichael Walsh 30785678948SMichael Walsh BuiltIn().set_log_level("NONE") 30885678948SMichael Walsh 3096741f740SMichael Walsh boot_pass, boot_fail = boot_results.return_total_pass_fail() 3100bbd860fSMichael Walsh if boot_pass > 1: 3110bbd860fSMichael Walsh test_really_running = 1 3120bbd860fSMichael Walsh else: 3130bbd860fSMichael Walsh test_really_running = 0 3140bbd860fSMichael Walsh 3156741f740SMichael Walsh BuiltIn().set_global_variable("${test_really_running}", 3166741f740SMichael Walsh test_really_running) 3176741f740SMichael Walsh BuiltIn().set_global_variable("${boot_type_desc}", next_boot) 3186741f740SMichael Walsh BuiltIn().set_global_variable("${boot_pass}", boot_pass) 3196741f740SMichael Walsh BuiltIn().set_global_variable("${boot_fail}", boot_fail) 3206741f740SMichael Walsh BuiltIn().set_global_variable("${boot_success}", boot_success) 3216741f740SMichael Walsh BuiltIn().set_global_variable("${ffdc_prefix}", ffdc_prefix) 322325eb548SSunil M BuiltIn().set_global_variable("${boot_start_time}", boot_start_time) 323325eb548SSunil M BuiltIn().set_global_variable("${boot_end_time}", boot_end_time) 3244c9a6453SMichael Walsh 3250bbd860fSMichael Walsh # For each program parameter, set the corresponding AUTOBOOT_ environment 3260bbd860fSMichael Walsh # variable value. Also, set an AUTOBOOT_ environment variable for every 3270bbd860fSMichael Walsh # element in additional_values. 3280bbd860fSMichael Walsh additional_values = ["boot_type_desc", "boot_success", "boot_pass", 329325eb548SSunil M "boot_fail", "test_really_running", "ffdc_prefix", 330325eb548SSunil M "boot_start_time", "boot_end_time"] 3310bbd860fSMichael Walsh 33285678948SMichael Walsh plug_in_vars = additional_values 3330bbd860fSMichael Walsh 3340bbd860fSMichael Walsh for var_name in plug_in_vars: 3350bbd860fSMichael Walsh var_value = BuiltIn().get_variable_value("${" + var_name + "}") 3360bbd860fSMichael Walsh var_name = var_name.upper() 3370bbd860fSMichael Walsh if var_value is None: 3380bbd860fSMichael Walsh var_value = "" 3396741f740SMichael Walsh os.environ["AUTOBOOT_" + var_name] = str(var_value) 3400bbd860fSMichael Walsh 3410bbd860fSMichael Walsh if debug: 3426741f740SMichael Walsh shell_rc, out_buf = \ 3436741f740SMichael Walsh gc.cmd_fnc_u("printenv | egrep AUTOBOOT_ | sort -u") 3440bbd860fSMichael Walsh 34585678948SMichael Walsh BuiltIn().set_log_level(LOG_LEVEL) 34685678948SMichael Walsh 3470bbd860fSMichael Walsh 348e0cf8d70SMichael Walshdef pre_boot_plug_in_setup(): 349e0cf8d70SMichael Walsh 350e0cf8d70SMichael Walsh # Clear the ffdc_list_file_path file. Plug-ins may now write to it. 351e0cf8d70SMichael Walsh try: 352e0cf8d70SMichael Walsh os.remove(ffdc_list_file_path) 353e0cf8d70SMichael Walsh except OSError: 354e0cf8d70SMichael Walsh pass 355e0cf8d70SMichael Walsh 356e0cf8d70SMichael Walsh # Clear the ffdc_report_list_path file. Plug-ins may now write to it. 357e0cf8d70SMichael Walsh try: 358e0cf8d70SMichael Walsh os.remove(ffdc_report_list_path) 359e0cf8d70SMichael Walsh except OSError: 360e0cf8d70SMichael Walsh pass 361e0cf8d70SMichael Walsh 362600876daSMichael Walsh # Clear the ffdc_summary_list_path file. Plug-ins may now write to it. 363600876daSMichael Walsh try: 364600876daSMichael Walsh os.remove(ffdc_summary_list_path) 365600876daSMichael Walsh except OSError: 366600876daSMichael Walsh pass 367600876daSMichael Walsh 368e1974b96SMichael Walsh global ffdc_prefix 369e1974b96SMichael Walsh 370e1974b96SMichael Walsh seconds = time.time() 371e1974b96SMichael Walsh loc_time = time.localtime(seconds) 372e1974b96SMichael Walsh time_string = time.strftime("%y%m%d.%H%M%S.", loc_time) 373e1974b96SMichael Walsh 374e1974b96SMichael Walsh ffdc_prefix = openbmc_nickname + "." + time_string 375e1974b96SMichael Walsh 376e0cf8d70SMichael Walsh 377f566fb1fSMichael Walshdef default_sigusr1(signal_number=0, 378f566fb1fSMichael Walsh frame=None): 379f566fb1fSMichael Walsh r""" 380f566fb1fSMichael Walsh Handle SIGUSR1 by doing nothing. 381f566fb1fSMichael Walsh 382f566fb1fSMichael Walsh This function assists in debugging SIGUSR1 processing by printing messages 383f566fb1fSMichael Walsh to stdout and to the log.html file. 384f566fb1fSMichael Walsh 385f566fb1fSMichael Walsh Description of argument(s): 386f566fb1fSMichael Walsh signal_number The signal number (should always be 10 for SIGUSR1). 387f566fb1fSMichael Walsh frame The frame data. 388f566fb1fSMichael Walsh """ 389f566fb1fSMichael Walsh 39080dddde9SMichael Walsh gp.qprintn() 39180dddde9SMichael Walsh gp.qprint_executing() 392f566fb1fSMichael Walsh gp.lprint_executing() 393f566fb1fSMichael Walsh 394f566fb1fSMichael Walsh 395f566fb1fSMichael Walshdef set_default_siguser1(): 396f566fb1fSMichael Walsh r""" 397f566fb1fSMichael Walsh Set the default_sigusr1 function to be the SIGUSR1 handler. 398f566fb1fSMichael Walsh """ 399f566fb1fSMichael Walsh 40080dddde9SMichael Walsh gp.qprintn() 40180dddde9SMichael Walsh gp.qprint_executing() 402f566fb1fSMichael Walsh gp.lprint_executing() 403f566fb1fSMichael Walsh signal.signal(signal.SIGUSR1, default_sigusr1) 404f566fb1fSMichael Walsh 405f566fb1fSMichael Walsh 4066741f740SMichael Walshdef setup(): 4070bbd860fSMichael Walsh r""" 4086741f740SMichael Walsh Do general program setup tasks. 4090bbd860fSMichael Walsh """ 4100bbd860fSMichael Walsh 4116741f740SMichael Walsh global cp_setup_called 41281816748SMichael Walsh global transitional_boot_selected 4130bbd860fSMichael Walsh 414b5839d00SMichael Walsh gp.qprintn() 415b5839d00SMichael Walsh 416a54e06f5SGeorge Keishing if redfish_supported: 417a54e06f5SGeorge Keishing redfish.login() 418a54e06f5SGeorge Keishing 419f566fb1fSMichael Walsh set_default_siguser1() 42081816748SMichael Walsh transitional_boot_selected = False 42181816748SMichael Walsh 42283f4bc77SMichael Walsh robot_pgm_dir_path = os.path.dirname(__file__) + os.sep 42383f4bc77SMichael Walsh repo_bin_path = robot_pgm_dir_path.replace("/lib/", "/bin/") 424d061c043SMichael Walsh # If we can't find process_plug_in_packages.py, ssh_pw or 425d061c043SMichael Walsh # validate_plug_ins.py, then we don't have our repo bin in PATH. 426004ad3c9SJoy Onyerikwu shell_rc, out_buf = gc.cmd_fnc_u("which process_plug_in_packages.py" 427004ad3c9SJoy Onyerikwu + " ssh_pw validate_plug_ins.py", quiet=1, 428d061c043SMichael Walsh print_output=0, show_err=0) 429b5839d00SMichael Walsh if shell_rc != 0: 43083f4bc77SMichael Walsh os.environ['PATH'] = repo_bin_path + ":" + os.environ.get('PATH', "") 43183f4bc77SMichael Walsh # Likewise, our repo lib subdir needs to be in sys.path and PYTHONPATH. 43283f4bc77SMichael Walsh if robot_pgm_dir_path not in sys.path: 43383f4bc77SMichael Walsh sys.path.append(robot_pgm_dir_path) 43483f4bc77SMichael Walsh PYTHONPATH = os.environ.get("PYTHONPATH", "") 43583f4bc77SMichael Walsh if PYTHONPATH == "": 43683f4bc77SMichael Walsh os.environ['PYTHONPATH'] = robot_pgm_dir_path 43783f4bc77SMichael Walsh else: 43883f4bc77SMichael Walsh os.environ['PYTHONPATH'] = robot_pgm_dir_path + ":" + PYTHONPATH 4396741f740SMichael Walsh 4406741f740SMichael Walsh validate_parms() 4416741f740SMichael Walsh 442c108e429SMichael Walsh gp.qprint_pgm_header() 4436741f740SMichael Walsh 444a54e06f5SGeorge Keishing grk.run_key_u(default_set_power_policy) 44511cfc8c0SMichael Walsh 44685678948SMichael Walsh initial_plug_in_setup() 44785678948SMichael Walsh 4486741f740SMichael Walsh plug_in_setup() 4496741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 4506741f740SMichael Walsh call_point='setup') 4516741f740SMichael Walsh if rc != 0: 4526741f740SMichael Walsh error_message = "Plug-in setup failed.\n" 453c108e429SMichael Walsh gp.print_error_report(error_message) 4546741f740SMichael Walsh BuiltIn().fail(error_message) 4556741f740SMichael Walsh # Setting cp_setup_called lets our Teardown know that it needs to call 4566741f740SMichael Walsh # the cleanup plug-in call point. 4576741f740SMichael Walsh cp_setup_called = 1 4586741f740SMichael Walsh 4596741f740SMichael Walsh # Keyword "FFDC" will fail if TEST_MESSAGE is not set. 4606741f740SMichael Walsh BuiltIn().set_global_variable("${TEST_MESSAGE}", "${EMPTY}") 46185678948SMichael Walsh # FFDC_LOG_PATH is used by "FFDC" keyword. 46285678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_LOG_PATH}", ffdc_dir_path) 4636741f740SMichael Walsh 464dc80d67dSMichael Walsh # Also printed by FFDC. 465dc80d67dSMichael Walsh global host_name 466dc80d67dSMichael Walsh global host_ip 467dc80d67dSMichael Walsh host = socket.gethostname() 468dc80d67dSMichael Walsh host_name, host_ip = gm.get_host_name_ip(host) 469dc80d67dSMichael Walsh 470986d8aeeSMichael Walsh gp.dprint_var(boot_table) 471b5839d00SMichael Walsh gp.dprint_var(boot_lists) 4720bbd860fSMichael Walsh 4730bbd860fSMichael Walsh 4746741f740SMichael Walshdef validate_parms(): 4750bbd860fSMichael Walsh r""" 4766741f740SMichael Walsh Validate all program parameters. 4770bbd860fSMichael Walsh """ 4780bbd860fSMichael Walsh 479b5839d00SMichael Walsh process_pgm_parms() 4800bbd860fSMichael Walsh 481b5839d00SMichael Walsh gp.qprintn() 482b5839d00SMichael Walsh 483b5839d00SMichael Walsh global openbmc_model 484f5ce38c3SMichael Walsh if openbmc_model == "": 485f5ce38c3SMichael Walsh status, ret_values =\ 486f5ce38c3SMichael Walsh grk.run_key_u("Get BMC System Model") 487f5ce38c3SMichael Walsh openbmc_model = ret_values 488f5ce38c3SMichael Walsh BuiltIn().set_global_variable("${openbmc_model}", openbmc_model) 489f5ce38c3SMichael Walsh gv.set_exit_on_error(True) 49044cef258SMichael Walsh gv.valid_value(openbmc_host) 49144cef258SMichael Walsh gv.valid_value(openbmc_username) 49244cef258SMichael Walsh gv.valid_value(openbmc_password) 49344cef258SMichael Walsh gv.valid_value(rest_username) 49444cef258SMichael Walsh gv.valid_value(rest_password) 49544cef258SMichael Walsh gv.valid_value(ipmi_username) 49644cef258SMichael Walsh gv.valid_value(ipmi_password) 4976741f740SMichael Walsh if os_host != "": 49844cef258SMichael Walsh gv.valid_value(os_username) 49944cef258SMichael Walsh gv.valid_value(os_password) 5006741f740SMichael Walsh if pdu_host != "": 50144cef258SMichael Walsh gv.valid_value(pdu_username) 50244cef258SMichael Walsh gv.valid_value(pdu_password) 50344cef258SMichael Walsh gv.valid_integer(pdu_slot_no) 5046741f740SMichael Walsh if openbmc_serial_host != "": 50544cef258SMichael Walsh gv.valid_integer(openbmc_serial_port) 50644cef258SMichael Walsh gv.valid_value(openbmc_model) 50744cef258SMichael Walsh gv.valid_integer(max_num_tests) 50844cef258SMichael Walsh gv.valid_integer(boot_pass) 50944cef258SMichael Walsh gv.valid_integer(boot_fail) 5106741f740SMichael Walsh plug_in_packages_list = grpi.rvalidate_plug_ins(plug_in_dir_paths) 5116741f740SMichael Walsh BuiltIn().set_global_variable("${plug_in_packages_list}", 5126741f740SMichael Walsh plug_in_packages_list) 51344cef258SMichael Walsh gv.valid_value(stack_mode, valid_values=['normal', 'skip']) 514f5ce38c3SMichael Walsh gv.set_exit_on_error(False) 515a20da401SMichael Walsh if len(boot_list) == 0 and len(boot_stack) == 0 and not ffdc_only: 5166741f740SMichael Walsh error_message = "You must provide either a value for either the" +\ 5176741f740SMichael Walsh " boot_list or the boot_stack parm.\n" 5186741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 5196741f740SMichael Walsh valid_boot_list(boot_list, valid_boot_types) 5206741f740SMichael Walsh valid_boot_list(boot_stack, valid_boot_types) 521004ad3c9SJoy Onyerikwu selected_PDU_boots = list(set(boot_list + boot_stack) 522004ad3c9SJoy Onyerikwu & set(boot_lists['PDU_reboot'])) 52311cfc8c0SMichael Walsh if len(selected_PDU_boots) > 0 and pdu_host == "": 52411cfc8c0SMichael Walsh error_message = "You have selected the following boots which" +\ 52511cfc8c0SMichael Walsh " require a PDU host but no value for pdu_host:\n" 52611cfc8c0SMichael Walsh error_message += gp.sprint_var(selected_PDU_boots) 527986d8aeeSMichael Walsh error_message += gp.sprint_var(pdu_host, fmt=gp.blank()) 52811cfc8c0SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 52911cfc8c0SMichael Walsh 5306741f740SMichael Walsh return 5310bbd860fSMichael Walsh 5320bbd860fSMichael Walsh 5336741f740SMichael Walshdef my_get_state(): 5340bbd860fSMichael Walsh r""" 5356741f740SMichael Walsh Get the system state plus a little bit of wrapping. 5360bbd860fSMichael Walsh """ 5370bbd860fSMichael Walsh 5386741f740SMichael Walsh global state 5396741f740SMichael Walsh 5406741f740SMichael Walsh req_states = ['epoch_seconds'] + st.default_req_states 5416741f740SMichael Walsh 542b5839d00SMichael Walsh gp.qprint_timen("Getting system state.") 5436741f740SMichael Walsh if test_mode: 5446741f740SMichael Walsh state['epoch_seconds'] = int(time.time()) 5456741f740SMichael Walsh else: 546b5839d00SMichael Walsh state = st.get_state(req_states=req_states, quiet=quiet) 547b5839d00SMichael Walsh gp.qprint_var(state) 548341c21ebSMichael Walsh 549341c21ebSMichael Walsh 55045ca6e4cSMichael Walshdef valid_state(): 55145ca6e4cSMichael Walsh r""" 55245ca6e4cSMichael Walsh Verify that our state dictionary contains no blank values. If we don't get 55345ca6e4cSMichael Walsh valid state data, we cannot continue to work. 55445ca6e4cSMichael Walsh """ 55545ca6e4cSMichael Walsh 55645ca6e4cSMichael Walsh if st.compare_states(state, st.invalid_state_match, 'or'): 55745ca6e4cSMichael Walsh error_message = "The state dictionary contains blank fields which" +\ 55845ca6e4cSMichael Walsh " is illegal.\n" + gp.sprint_var(state) 55945ca6e4cSMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 56045ca6e4cSMichael Walsh 56145ca6e4cSMichael Walsh 5626741f740SMichael Walshdef select_boot(): 563341c21ebSMichael Walsh r""" 564341c21ebSMichael Walsh Select a boot test to be run based on our current state and return the 565341c21ebSMichael Walsh chosen boot type. 566341c21ebSMichael Walsh 567341c21ebSMichael Walsh Description of arguments: 5686741f740SMichael Walsh state The state of the machine. 569341c21ebSMichael Walsh """ 570341c21ebSMichael Walsh 57181816748SMichael Walsh global transitional_boot_selected 57230dadae2SMichael Walsh global boot_stack 57330dadae2SMichael Walsh 574b5839d00SMichael Walsh gp.qprint_timen("Selecting a boot test.") 5756741f740SMichael Walsh 57681816748SMichael Walsh if transitional_boot_selected and not boot_success: 57781816748SMichael Walsh prior_boot = next_boot 57881816748SMichael Walsh boot_candidate = boot_stack.pop() 579004ad3c9SJoy Onyerikwu gp.qprint_timen("The prior '" + next_boot + "' was chosen to" 580004ad3c9SJoy Onyerikwu + " transition to a valid state for '" + boot_candidate 581004ad3c9SJoy Onyerikwu + "' which was at the top of the boot_stack. Since" 582004ad3c9SJoy Onyerikwu + " the '" + next_boot + "' failed, the '" 583004ad3c9SJoy Onyerikwu + boot_candidate + "' has been removed from the stack" 584004ad3c9SJoy Onyerikwu + " to avoid and endless failure loop.") 58581816748SMichael Walsh if len(boot_stack) == 0: 58681816748SMichael Walsh return "" 58781816748SMichael Walsh 5886741f740SMichael Walsh my_get_state() 58945ca6e4cSMichael Walsh valid_state() 5906741f740SMichael Walsh 59181816748SMichael Walsh transitional_boot_selected = False 5926741f740SMichael Walsh stack_popped = 0 5936741f740SMichael Walsh if len(boot_stack) > 0: 5946741f740SMichael Walsh stack_popped = 1 595b5839d00SMichael Walsh gp.qprint_dashes() 596b5839d00SMichael Walsh gp.qprint_var(boot_stack) 597b5839d00SMichael Walsh gp.qprint_dashes() 598b5839d00SMichael Walsh skip_boot_printed = 0 599b5839d00SMichael Walsh while len(boot_stack) > 0: 6006741f740SMichael Walsh boot_candidate = boot_stack.pop() 601b5839d00SMichael Walsh if stack_mode == 'normal': 602b5839d00SMichael Walsh break 603b5839d00SMichael Walsh else: 604b5839d00SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['end']): 605b5839d00SMichael Walsh if not skip_boot_printed: 606ff340006SMichael Walsh gp.qprint_var(stack_mode) 607ff340006SMichael Walsh gp.qprintn() 608004ad3c9SJoy Onyerikwu gp.qprint_timen("Skipping the following boot tests" 609004ad3c9SJoy Onyerikwu + " which are unnecessary since their" 610004ad3c9SJoy Onyerikwu + " required end states match the" 611004ad3c9SJoy Onyerikwu + " current machine state:") 612b5839d00SMichael Walsh skip_boot_printed = 1 613ff340006SMichael Walsh gp.qprint_var(boot_candidate) 614b5839d00SMichael Walsh boot_candidate = "" 615b5839d00SMichael Walsh if boot_candidate == "": 616b5839d00SMichael Walsh gp.qprint_dashes() 617b5839d00SMichael Walsh gp.qprint_var(boot_stack) 618b5839d00SMichael Walsh gp.qprint_dashes() 619b5839d00SMichael Walsh return boot_candidate 6206741f740SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['start']): 621004ad3c9SJoy Onyerikwu gp.qprint_timen("The machine state is valid for a '" 622004ad3c9SJoy Onyerikwu + boot_candidate + "' boot test.") 623b5839d00SMichael Walsh gp.qprint_dashes() 624b5839d00SMichael Walsh gp.qprint_var(boot_stack) 625b5839d00SMichael Walsh gp.qprint_dashes() 6266741f740SMichael Walsh return boot_candidate 627341c21ebSMichael Walsh else: 628004ad3c9SJoy Onyerikwu gp.qprint_timen("The machine state does not match the required" 629004ad3c9SJoy Onyerikwu + " starting state for a '" + boot_candidate 630004ad3c9SJoy Onyerikwu + "' boot test:") 631986d8aeeSMichael Walsh gp.qprint_varx("boot_table_start_entry", 632986d8aeeSMichael Walsh boot_table[boot_candidate]['start']) 6336741f740SMichael Walsh boot_stack.append(boot_candidate) 63481816748SMichael Walsh transitional_boot_selected = True 6356741f740SMichael Walsh popped_boot = boot_candidate 6366741f740SMichael Walsh 6376741f740SMichael Walsh # Loop through your list selecting a boot_candidates 6386741f740SMichael Walsh boot_candidates = [] 6396741f740SMichael Walsh for boot_candidate in boot_list: 6406741f740SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['start']): 6416741f740SMichael Walsh if stack_popped: 6426741f740SMichael Walsh if st.compare_states(boot_table[boot_candidate]['end'], 6436741f740SMichael Walsh boot_table[popped_boot]['start']): 6446741f740SMichael Walsh boot_candidates.append(boot_candidate) 645341c21ebSMichael Walsh else: 6466741f740SMichael Walsh boot_candidates.append(boot_candidate) 6476741f740SMichael Walsh 6486741f740SMichael Walsh if len(boot_candidates) == 0: 649004ad3c9SJoy Onyerikwu gp.qprint_timen("The user's boot list contained no boot tests" 650004ad3c9SJoy Onyerikwu + " which are valid for the current machine state.") 6516741f740SMichael Walsh boot_candidate = default_power_on 6526741f740SMichael Walsh if not st.compare_states(state, boot_table[default_power_on]['start']): 6536741f740SMichael Walsh boot_candidate = default_power_off 6546741f740SMichael Walsh boot_candidates.append(boot_candidate) 655004ad3c9SJoy Onyerikwu gp.qprint_timen("Using default '" + boot_candidate 656004ad3c9SJoy Onyerikwu + "' boot type to transition to valid state.") 6576741f740SMichael Walsh 658b5839d00SMichael Walsh gp.dprint_var(boot_candidates) 6596741f740SMichael Walsh 6606741f740SMichael Walsh # Randomly select a boot from the candidate list. 6616741f740SMichael Walsh boot = random.choice(boot_candidates) 662341c21ebSMichael Walsh 663341c21ebSMichael Walsh return boot 6640bbd860fSMichael Walsh 66555302295SMichael Walsh 666b2e53ecdSMichael Walshdef print_defect_report(ffdc_file_list): 667341c21ebSMichael Walsh r""" 668341c21ebSMichael Walsh Print a defect report. 669b2e53ecdSMichael Walsh 670b2e53ecdSMichael Walsh Description of argument(s): 671b2e53ecdSMichael Walsh ffdc_file_list A list of files which were collected by our ffdc functions. 672341c21ebSMichael Walsh """ 673341c21ebSMichael Walsh 674600876daSMichael Walsh # Making deliberate choice to NOT run plug_in_setup(). We don't want 675600876daSMichael Walsh # ffdc_prefix updated. 676600876daSMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 677600876daSMichael Walsh call_point='ffdc_report', stop_on_plug_in_failure=0) 678600876daSMichael Walsh 679e0cf8d70SMichael Walsh # Get additional header data which may have been created by ffdc plug-ins. 680e0cf8d70SMichael Walsh # Also, delete the individual header files to cleanup. 681e0cf8d70SMichael Walsh cmd_buf = "file_list=$(cat " + ffdc_report_list_path + " 2>/dev/null)" +\ 682e0cf8d70SMichael Walsh " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\ 683e0cf8d70SMichael Walsh " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :" 684e0cf8d70SMichael Walsh shell_rc, more_header_info = gc.cmd_fnc_u(cmd_buf, print_output=0, 685e0cf8d70SMichael Walsh show_err=0) 686e0cf8d70SMichael Walsh 687b2e53ecdSMichael Walsh # Get additional summary data which may have been created by ffdc plug-ins. 688600876daSMichael Walsh # Also, delete the individual header files to cleanup. 689600876daSMichael Walsh cmd_buf = "file_list=$(cat " + ffdc_summary_list_path + " 2>/dev/null)" +\ 690600876daSMichael Walsh " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\ 691600876daSMichael Walsh " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :" 692600876daSMichael Walsh shell_rc, ffdc_summary_info = gc.cmd_fnc_u(cmd_buf, print_output=0, 693600876daSMichael Walsh show_err=0) 694600876daSMichael Walsh 695b2e53ecdSMichael Walsh # ffdc_list_file_path contains a list of any ffdc files created by plug- 696b2e53ecdSMichael Walsh # ins, etc. Read that data into a list. 697341c21ebSMichael Walsh try: 698b2e53ecdSMichael Walsh plug_in_ffdc_list = \ 699b2e53ecdSMichael Walsh open(ffdc_list_file_path, 'r').read().rstrip("\n").split("\n") 70036efbc04SGeorge Keishing plug_in_ffdc_list = list(filter(None, plug_in_ffdc_list)) 701341c21ebSMichael Walsh except IOError: 702b2e53ecdSMichael Walsh plug_in_ffdc_list = [] 703b2e53ecdSMichael Walsh 704b2e53ecdSMichael Walsh # Combine the files from plug_in_ffdc_list with the ffdc_file_list passed 705b2e53ecdSMichael Walsh # in. Eliminate duplicates and sort the list. 706004ad3c9SJoy Onyerikwu ffdc_file_list = sorted(set(ffdc_file_list + plug_in_ffdc_list)) 707b2e53ecdSMichael Walsh 708b2e53ecdSMichael Walsh if status_file_path != "": 709b2e53ecdSMichael Walsh ffdc_file_list.insert(0, status_file_path) 710b2e53ecdSMichael Walsh 711b2e53ecdSMichael Walsh # Convert the list to a printable list. 712b2e53ecdSMichael Walsh printable_ffdc_file_list = "\n".join(ffdc_file_list) 713341c21ebSMichael Walsh 71468a61162SMichael Walsh # Open ffdc_file_list for writing. We will write a complete list of 71568a61162SMichael Walsh # FFDC files to it for possible use by plug-ins like cp_stop_check. 71668a61162SMichael Walsh ffdc_list_file = open(ffdc_list_file_path, 'w') 717b2e53ecdSMichael Walsh ffdc_list_file.write(printable_ffdc_file_list + "\n") 718b2e53ecdSMichael Walsh ffdc_list_file.close() 719b2e53ecdSMichael Walsh 720b2e53ecdSMichael Walsh indent = 0 721b2e53ecdSMichael Walsh width = 90 722b2e53ecdSMichael Walsh linefeed = 1 723b2e53ecdSMichael Walsh char = "=" 72468a61162SMichael Walsh 72568a61162SMichael Walsh gp.qprintn() 726b2e53ecdSMichael Walsh gp.qprint_dashes(indent, width, linefeed, char) 72768a61162SMichael Walsh gp.qprintn("Copy this data to the defect:\n") 72868a61162SMichael Walsh 729e0cf8d70SMichael Walsh if len(more_header_info) > 0: 730ff340006SMichael Walsh gp.qprintn(more_header_info) 731dc80d67dSMichael Walsh gp.qpvars(host_name, host_ip, openbmc_nickname, openbmc_host, 732dc80d67dSMichael Walsh openbmc_host_name, openbmc_ip, openbmc_username, 7330a3bdb4cSMichael Walsh openbmc_password, rest_username, rest_password, ipmi_username, 7340a3bdb4cSMichael Walsh ipmi_password, os_host, os_host_name, os_ip, os_username, 735dc80d67dSMichael Walsh os_password, pdu_host, pdu_host_name, pdu_ip, pdu_username, 736dc80d67dSMichael Walsh pdu_password, pdu_slot_no, openbmc_serial_host, 737dc80d67dSMichael Walsh openbmc_serial_host_name, openbmc_serial_ip, openbmc_serial_port) 73868a61162SMichael Walsh 73968a61162SMichael Walsh gp.qprintn() 740986d8aeeSMichael Walsh print_boot_history(boot_history) 74168a61162SMichael Walsh gp.qprintn() 74268a61162SMichael Walsh gp.qprint_var(state) 743b5839d00SMichael Walsh gp.qprintn() 744b5839d00SMichael Walsh gp.qprintn("FFDC data files:") 745b2e53ecdSMichael Walsh gp.qprintn(printable_ffdc_file_list) 746b5839d00SMichael Walsh gp.qprintn() 747341c21ebSMichael Walsh 748600876daSMichael Walsh if len(ffdc_summary_info) > 0: 749ff340006SMichael Walsh gp.qprintn(ffdc_summary_info) 750600876daSMichael Walsh 751b2e53ecdSMichael Walsh gp.qprint_dashes(indent, width, linefeed, char) 75268a61162SMichael Walsh 7536741f740SMichael Walsh 7546741f740SMichael Walshdef my_ffdc(): 7556741f740SMichael Walsh r""" 7566741f740SMichael Walsh Collect FFDC data. 7576741f740SMichael Walsh """ 7586741f740SMichael Walsh 7596741f740SMichael Walsh global state 7606741f740SMichael Walsh 7616741f740SMichael Walsh plug_in_setup() 7626741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 763600876daSMichael Walsh call_point='ffdc', stop_on_plug_in_failure=0) 7646741f740SMichael Walsh 7656741f740SMichael Walsh AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX'] 766004ad3c9SJoy Onyerikwu status, ffdc_file_list = grk.run_key_u("FFDC ffdc_prefix=" 767004ad3c9SJoy Onyerikwu + AUTOBOOT_FFDC_PREFIX 768004ad3c9SJoy Onyerikwu + " ffdc_function_list=" 769004ad3c9SJoy Onyerikwu + ffdc_function_list, ignore=1) 77083f4bc77SMichael Walsh if status != 'PASS': 771ff340006SMichael Walsh gp.qprint_error("Call to ffdc failed.\n") 772c9bd2e87SMichael Walsh if type(ffdc_file_list) is not list: 773c9bd2e87SMichael Walsh ffdc_file_list = [] 774c9bd2e87SMichael Walsh # Leave a record for caller that "soft" errors occurred. 775c9bd2e87SMichael Walsh soft_errors = 1 776c9bd2e87SMichael Walsh gpu.save_plug_in_value(soft_errors, pgm_name) 7776741f740SMichael Walsh 7786741f740SMichael Walsh my_get_state() 7796741f740SMichael Walsh 780b2e53ecdSMichael Walsh print_defect_report(ffdc_file_list) 7816741f740SMichael Walsh 7826741f740SMichael Walsh 7836741f740SMichael Walshdef print_test_start_message(boot_keyword): 7846741f740SMichael Walsh r""" 7856741f740SMichael Walsh Print a message indicating what boot test is about to run. 7866741f740SMichael Walsh 7876741f740SMichael Walsh Description of arguments: 7886741f740SMichael Walsh boot_keyword The name of the boot which is to be run 7896741f740SMichael Walsh (e.g. "BMC Power On"). 7906741f740SMichael Walsh """ 7916741f740SMichael Walsh 792986d8aeeSMichael Walsh global boot_history 793325eb548SSunil M global boot_start_time 7946741f740SMichael Walsh 7956741f740SMichael Walsh doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".") 796325eb548SSunil M 797325eb548SSunil M # Set boot_start_time for use by plug-ins. 798325eb548SSunil M boot_start_time = doing_msg[1:33] 799325eb548SSunil M gp.qprint_var(boot_start_time) 800325eb548SSunil M 801b5839d00SMichael Walsh gp.qprint(doing_msg) 8026741f740SMichael Walsh 803986d8aeeSMichael Walsh update_boot_history(boot_history, doing_msg, max_boot_history) 8046741f740SMichael Walsh 8056741f740SMichael Walsh 806f566fb1fSMichael Walshdef stop_boot_test(signal_number=0, 807f566fb1fSMichael Walsh frame=None): 808f566fb1fSMichael Walsh r""" 809f566fb1fSMichael Walsh Handle SIGUSR1 by aborting the boot test that is running. 810f566fb1fSMichael Walsh 811f566fb1fSMichael Walsh Description of argument(s): 812f566fb1fSMichael Walsh signal_number The signal number (should always be 10 for SIGUSR1). 813f566fb1fSMichael Walsh frame The frame data. 814f566fb1fSMichael Walsh """ 815f566fb1fSMichael Walsh 81680dddde9SMichael Walsh gp.qprintn() 81780dddde9SMichael Walsh gp.qprint_executing() 818f566fb1fSMichael Walsh gp.lprint_executing() 819f566fb1fSMichael Walsh 820f566fb1fSMichael Walsh # Restore original sigusr1 handler. 821f566fb1fSMichael Walsh set_default_siguser1() 822f566fb1fSMichael Walsh 823f566fb1fSMichael Walsh message = "The caller has asked that the boot test be stopped and marked" 824f566fb1fSMichael Walsh message += " as a failure." 825f566fb1fSMichael Walsh 826f566fb1fSMichael Walsh function_stack = gm.get_function_stack() 827f566fb1fSMichael Walsh if "wait_state" in function_stack: 828c44aa538SMichael Walsh st.set_exit_wait_early_message(message) 829f566fb1fSMichael Walsh else: 830f566fb1fSMichael Walsh BuiltIn().fail(gp.sprint_error(message)) 831f566fb1fSMichael Walsh 832f566fb1fSMichael Walsh 8336741f740SMichael Walshdef run_boot(boot): 8346741f740SMichael Walsh r""" 8356741f740SMichael Walsh Run the specified boot. 8366741f740SMichael Walsh 8376741f740SMichael Walsh Description of arguments: 8386741f740SMichael Walsh boot The name of the boot test to be performed. 8396741f740SMichael Walsh """ 8406741f740SMichael Walsh 8416741f740SMichael Walsh global state 8426741f740SMichael Walsh 843f566fb1fSMichael Walsh signal.signal(signal.SIGUSR1, stop_boot_test) 844f566fb1fSMichael Walsh gp.qprint_timen("stop_boot_test is armed.") 845f566fb1fSMichael Walsh 8466741f740SMichael Walsh print_test_start_message(boot) 8476741f740SMichael Walsh 8486741f740SMichael Walsh plug_in_setup() 8496741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 8506741f740SMichael Walsh grpi.rprocess_plug_in_packages(call_point="pre_boot") 8516741f740SMichael Walsh if rc != 0: 8526741f740SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" +\ 853986d8aeeSMichael Walsh gp.sprint_var(rc, fmt=gp.hexa()) 854f566fb1fSMichael Walsh set_default_siguser1() 8556741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 8566741f740SMichael Walsh 8576741f740SMichael Walsh if test_mode: 8586741f740SMichael Walsh # In test mode, we'll pretend the boot worked by assigning its 8596741f740SMichael Walsh # required end state to the default state value. 86030dadae2SMichael Walsh state = st.strip_anchor_state(boot_table[boot]['end']) 8616741f740SMichael Walsh else: 8626741f740SMichael Walsh # Assertion: We trust that the state data was made fresh by the 8636741f740SMichael Walsh # caller. 8646741f740SMichael Walsh 865b5839d00SMichael Walsh gp.qprintn() 8666741f740SMichael Walsh 8676741f740SMichael Walsh if boot_table[boot]['method_type'] == "keyword": 8680b93fbf8SMichael Walsh rk.my_run_keywords(boot_table[boot].get('lib_file_path', ''), 869b5839d00SMichael Walsh boot_table[boot]['method'], 870b5839d00SMichael Walsh quiet=quiet) 8716741f740SMichael Walsh 8726741f740SMichael Walsh if boot_table[boot]['bmc_reboot']: 8736741f740SMichael Walsh st.wait_for_comm_cycle(int(state['epoch_seconds'])) 87430dadae2SMichael Walsh plug_in_setup() 87530dadae2SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 87630dadae2SMichael Walsh grpi.rprocess_plug_in_packages(call_point="post_reboot") 87730dadae2SMichael Walsh if rc != 0: 8780b93fbf8SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" 879986d8aeeSMichael Walsh error_message += gp.sprint_var(rc, fmt=gp.hexa()) 880f566fb1fSMichael Walsh set_default_siguser1() 88130dadae2SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 8826741f740SMichael Walsh else: 8836741f740SMichael Walsh match_state = st.anchor_state(state) 8846741f740SMichael Walsh del match_state['epoch_seconds'] 8856741f740SMichael Walsh # Wait for the state to change in any way. 8866741f740SMichael Walsh st.wait_state(match_state, wait_time=state_change_timeout, 887600876daSMichael Walsh interval="10 seconds", invert=1) 8886741f740SMichael Walsh 889b5839d00SMichael Walsh gp.qprintn() 8906741f740SMichael Walsh if boot_table[boot]['end']['chassis'] == "Off": 8916741f740SMichael Walsh boot_timeout = power_off_timeout 8926741f740SMichael Walsh else: 8936741f740SMichael Walsh boot_timeout = power_on_timeout 8946741f740SMichael Walsh st.wait_state(boot_table[boot]['end'], wait_time=boot_timeout, 895600876daSMichael Walsh interval="10 seconds") 8966741f740SMichael Walsh 8976741f740SMichael Walsh plug_in_setup() 8986741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 8996741f740SMichael Walsh grpi.rprocess_plug_in_packages(call_point="post_boot") 9006741f740SMichael Walsh if rc != 0: 9016741f740SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" +\ 902986d8aeeSMichael Walsh gp.sprint_var(rc, fmt=gp.hexa()) 903f566fb1fSMichael Walsh set_default_siguser1() 9046741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 9056741f740SMichael Walsh 906f566fb1fSMichael Walsh # Restore original sigusr1 handler. 907f566fb1fSMichael Walsh set_default_siguser1() 908f566fb1fSMichael Walsh 9096741f740SMichael Walsh 9106741f740SMichael Walshdef test_loop_body(): 9116741f740SMichael Walsh r""" 9126741f740SMichael Walsh The main loop body for the loop in main_py. 9136741f740SMichael Walsh 9146741f740SMichael Walsh Description of arguments: 9156741f740SMichael Walsh boot_count The iteration number (starts at 1). 9166741f740SMichael Walsh """ 9176741f740SMichael Walsh 9186741f740SMichael Walsh global boot_count 9196741f740SMichael Walsh global state 9206741f740SMichael Walsh global next_boot 9216741f740SMichael Walsh global boot_success 922325eb548SSunil M global boot_end_time 9236741f740SMichael Walsh 924b5839d00SMichael Walsh gp.qprintn() 9256741f740SMichael Walsh 9266741f740SMichael Walsh next_boot = select_boot() 927b5839d00SMichael Walsh if next_boot == "": 928b5839d00SMichael Walsh return True 9296741f740SMichael Walsh 930b5839d00SMichael Walsh boot_count += 1 931b5839d00SMichael Walsh gp.qprint_timen("Starting boot " + str(boot_count) + ".") 9326741f740SMichael Walsh 933e0cf8d70SMichael Walsh pre_boot_plug_in_setup() 9346741f740SMichael Walsh 9356741f740SMichael Walsh cmd_buf = ["run_boot", next_boot] 9366741f740SMichael Walsh boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf) 9376741f740SMichael Walsh if boot_status == "FAIL": 938b5839d00SMichael Walsh gp.qprint(msg) 9396741f740SMichael Walsh 940b5839d00SMichael Walsh gp.qprintn() 9416741f740SMichael Walsh if boot_status == "PASS": 9426741f740SMichael Walsh boot_success = 1 943004ad3c9SJoy Onyerikwu completion_msg = gp.sprint_timen("BOOT_SUCCESS: \"" + next_boot 944004ad3c9SJoy Onyerikwu + "\" succeeded.") 9456741f740SMichael Walsh else: 9466741f740SMichael Walsh boot_success = 0 947004ad3c9SJoy Onyerikwu completion_msg = gp.sprint_timen("BOOT_FAILED: \"" + next_boot 948004ad3c9SJoy Onyerikwu + "\" failed.") 949325eb548SSunil M 950325eb548SSunil M # Set boot_end_time for use by plug-ins. 951325eb548SSunil M boot_end_time = completion_msg[1:33] 952325eb548SSunil M gp.qprint_var(boot_end_time) 953325eb548SSunil M 954325eb548SSunil M gp.qprint(completion_msg) 9556741f740SMichael Walsh 9566741f740SMichael Walsh boot_results.update(next_boot, boot_status) 9576741f740SMichael Walsh 9586741f740SMichael Walsh plug_in_setup() 9596741f740SMichael Walsh # NOTE: A post_test_case call point failure is NOT counted as a boot 9606741f740SMichael Walsh # failure. 9616741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 962600876daSMichael Walsh call_point='post_test_case', stop_on_plug_in_failure=0) 9636741f740SMichael Walsh 9646741f740SMichael Walsh plug_in_setup() 9656741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 96689de14a4SMichael Walsh call_point='ffdc_check', shell_rc=dump_ffdc_rc(), 9676741f740SMichael Walsh stop_on_plug_in_failure=1, stop_on_non_zero_rc=1) 96812059e26SMichael Walsh if ffdc_check == "All" or\ 96989de14a4SMichael Walsh shell_rc == dump_ffdc_rc(): 97083f4bc77SMichael Walsh status, ret_values = grk.run_key_u("my_ffdc", ignore=1) 97183f4bc77SMichael Walsh if status != 'PASS': 972ff340006SMichael Walsh gp.qprint_error("Call to my_ffdc failed.\n") 973c9bd2e87SMichael Walsh # Leave a record for caller that "soft" errors occurred. 974c9bd2e87SMichael Walsh soft_errors = 1 975c9bd2e87SMichael Walsh gpu.save_plug_in_value(soft_errors, pgm_name) 9766741f740SMichael Walsh 977aabef1e3SMichael Walsh if delete_errlogs: 9781a67b08aSMichael Shepos # print error logs before delete 979*438fd3b6SGeorge Keishing if redfish_support_trans_state: 980*438fd3b6SGeorge Keishing status, error_logs = grk.run_key_u("Get Redfish Event Logs") 981*438fd3b6SGeorge Keishing log.print_error_logs(error_logs, "AdditionalDataURI Message Severity") 982*438fd3b6SGeorge Keishing else: 9831a67b08aSMichael Shepos status, error_logs = grk.run_key_u("Get Error Logs") 9840e5f1137SMichael Shepos log.print_error_logs(error_logs, "AdditionalData Message Severity") 985*438fd3b6SGeorge Keishing pels = pel.peltool("-l", ignore_err=1) 9860e5f1137SMichael Shepos gp.qprint_var(pels) 9871a67b08aSMichael Shepos 988d139f286SMichael Walsh # We need to purge error logs between boots or they build up. 989409ad35aSMichael Walsh grk.run_key(delete_errlogs_cmd, ignore=1) 99092a54bf5SMichael Shepos grk.run_key(delete_bmcdump_cmd, ignore=1) 9912ef6a7dbSGeorge Keishing if redfish_support_trans_state: 9922ef6a7dbSGeorge Keishing grk.run_key(delete_sysdump_cmd, ignore=1) 993d139f286SMichael Walsh 994952f9b09SMichael Walsh boot_results.print_report() 995b5839d00SMichael Walsh gp.qprint_timen("Finished boot " + str(boot_count) + ".") 996952f9b09SMichael Walsh 9976741f740SMichael Walsh plug_in_setup() 9986741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 99989de14a4SMichael Walsh call_point='stop_check', shell_rc=stop_test_rc(), 100089de14a4SMichael Walsh stop_on_non_zero_rc=1) 100189de14a4SMichael Walsh if shell_rc == stop_test_rc(): 10023ba8ecdcSMichael Walsh message = "Stopping as requested by user.\n" 100380dddde9SMichael Walsh gp.qprint_time(message) 10043ba8ecdcSMichael Walsh BuiltIn().fail(message) 10056741f740SMichael Walsh 1006d139f286SMichael Walsh # This should help prevent ConnectionErrors. 10074d65c86dSGeorge Keishing # Purge all redfish and REST connection sessions. 1008d86e45c6SGeorge Keishing if redfish_delete_sessions: 10094d65c86dSGeorge Keishing grk.run_key_u("Close All Connections", ignore=1) 10104d65c86dSGeorge Keishing grk.run_key_u("Delete All Redfish Sessions", ignore=1) 1011d139f286SMichael Walsh 10126741f740SMichael Walsh return True 10136741f740SMichael Walsh 10146741f740SMichael Walsh 101583f4bc77SMichael Walshdef obmc_boot_test_teardown(): 10166741f740SMichael Walsh r""" 1017f75d4354SMichael Walsh Clean up after the main keyword. 10186741f740SMichael Walsh """ 1019f75d4354SMichael Walsh gp.qprint_executing() 1020f75d4354SMichael Walsh 1021f75d4354SMichael Walsh if ga.psutil_imported: 1022f75d4354SMichael Walsh ga.terminate_descendants() 10236741f740SMichael Walsh 10246741f740SMichael Walsh if cp_setup_called: 10256741f740SMichael Walsh plug_in_setup() 10266741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 1027600876daSMichael Walsh call_point='cleanup', stop_on_plug_in_failure=0) 10286741f740SMichael Walsh 1029600876daSMichael Walsh if 'boot_results_file_path' in globals(): 1030986d8aeeSMichael Walsh # Save boot_results and boot_history objects to a file in case they are 10316c64574bSMichael Walsh # needed again. 1032b5839d00SMichael Walsh gp.qprint_timen("Saving boot_results to the following path.") 1033b5839d00SMichael Walsh gp.qprint_var(boot_results_file_path) 1034986d8aeeSMichael Walsh pickle.dump((boot_results, boot_history), 10356c64574bSMichael Walsh open(boot_results_file_path, 'wb'), 10360b93fbf8SMichael Walsh pickle.HIGHEST_PROTOCOL) 10370b93fbf8SMichael Walsh 1038ff340006SMichael Walsh global save_stack 1039ff340006SMichael Walsh # Restore any global values saved on the save_stack. 1040ff340006SMichael Walsh for parm_name in main_func_parm_list: 1041ff340006SMichael Walsh # Get the parm_value if it was saved on the stack. 1042ff340006SMichael Walsh try: 1043ff340006SMichael Walsh parm_value = save_stack.pop(parm_name) 1044004ad3c9SJoy Onyerikwu except BaseException: 1045ff340006SMichael Walsh # If it was not saved, no further action is required. 1046ff340006SMichael Walsh continue 1047ff340006SMichael Walsh 1048ff340006SMichael Walsh # Restore the saved value. 1049ff340006SMichael Walsh cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\ 1050ff340006SMichael Walsh "}\", parm_value)" 1051ff340006SMichael Walsh gp.dpissuing(cmd_buf) 1052ff340006SMichael Walsh exec(cmd_buf) 1053ff340006SMichael Walsh 1054ff340006SMichael Walsh gp.dprintn(save_stack.sprint_obj()) 1055ff340006SMichael Walsh 10566741f740SMichael Walsh 1057c9116811SMichael Walshdef test_teardown(): 1058c9116811SMichael Walsh r""" 1059c9116811SMichael Walsh Clean up after this test case. 1060c9116811SMichael Walsh """ 1061c9116811SMichael Walsh 1062c9116811SMichael Walsh gp.qprintn() 1063f75d4354SMichael Walsh gp.qprint_executing() 1064f75d4354SMichael Walsh 1065f75d4354SMichael Walsh if ga.psutil_imported: 1066f75d4354SMichael Walsh ga.terminate_descendants() 1067f75d4354SMichael Walsh 1068c9116811SMichael Walsh cmd_buf = ["Print Error", 1069c9116811SMichael Walsh "A keyword timeout occurred ending this program.\n"] 1070c9116811SMichael Walsh BuiltIn().run_keyword_if_timeout_occurred(*cmd_buf) 1071c9116811SMichael Walsh 1072a54e06f5SGeorge Keishing if redfish_supported: 1073a54e06f5SGeorge Keishing redfish.logout() 1074a54e06f5SGeorge Keishing 1075c108e429SMichael Walsh gp.qprint_pgm_footer() 1076b5839d00SMichael Walsh 1077c9116811SMichael Walsh 107889de14a4SMichael Walshdef post_stack(): 107989de14a4SMichael Walsh r""" 108089de14a4SMichael Walsh Process post_stack plug-in programs. 108189de14a4SMichael Walsh """ 108289de14a4SMichael Walsh 108389de14a4SMichael Walsh if not call_post_stack_plug: 108489de14a4SMichael Walsh # The caller does not wish to have post_stack plug-in processing done. 108589de14a4SMichael Walsh return 108689de14a4SMichael Walsh 108789de14a4SMichael Walsh global boot_success 108889de14a4SMichael Walsh 108989de14a4SMichael Walsh # NOTE: A post_stack call-point failure is NOT counted as a boot failure. 109089de14a4SMichael Walsh pre_boot_plug_in_setup() 109189de14a4SMichael Walsh # For the purposes of the following plug-ins, mark the "boot" as a success. 109289de14a4SMichael Walsh boot_success = 1 109389de14a4SMichael Walsh plug_in_setup() 1094815b1d5bSMichael Walsh rc, shell_rc, failed_plug_in_name, history =\ 1095815b1d5bSMichael Walsh grpi.rprocess_plug_in_packages(call_point='post_stack', 1096815b1d5bSMichael Walsh stop_on_plug_in_failure=0, 1097815b1d5bSMichael Walsh return_history=True) 1098986d8aeeSMichael Walsh for doing_msg in history: 1099986d8aeeSMichael Walsh update_boot_history(boot_history, doing_msg, max_boot_history) 1100815b1d5bSMichael Walsh if rc != 0: 1101815b1d5bSMichael Walsh boot_success = 0 110289de14a4SMichael Walsh 110389de14a4SMichael Walsh plug_in_setup() 1104815b1d5bSMichael Walsh rc, shell_rc, failed_plug_in_name =\ 1105815b1d5bSMichael Walsh grpi.rprocess_plug_in_packages(call_point='ffdc_check', 1106815b1d5bSMichael Walsh shell_rc=dump_ffdc_rc(), 1107815b1d5bSMichael Walsh stop_on_plug_in_failure=1, 1108815b1d5bSMichael Walsh stop_on_non_zero_rc=1) 1109815b1d5bSMichael Walsh if shell_rc == dump_ffdc_rc(): 111089de14a4SMichael Walsh status, ret_values = grk.run_key_u("my_ffdc", ignore=1) 111189de14a4SMichael Walsh if status != 'PASS': 111289de14a4SMichael Walsh gp.qprint_error("Call to my_ffdc failed.\n") 1113c9bd2e87SMichael Walsh # Leave a record for caller that "soft" errors occurred. 1114c9bd2e87SMichael Walsh soft_errors = 1 1115c9bd2e87SMichael Walsh gpu.save_plug_in_value(soft_errors, pgm_name) 111689de14a4SMichael Walsh 111789de14a4SMichael Walsh plug_in_setup() 111889de14a4SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 111989de14a4SMichael Walsh call_point='stop_check', shell_rc=stop_test_rc(), 112089de14a4SMichael Walsh stop_on_non_zero_rc=1) 112189de14a4SMichael Walsh if shell_rc == stop_test_rc(): 112289de14a4SMichael Walsh message = "Stopping as requested by user.\n" 112380dddde9SMichael Walsh gp.qprint_time(message) 112489de14a4SMichael Walsh BuiltIn().fail(message) 112589de14a4SMichael Walsh 112689de14a4SMichael Walsh 1127ff340006SMichael Walshdef obmc_boot_test_py(loc_boot_stack=None, 1128ff340006SMichael Walsh loc_stack_mode=None, 1129ff340006SMichael Walsh loc_quiet=None): 11306741f740SMichael Walsh r""" 11316741f740SMichael Walsh Do main program processing. 11326741f740SMichael Walsh """ 11336741f740SMichael Walsh 1134ff340006SMichael Walsh global save_stack 1135ff340006SMichael Walsh 1136f75d4354SMichael Walsh ga.set_term_options(term_requests={'pgm_names': ['process_plug_in_packages.py']}) 1137f75d4354SMichael Walsh 113836efbc04SGeorge Keishing gp.dprintn() 1139ff340006SMichael Walsh # Process function parms. 1140ff340006SMichael Walsh for parm_name in main_func_parm_list: 1141ff340006SMichael Walsh # Get parm's value. 114236efbc04SGeorge Keishing parm_value = eval("loc_" + parm_name) 114336efbc04SGeorge Keishing gp.dpvars(parm_name, parm_value) 1144ff340006SMichael Walsh 114536efbc04SGeorge Keishing if parm_value is not None: 1146ff340006SMichael Walsh # Save the global value on a stack. 1147ff340006SMichael Walsh cmd_buf = "save_stack.push(BuiltIn().get_variable_value(\"${" +\ 1148ff340006SMichael Walsh parm_name + "}\"), \"" + parm_name + "\")" 1149ff340006SMichael Walsh gp.dpissuing(cmd_buf) 1150ff340006SMichael Walsh exec(cmd_buf) 1151ff340006SMichael Walsh 1152ff340006SMichael Walsh # Set the global value to the passed value. 1153ff340006SMichael Walsh cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\ 1154ff340006SMichael Walsh "}\", loc_" + parm_name + ")" 1155ff340006SMichael Walsh gp.dpissuing(cmd_buf) 1156ff340006SMichael Walsh exec(cmd_buf) 1157ff340006SMichael Walsh 1158ff340006SMichael Walsh gp.dprintn(save_stack.sprint_obj()) 1159b5839d00SMichael Walsh 11606741f740SMichael Walsh setup() 11616741f740SMichael Walsh 1162cd9fbfd7SMichael Walsh init_boot_pass, init_boot_fail = boot_results.return_total_pass_fail() 1163cd9fbfd7SMichael Walsh 1164a20da401SMichael Walsh if ffdc_only: 1165a20da401SMichael Walsh gp.qprint_timen("Caller requested ffdc_only.") 1166986d8aeeSMichael Walsh if do_pre_boot_plug_in_setup: 1167e0cf8d70SMichael Walsh pre_boot_plug_in_setup() 116883f4bc77SMichael Walsh grk.run_key_u("my_ffdc") 1169764d2f83SMichael Walsh return 1170a20da401SMichael Walsh 1171409ad35aSMichael Walsh if delete_errlogs: 11721a67b08aSMichael Shepos # print error logs before delete 1173*438fd3b6SGeorge Keishing if redfish_support_trans_state: 1174*438fd3b6SGeorge Keishing status, error_logs = grk.run_key_u("Get Redfish Event Logs") 1175*438fd3b6SGeorge Keishing log.print_error_logs(error_logs, "AdditionalDataURI Message Severity") 1176*438fd3b6SGeorge Keishing else: 11771a67b08aSMichael Shepos status, error_logs = grk.run_key_u("Get Error Logs") 11780e5f1137SMichael Shepos log.print_error_logs(error_logs, "AdditionalData Message Severity") 1179*438fd3b6SGeorge Keishing pels = pel.peltool("-l", ignore_err=1) 11800e5f1137SMichael Shepos gp.qprint_var(pels) 11811a67b08aSMichael Shepos 1182409ad35aSMichael Walsh # Delete errlogs prior to doing any boot tests. 1183409ad35aSMichael Walsh grk.run_key(delete_errlogs_cmd, ignore=1) 118492a54bf5SMichael Shepos grk.run_key(delete_bmcdump_cmd, ignore=1) 11852ef6a7dbSGeorge Keishing if redfish_support_trans_state: 11862ef6a7dbSGeorge Keishing grk.run_key(delete_sysdump_cmd, ignore=1) 1187409ad35aSMichael Walsh 11886741f740SMichael Walsh # Process caller's boot_stack. 11896741f740SMichael Walsh while (len(boot_stack) > 0): 11906741f740SMichael Walsh test_loop_body() 11916741f740SMichael Walsh 1192b5839d00SMichael Walsh gp.qprint_timen("Finished processing stack.") 119330dadae2SMichael Walsh 119489de14a4SMichael Walsh post_stack() 119589de14a4SMichael Walsh 11966741f740SMichael Walsh # Process caller's boot_list. 11976741f740SMichael Walsh if len(boot_list) > 0: 11986741f740SMichael Walsh for ix in range(1, max_num_tests + 1): 11996741f740SMichael Walsh test_loop_body() 12006741f740SMichael Walsh 1201b5839d00SMichael Walsh gp.qprint_timen("Completed all requested boot tests.") 1202b5839d00SMichael Walsh 1203b5839d00SMichael Walsh boot_pass, boot_fail = boot_results.return_total_pass_fail() 1204cd9fbfd7SMichael Walsh new_fail = boot_fail - init_boot_fail 1205cd9fbfd7SMichael Walsh if new_fail > boot_fail_threshold: 1206b5839d00SMichael Walsh error_message = "Boot failures exceed the boot failure" +\ 1207b5839d00SMichael Walsh " threshold:\n" +\ 1208cd9fbfd7SMichael Walsh gp.sprint_var(new_fail) +\ 1209b5839d00SMichael Walsh gp.sprint_var(boot_fail_threshold) 1210b5839d00SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 1211