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 13d54bbc22SGeorge Keishingtry: 140b93fbf8SMichael Walsh import cPickle as pickle 15d54bbc22SGeorge Keishingexcept ImportError: 16d54bbc22SGeorge Keishing import pickle 17dc80d67dSMichael Walshimport socket 180b93fbf8SMichael Walsh 190b93fbf8SMichael Walshfrom robot.utils import DotDict 200b93fbf8SMichael Walshfrom robot.libraries.BuiltIn import BuiltIn 210b93fbf8SMichael Walsh 226741f740SMichael Walshfrom boot_data import * 23c9116811SMichael Walshimport gen_print as gp 240bbd860fSMichael Walshimport gen_robot_print as grp 2555302295SMichael Walshimport gen_robot_plug_in as grpi 266741f740SMichael Walshimport gen_robot_valid as grv 276741f740SMichael Walshimport gen_misc as gm 286741f740SMichael Walshimport gen_cmd as gc 29b5839d00SMichael Walshimport gen_robot_keyword as grk 3055302295SMichael Walshimport state as st 31ff340006SMichael Walshimport var_stack as vs 320bbd860fSMichael Walsh 330b93fbf8SMichael Walshbase_path = os.path.dirname(os.path.dirname( 340b93fbf8SMichael Walsh imp.find_module("gen_robot_print")[1])) +\ 350b93fbf8SMichael Walsh os.sep 360b93fbf8SMichael Walshsys.path.append(base_path + "extended/") 370b93fbf8SMichael Walshimport run_keyword as rk 380bbd860fSMichael Walsh 39e1e26448SMichael Walsh# Setting master_pid correctly influences the behavior of plug-ins like 40e1e26448SMichael Walsh# DB_Logging 41e1e26448SMichael Walshprogram_pid = os.getpid() 42e1e26448SMichael Walshmaster_pid = os.environ.get('AUTOBOOT_MASTER_PID', program_pid) 43004ad3c9SJoy Onyerikwupgm_name = re.sub('\\.py$', '', os.path.basename(__file__)) 44e1e26448SMichael Walsh 45b5839d00SMichael Walsh# Set up boot data structures. 46b5839d00SMichael Walshboot_table = create_boot_table() 47b5839d00SMichael Walshvalid_boot_types = create_valid_boot_list(boot_table) 480b93fbf8SMichael Walsh 496741f740SMichael Walshboot_lists = read_boot_lists() 506741f740SMichael Walshlast_ten = [] 516741f740SMichael Walsh 527dc885b6SMichael Walshstate = st.return_state_constant('default_state') 536741f740SMichael Walshcp_setup_called = 0 546741f740SMichael Walshnext_boot = "" 556741f740SMichael Walshbase_tool_dir_path = os.path.normpath(os.environ.get( 566741f740SMichael Walsh 'AUTOBOOT_BASE_TOOL_DIR_PATH', "/tmp")) + os.sep 57b5839d00SMichael Walsh 586741f740SMichael Walshffdc_dir_path = os.path.normpath(os.environ.get('FFDC_DIR_PATH', '')) + os.sep 596741f740SMichael Walshboot_success = 0 606741f740SMichael Walshstatus_dir_path = os.environ.get('STATUS_DIR_PATH', "") 616741f740SMichael Walshif status_dir_path != "": 626741f740SMichael Walsh status_dir_path = os.path.normpath(status_dir_path) + os.sep 630b93fbf8SMichael Walshdefault_power_on = "REST Power On" 640b93fbf8SMichael Walshdefault_power_off = "REST Power Off" 656741f740SMichael Walshboot_count = 0 660bbd860fSMichael Walsh 6785678948SMichael WalshLOG_LEVEL = BuiltIn().get_variable_value("${LOG_LEVEL}") 68e1974b96SMichael Walshffdc_prefix = "" 69325eb548SSunil Mboot_start_time = "" 70325eb548SSunil Mboot_end_time = "" 71ff340006SMichael Walshsave_stack = vs.var_stack('save_stack') 72ff340006SMichael Walshmain_func_parm_list = ['boot_stack', 'stack_mode', 'quiet'] 7385678948SMichael Walsh 7485678948SMichael Walsh 75*89de14a4SMichael Walshdef dump_ffdc_rc(): 76*89de14a4SMichael Walsh r""" 77*89de14a4SMichael Walsh Return the constant dump ffdc test return code value. 78*89de14a4SMichael Walsh 79*89de14a4SMichael Walsh When a plug-in call point program returns this value, it indicates that 80*89de14a4SMichael Walsh this program should collect FFDC. 81*89de14a4SMichael Walsh """ 82*89de14a4SMichael Walsh 83*89de14a4SMichael Walsh return 0x00000200 84*89de14a4SMichael Walsh 85*89de14a4SMichael Walsh 86*89de14a4SMichael Walshdef stop_test_rc(): 87*89de14a4SMichael Walsh r""" 88*89de14a4SMichael Walsh Return the constant stop test return code value. 89*89de14a4SMichael Walsh 90*89de14a4SMichael Walsh When a plug-in call point program returns this value, it indicates that 91*89de14a4SMichael Walsh this program should stop running. 92*89de14a4SMichael Walsh """ 93*89de14a4SMichael Walsh 94*89de14a4SMichael Walsh return 0x00000200 95*89de14a4SMichael Walsh 96*89de14a4SMichael Walsh 970ad0f7f8SMichael Walshdef process_host(host, 980ad0f7f8SMichael Walsh host_var_name=""): 990ad0f7f8SMichael Walsh r""" 1000ad0f7f8SMichael Walsh Process a host by getting the associated host name and IP address and 1010ad0f7f8SMichael Walsh setting them in global variables. 1020ad0f7f8SMichael Walsh 1030ad0f7f8SMichael Walsh If the caller does not pass the host_var_name, this function will try to 1040ad0f7f8SMichael Walsh figure out the name of the variable used by the caller for the host parm. 1050ad0f7f8SMichael Walsh Callers are advised to explicitly specify the host_var_name when calling 1060ad0f7f8SMichael Walsh with an exec command. In such cases, the get_arg_name cannot figure out 1070ad0f7f8SMichael Walsh the host variable name. 1080ad0f7f8SMichael Walsh 1090ad0f7f8SMichael Walsh This function will then create similar global variable names by 1100ad0f7f8SMichael Walsh removing "_host" and appending "_host_name" or "_ip" to the host variable 1110ad0f7f8SMichael Walsh name. 1120ad0f7f8SMichael Walsh 1130ad0f7f8SMichael Walsh Example: 1140ad0f7f8SMichael Walsh 1150ad0f7f8SMichael Walsh If a call is made like this: 1160ad0f7f8SMichael Walsh process_host(openbmc_host) 1170ad0f7f8SMichael Walsh 1180ad0f7f8SMichael Walsh Global variables openbmc_host_name and openbmc_ip will be set. 1190ad0f7f8SMichael Walsh 1200ad0f7f8SMichael Walsh Description of argument(s): 1210ad0f7f8SMichael Walsh host A host name or IP. The name of the variable used should 1220ad0f7f8SMichael Walsh have a suffix of "_host". 1230ad0f7f8SMichael Walsh host_var_name The name of the variable being used as the host parm. 1240ad0f7f8SMichael Walsh """ 1250ad0f7f8SMichael Walsh 1260ad0f7f8SMichael Walsh if host_var_name == "": 1270ad0f7f8SMichael Walsh host_var_name = gp.get_arg_name(0, 1, stack_frame_ix=2) 1280ad0f7f8SMichael Walsh 1290ad0f7f8SMichael Walsh host_name_var_name = re.sub("host", "host_name", host_var_name) 1300ad0f7f8SMichael Walsh ip_var_name = re.sub("host", "ip", host_var_name) 1310ad0f7f8SMichael Walsh cmd_buf = "global " + host_name_var_name + ", " + ip_var_name + " ; " +\ 1320ad0f7f8SMichael Walsh host_name_var_name + ", " + ip_var_name + " = gm.get_host_name_ip('" +\ 1330ad0f7f8SMichael Walsh host + "')" 1340ad0f7f8SMichael Walsh exec(cmd_buf) 1350ad0f7f8SMichael Walsh 1360ad0f7f8SMichael Walsh 137b5839d00SMichael Walshdef process_pgm_parms(): 138b5839d00SMichael Walsh r""" 139b5839d00SMichael Walsh Process the program parameters by assigning them all to corresponding 140b5839d00SMichael Walsh globals. Also, set some global values that depend on program parameters. 141b5839d00SMichael Walsh """ 142b5839d00SMichael Walsh 143b5839d00SMichael Walsh # Program parameter processing. 144b5839d00SMichael Walsh # Assign all program parms to python variables which are global to this 145b5839d00SMichael Walsh # module. 146b5839d00SMichael Walsh 147b5839d00SMichael Walsh global parm_list 148b5839d00SMichael Walsh parm_list = BuiltIn().get_variable_value("${parm_list}") 149b5839d00SMichael Walsh # The following subset of parms should be processed as integers. 150b5839d00SMichael Walsh int_list = ['max_num_tests', 'boot_pass', 'boot_fail', 'ffdc_only', 151*89de14a4SMichael Walsh 'boot_fail_threshold', 'delete_errlogs', 152*89de14a4SMichael Walsh 'call_post_stack_plug', 'quiet', 'test_mode', 'debug'] 153b5839d00SMichael Walsh for parm in parm_list: 154b5839d00SMichael Walsh if parm in int_list: 155b5839d00SMichael Walsh sub_cmd = "int(BuiltIn().get_variable_value(\"${" + parm +\ 156b5839d00SMichael Walsh "}\", \"0\"))" 157b5839d00SMichael Walsh else: 158b5839d00SMichael Walsh sub_cmd = "BuiltIn().get_variable_value(\"${" + parm + "}\")" 159b5839d00SMichael Walsh cmd_buf = "global " + parm + " ; " + parm + " = " + sub_cmd 160ff340006SMichael Walsh gp.dpissuing(cmd_buf) 161b5839d00SMichael Walsh exec(cmd_buf) 1620ad0f7f8SMichael Walsh if re.match(r".*_host$", parm): 1630ad0f7f8SMichael Walsh cmd_buf = "process_host(" + parm + ", '" + parm + "')" 1640ad0f7f8SMichael Walsh exec(cmd_buf) 1650ad0f7f8SMichael Walsh if re.match(r".*_password$", parm): 1660ad0f7f8SMichael Walsh # Register the value of any parm whose name ends in _password. 1670ad0f7f8SMichael Walsh # This will cause the print functions to replace passwords with 1680ad0f7f8SMichael Walsh # asterisks in the output. 1690ad0f7f8SMichael Walsh cmd_buf = "gp.register_passwords(" + parm + ")" 1700ad0f7f8SMichael Walsh exec(cmd_buf) 171b5839d00SMichael Walsh 172b5839d00SMichael Walsh global ffdc_dir_path_style 173b5839d00SMichael Walsh global boot_list 174b5839d00SMichael Walsh global boot_stack 175b5839d00SMichael Walsh global boot_results_file_path 176b5839d00SMichael Walsh global boot_results 1776c64574bSMichael Walsh global last_ten 178b5839d00SMichael Walsh global ffdc_list_file_path 179e0cf8d70SMichael Walsh global ffdc_report_list_path 180600876daSMichael Walsh global ffdc_summary_list_path 181b5839d00SMichael Walsh 182b5839d00SMichael Walsh if ffdc_dir_path_style == "": 183b5839d00SMichael Walsh ffdc_dir_path_style = int(os.environ.get('FFDC_DIR_PATH_STYLE', '0')) 184b5839d00SMichael Walsh 185b5839d00SMichael Walsh # Convert these program parms to lists for easier processing.. 186b5839d00SMichael Walsh boot_list = filter(None, boot_list.split(":")) 187b5839d00SMichael Walsh boot_stack = filter(None, boot_stack.split(":")) 188b5839d00SMichael Walsh 189903e0b20SMichael Walsh cleanup_boot_results_file() 190903e0b20SMichael Walsh boot_results_file_path = create_boot_results_file_path(pgm_name, 191903e0b20SMichael Walsh openbmc_nickname, 192903e0b20SMichael Walsh master_pid) 193b5839d00SMichael Walsh 194b5839d00SMichael Walsh if os.path.isfile(boot_results_file_path): 195b5839d00SMichael Walsh # We've been called before in this run so we'll load the saved 1966c64574bSMichael Walsh # boot_results and last_ten objects. 1976c64574bSMichael Walsh boot_results, last_ten =\ 1986c64574bSMichael Walsh pickle.load(open(boot_results_file_path, 'rb')) 199b5839d00SMichael Walsh else: 200b5839d00SMichael Walsh boot_results = boot_results(boot_table, boot_pass, boot_fail) 201b5839d00SMichael Walsh 202b5839d00SMichael Walsh ffdc_list_file_path = base_tool_dir_path + openbmc_nickname +\ 203b5839d00SMichael Walsh "/FFDC_FILE_LIST" 204e0cf8d70SMichael Walsh ffdc_report_list_path = base_tool_dir_path + openbmc_nickname +\ 205e0cf8d70SMichael Walsh "/FFDC_REPORT_FILE_LIST" 206b5839d00SMichael Walsh 207600876daSMichael Walsh ffdc_summary_list_path = base_tool_dir_path + openbmc_nickname +\ 208600876daSMichael Walsh "/FFDC_SUMMARY_FILE_LIST" 209600876daSMichael Walsh 210b5839d00SMichael Walsh 21185678948SMichael Walshdef initial_plug_in_setup(): 21285678948SMichael Walsh r""" 21385678948SMichael Walsh Initialize all plug-in environment variables which do not change for the 21485678948SMichael Walsh duration of the program. 21585678948SMichael Walsh 21685678948SMichael Walsh """ 21785678948SMichael Walsh 21885678948SMichael Walsh global LOG_LEVEL 21985678948SMichael Walsh BuiltIn().set_log_level("NONE") 22085678948SMichael Walsh 22185678948SMichael Walsh BuiltIn().set_global_variable("${master_pid}", master_pid) 22285678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path) 22385678948SMichael Walsh BuiltIn().set_global_variable("${STATUS_DIR_PATH}", status_dir_path) 22485678948SMichael Walsh BuiltIn().set_global_variable("${BASE_TOOL_DIR_PATH}", base_tool_dir_path) 22585678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_LIST_FILE_PATH}", 22685678948SMichael Walsh ffdc_list_file_path) 227e0cf8d70SMichael Walsh BuiltIn().set_global_variable("${FFDC_REPORT_LIST_PATH}", 228e0cf8d70SMichael Walsh ffdc_report_list_path) 229600876daSMichael Walsh BuiltIn().set_global_variable("${FFDC_SUMMARY_LIST_PATH}", 230600876daSMichael Walsh ffdc_summary_list_path) 23185678948SMichael Walsh 23285678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_DIR_PATH_STYLE}", 23385678948SMichael Walsh ffdc_dir_path_style) 23485678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_CHECK}", 23585678948SMichael Walsh ffdc_check) 23685678948SMichael Walsh 23785678948SMichael Walsh # For each program parameter, set the corresponding AUTOBOOT_ environment 23885678948SMichael Walsh # variable value. Also, set an AUTOBOOT_ environment variable for every 23985678948SMichael Walsh # element in additional_values. 24085678948SMichael Walsh additional_values = ["program_pid", "master_pid", "ffdc_dir_path", 24185678948SMichael Walsh "status_dir_path", "base_tool_dir_path", 242600876daSMichael Walsh "ffdc_list_file_path", "ffdc_report_list_path", 243600876daSMichael Walsh "ffdc_summary_list_path"] 24485678948SMichael Walsh 24585678948SMichael Walsh plug_in_vars = parm_list + additional_values 24685678948SMichael Walsh 24785678948SMichael Walsh for var_name in plug_in_vars: 24885678948SMichael Walsh var_value = BuiltIn().get_variable_value("${" + var_name + "}") 24985678948SMichael Walsh var_name = var_name.upper() 25085678948SMichael Walsh if var_value is None: 25185678948SMichael Walsh var_value = "" 25285678948SMichael Walsh os.environ["AUTOBOOT_" + var_name] = str(var_value) 25385678948SMichael Walsh 25485678948SMichael Walsh BuiltIn().set_log_level(LOG_LEVEL) 25585678948SMichael Walsh 25668a61162SMichael Walsh # Make sure the ffdc list directory exists. 25768a61162SMichael Walsh ffdc_list_dir_path = os.path.dirname(ffdc_list_file_path) + os.sep 25868a61162SMichael Walsh if not os.path.exists(ffdc_list_dir_path): 25968a61162SMichael Walsh os.makedirs(ffdc_list_dir_path) 26085678948SMichael Walsh 26185678948SMichael Walsh 2620bbd860fSMichael Walshdef plug_in_setup(): 2630bbd860fSMichael Walsh r""" 26485678948SMichael Walsh Initialize all changing plug-in environment variables for use by the 26585678948SMichael Walsh plug-in programs. 2660bbd860fSMichael Walsh """ 2670bbd860fSMichael Walsh 26885678948SMichael Walsh global LOG_LEVEL 26985678948SMichael Walsh global test_really_running 27085678948SMichael Walsh 27185678948SMichael Walsh BuiltIn().set_log_level("NONE") 27285678948SMichael Walsh 2736741f740SMichael Walsh boot_pass, boot_fail = boot_results.return_total_pass_fail() 2740bbd860fSMichael Walsh if boot_pass > 1: 2750bbd860fSMichael Walsh test_really_running = 1 2760bbd860fSMichael Walsh else: 2770bbd860fSMichael Walsh test_really_running = 0 2780bbd860fSMichael Walsh 2796741f740SMichael Walsh BuiltIn().set_global_variable("${test_really_running}", 2806741f740SMichael Walsh test_really_running) 2816741f740SMichael Walsh BuiltIn().set_global_variable("${boot_type_desc}", next_boot) 2826741f740SMichael Walsh BuiltIn().set_global_variable("${boot_pass}", boot_pass) 2836741f740SMichael Walsh BuiltIn().set_global_variable("${boot_fail}", boot_fail) 2846741f740SMichael Walsh BuiltIn().set_global_variable("${boot_success}", boot_success) 2856741f740SMichael Walsh BuiltIn().set_global_variable("${ffdc_prefix}", ffdc_prefix) 286325eb548SSunil M BuiltIn().set_global_variable("${boot_start_time}", boot_start_time) 287325eb548SSunil M BuiltIn().set_global_variable("${boot_end_time}", boot_end_time) 2884c9a6453SMichael Walsh 2890bbd860fSMichael Walsh # For each program parameter, set the corresponding AUTOBOOT_ environment 2900bbd860fSMichael Walsh # variable value. Also, set an AUTOBOOT_ environment variable for every 2910bbd860fSMichael Walsh # element in additional_values. 2920bbd860fSMichael Walsh additional_values = ["boot_type_desc", "boot_success", "boot_pass", 293325eb548SSunil M "boot_fail", "test_really_running", "ffdc_prefix", 294325eb548SSunil M "boot_start_time", "boot_end_time"] 2950bbd860fSMichael Walsh 29685678948SMichael Walsh plug_in_vars = additional_values 2970bbd860fSMichael Walsh 2980bbd860fSMichael Walsh for var_name in plug_in_vars: 2990bbd860fSMichael Walsh var_value = BuiltIn().get_variable_value("${" + var_name + "}") 3000bbd860fSMichael Walsh var_name = var_name.upper() 3010bbd860fSMichael Walsh if var_value is None: 3020bbd860fSMichael Walsh var_value = "" 3036741f740SMichael Walsh os.environ["AUTOBOOT_" + var_name] = str(var_value) 3040bbd860fSMichael Walsh 3050bbd860fSMichael Walsh if debug: 3066741f740SMichael Walsh shell_rc, out_buf = \ 3076741f740SMichael Walsh gc.cmd_fnc_u("printenv | egrep AUTOBOOT_ | sort -u") 3080bbd860fSMichael Walsh 30985678948SMichael Walsh BuiltIn().set_log_level(LOG_LEVEL) 31085678948SMichael Walsh 3110bbd860fSMichael Walsh 312e0cf8d70SMichael Walshdef pre_boot_plug_in_setup(): 313e0cf8d70SMichael Walsh 314e0cf8d70SMichael Walsh # Clear the ffdc_list_file_path file. Plug-ins may now write to it. 315e0cf8d70SMichael Walsh try: 316e0cf8d70SMichael Walsh os.remove(ffdc_list_file_path) 317e0cf8d70SMichael Walsh except OSError: 318e0cf8d70SMichael Walsh pass 319e0cf8d70SMichael Walsh 320e0cf8d70SMichael Walsh # Clear the ffdc_report_list_path file. Plug-ins may now write to it. 321e0cf8d70SMichael Walsh try: 322e0cf8d70SMichael Walsh os.remove(ffdc_report_list_path) 323e0cf8d70SMichael Walsh except OSError: 324e0cf8d70SMichael Walsh pass 325e0cf8d70SMichael Walsh 326600876daSMichael Walsh # Clear the ffdc_summary_list_path file. Plug-ins may now write to it. 327600876daSMichael Walsh try: 328600876daSMichael Walsh os.remove(ffdc_summary_list_path) 329600876daSMichael Walsh except OSError: 330600876daSMichael Walsh pass 331600876daSMichael Walsh 332e1974b96SMichael Walsh global ffdc_prefix 333e1974b96SMichael Walsh 334e1974b96SMichael Walsh seconds = time.time() 335e1974b96SMichael Walsh loc_time = time.localtime(seconds) 336e1974b96SMichael Walsh time_string = time.strftime("%y%m%d.%H%M%S.", loc_time) 337e1974b96SMichael Walsh 338e1974b96SMichael Walsh ffdc_prefix = openbmc_nickname + "." + time_string 339e1974b96SMichael Walsh 340e0cf8d70SMichael Walsh 3416741f740SMichael Walshdef setup(): 3420bbd860fSMichael Walsh r""" 3436741f740SMichael Walsh Do general program setup tasks. 3440bbd860fSMichael Walsh """ 3450bbd860fSMichael Walsh 3466741f740SMichael Walsh global cp_setup_called 34781816748SMichael Walsh global transitional_boot_selected 3480bbd860fSMichael Walsh 349b5839d00SMichael Walsh gp.qprintn() 350b5839d00SMichael Walsh 35181816748SMichael Walsh transitional_boot_selected = False 35281816748SMichael Walsh 35383f4bc77SMichael Walsh robot_pgm_dir_path = os.path.dirname(__file__) + os.sep 35483f4bc77SMichael Walsh repo_bin_path = robot_pgm_dir_path.replace("/lib/", "/bin/") 355d061c043SMichael Walsh # If we can't find process_plug_in_packages.py, ssh_pw or 356d061c043SMichael Walsh # validate_plug_ins.py, then we don't have our repo bin in PATH. 357004ad3c9SJoy Onyerikwu shell_rc, out_buf = gc.cmd_fnc_u("which process_plug_in_packages.py" 358004ad3c9SJoy Onyerikwu + " ssh_pw validate_plug_ins.py", quiet=1, 359d061c043SMichael Walsh print_output=0, show_err=0) 360b5839d00SMichael Walsh if shell_rc != 0: 36183f4bc77SMichael Walsh os.environ['PATH'] = repo_bin_path + ":" + os.environ.get('PATH', "") 36283f4bc77SMichael Walsh # Likewise, our repo lib subdir needs to be in sys.path and PYTHONPATH. 36383f4bc77SMichael Walsh if robot_pgm_dir_path not in sys.path: 36483f4bc77SMichael Walsh sys.path.append(robot_pgm_dir_path) 36583f4bc77SMichael Walsh PYTHONPATH = os.environ.get("PYTHONPATH", "") 36683f4bc77SMichael Walsh if PYTHONPATH == "": 36783f4bc77SMichael Walsh os.environ['PYTHONPATH'] = robot_pgm_dir_path 36883f4bc77SMichael Walsh else: 36983f4bc77SMichael Walsh os.environ['PYTHONPATH'] = robot_pgm_dir_path + ":" + PYTHONPATH 3706741f740SMichael Walsh 3716741f740SMichael Walsh validate_parms() 3726741f740SMichael Walsh 3736741f740SMichael Walsh grp.rqprint_pgm_header() 3746741f740SMichael Walsh 375efc3ff2bSGeorge Keishing grk.run_key("Set BMC Power Policy ALWAYS_POWER_OFF") 37611cfc8c0SMichael Walsh 37785678948SMichael Walsh initial_plug_in_setup() 37885678948SMichael Walsh 3796741f740SMichael Walsh plug_in_setup() 3806741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 3816741f740SMichael Walsh call_point='setup') 3826741f740SMichael Walsh if rc != 0: 3836741f740SMichael Walsh error_message = "Plug-in setup failed.\n" 3846741f740SMichael Walsh grp.rprint_error_report(error_message) 3856741f740SMichael Walsh BuiltIn().fail(error_message) 3866741f740SMichael Walsh # Setting cp_setup_called lets our Teardown know that it needs to call 3876741f740SMichael Walsh # the cleanup plug-in call point. 3886741f740SMichael Walsh cp_setup_called = 1 3896741f740SMichael Walsh 3906741f740SMichael Walsh # Keyword "FFDC" will fail if TEST_MESSAGE is not set. 3916741f740SMichael Walsh BuiltIn().set_global_variable("${TEST_MESSAGE}", "${EMPTY}") 39285678948SMichael Walsh # FFDC_LOG_PATH is used by "FFDC" keyword. 39385678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_LOG_PATH}", ffdc_dir_path) 3946741f740SMichael Walsh 395dc80d67dSMichael Walsh # Also printed by FFDC. 396dc80d67dSMichael Walsh global host_name 397dc80d67dSMichael Walsh global host_ip 398dc80d67dSMichael Walsh host = socket.gethostname() 399dc80d67dSMichael Walsh host_name, host_ip = gm.get_host_name_ip(host) 400dc80d67dSMichael Walsh 401b5839d00SMichael Walsh gp.dprint_var(boot_table, 1) 402b5839d00SMichael Walsh gp.dprint_var(boot_lists) 4030bbd860fSMichael Walsh 4040bbd860fSMichael Walsh 4056741f740SMichael Walshdef validate_parms(): 4060bbd860fSMichael Walsh r""" 4076741f740SMichael Walsh Validate all program parameters. 4080bbd860fSMichael Walsh """ 4090bbd860fSMichael Walsh 410b5839d00SMichael Walsh process_pgm_parms() 4110bbd860fSMichael Walsh 412b5839d00SMichael Walsh gp.qprintn() 413b5839d00SMichael Walsh 414b5839d00SMichael Walsh global openbmc_model 4156741f740SMichael Walsh grv.rvalid_value("openbmc_host") 4166741f740SMichael Walsh grv.rvalid_value("openbmc_username") 4176741f740SMichael Walsh grv.rvalid_value("openbmc_password") 4186741f740SMichael Walsh if os_host != "": 4196741f740SMichael Walsh grv.rvalid_value("os_username") 4206741f740SMichael Walsh grv.rvalid_value("os_password") 4210bbd860fSMichael Walsh 4226741f740SMichael Walsh if pdu_host != "": 4236741f740SMichael Walsh grv.rvalid_value("pdu_username") 4246741f740SMichael Walsh grv.rvalid_value("pdu_password") 4256741f740SMichael Walsh grv.rvalid_integer("pdu_slot_no") 4266741f740SMichael Walsh if openbmc_serial_host != "": 4276741f740SMichael Walsh grv.rvalid_integer("openbmc_serial_port") 428b5839d00SMichael Walsh if openbmc_model == "": 429b5839d00SMichael Walsh status, ret_values =\ 430b5839d00SMichael Walsh grk.run_key_u("Get BMC System Model") 431b5839d00SMichael Walsh openbmc_model = ret_values 432b5839d00SMichael Walsh BuiltIn().set_global_variable("${openbmc_model}", openbmc_model) 4336741f740SMichael Walsh grv.rvalid_value("openbmc_model") 434b5839d00SMichael Walsh grv.rvalid_integer("max_num_tests") 4356741f740SMichael Walsh grv.rvalid_integer("boot_pass") 4366741f740SMichael Walsh grv.rvalid_integer("boot_fail") 4376741f740SMichael Walsh 4386741f740SMichael Walsh plug_in_packages_list = grpi.rvalidate_plug_ins(plug_in_dir_paths) 4396741f740SMichael Walsh BuiltIn().set_global_variable("${plug_in_packages_list}", 4406741f740SMichael Walsh plug_in_packages_list) 4416741f740SMichael Walsh 442b5839d00SMichael Walsh grv.rvalid_value("stack_mode", valid_values=['normal', 'skip']) 443a20da401SMichael Walsh if len(boot_list) == 0 and len(boot_stack) == 0 and not ffdc_only: 4446741f740SMichael Walsh error_message = "You must provide either a value for either the" +\ 4456741f740SMichael Walsh " boot_list or the boot_stack parm.\n" 4466741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 4476741f740SMichael Walsh 4486741f740SMichael Walsh valid_boot_list(boot_list, valid_boot_types) 4496741f740SMichael Walsh valid_boot_list(boot_stack, valid_boot_types) 4506741f740SMichael Walsh 451004ad3c9SJoy Onyerikwu selected_PDU_boots = list(set(boot_list + boot_stack) 452004ad3c9SJoy Onyerikwu & set(boot_lists['PDU_reboot'])) 45311cfc8c0SMichael Walsh 45411cfc8c0SMichael Walsh if len(selected_PDU_boots) > 0 and pdu_host == "": 45511cfc8c0SMichael Walsh error_message = "You have selected the following boots which" +\ 45611cfc8c0SMichael Walsh " require a PDU host but no value for pdu_host:\n" 45711cfc8c0SMichael Walsh error_message += gp.sprint_var(selected_PDU_boots) 45811cfc8c0SMichael Walsh error_message += gp.sprint_var(pdu_host, 2) 45911cfc8c0SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 46011cfc8c0SMichael Walsh 4616741f740SMichael Walsh return 4620bbd860fSMichael Walsh 4630bbd860fSMichael Walsh 4646741f740SMichael Walshdef my_get_state(): 4650bbd860fSMichael Walsh r""" 4666741f740SMichael Walsh Get the system state plus a little bit of wrapping. 4670bbd860fSMichael Walsh """ 4680bbd860fSMichael Walsh 4696741f740SMichael Walsh global state 4706741f740SMichael Walsh 4716741f740SMichael Walsh req_states = ['epoch_seconds'] + st.default_req_states 4726741f740SMichael Walsh 473b5839d00SMichael Walsh gp.qprint_timen("Getting system state.") 4746741f740SMichael Walsh if test_mode: 4756741f740SMichael Walsh state['epoch_seconds'] = int(time.time()) 4766741f740SMichael Walsh else: 477b5839d00SMichael Walsh state = st.get_state(req_states=req_states, quiet=quiet) 478b5839d00SMichael Walsh gp.qprint_var(state) 479341c21ebSMichael Walsh 480341c21ebSMichael Walsh 48145ca6e4cSMichael Walshdef valid_state(): 48245ca6e4cSMichael Walsh r""" 48345ca6e4cSMichael Walsh Verify that our state dictionary contains no blank values. If we don't get 48445ca6e4cSMichael Walsh valid state data, we cannot continue to work. 48545ca6e4cSMichael Walsh """ 48645ca6e4cSMichael Walsh 48745ca6e4cSMichael Walsh if st.compare_states(state, st.invalid_state_match, 'or'): 48845ca6e4cSMichael Walsh error_message = "The state dictionary contains blank fields which" +\ 48945ca6e4cSMichael Walsh " is illegal.\n" + gp.sprint_var(state) 49045ca6e4cSMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 49145ca6e4cSMichael Walsh 49245ca6e4cSMichael Walsh 4936741f740SMichael Walshdef select_boot(): 494341c21ebSMichael Walsh r""" 495341c21ebSMichael Walsh Select a boot test to be run based on our current state and return the 496341c21ebSMichael Walsh chosen boot type. 497341c21ebSMichael Walsh 498341c21ebSMichael Walsh Description of arguments: 4996741f740SMichael Walsh state The state of the machine. 500341c21ebSMichael Walsh """ 501341c21ebSMichael Walsh 50281816748SMichael Walsh global transitional_boot_selected 50330dadae2SMichael Walsh global boot_stack 50430dadae2SMichael Walsh 505b5839d00SMichael Walsh gp.qprint_timen("Selecting a boot test.") 5066741f740SMichael Walsh 50781816748SMichael Walsh if transitional_boot_selected and not boot_success: 50881816748SMichael Walsh prior_boot = next_boot 50981816748SMichael Walsh boot_candidate = boot_stack.pop() 510004ad3c9SJoy Onyerikwu gp.qprint_timen("The prior '" + next_boot + "' was chosen to" 511004ad3c9SJoy Onyerikwu + " transition to a valid state for '" + boot_candidate 512004ad3c9SJoy Onyerikwu + "' which was at the top of the boot_stack. Since" 513004ad3c9SJoy Onyerikwu + " the '" + next_boot + "' failed, the '" 514004ad3c9SJoy Onyerikwu + boot_candidate + "' has been removed from the stack" 515004ad3c9SJoy Onyerikwu + " to avoid and endless failure loop.") 51681816748SMichael Walsh if len(boot_stack) == 0: 51781816748SMichael Walsh return "" 51881816748SMichael Walsh 5196741f740SMichael Walsh my_get_state() 52045ca6e4cSMichael Walsh valid_state() 5216741f740SMichael Walsh 52281816748SMichael Walsh transitional_boot_selected = False 5236741f740SMichael Walsh stack_popped = 0 5246741f740SMichael Walsh if len(boot_stack) > 0: 5256741f740SMichael Walsh stack_popped = 1 526b5839d00SMichael Walsh gp.qprint_dashes() 527b5839d00SMichael Walsh gp.qprint_var(boot_stack) 528b5839d00SMichael Walsh gp.qprint_dashes() 529b5839d00SMichael Walsh skip_boot_printed = 0 530b5839d00SMichael Walsh while len(boot_stack) > 0: 5316741f740SMichael Walsh boot_candidate = boot_stack.pop() 532b5839d00SMichael Walsh if stack_mode == 'normal': 533b5839d00SMichael Walsh break 534b5839d00SMichael Walsh else: 535b5839d00SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['end']): 536b5839d00SMichael Walsh if not skip_boot_printed: 537ff340006SMichael Walsh gp.qprint_var(stack_mode) 538ff340006SMichael Walsh gp.qprintn() 539004ad3c9SJoy Onyerikwu gp.qprint_timen("Skipping the following boot tests" 540004ad3c9SJoy Onyerikwu + " which are unnecessary since their" 541004ad3c9SJoy Onyerikwu + " required end states match the" 542004ad3c9SJoy Onyerikwu + " current machine state:") 543b5839d00SMichael Walsh skip_boot_printed = 1 544ff340006SMichael Walsh gp.qprint_var(boot_candidate) 545b5839d00SMichael Walsh boot_candidate = "" 546b5839d00SMichael Walsh if boot_candidate == "": 547b5839d00SMichael Walsh gp.qprint_dashes() 548b5839d00SMichael Walsh gp.qprint_var(boot_stack) 549b5839d00SMichael Walsh gp.qprint_dashes() 550b5839d00SMichael Walsh return boot_candidate 5516741f740SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['start']): 552004ad3c9SJoy Onyerikwu gp.qprint_timen("The machine state is valid for a '" 553004ad3c9SJoy Onyerikwu + boot_candidate + "' boot test.") 554b5839d00SMichael Walsh gp.qprint_dashes() 555b5839d00SMichael Walsh gp.qprint_var(boot_stack) 556b5839d00SMichael Walsh gp.qprint_dashes() 5576741f740SMichael Walsh return boot_candidate 558341c21ebSMichael Walsh else: 559004ad3c9SJoy Onyerikwu gp.qprint_timen("The machine state does not match the required" 560004ad3c9SJoy Onyerikwu + " starting state for a '" + boot_candidate 561004ad3c9SJoy Onyerikwu + "' boot test:") 562ff340006SMichael Walsh gp.qprint_varx("boot_table[" + boot_candidate + "][start]", 563b5839d00SMichael Walsh boot_table[boot_candidate]['start'], 1) 5646741f740SMichael Walsh boot_stack.append(boot_candidate) 56581816748SMichael Walsh transitional_boot_selected = True 5666741f740SMichael Walsh popped_boot = boot_candidate 5676741f740SMichael Walsh 5686741f740SMichael Walsh # Loop through your list selecting a boot_candidates 5696741f740SMichael Walsh boot_candidates = [] 5706741f740SMichael Walsh for boot_candidate in boot_list: 5716741f740SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['start']): 5726741f740SMichael Walsh if stack_popped: 5736741f740SMichael Walsh if st.compare_states(boot_table[boot_candidate]['end'], 5746741f740SMichael Walsh boot_table[popped_boot]['start']): 5756741f740SMichael Walsh boot_candidates.append(boot_candidate) 576341c21ebSMichael Walsh else: 5776741f740SMichael Walsh boot_candidates.append(boot_candidate) 5786741f740SMichael Walsh 5796741f740SMichael Walsh if len(boot_candidates) == 0: 580004ad3c9SJoy Onyerikwu gp.qprint_timen("The user's boot list contained no boot tests" 581004ad3c9SJoy Onyerikwu + " which are valid for the current machine state.") 5826741f740SMichael Walsh boot_candidate = default_power_on 5836741f740SMichael Walsh if not st.compare_states(state, boot_table[default_power_on]['start']): 5846741f740SMichael Walsh boot_candidate = default_power_off 5856741f740SMichael Walsh boot_candidates.append(boot_candidate) 586004ad3c9SJoy Onyerikwu gp.qprint_timen("Using default '" + boot_candidate 587004ad3c9SJoy Onyerikwu + "' boot type to transition to valid state.") 5886741f740SMichael Walsh 589b5839d00SMichael Walsh gp.dprint_var(boot_candidates) 5906741f740SMichael Walsh 5916741f740SMichael Walsh # Randomly select a boot from the candidate list. 5926741f740SMichael Walsh boot = random.choice(boot_candidates) 593341c21ebSMichael Walsh 594341c21ebSMichael Walsh return boot 5950bbd860fSMichael Walsh 59655302295SMichael Walsh 597341c21ebSMichael Walshdef print_last_boots(): 598341c21ebSMichael Walsh r""" 599341c21ebSMichael Walsh Print the last ten boots done with their time stamps. 600341c21ebSMichael Walsh """ 601341c21ebSMichael Walsh 602341c21ebSMichael Walsh # indent 0, 90 chars wide, linefeed, char is "=" 603b5839d00SMichael Walsh gp.qprint_dashes(0, 90) 604b5839d00SMichael Walsh gp.qprintn("Last 10 boots:\n") 605341c21ebSMichael Walsh 606341c21ebSMichael Walsh for boot_entry in last_ten: 607341c21ebSMichael Walsh grp.rqprint(boot_entry) 608b5839d00SMichael Walsh gp.qprint_dashes(0, 90) 609341c21ebSMichael Walsh 610341c21ebSMichael Walsh 611b2e53ecdSMichael Walshdef print_defect_report(ffdc_file_list): 612341c21ebSMichael Walsh r""" 613341c21ebSMichael Walsh Print a defect report. 614b2e53ecdSMichael Walsh 615b2e53ecdSMichael Walsh Description of argument(s): 616b2e53ecdSMichael Walsh ffdc_file_list A list of files which were collected by our ffdc functions. 617341c21ebSMichael Walsh """ 618341c21ebSMichael Walsh 619600876daSMichael Walsh # Making deliberate choice to NOT run plug_in_setup(). We don't want 620600876daSMichael Walsh # ffdc_prefix updated. 621600876daSMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 622600876daSMichael Walsh call_point='ffdc_report', stop_on_plug_in_failure=0) 623600876daSMichael Walsh 624e0cf8d70SMichael Walsh # Get additional header data which may have been created by ffdc plug-ins. 625e0cf8d70SMichael Walsh # Also, delete the individual header files to cleanup. 626e0cf8d70SMichael Walsh cmd_buf = "file_list=$(cat " + ffdc_report_list_path + " 2>/dev/null)" +\ 627e0cf8d70SMichael Walsh " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\ 628e0cf8d70SMichael Walsh " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :" 629e0cf8d70SMichael Walsh shell_rc, more_header_info = gc.cmd_fnc_u(cmd_buf, print_output=0, 630e0cf8d70SMichael Walsh show_err=0) 631e0cf8d70SMichael Walsh 632b2e53ecdSMichael Walsh # Get additional summary data which may have been created by ffdc plug-ins. 633600876daSMichael Walsh # Also, delete the individual header files to cleanup. 634600876daSMichael Walsh cmd_buf = "file_list=$(cat " + ffdc_summary_list_path + " 2>/dev/null)" +\ 635600876daSMichael Walsh " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\ 636600876daSMichael Walsh " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :" 637600876daSMichael Walsh shell_rc, ffdc_summary_info = gc.cmd_fnc_u(cmd_buf, print_output=0, 638600876daSMichael Walsh show_err=0) 639600876daSMichael Walsh 640b2e53ecdSMichael Walsh # ffdc_list_file_path contains a list of any ffdc files created by plug- 641b2e53ecdSMichael Walsh # ins, etc. Read that data into a list. 642341c21ebSMichael Walsh try: 643b2e53ecdSMichael Walsh plug_in_ffdc_list = \ 644b2e53ecdSMichael Walsh open(ffdc_list_file_path, 'r').read().rstrip("\n").split("\n") 645b2e53ecdSMichael Walsh plug_in_ffdc_list = filter(None, plug_in_ffdc_list) 646341c21ebSMichael Walsh except IOError: 647b2e53ecdSMichael Walsh plug_in_ffdc_list = [] 648b2e53ecdSMichael Walsh 649b2e53ecdSMichael Walsh # Combine the files from plug_in_ffdc_list with the ffdc_file_list passed 650b2e53ecdSMichael Walsh # in. Eliminate duplicates and sort the list. 651004ad3c9SJoy Onyerikwu ffdc_file_list = sorted(set(ffdc_file_list + plug_in_ffdc_list)) 652b2e53ecdSMichael Walsh 653b2e53ecdSMichael Walsh if status_file_path != "": 654b2e53ecdSMichael Walsh ffdc_file_list.insert(0, status_file_path) 655b2e53ecdSMichael Walsh 656b2e53ecdSMichael Walsh # Convert the list to a printable list. 657b2e53ecdSMichael Walsh printable_ffdc_file_list = "\n".join(ffdc_file_list) 658341c21ebSMichael Walsh 65968a61162SMichael Walsh # Open ffdc_file_list for writing. We will write a complete list of 66068a61162SMichael Walsh # FFDC files to it for possible use by plug-ins like cp_stop_check. 66168a61162SMichael Walsh ffdc_list_file = open(ffdc_list_file_path, 'w') 662b2e53ecdSMichael Walsh ffdc_list_file.write(printable_ffdc_file_list + "\n") 663b2e53ecdSMichael Walsh ffdc_list_file.close() 664b2e53ecdSMichael Walsh 665b2e53ecdSMichael Walsh indent = 0 666b2e53ecdSMichael Walsh width = 90 667b2e53ecdSMichael Walsh linefeed = 1 668b2e53ecdSMichael Walsh char = "=" 66968a61162SMichael Walsh 67068a61162SMichael Walsh gp.qprintn() 671b2e53ecdSMichael Walsh gp.qprint_dashes(indent, width, linefeed, char) 67268a61162SMichael Walsh gp.qprintn("Copy this data to the defect:\n") 67368a61162SMichael Walsh 674e0cf8d70SMichael Walsh if len(more_header_info) > 0: 675ff340006SMichael Walsh gp.qprintn(more_header_info) 676dc80d67dSMichael Walsh gp.qpvars(host_name, host_ip, openbmc_nickname, openbmc_host, 677dc80d67dSMichael Walsh openbmc_host_name, openbmc_ip, openbmc_username, 678dc80d67dSMichael Walsh openbmc_password, os_host, os_host_name, os_ip, os_username, 679dc80d67dSMichael Walsh os_password, pdu_host, pdu_host_name, pdu_ip, pdu_username, 680dc80d67dSMichael Walsh pdu_password, pdu_slot_no, openbmc_serial_host, 681dc80d67dSMichael Walsh openbmc_serial_host_name, openbmc_serial_ip, openbmc_serial_port) 68268a61162SMichael Walsh 68368a61162SMichael Walsh gp.qprintn() 68468a61162SMichael Walsh print_last_boots() 68568a61162SMichael Walsh gp.qprintn() 68668a61162SMichael Walsh gp.qprint_var(state) 687b5839d00SMichael Walsh gp.qprintn() 688b5839d00SMichael Walsh gp.qprintn("FFDC data files:") 689b2e53ecdSMichael Walsh gp.qprintn(printable_ffdc_file_list) 690b5839d00SMichael Walsh gp.qprintn() 691341c21ebSMichael Walsh 692600876daSMichael Walsh if len(ffdc_summary_info) > 0: 693ff340006SMichael Walsh gp.qprintn(ffdc_summary_info) 694600876daSMichael Walsh 695b2e53ecdSMichael Walsh gp.qprint_dashes(indent, width, linefeed, char) 69668a61162SMichael Walsh 6976741f740SMichael Walsh 6986741f740SMichael Walshdef my_ffdc(): 6996741f740SMichael Walsh r""" 7006741f740SMichael Walsh Collect FFDC data. 7016741f740SMichael Walsh """ 7026741f740SMichael Walsh 7036741f740SMichael Walsh global state 7046741f740SMichael Walsh 7056741f740SMichael Walsh plug_in_setup() 7066741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 707600876daSMichael Walsh call_point='ffdc', stop_on_plug_in_failure=0) 7086741f740SMichael Walsh 7096741f740SMichael Walsh AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX'] 710004ad3c9SJoy Onyerikwu status, ffdc_file_list = grk.run_key_u("FFDC ffdc_prefix=" 711004ad3c9SJoy Onyerikwu + AUTOBOOT_FFDC_PREFIX 712004ad3c9SJoy Onyerikwu + " ffdc_function_list=" 713004ad3c9SJoy Onyerikwu + ffdc_function_list, ignore=1) 71483f4bc77SMichael Walsh if status != 'PASS': 715ff340006SMichael Walsh gp.qprint_error("Call to ffdc failed.\n") 7166741f740SMichael Walsh 7176741f740SMichael Walsh my_get_state() 7186741f740SMichael Walsh 719b2e53ecdSMichael Walsh print_defect_report(ffdc_file_list) 7206741f740SMichael Walsh 7216741f740SMichael Walsh 7226741f740SMichael Walshdef print_test_start_message(boot_keyword): 7236741f740SMichael Walsh r""" 7246741f740SMichael Walsh Print a message indicating what boot test is about to run. 7256741f740SMichael Walsh 7266741f740SMichael Walsh Description of arguments: 7276741f740SMichael Walsh boot_keyword The name of the boot which is to be run 7286741f740SMichael Walsh (e.g. "BMC Power On"). 7296741f740SMichael Walsh """ 7306741f740SMichael Walsh 7316741f740SMichael Walsh global last_ten 732325eb548SSunil M global boot_start_time 7336741f740SMichael Walsh 7346741f740SMichael Walsh doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".") 735325eb548SSunil M 736325eb548SSunil M # Set boot_start_time for use by plug-ins. 737325eb548SSunil M boot_start_time = doing_msg[1:33] 738325eb548SSunil M gp.qprint_var(boot_start_time) 739325eb548SSunil M 740b5839d00SMichael Walsh gp.qprint(doing_msg) 7416741f740SMichael Walsh 7426741f740SMichael Walsh last_ten.append(doing_msg) 7436741f740SMichael Walsh 7446741f740SMichael Walsh if len(last_ten) > 10: 7456741f740SMichael Walsh del last_ten[0] 7466741f740SMichael Walsh 7476741f740SMichael Walsh 7486741f740SMichael Walshdef run_boot(boot): 7496741f740SMichael Walsh r""" 7506741f740SMichael Walsh Run the specified boot. 7516741f740SMichael Walsh 7526741f740SMichael Walsh Description of arguments: 7536741f740SMichael Walsh boot The name of the boot test to be performed. 7546741f740SMichael Walsh """ 7556741f740SMichael Walsh 7566741f740SMichael Walsh global state 7576741f740SMichael Walsh 7586741f740SMichael Walsh print_test_start_message(boot) 7596741f740SMichael Walsh 7606741f740SMichael Walsh plug_in_setup() 7616741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 7626741f740SMichael Walsh grpi.rprocess_plug_in_packages(call_point="pre_boot") 7636741f740SMichael Walsh if rc != 0: 7646741f740SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" +\ 7656741f740SMichael Walsh gp.sprint_var(rc, 1) 7666741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 7676741f740SMichael Walsh 7686741f740SMichael Walsh if test_mode: 7696741f740SMichael Walsh # In test mode, we'll pretend the boot worked by assigning its 7706741f740SMichael Walsh # required end state to the default state value. 77130dadae2SMichael Walsh state = st.strip_anchor_state(boot_table[boot]['end']) 7726741f740SMichael Walsh else: 7736741f740SMichael Walsh # Assertion: We trust that the state data was made fresh by the 7746741f740SMichael Walsh # caller. 7756741f740SMichael Walsh 776b5839d00SMichael Walsh gp.qprintn() 7776741f740SMichael Walsh 7786741f740SMichael Walsh if boot_table[boot]['method_type'] == "keyword": 7790b93fbf8SMichael Walsh rk.my_run_keywords(boot_table[boot].get('lib_file_path', ''), 780b5839d00SMichael Walsh boot_table[boot]['method'], 781b5839d00SMichael Walsh quiet=quiet) 7826741f740SMichael Walsh 7836741f740SMichael Walsh if boot_table[boot]['bmc_reboot']: 7846741f740SMichael Walsh st.wait_for_comm_cycle(int(state['epoch_seconds'])) 78530dadae2SMichael Walsh plug_in_setup() 78630dadae2SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 78730dadae2SMichael Walsh grpi.rprocess_plug_in_packages(call_point="post_reboot") 78830dadae2SMichael Walsh if rc != 0: 7890b93fbf8SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" 7900b93fbf8SMichael Walsh error_message += gp.sprint_var(rc, 1) 79130dadae2SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 7926741f740SMichael Walsh else: 7936741f740SMichael Walsh match_state = st.anchor_state(state) 7946741f740SMichael Walsh del match_state['epoch_seconds'] 7956741f740SMichael Walsh # Wait for the state to change in any way. 7966741f740SMichael Walsh st.wait_state(match_state, wait_time=state_change_timeout, 797600876daSMichael Walsh interval="10 seconds", invert=1) 7986741f740SMichael Walsh 799b5839d00SMichael Walsh gp.qprintn() 8006741f740SMichael Walsh if boot_table[boot]['end']['chassis'] == "Off": 8016741f740SMichael Walsh boot_timeout = power_off_timeout 8026741f740SMichael Walsh else: 8036741f740SMichael Walsh boot_timeout = power_on_timeout 8046741f740SMichael Walsh st.wait_state(boot_table[boot]['end'], wait_time=boot_timeout, 805600876daSMichael Walsh interval="10 seconds") 8066741f740SMichael Walsh 8076741f740SMichael Walsh plug_in_setup() 8086741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 8096741f740SMichael Walsh grpi.rprocess_plug_in_packages(call_point="post_boot") 8106741f740SMichael Walsh if rc != 0: 8116741f740SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" +\ 8126741f740SMichael Walsh gp.sprint_var(rc, 1) 8136741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 8146741f740SMichael Walsh 8156741f740SMichael Walsh 8166741f740SMichael Walshdef test_loop_body(): 8176741f740SMichael Walsh r""" 8186741f740SMichael Walsh The main loop body for the loop in main_py. 8196741f740SMichael Walsh 8206741f740SMichael Walsh Description of arguments: 8216741f740SMichael Walsh boot_count The iteration number (starts at 1). 8226741f740SMichael Walsh """ 8236741f740SMichael Walsh 8246741f740SMichael Walsh global boot_count 8256741f740SMichael Walsh global state 8266741f740SMichael Walsh global next_boot 8276741f740SMichael Walsh global boot_success 828325eb548SSunil M global boot_end_time 8296741f740SMichael Walsh 830b5839d00SMichael Walsh gp.qprintn() 8316741f740SMichael Walsh 8326741f740SMichael Walsh next_boot = select_boot() 833b5839d00SMichael Walsh if next_boot == "": 834b5839d00SMichael Walsh return True 8356741f740SMichael Walsh 836b5839d00SMichael Walsh boot_count += 1 837b5839d00SMichael Walsh gp.qprint_timen("Starting boot " + str(boot_count) + ".") 8386741f740SMichael Walsh 839e0cf8d70SMichael Walsh pre_boot_plug_in_setup() 8406741f740SMichael Walsh 8416741f740SMichael Walsh cmd_buf = ["run_boot", next_boot] 8426741f740SMichael Walsh boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf) 8436741f740SMichael Walsh if boot_status == "FAIL": 844b5839d00SMichael Walsh gp.qprint(msg) 8456741f740SMichael Walsh 846b5839d00SMichael Walsh gp.qprintn() 8476741f740SMichael Walsh if boot_status == "PASS": 8486741f740SMichael Walsh boot_success = 1 849004ad3c9SJoy Onyerikwu completion_msg = gp.sprint_timen("BOOT_SUCCESS: \"" + next_boot 850004ad3c9SJoy Onyerikwu + "\" succeeded.") 8516741f740SMichael Walsh else: 8526741f740SMichael Walsh boot_success = 0 853004ad3c9SJoy Onyerikwu completion_msg = gp.sprint_timen("BOOT_FAILED: \"" + next_boot 854004ad3c9SJoy Onyerikwu + "\" failed.") 855325eb548SSunil M 856325eb548SSunil M # Set boot_end_time for use by plug-ins. 857325eb548SSunil M boot_end_time = completion_msg[1:33] 858325eb548SSunil M gp.qprint_var(boot_end_time) 859325eb548SSunil M 860325eb548SSunil M gp.qprint(completion_msg) 8616741f740SMichael Walsh 8626741f740SMichael Walsh boot_results.update(next_boot, boot_status) 8636741f740SMichael Walsh 8646741f740SMichael Walsh plug_in_setup() 8656741f740SMichael Walsh # NOTE: A post_test_case call point failure is NOT counted as a boot 8666741f740SMichael Walsh # failure. 8676741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 868600876daSMichael Walsh call_point='post_test_case', stop_on_plug_in_failure=0) 8696741f740SMichael Walsh 8706741f740SMichael Walsh plug_in_setup() 8716741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 872*89de14a4SMichael Walsh call_point='ffdc_check', shell_rc=dump_ffdc_rc(), 8736741f740SMichael Walsh stop_on_plug_in_failure=1, stop_on_non_zero_rc=1) 874*89de14a4SMichael Walsh if boot_status != "PASS" or ffdc_check == "All" or\ 875*89de14a4SMichael Walsh shell_rc == dump_ffdc_rc(): 87683f4bc77SMichael Walsh status, ret_values = grk.run_key_u("my_ffdc", ignore=1) 87783f4bc77SMichael Walsh if status != 'PASS': 878ff340006SMichael Walsh gp.qprint_error("Call to my_ffdc failed.\n") 8796741f740SMichael Walsh 880aabef1e3SMichael Walsh if delete_errlogs: 881d139f286SMichael Walsh # We need to purge error logs between boots or they build up. 882b5839d00SMichael Walsh grk.run_key("Delete Error logs", ignore=1) 883d139f286SMichael Walsh 884952f9b09SMichael Walsh boot_results.print_report() 885b5839d00SMichael Walsh gp.qprint_timen("Finished boot " + str(boot_count) + ".") 886952f9b09SMichael Walsh 8876741f740SMichael Walsh plug_in_setup() 8886741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 889*89de14a4SMichael Walsh call_point='stop_check', shell_rc=stop_test_rc(), 890*89de14a4SMichael Walsh stop_on_non_zero_rc=1) 891*89de14a4SMichael Walsh if shell_rc == stop_test_rc(): 8923ba8ecdcSMichael Walsh message = "Stopping as requested by user.\n" 8933ba8ecdcSMichael Walsh gp.print_time(message) 8943ba8ecdcSMichael Walsh BuiltIn().fail(message) 8956741f740SMichael Walsh 896d139f286SMichael Walsh # This should help prevent ConnectionErrors. 8970960b384SMichael Walsh grk.run_key_u("Close All Connections") 898d139f286SMichael Walsh 8996741f740SMichael Walsh return True 9006741f740SMichael Walsh 9016741f740SMichael Walsh 90283f4bc77SMichael Walshdef obmc_boot_test_teardown(): 9036741f740SMichael Walsh r""" 904c9116811SMichael Walsh Clean up after the Main keyword. 9056741f740SMichael Walsh """ 9066741f740SMichael Walsh 9076741f740SMichael Walsh if cp_setup_called: 9086741f740SMichael Walsh plug_in_setup() 9096741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 910600876daSMichael Walsh call_point='cleanup', stop_on_plug_in_failure=0) 9116741f740SMichael Walsh 912600876daSMichael Walsh if 'boot_results_file_path' in globals(): 9136c64574bSMichael Walsh # Save boot_results and last_ten objects to a file in case they are 9146c64574bSMichael Walsh # needed again. 915b5839d00SMichael Walsh gp.qprint_timen("Saving boot_results to the following path.") 916b5839d00SMichael Walsh gp.qprint_var(boot_results_file_path) 9176c64574bSMichael Walsh pickle.dump((boot_results, last_ten), 9186c64574bSMichael Walsh open(boot_results_file_path, 'wb'), 9190b93fbf8SMichael Walsh pickle.HIGHEST_PROTOCOL) 9200b93fbf8SMichael Walsh 921ff340006SMichael Walsh global save_stack 922ff340006SMichael Walsh # Restore any global values saved on the save_stack. 923ff340006SMichael Walsh for parm_name in main_func_parm_list: 924ff340006SMichael Walsh # Get the parm_value if it was saved on the stack. 925ff340006SMichael Walsh try: 926ff340006SMichael Walsh parm_value = save_stack.pop(parm_name) 927004ad3c9SJoy Onyerikwu except BaseException: 928ff340006SMichael Walsh # If it was not saved, no further action is required. 929ff340006SMichael Walsh continue 930ff340006SMichael Walsh 931ff340006SMichael Walsh # Restore the saved value. 932ff340006SMichael Walsh cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\ 933ff340006SMichael Walsh "}\", parm_value)" 934ff340006SMichael Walsh gp.dpissuing(cmd_buf) 935ff340006SMichael Walsh exec(cmd_buf) 936ff340006SMichael Walsh 937ff340006SMichael Walsh gp.dprintn(save_stack.sprint_obj()) 938ff340006SMichael Walsh 9396741f740SMichael Walsh 940c9116811SMichael Walshdef test_teardown(): 941c9116811SMichael Walsh r""" 942c9116811SMichael Walsh Clean up after this test case. 943c9116811SMichael Walsh """ 944c9116811SMichael Walsh 945c9116811SMichael Walsh gp.qprintn() 946c9116811SMichael Walsh cmd_buf = ["Print Error", 947c9116811SMichael Walsh "A keyword timeout occurred ending this program.\n"] 948c9116811SMichael Walsh BuiltIn().run_keyword_if_timeout_occurred(*cmd_buf) 949c9116811SMichael Walsh 950b5839d00SMichael Walsh grp.rqprint_pgm_footer() 951b5839d00SMichael Walsh 952c9116811SMichael Walsh 953*89de14a4SMichael Walshdef post_stack(): 954*89de14a4SMichael Walsh r""" 955*89de14a4SMichael Walsh Process post_stack plug-in programs. 956*89de14a4SMichael Walsh """ 957*89de14a4SMichael Walsh 958*89de14a4SMichael Walsh if not call_post_stack_plug: 959*89de14a4SMichael Walsh # The caller does not wish to have post_stack plug-in processing done. 960*89de14a4SMichael Walsh return 961*89de14a4SMichael Walsh 962*89de14a4SMichael Walsh global boot_success 963*89de14a4SMichael Walsh 964*89de14a4SMichael Walsh # NOTE: A post_stack call-point failure is NOT counted as a boot failure. 965*89de14a4SMichael Walsh pre_boot_plug_in_setup() 966*89de14a4SMichael Walsh # For the purposes of the following plug-ins, mark the "boot" as a success. 967*89de14a4SMichael Walsh boot_success = 1 968*89de14a4SMichael Walsh plug_in_setup() 969*89de14a4SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 970*89de14a4SMichael Walsh call_point='post_stack', stop_on_plug_in_failure=0) 971*89de14a4SMichael Walsh 972*89de14a4SMichael Walsh plug_in_setup() 973*89de14a4SMichael Walsh if rc == 0: 974*89de14a4SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 975*89de14a4SMichael Walsh call_point='ffdc_check', shell_rc=dump_ffdc_rc(), 976*89de14a4SMichael Walsh stop_on_plug_in_failure=1, stop_on_non_zero_rc=1) 977*89de14a4SMichael Walsh if rc != 0 or shell_rc == dump_ffdc_rc(): 978*89de14a4SMichael Walsh status, ret_values = grk.run_key_u("my_ffdc", ignore=1) 979*89de14a4SMichael Walsh if status != 'PASS': 980*89de14a4SMichael Walsh gp.qprint_error("Call to my_ffdc failed.\n") 981*89de14a4SMichael Walsh 982*89de14a4SMichael Walsh plug_in_setup() 983*89de14a4SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 984*89de14a4SMichael Walsh call_point='stop_check', shell_rc=stop_test_rc(), 985*89de14a4SMichael Walsh stop_on_non_zero_rc=1) 986*89de14a4SMichael Walsh if shell_rc == stop_test_rc(): 987*89de14a4SMichael Walsh message = "Stopping as requested by user.\n" 988*89de14a4SMichael Walsh gp.print_time(message) 989*89de14a4SMichael Walsh BuiltIn().fail(message) 990*89de14a4SMichael Walsh 991*89de14a4SMichael Walsh 992ff340006SMichael Walshdef obmc_boot_test_py(loc_boot_stack=None, 993ff340006SMichael Walsh loc_stack_mode=None, 994ff340006SMichael Walsh loc_quiet=None): 9956741f740SMichael Walsh r""" 9966741f740SMichael Walsh Do main program processing. 9976741f740SMichael Walsh """ 9986741f740SMichael Walsh 999ff340006SMichael Walsh global save_stack 1000ff340006SMichael Walsh 1001ff340006SMichael Walsh # Process function parms. 1002ff340006SMichael Walsh for parm_name in main_func_parm_list: 1003ff340006SMichael Walsh # Get parm's value. 1004ff340006SMichael Walsh cmd_buf = "parm_value = loc_" + parm_name 1005ff340006SMichael Walsh exec(cmd_buf) 1006ff340006SMichael Walsh gp.dpvar(parm_name) 1007ff340006SMichael Walsh gp.dpvar(parm_value) 1008ff340006SMichael Walsh 1009ff340006SMichael Walsh if parm_value is None: 1010ff340006SMichael Walsh # Parm was not specified by the calling function so set it to its 1011ff340006SMichael Walsh # corresponding global value. 1012ff340006SMichael Walsh cmd_buf = "loc_" + parm_name + " = BuiltIn().get_variable_value" +\ 1013ff340006SMichael Walsh "(\"${" + parm_name + "}\")" 1014ff340006SMichael Walsh gp.dpissuing(cmd_buf) 1015ff340006SMichael Walsh exec(cmd_buf) 1016ff340006SMichael Walsh else: 1017ff340006SMichael Walsh # Save the global value on a stack. 1018ff340006SMichael Walsh cmd_buf = "save_stack.push(BuiltIn().get_variable_value(\"${" +\ 1019ff340006SMichael Walsh parm_name + "}\"), \"" + parm_name + "\")" 1020ff340006SMichael Walsh gp.dpissuing(cmd_buf) 1021ff340006SMichael Walsh exec(cmd_buf) 1022ff340006SMichael Walsh 1023ff340006SMichael Walsh # Set the global value to the passed value. 1024ff340006SMichael Walsh cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\ 1025ff340006SMichael Walsh "}\", loc_" + parm_name + ")" 1026ff340006SMichael Walsh gp.dpissuing(cmd_buf) 1027ff340006SMichael Walsh exec(cmd_buf) 1028ff340006SMichael Walsh 1029ff340006SMichael Walsh gp.dprintn(save_stack.sprint_obj()) 1030b5839d00SMichael Walsh 10316741f740SMichael Walsh setup() 10326741f740SMichael Walsh 1033cd9fbfd7SMichael Walsh init_boot_pass, init_boot_fail = boot_results.return_total_pass_fail() 1034cd9fbfd7SMichael Walsh 1035a20da401SMichael Walsh if ffdc_only: 1036a20da401SMichael Walsh gp.qprint_timen("Caller requested ffdc_only.") 1037e0cf8d70SMichael Walsh pre_boot_plug_in_setup() 103883f4bc77SMichael Walsh grk.run_key_u("my_ffdc") 1039764d2f83SMichael Walsh return 1040a20da401SMichael Walsh 10416741f740SMichael Walsh # Process caller's boot_stack. 10426741f740SMichael Walsh while (len(boot_stack) > 0): 10436741f740SMichael Walsh test_loop_body() 10446741f740SMichael Walsh 1045b5839d00SMichael Walsh gp.qprint_timen("Finished processing stack.") 104630dadae2SMichael Walsh 1047*89de14a4SMichael Walsh post_stack() 1048*89de14a4SMichael Walsh 10496741f740SMichael Walsh # Process caller's boot_list. 10506741f740SMichael Walsh if len(boot_list) > 0: 10516741f740SMichael Walsh for ix in range(1, max_num_tests + 1): 10526741f740SMichael Walsh test_loop_body() 10536741f740SMichael Walsh 1054b5839d00SMichael Walsh gp.qprint_timen("Completed all requested boot tests.") 1055b5839d00SMichael Walsh 1056b5839d00SMichael Walsh boot_pass, boot_fail = boot_results.return_total_pass_fail() 1057cd9fbfd7SMichael Walsh new_fail = boot_fail - init_boot_fail 1058cd9fbfd7SMichael Walsh if new_fail > boot_fail_threshold: 1059b5839d00SMichael Walsh error_message = "Boot failures exceed the boot failure" +\ 1060b5839d00SMichael Walsh " threshold:\n" +\ 1061cd9fbfd7SMichael Walsh gp.sprint_var(new_fail) +\ 1062b5839d00SMichael Walsh gp.sprint_var(boot_fail_threshold) 1063b5839d00SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 1064