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 120b93fbf8SMichael Walshimport cPickle as pickle 130b93fbf8SMichael Walsh 140b93fbf8SMichael Walshfrom robot.utils import DotDict 150b93fbf8SMichael Walshfrom robot.libraries.BuiltIn import BuiltIn 160b93fbf8SMichael Walsh 176741f740SMichael Walshfrom boot_data import * 18c9116811SMichael Walshimport gen_print as gp 190bbd860fSMichael Walshimport gen_robot_print as grp 2055302295SMichael Walshimport gen_robot_plug_in as grpi 216741f740SMichael Walshimport gen_robot_valid as grv 226741f740SMichael Walshimport gen_misc as gm 236741f740SMichael Walshimport gen_cmd as gc 2455302295SMichael Walshimport state as st 250bbd860fSMichael Walsh 260b93fbf8SMichael Walshbase_path = os.path.dirname(os.path.dirname( 270b93fbf8SMichael Walsh imp.find_module("gen_robot_print")[1])) +\ 280b93fbf8SMichael Walsh os.sep 290b93fbf8SMichael Walshsys.path.append(base_path + "extended/") 300b93fbf8SMichael Walshimport run_keyword as rk 310bbd860fSMichael Walsh 326741f740SMichael Walsh# Program parameter processing. 336741f740SMichael Walsh# Assign all program parms to python variables which are global to this module. 346741f740SMichael Walshparm_list = BuiltIn().get_variable_value("${parm_list}") 35a20da401SMichael Walshint_list = ['max_num_tests', 'boot_pass', 'boot_fail', 'ffdc_only', 'quiet', 36a20da401SMichael Walsh 'test_mode', 'debug'] 376741f740SMichael Walshfor parm in parm_list: 386741f740SMichael Walsh if parm in int_list: 396741f740SMichael Walsh sub_cmd = "int(BuiltIn().get_variable_value(\"${" + parm +\ 406741f740SMichael Walsh "}\", \"0\"))" 416741f740SMichael Walsh else: 426741f740SMichael Walsh sub_cmd = "BuiltIn().get_variable_value(\"${" + parm + "}\")" 436741f740SMichael Walsh cmd_buf = parm + " = " + sub_cmd 446741f740SMichael Walsh exec(cmd_buf) 450bbd860fSMichael Walsh 466741f740SMichael Walshif ffdc_dir_path_style == "": 476741f740SMichael Walsh ffdc_dir_path_style = int(os.environ.get('FFDC_DIR_PATH_STYLE', '0')) 486741f740SMichael Walsh 496741f740SMichael Walsh# Set up boot data structures. 506741f740SMichael Walshboot_table = create_boot_table() 516741f740SMichael Walshvalid_boot_types = create_valid_boot_list(boot_table) 520b93fbf8SMichael Walsh 53e1e26448SMichael Walsh# Setting master_pid correctly influences the behavior of plug-ins like 54e1e26448SMichael Walsh# DB_Logging 55e1e26448SMichael Walshprogram_pid = os.getpid() 56e1e26448SMichael Walshmaster_pid = os.environ.get('AUTOBOOT_MASTER_PID', program_pid) 57e1e26448SMichael Walsh 58e1e26448SMichael Walshboot_results_file_path = "/tmp/" + openbmc_nickname + ":pid_" +\ 59e1e26448SMichael Walsh str(master_pid) + ":boot_results" 60e1e26448SMichael Walshif os.path.isfile(boot_results_file_path): 610b93fbf8SMichael Walsh # We've been called before in this run so we'll load the saved 620b93fbf8SMichael Walsh # boot_results object. 630b93fbf8SMichael Walsh boot_results = pickle.load(open(boot_results_file_path, 'rb')) 640b93fbf8SMichael Walshelse: 656741f740SMichael Walsh boot_results = boot_results(boot_table, boot_pass, boot_fail) 660b93fbf8SMichael Walsh 676741f740SMichael Walshboot_lists = read_boot_lists() 686741f740SMichael Walshlast_ten = [] 696741f740SMichael Walsh# Convert these program parms to more useable lists. 706741f740SMichael Walshboot_list = filter(None, boot_list.split(":")) 716741f740SMichael Walshboot_stack = filter(None, boot_stack.split(":")) 726741f740SMichael Walsh 736741f740SMichael Walshstate = st.return_default_state() 746741f740SMichael Walshcp_setup_called = 0 756741f740SMichael Walshnext_boot = "" 766741f740SMichael Walshbase_tool_dir_path = os.path.normpath(os.environ.get( 776741f740SMichael Walsh 'AUTOBOOT_BASE_TOOL_DIR_PATH', "/tmp")) + os.sep 786741f740SMichael Walshffdc_dir_path = os.path.normpath(os.environ.get('FFDC_DIR_PATH', '')) + os.sep 796741f740SMichael Walshffdc_list_file_path = base_tool_dir_path + openbmc_nickname + "/FFDC_FILE_LIST" 806741f740SMichael Walshboot_success = 0 816741f740SMichael Walshstatus_dir_path = os.environ.get('STATUS_DIR_PATH', "") 826741f740SMichael Walshif status_dir_path != "": 836741f740SMichael Walsh status_dir_path = os.path.normpath(status_dir_path) + os.sep 840b93fbf8SMichael Walshdefault_power_on = "REST Power On" 850b93fbf8SMichael Walshdefault_power_off = "REST Power Off" 866741f740SMichael Walshboot_count = 0 870bbd860fSMichael Walsh 8885678948SMichael WalshLOG_LEVEL = BuiltIn().get_variable_value("${LOG_LEVEL}") 8985678948SMichael Walsh 9085678948SMichael Walsh 9185678948SMichael Walsh############################################################################### 9285678948SMichael Walshdef initial_plug_in_setup(): 9385678948SMichael Walsh 9485678948SMichael Walsh r""" 9585678948SMichael Walsh Initialize all plug-in environment variables which do not change for the 9685678948SMichael Walsh duration of the program. 9785678948SMichael Walsh 9885678948SMichael Walsh """ 9985678948SMichael Walsh 10085678948SMichael Walsh global LOG_LEVEL 10185678948SMichael Walsh BuiltIn().set_log_level("NONE") 10285678948SMichael Walsh 10385678948SMichael Walsh BuiltIn().set_global_variable("${master_pid}", master_pid) 10485678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path) 10585678948SMichael Walsh BuiltIn().set_global_variable("${STATUS_DIR_PATH}", status_dir_path) 10685678948SMichael Walsh BuiltIn().set_global_variable("${BASE_TOOL_DIR_PATH}", base_tool_dir_path) 10785678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_LIST_FILE_PATH}", 10885678948SMichael Walsh ffdc_list_file_path) 10985678948SMichael Walsh 11085678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_DIR_PATH_STYLE}", 11185678948SMichael Walsh ffdc_dir_path_style) 11285678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_CHECK}", 11385678948SMichael Walsh ffdc_check) 11485678948SMichael Walsh 11585678948SMichael Walsh # For each program parameter, set the corresponding AUTOBOOT_ environment 11685678948SMichael Walsh # variable value. Also, set an AUTOBOOT_ environment variable for every 11785678948SMichael Walsh # element in additional_values. 11885678948SMichael Walsh additional_values = ["program_pid", "master_pid", "ffdc_dir_path", 11985678948SMichael Walsh "status_dir_path", "base_tool_dir_path", 12085678948SMichael Walsh "ffdc_list_file_path"] 12185678948SMichael Walsh 12285678948SMichael Walsh plug_in_vars = parm_list + additional_values 12385678948SMichael Walsh 12485678948SMichael Walsh for var_name in plug_in_vars: 12585678948SMichael Walsh var_value = BuiltIn().get_variable_value("${" + var_name + "}") 12685678948SMichael Walsh var_name = var_name.upper() 12785678948SMichael Walsh if var_value is None: 12885678948SMichael Walsh var_value = "" 12985678948SMichael Walsh os.environ["AUTOBOOT_" + var_name] = str(var_value) 13085678948SMichael Walsh 13185678948SMichael Walsh BuiltIn().set_log_level(LOG_LEVEL) 13285678948SMichael Walsh 13385678948SMichael Walsh 13485678948SMichael Walsh############################################################################### 13585678948SMichael Walsh 1360bbd860fSMichael Walsh 1370bbd860fSMichael Walsh############################################################################### 1380bbd860fSMichael Walshdef plug_in_setup(): 1390bbd860fSMichael Walsh 1400bbd860fSMichael Walsh r""" 14185678948SMichael Walsh Initialize all changing plug-in environment variables for use by the 14285678948SMichael Walsh plug-in programs. 1430bbd860fSMichael Walsh """ 1440bbd860fSMichael Walsh 14585678948SMichael Walsh global LOG_LEVEL 14685678948SMichael Walsh global test_really_running 14785678948SMichael Walsh 14885678948SMichael Walsh BuiltIn().set_log_level("NONE") 14985678948SMichael Walsh 1506741f740SMichael Walsh boot_pass, boot_fail = boot_results.return_total_pass_fail() 1510bbd860fSMichael Walsh if boot_pass > 1: 1520bbd860fSMichael Walsh test_really_running = 1 1530bbd860fSMichael Walsh else: 1540bbd860fSMichael Walsh test_really_running = 0 1550bbd860fSMichael Walsh 1560bbd860fSMichael Walsh seconds = time.time() 1570bbd860fSMichael Walsh loc_time = time.localtime(seconds) 1580bbd860fSMichael Walsh time_string = time.strftime("%y%m%d.%H%M%S.", loc_time) 1590bbd860fSMichael Walsh 1606741f740SMichael Walsh ffdc_prefix = openbmc_nickname + "." + time_string 1610bbd860fSMichael Walsh 1626741f740SMichael Walsh BuiltIn().set_global_variable("${test_really_running}", 1636741f740SMichael Walsh test_really_running) 1646741f740SMichael Walsh BuiltIn().set_global_variable("${boot_type_desc}", next_boot) 1656741f740SMichael Walsh BuiltIn().set_global_variable("${boot_pass}", boot_pass) 1666741f740SMichael Walsh BuiltIn().set_global_variable("${boot_fail}", boot_fail) 1676741f740SMichael Walsh BuiltIn().set_global_variable("${boot_success}", boot_success) 1686741f740SMichael Walsh BuiltIn().set_global_variable("${ffdc_prefix}", ffdc_prefix) 1694c9a6453SMichael Walsh 1700bbd860fSMichael Walsh # For each program parameter, set the corresponding AUTOBOOT_ environment 1710bbd860fSMichael Walsh # variable value. Also, set an AUTOBOOT_ environment variable for every 1720bbd860fSMichael Walsh # element in additional_values. 1730bbd860fSMichael Walsh additional_values = ["boot_type_desc", "boot_success", "boot_pass", 17485678948SMichael Walsh "boot_fail", "test_really_running", "ffdc_prefix"] 1750bbd860fSMichael Walsh 17685678948SMichael Walsh plug_in_vars = additional_values 1770bbd860fSMichael Walsh 1780bbd860fSMichael Walsh for var_name in plug_in_vars: 1790bbd860fSMichael Walsh var_value = BuiltIn().get_variable_value("${" + var_name + "}") 1800bbd860fSMichael Walsh var_name = var_name.upper() 1810bbd860fSMichael Walsh if var_value is None: 1820bbd860fSMichael Walsh var_value = "" 1836741f740SMichael Walsh os.environ["AUTOBOOT_" + var_name] = str(var_value) 1840bbd860fSMichael Walsh 1850bbd860fSMichael Walsh if debug: 1866741f740SMichael Walsh shell_rc, out_buf = \ 1876741f740SMichael Walsh gc.cmd_fnc_u("printenv | egrep AUTOBOOT_ | sort -u") 1880bbd860fSMichael Walsh 18985678948SMichael Walsh BuiltIn().set_log_level(LOG_LEVEL) 19085678948SMichael Walsh 1910bbd860fSMichael Walsh############################################################################### 1920bbd860fSMichael Walsh 1930bbd860fSMichael Walsh 1940bbd860fSMichael Walsh############################################################################### 1956741f740SMichael Walshdef setup(): 1960bbd860fSMichael Walsh 1970bbd860fSMichael Walsh r""" 1986741f740SMichael Walsh Do general program setup tasks. 1990bbd860fSMichael Walsh """ 2000bbd860fSMichael Walsh 2016741f740SMichael Walsh global cp_setup_called 2020bbd860fSMichael Walsh 2036741f740SMichael Walsh grp.rqprintn() 2046741f740SMichael Walsh 2056741f740SMichael Walsh validate_parms() 2066741f740SMichael Walsh 2076741f740SMichael Walsh grp.rqprint_pgm_header() 2086741f740SMichael Walsh 20911cfc8c0SMichael Walsh cmd_buf = ["Set BMC Power Policy", "RESTORE_LAST_STATE"] 21011cfc8c0SMichael Walsh grp.rpissuing_keyword(cmd_buf, test_mode) 21111cfc8c0SMichael Walsh if not test_mode: 21211cfc8c0SMichael Walsh BuiltIn().run_keyword(*cmd_buf) 21311cfc8c0SMichael Walsh 21485678948SMichael Walsh initial_plug_in_setup() 21585678948SMichael Walsh 2166741f740SMichael Walsh plug_in_setup() 2176741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 2186741f740SMichael Walsh call_point='setup') 2196741f740SMichael Walsh if rc != 0: 2206741f740SMichael Walsh error_message = "Plug-in setup failed.\n" 2216741f740SMichael Walsh grp.rprint_error_report(error_message) 2226741f740SMichael Walsh BuiltIn().fail(error_message) 2236741f740SMichael Walsh # Setting cp_setup_called lets our Teardown know that it needs to call 2246741f740SMichael Walsh # the cleanup plug-in call point. 2256741f740SMichael Walsh cp_setup_called = 1 2266741f740SMichael Walsh 2276741f740SMichael Walsh # Keyword "FFDC" will fail if TEST_MESSAGE is not set. 2286741f740SMichael Walsh BuiltIn().set_global_variable("${TEST_MESSAGE}", "${EMPTY}") 22985678948SMichael Walsh # FFDC_LOG_PATH is used by "FFDC" keyword. 23085678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_LOG_PATH}", ffdc_dir_path) 2316741f740SMichael Walsh 2326741f740SMichael Walsh grp.rdprint_var(boot_table, 1) 2336741f740SMichael Walsh grp.rdprint_var(boot_lists) 2340bbd860fSMichael Walsh 2350bbd860fSMichael Walsh############################################################################### 2360bbd860fSMichael Walsh 2370bbd860fSMichael Walsh 2380bbd860fSMichael Walsh############################################################################### 2396741f740SMichael Walshdef validate_parms(): 2400bbd860fSMichael Walsh 2410bbd860fSMichael Walsh r""" 2426741f740SMichael Walsh Validate all program parameters. 2430bbd860fSMichael Walsh """ 2440bbd860fSMichael Walsh 2456741f740SMichael Walsh grp.rqprintn() 2460bbd860fSMichael Walsh 2476741f740SMichael Walsh grv.rvalid_value("openbmc_host") 2486741f740SMichael Walsh grv.rvalid_value("openbmc_username") 2496741f740SMichael Walsh grv.rvalid_value("openbmc_password") 2506741f740SMichael Walsh if os_host != "": 2516741f740SMichael Walsh grv.rvalid_value("os_username") 2526741f740SMichael Walsh grv.rvalid_value("os_password") 2530bbd860fSMichael Walsh 2546741f740SMichael Walsh if pdu_host != "": 2556741f740SMichael Walsh grv.rvalid_value("pdu_username") 2566741f740SMichael Walsh grv.rvalid_value("pdu_password") 2576741f740SMichael Walsh grv.rvalid_integer("pdu_slot_no") 2586741f740SMichael Walsh if openbmc_serial_host != "": 2596741f740SMichael Walsh grv.rvalid_integer("openbmc_serial_port") 2606741f740SMichael Walsh grv.rvalid_integer("max_num_tests") 2616741f740SMichael Walsh grv.rvalid_value("openbmc_model") 2626741f740SMichael Walsh grv.rvalid_integer("boot_pass") 2636741f740SMichael Walsh grv.rvalid_integer("boot_fail") 2646741f740SMichael Walsh 2656741f740SMichael Walsh plug_in_packages_list = grpi.rvalidate_plug_ins(plug_in_dir_paths) 2666741f740SMichael Walsh BuiltIn().set_global_variable("${plug_in_packages_list}", 2676741f740SMichael Walsh plug_in_packages_list) 2686741f740SMichael Walsh 269a20da401SMichael Walsh if len(boot_list) == 0 and len(boot_stack) == 0 and not ffdc_only: 2706741f740SMichael Walsh error_message = "You must provide either a value for either the" +\ 2716741f740SMichael Walsh " boot_list or the boot_stack parm.\n" 2726741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 2736741f740SMichael Walsh 2746741f740SMichael Walsh valid_boot_list(boot_list, valid_boot_types) 2756741f740SMichael Walsh valid_boot_list(boot_stack, valid_boot_types) 2766741f740SMichael Walsh 27711cfc8c0SMichael Walsh selected_PDU_boots = list(set(boot_list + boot_stack) & 27811cfc8c0SMichael Walsh set(boot_lists['PDU_reboot'])) 27911cfc8c0SMichael Walsh 28011cfc8c0SMichael Walsh if len(selected_PDU_boots) > 0 and pdu_host == "": 28111cfc8c0SMichael Walsh error_message = "You have selected the following boots which" +\ 28211cfc8c0SMichael Walsh " require a PDU host but no value for pdu_host:\n" 28311cfc8c0SMichael Walsh error_message += gp.sprint_var(selected_PDU_boots) 28411cfc8c0SMichael Walsh error_message += gp.sprint_var(pdu_host, 2) 28511cfc8c0SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 28611cfc8c0SMichael Walsh 2876741f740SMichael Walsh return 2880bbd860fSMichael Walsh 2890bbd860fSMichael Walsh############################################################################### 2900bbd860fSMichael Walsh 2910bbd860fSMichael Walsh 2920bbd860fSMichael Walsh############################################################################### 2936741f740SMichael Walshdef my_get_state(): 2940bbd860fSMichael Walsh 2950bbd860fSMichael Walsh r""" 2966741f740SMichael Walsh Get the system state plus a little bit of wrapping. 2970bbd860fSMichael Walsh """ 2980bbd860fSMichael Walsh 2996741f740SMichael Walsh global state 3006741f740SMichael Walsh 3016741f740SMichael Walsh req_states = ['epoch_seconds'] + st.default_req_states 3026741f740SMichael Walsh 3036741f740SMichael Walsh grp.rqprint_timen("Getting system state.") 3046741f740SMichael Walsh if test_mode: 3056741f740SMichael Walsh state['epoch_seconds'] = int(time.time()) 3066741f740SMichael Walsh else: 3076741f740SMichael Walsh state = st.get_state(req_states=req_states, quiet=0) 3086741f740SMichael Walsh grp.rprint_var(state) 309341c21ebSMichael Walsh 310341c21ebSMichael Walsh############################################################################### 311341c21ebSMichael Walsh 312341c21ebSMichael Walsh 313341c21ebSMichael Walsh############################################################################### 3146741f740SMichael Walshdef select_boot(): 315341c21ebSMichael Walsh 316341c21ebSMichael Walsh r""" 317341c21ebSMichael Walsh Select a boot test to be run based on our current state and return the 318341c21ebSMichael Walsh chosen boot type. 319341c21ebSMichael Walsh 320341c21ebSMichael Walsh Description of arguments: 3216741f740SMichael Walsh state The state of the machine. 322341c21ebSMichael Walsh """ 323341c21ebSMichael Walsh 32430dadae2SMichael Walsh global boot_stack 32530dadae2SMichael Walsh 3266741f740SMichael Walsh grp.rprint_timen("Selecting a boot test.") 3276741f740SMichael Walsh 3286741f740SMichael Walsh my_get_state() 3296741f740SMichael Walsh 3306741f740SMichael Walsh stack_popped = 0 3316741f740SMichael Walsh if len(boot_stack) > 0: 3326741f740SMichael Walsh stack_popped = 1 3336741f740SMichael Walsh grp.rprint_dashes() 3346741f740SMichael Walsh grp.rprint_var(boot_stack) 3356741f740SMichael Walsh grp.rprint_dashes() 3366741f740SMichael Walsh boot_candidate = boot_stack.pop() 3376741f740SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['start']): 3386741f740SMichael Walsh grp.rprint_timen("The machine state is valid for a '" + 3396741f740SMichael Walsh boot_candidate + "' boot test.") 3406741f740SMichael Walsh grp.rprint_dashes() 3416741f740SMichael Walsh grp.rprint_var(boot_stack) 3426741f740SMichael Walsh grp.rprint_dashes() 3436741f740SMichael Walsh return boot_candidate 344341c21ebSMichael Walsh else: 3456741f740SMichael Walsh grp.rprint_timen("The machine state is not valid for a '" + 3466741f740SMichael Walsh boot_candidate + "' boot test.") 3476741f740SMichael Walsh boot_stack.append(boot_candidate) 3486741f740SMichael Walsh popped_boot = boot_candidate 3496741f740SMichael Walsh 3506741f740SMichael Walsh # Loop through your list selecting a boot_candidates 3516741f740SMichael Walsh boot_candidates = [] 3526741f740SMichael Walsh for boot_candidate in boot_list: 3536741f740SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['start']): 3546741f740SMichael Walsh if stack_popped: 3556741f740SMichael Walsh if st.compare_states(boot_table[boot_candidate]['end'], 3566741f740SMichael Walsh boot_table[popped_boot]['start']): 3576741f740SMichael Walsh boot_candidates.append(boot_candidate) 358341c21ebSMichael Walsh else: 3596741f740SMichael Walsh boot_candidates.append(boot_candidate) 3606741f740SMichael Walsh 3616741f740SMichael Walsh if len(boot_candidates) == 0: 3626741f740SMichael Walsh grp.rprint_timen("The user's boot list contained no boot tests" + 3636741f740SMichael Walsh " which are valid for the current machine state.") 3646741f740SMichael Walsh boot_candidate = default_power_on 3656741f740SMichael Walsh if not st.compare_states(state, boot_table[default_power_on]['start']): 3666741f740SMichael Walsh boot_candidate = default_power_off 3676741f740SMichael Walsh boot_candidates.append(boot_candidate) 3686741f740SMichael Walsh grp.rprint_timen("Using default '" + boot_candidate + 3696741f740SMichael Walsh "' boot type to transtion to valid state.") 3706741f740SMichael Walsh 3716741f740SMichael Walsh grp.rdprint_var(boot_candidates) 3726741f740SMichael Walsh 3736741f740SMichael Walsh # Randomly select a boot from the candidate list. 3746741f740SMichael Walsh boot = random.choice(boot_candidates) 375341c21ebSMichael Walsh 376341c21ebSMichael Walsh return boot 3770bbd860fSMichael Walsh 3780bbd860fSMichael Walsh############################################################################### 37955302295SMichael Walsh 38055302295SMichael Walsh 38155302295SMichael Walsh############################################################################### 382341c21ebSMichael Walshdef print_last_boots(): 383341c21ebSMichael Walsh 384341c21ebSMichael Walsh r""" 385341c21ebSMichael Walsh Print the last ten boots done with their time stamps. 386341c21ebSMichael Walsh """ 387341c21ebSMichael Walsh 388341c21ebSMichael Walsh # indent 0, 90 chars wide, linefeed, char is "=" 389341c21ebSMichael Walsh grp.rqprint_dashes(0, 90) 390341c21ebSMichael Walsh grp.rqprintn("Last 10 boots:\n") 391341c21ebSMichael Walsh 392341c21ebSMichael Walsh for boot_entry in last_ten: 393341c21ebSMichael Walsh grp.rqprint(boot_entry) 394341c21ebSMichael Walsh grp.rqprint_dashes(0, 90) 395341c21ebSMichael Walsh 396341c21ebSMichael Walsh############################################################################### 397341c21ebSMichael Walsh 398341c21ebSMichael Walsh 399341c21ebSMichael Walsh############################################################################### 400341c21ebSMichael Walshdef print_defect_report(): 401341c21ebSMichael Walsh 402341c21ebSMichael Walsh r""" 403341c21ebSMichael Walsh Print a defect report. 404341c21ebSMichael Walsh """ 405341c21ebSMichael Walsh 406341c21ebSMichael Walsh grp.rqprintn() 407341c21ebSMichael Walsh # indent=0, width=90, linefeed=1, char="=" 408341c21ebSMichael Walsh grp.rqprint_dashes(0, 90, 1, "=") 409341c21ebSMichael Walsh grp.rqprintn("Copy this data to the defect:\n") 410341c21ebSMichael Walsh 411341c21ebSMichael Walsh grp.rqpvars(*parm_list) 412341c21ebSMichael Walsh 413341c21ebSMichael Walsh grp.rqprintn() 414341c21ebSMichael Walsh 415341c21ebSMichael Walsh print_last_boots() 416341c21ebSMichael Walsh grp.rqprintn() 417341c21ebSMichael Walsh grp.rqpvar(state) 418341c21ebSMichael Walsh 419341c21ebSMichael Walsh # At some point I'd like to have the 'Call FFDC Methods' return a list 420341c21ebSMichael Walsh # of files it has collected. In that case, the following "ls" command 421341c21ebSMichael Walsh # would no longer be needed. For now, however, glob shows the files 422341c21ebSMichael Walsh # named in FFDC_LIST_FILE_PATH so I will refrain from printing those 423341c21ebSMichael Walsh # out (so we don't see duplicates in the list). 424341c21ebSMichael Walsh 425341c21ebSMichael Walsh LOG_PREFIX = BuiltIn().get_variable_value("${LOG_PREFIX}") 426341c21ebSMichael Walsh 427341c21ebSMichael Walsh output = '\n'.join(glob.glob(LOG_PREFIX + '*')) 428341c21ebSMichael Walsh try: 4296741f740SMichael Walsh ffdc_list = open(ffdc_list_file_path, 'r') 430341c21ebSMichael Walsh except IOError: 431341c21ebSMichael Walsh ffdc_list = "" 432341c21ebSMichael Walsh 433341c21ebSMichael Walsh grp.rqprintn() 434341c21ebSMichael Walsh grp.rqprintn("FFDC data files:") 435341c21ebSMichael Walsh if status_file_path != "": 436341c21ebSMichael Walsh grp.rqprintn(status_file_path) 437341c21ebSMichael Walsh 438341c21ebSMichael Walsh grp.rqprintn(output) 439341c21ebSMichael Walsh # grp.rqprintn(ffdc_list) 440341c21ebSMichael Walsh grp.rqprintn() 441341c21ebSMichael Walsh 442341c21ebSMichael Walsh grp.rqprint_dashes(0, 90, 1, "=") 443341c21ebSMichael Walsh 444341c21ebSMichael Walsh############################################################################### 4456741f740SMichael Walsh 4466741f740SMichael Walsh 4476741f740SMichael Walsh############################################################################### 4486741f740SMichael Walshdef my_ffdc(): 4496741f740SMichael Walsh 4506741f740SMichael Walsh r""" 4516741f740SMichael Walsh Collect FFDC data. 4526741f740SMichael Walsh """ 4536741f740SMichael Walsh 4546741f740SMichael Walsh global state 4556741f740SMichael Walsh 4566741f740SMichael Walsh plug_in_setup() 4576741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 4586741f740SMichael Walsh call_point='ffdc', stop_on_plug_in_failure=1) 4596741f740SMichael Walsh 4606741f740SMichael Walsh AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX'] 4616741f740SMichael Walsh 4626741f740SMichael Walsh cmd_buf = ["FFDC", "ffdc_prefix=" + AUTOBOOT_FFDC_PREFIX] 4636741f740SMichael Walsh grp.rpissuing_keyword(cmd_buf) 4643328caffSMichael Walsh try: 465c9116811SMichael Walsh BuiltIn().run_keyword_and_continue_on_failure(*cmd_buf) 4663328caffSMichael Walsh except: 4673328caffSMichael Walsh gp.print_error("Call to ffdc failed.\n") 4686741f740SMichael Walsh 4696741f740SMichael Walsh my_get_state() 4706741f740SMichael Walsh 4716741f740SMichael Walsh print_defect_report() 4726741f740SMichael Walsh 4736741f740SMichael Walsh############################################################################### 4746741f740SMichael Walsh 4756741f740SMichael Walsh 4766741f740SMichael Walsh############################################################################### 4776741f740SMichael Walshdef print_test_start_message(boot_keyword): 4786741f740SMichael Walsh 4796741f740SMichael Walsh r""" 4806741f740SMichael Walsh Print a message indicating what boot test is about to run. 4816741f740SMichael Walsh 4826741f740SMichael Walsh Description of arguments: 4836741f740SMichael Walsh boot_keyword The name of the boot which is to be run 4846741f740SMichael Walsh (e.g. "BMC Power On"). 4856741f740SMichael Walsh """ 4866741f740SMichael Walsh 4876741f740SMichael Walsh global last_ten 4886741f740SMichael Walsh 4896741f740SMichael Walsh doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".") 4906741f740SMichael Walsh grp.rqprint(doing_msg) 4916741f740SMichael Walsh 4926741f740SMichael Walsh last_ten.append(doing_msg) 4936741f740SMichael Walsh 4946741f740SMichael Walsh if len(last_ten) > 10: 4956741f740SMichael Walsh del last_ten[0] 4966741f740SMichael Walsh 4976741f740SMichael Walsh############################################################################### 4986741f740SMichael Walsh 4996741f740SMichael Walsh 5006741f740SMichael Walsh############################################################################### 5016741f740SMichael Walshdef run_boot(boot): 5026741f740SMichael Walsh 5036741f740SMichael Walsh r""" 5046741f740SMichael Walsh Run the specified boot. 5056741f740SMichael Walsh 5066741f740SMichael Walsh Description of arguments: 5076741f740SMichael Walsh boot The name of the boot test to be performed. 5086741f740SMichael Walsh """ 5096741f740SMichael Walsh 5106741f740SMichael Walsh global state 5116741f740SMichael Walsh 5126741f740SMichael Walsh print_test_start_message(boot) 5136741f740SMichael Walsh 5146741f740SMichael Walsh plug_in_setup() 5156741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 5166741f740SMichael Walsh grpi.rprocess_plug_in_packages(call_point="pre_boot") 5176741f740SMichael Walsh if rc != 0: 5186741f740SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" +\ 5196741f740SMichael Walsh gp.sprint_var(rc, 1) 5206741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 5216741f740SMichael Walsh 5226741f740SMichael Walsh if test_mode: 5236741f740SMichael Walsh # In test mode, we'll pretend the boot worked by assigning its 5246741f740SMichael Walsh # required end state to the default state value. 52530dadae2SMichael Walsh state = st.strip_anchor_state(boot_table[boot]['end']) 5266741f740SMichael Walsh else: 5276741f740SMichael Walsh # Assertion: We trust that the state data was made fresh by the 5286741f740SMichael Walsh # caller. 5296741f740SMichael Walsh 5306741f740SMichael Walsh grp.rprintn() 5316741f740SMichael Walsh 5326741f740SMichael Walsh if boot_table[boot]['method_type'] == "keyword": 5330b93fbf8SMichael Walsh rk.my_run_keywords(boot_table[boot].get('lib_file_path', ''), 5340b93fbf8SMichael Walsh boot_table[boot]['method']) 5356741f740SMichael Walsh 5366741f740SMichael Walsh if boot_table[boot]['bmc_reboot']: 5376741f740SMichael Walsh st.wait_for_comm_cycle(int(state['epoch_seconds'])) 53830dadae2SMichael Walsh plug_in_setup() 53930dadae2SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 54030dadae2SMichael Walsh grpi.rprocess_plug_in_packages(call_point="post_reboot") 54130dadae2SMichael Walsh if rc != 0: 5420b93fbf8SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" 5430b93fbf8SMichael Walsh error_message += gp.sprint_var(rc, 1) 54430dadae2SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 5456741f740SMichael Walsh else: 5466741f740SMichael Walsh match_state = st.anchor_state(state) 5476741f740SMichael Walsh del match_state['epoch_seconds'] 5486741f740SMichael Walsh # Wait for the state to change in any way. 5496741f740SMichael Walsh st.wait_state(match_state, wait_time=state_change_timeout, 5506741f740SMichael Walsh interval="3 seconds", invert=1) 5516741f740SMichael Walsh 5526741f740SMichael Walsh grp.rprintn() 5536741f740SMichael Walsh if boot_table[boot]['end']['chassis'] == "Off": 5546741f740SMichael Walsh boot_timeout = power_off_timeout 5556741f740SMichael Walsh else: 5566741f740SMichael Walsh boot_timeout = power_on_timeout 5576741f740SMichael Walsh st.wait_state(boot_table[boot]['end'], wait_time=boot_timeout, 5586741f740SMichael Walsh interval="3 seconds") 5596741f740SMichael Walsh 5606741f740SMichael Walsh plug_in_setup() 5616741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 5626741f740SMichael Walsh grpi.rprocess_plug_in_packages(call_point="post_boot") 5636741f740SMichael Walsh if rc != 0: 5646741f740SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" +\ 5656741f740SMichael Walsh gp.sprint_var(rc, 1) 5666741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 5676741f740SMichael Walsh 5686741f740SMichael Walsh############################################################################### 5696741f740SMichael Walsh 5706741f740SMichael Walsh 5716741f740SMichael Walsh############################################################################### 5726741f740SMichael Walshdef test_loop_body(): 5736741f740SMichael Walsh 5746741f740SMichael Walsh r""" 5756741f740SMichael Walsh The main loop body for the loop in main_py. 5766741f740SMichael Walsh 5776741f740SMichael Walsh Description of arguments: 5786741f740SMichael Walsh boot_count The iteration number (starts at 1). 5796741f740SMichael Walsh """ 5806741f740SMichael Walsh 5816741f740SMichael Walsh global boot_count 5826741f740SMichael Walsh global state 5836741f740SMichael Walsh global next_boot 5846741f740SMichael Walsh global boot_success 5856741f740SMichael Walsh 5866741f740SMichael Walsh grp.rqprintn() 5876741f740SMichael Walsh 5886741f740SMichael Walsh boot_count += 1 5896741f740SMichael Walsh 5906741f740SMichael Walsh next_boot = select_boot() 5916741f740SMichael Walsh 5926741f740SMichael Walsh grp.rqprint_timen("Starting boot " + str(boot_count) + ".") 5936741f740SMichael Walsh 5946741f740SMichael Walsh # Clear the ffdc_list_file_path file. Plug-ins may now write to it. 5956741f740SMichael Walsh try: 5966741f740SMichael Walsh os.remove(ffdc_list_file_path) 5976741f740SMichael Walsh except OSError: 5986741f740SMichael Walsh pass 5996741f740SMichael Walsh 6006741f740SMichael Walsh cmd_buf = ["run_boot", next_boot] 6016741f740SMichael Walsh boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf) 6026741f740SMichael Walsh if boot_status == "FAIL": 6036741f740SMichael Walsh grp.rprint(msg) 6046741f740SMichael Walsh 6056741f740SMichael Walsh grp.rqprintn() 6066741f740SMichael Walsh if boot_status == "PASS": 6076741f740SMichael Walsh boot_success = 1 6086741f740SMichael Walsh grp.rqprint_timen("BOOT_SUCCESS: \"" + next_boot + "\" succeeded.") 6096741f740SMichael Walsh else: 6106741f740SMichael Walsh boot_success = 0 6116741f740SMichael Walsh grp.rqprint_timen("BOOT_FAILED: \"" + next_boot + "\" failed.") 6126741f740SMichael Walsh 6136741f740SMichael Walsh boot_results.update(next_boot, boot_status) 6146741f740SMichael Walsh 6156741f740SMichael Walsh plug_in_setup() 6166741f740SMichael Walsh # NOTE: A post_test_case call point failure is NOT counted as a boot 6176741f740SMichael Walsh # failure. 6186741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 6196741f740SMichael Walsh call_point='post_test_case', stop_on_plug_in_failure=1) 6206741f740SMichael Walsh 6216741f740SMichael Walsh plug_in_setup() 6226741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 6236741f740SMichael Walsh call_point='ffdc_check', shell_rc=0x00000200, 6246741f740SMichael Walsh stop_on_plug_in_failure=1, stop_on_non_zero_rc=1) 6256741f740SMichael Walsh if boot_status != "PASS" or ffdc_check == "All" or shell_rc == 0x00000200: 6266741f740SMichael Walsh cmd_buf = ["my_ffdc"] 6276741f740SMichael Walsh grp.rpissuing_keyword(cmd_buf) 6283328caffSMichael Walsh try: 6296741f740SMichael Walsh BuiltIn().run_keyword_and_continue_on_failure(*cmd_buf) 6303328caffSMichael Walsh except: 6313328caffSMichael Walsh gp.print_error("Call to my_ffdc failed.\n") 6326741f740SMichael Walsh 633*d139f286SMichael Walsh # We need to purge error logs between boots or they build up. 634*d139f286SMichael Walsh cmd_buf = ["Delete Error logs"] 635*d139f286SMichael Walsh grp.rpissuing_keyword(cmd_buf, test_mode) 636*d139f286SMichael Walsh BuiltIn().run_keyword(*cmd_buf) 637*d139f286SMichael Walsh 638952f9b09SMichael Walsh boot_results.print_report() 639952f9b09SMichael Walsh grp.rqprint_timen("Finished boot " + str(boot_count) + ".") 640952f9b09SMichael Walsh 6416741f740SMichael Walsh plug_in_setup() 6426741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 6436741f740SMichael Walsh call_point='stop_check') 6446741f740SMichael Walsh if rc != 0: 6456741f740SMichael Walsh error_message = "Stopping as requested by user.\n" 6466741f740SMichael Walsh grp.rprint_error_report(error_message) 6476741f740SMichael Walsh BuiltIn().fail(error_message) 6486741f740SMichael Walsh 649*d139f286SMichael Walsh # This should help prevent ConnectionErrors. 650*d139f286SMichael Walsh cmd_buf = ["Delete All Sessions"] 651*d139f286SMichael Walsh grp.rpissuing_keyword(cmd_buf, test_mode) 652*d139f286SMichael Walsh BuiltIn().run_keyword(*cmd_buf) 653*d139f286SMichael Walsh 6546741f740SMichael Walsh return True 6556741f740SMichael Walsh 6566741f740SMichael Walsh############################################################################### 6576741f740SMichael Walsh 6586741f740SMichael Walsh 6596741f740SMichael Walsh############################################################################### 660c9116811SMichael Walshdef main_keyword_teardown(): 6616741f740SMichael Walsh 6626741f740SMichael Walsh r""" 663c9116811SMichael Walsh Clean up after the Main keyword. 6646741f740SMichael Walsh """ 6656741f740SMichael Walsh 6666741f740SMichael Walsh if cp_setup_called: 6676741f740SMichael Walsh plug_in_setup() 6686741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 6696741f740SMichael Walsh call_point='cleanup', stop_on_plug_in_failure=1) 6706741f740SMichael Walsh 6710b93fbf8SMichael Walsh # Save boot_results object to a file in case it is needed again. 6720b93fbf8SMichael Walsh grp.rprint_timen("Saving boot_results to the following path.") 6730b93fbf8SMichael Walsh grp.rprint_var(boot_results_file_path) 6740b93fbf8SMichael Walsh pickle.dump(boot_results, open(boot_results_file_path, 'wb'), 6750b93fbf8SMichael Walsh pickle.HIGHEST_PROTOCOL) 6760b93fbf8SMichael Walsh 6776741f740SMichael Walsh############################################################################### 6786741f740SMichael Walsh 6796741f740SMichael Walsh 6806741f740SMichael Walsh############################################################################### 681c9116811SMichael Walshdef test_teardown(): 682c9116811SMichael Walsh 683c9116811SMichael Walsh r""" 684c9116811SMichael Walsh Clean up after this test case. 685c9116811SMichael Walsh """ 686c9116811SMichael Walsh 687c9116811SMichael Walsh gp.qprintn() 688c9116811SMichael Walsh cmd_buf = ["Print Error", 689c9116811SMichael Walsh "A keyword timeout occurred ending this program.\n"] 690c9116811SMichael Walsh BuiltIn().run_keyword_if_timeout_occurred(*cmd_buf) 691c9116811SMichael Walsh 692c9116811SMichael Walsh############################################################################### 693c9116811SMichael Walsh 694c9116811SMichael Walsh 695c9116811SMichael Walsh############################################################################### 6966741f740SMichael Walshdef main_py(): 6976741f740SMichael Walsh 6986741f740SMichael Walsh r""" 6996741f740SMichael Walsh Do main program processing. 7006741f740SMichael Walsh """ 7016741f740SMichael Walsh 7026741f740SMichael Walsh setup() 7036741f740SMichael Walsh 704a20da401SMichael Walsh if ffdc_only: 705a20da401SMichael Walsh gp.qprint_timen("Caller requested ffdc_only.") 706a20da401SMichael Walsh cmd_buf = ["my_ffdc"] 707a20da401SMichael Walsh grp.rpissuing_keyword(cmd_buf) 708a20da401SMichael Walsh try: 709a20da401SMichael Walsh BuiltIn().run_keyword_and_continue_on_failure(*cmd_buf) 710a20da401SMichael Walsh except: 711a20da401SMichael Walsh gp.print_error("Call to my_ffdc failed.\n") 712a20da401SMichael Walsh 7136741f740SMichael Walsh # Process caller's boot_stack. 7146741f740SMichael Walsh while (len(boot_stack) > 0): 7156741f740SMichael Walsh test_loop_body() 7166741f740SMichael Walsh 71730dadae2SMichael Walsh grp.rprint_timen("Finished processing stack.") 71830dadae2SMichael Walsh 7196741f740SMichael Walsh # Process caller's boot_list. 7206741f740SMichael Walsh if len(boot_list) > 0: 7216741f740SMichael Walsh for ix in range(1, max_num_tests + 1): 7226741f740SMichael Walsh test_loop_body() 7236741f740SMichael Walsh 7246741f740SMichael Walsh grp.rqprint_timen("Completed all requested boot tests.") 7256741f740SMichael Walsh 7266741f740SMichael Walsh############################################################################### 727