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 * 180bbd860fSMichael Walshimport gen_robot_print as grp 1955302295SMichael Walshimport gen_robot_plug_in as grpi 206741f740SMichael Walshimport gen_robot_valid as grv 216741f740SMichael Walshimport gen_misc as gm 226741f740SMichael Walshimport gen_cmd as gc 2355302295SMichael Walshimport state as st 240bbd860fSMichael Walsh 250b93fbf8SMichael Walshbase_path = os.path.dirname(os.path.dirname( 260b93fbf8SMichael Walsh imp.find_module("gen_robot_print")[1])) +\ 270b93fbf8SMichael Walsh os.sep 280b93fbf8SMichael Walshsys.path.append(base_path + "extended/") 290b93fbf8SMichael Walshimport run_keyword as rk 300bbd860fSMichael Walsh 316741f740SMichael Walsh# Program parameter processing. 326741f740SMichael Walsh# Assign all program parms to python variables which are global to this module. 336741f740SMichael Walshparm_list = BuiltIn().get_variable_value("${parm_list}") 346741f740SMichael Walshint_list = ['max_num_tests', 'boot_pass', 'boot_fail', 'quiet', 'test_mode', 356741f740SMichael Walsh 'debug'] 366741f740SMichael Walshfor parm in parm_list: 376741f740SMichael Walsh if parm in int_list: 386741f740SMichael Walsh sub_cmd = "int(BuiltIn().get_variable_value(\"${" + parm +\ 396741f740SMichael Walsh "}\", \"0\"))" 406741f740SMichael Walsh else: 416741f740SMichael Walsh sub_cmd = "BuiltIn().get_variable_value(\"${" + parm + "}\")" 426741f740SMichael Walsh cmd_buf = parm + " = " + sub_cmd 436741f740SMichael Walsh exec(cmd_buf) 440bbd860fSMichael Walsh 456741f740SMichael Walshif ffdc_dir_path_style == "": 466741f740SMichael Walsh ffdc_dir_path_style = int(os.environ.get('FFDC_DIR_PATH_STYLE', '0')) 476741f740SMichael Walsh 486741f740SMichael Walsh# Set up boot data structures. 496741f740SMichael Walshboot_table = create_boot_table() 506741f740SMichael Walshvalid_boot_types = create_valid_boot_list(boot_table) 510b93fbf8SMichael Walsh 52e1e26448SMichael Walsh# Setting master_pid correctly influences the behavior of plug-ins like 53e1e26448SMichael Walsh# DB_Logging 54e1e26448SMichael Walshprogram_pid = os.getpid() 55e1e26448SMichael Walshmaster_pid = os.environ.get('AUTOBOOT_MASTER_PID', program_pid) 56e1e26448SMichael Walsh 57e1e26448SMichael Walshboot_results_file_path = "/tmp/" + openbmc_nickname + ":pid_" +\ 58e1e26448SMichael Walsh str(master_pid) + ":boot_results" 59e1e26448SMichael Walshif os.path.isfile(boot_results_file_path): 600b93fbf8SMichael Walsh # We've been called before in this run so we'll load the saved 610b93fbf8SMichael Walsh # boot_results object. 620b93fbf8SMichael Walsh boot_results = pickle.load(open(boot_results_file_path, 'rb')) 630b93fbf8SMichael Walshelse: 646741f740SMichael Walsh boot_results = boot_results(boot_table, boot_pass, boot_fail) 650b93fbf8SMichael Walsh 666741f740SMichael Walshboot_lists = read_boot_lists() 676741f740SMichael Walshlast_ten = [] 686741f740SMichael Walsh# Convert these program parms to more useable lists. 696741f740SMichael Walshboot_list = filter(None, boot_list.split(":")) 706741f740SMichael Walshboot_stack = filter(None, boot_stack.split(":")) 716741f740SMichael Walsh 726741f740SMichael Walshstate = st.return_default_state() 736741f740SMichael Walshcp_setup_called = 0 746741f740SMichael Walshnext_boot = "" 756741f740SMichael Walshbase_tool_dir_path = os.path.normpath(os.environ.get( 766741f740SMichael Walsh 'AUTOBOOT_BASE_TOOL_DIR_PATH', "/tmp")) + os.sep 776741f740SMichael Walshffdc_dir_path = os.path.normpath(os.environ.get('FFDC_DIR_PATH', '')) + os.sep 786741f740SMichael Walshffdc_list_file_path = base_tool_dir_path + openbmc_nickname + "/FFDC_FILE_LIST" 796741f740SMichael Walshboot_success = 0 806741f740SMichael Walshstatus_dir_path = os.environ.get('STATUS_DIR_PATH', "") 816741f740SMichael Walshif status_dir_path != "": 826741f740SMichael Walsh status_dir_path = os.path.normpath(status_dir_path) + os.sep 830b93fbf8SMichael Walshdefault_power_on = "REST Power On" 840b93fbf8SMichael Walshdefault_power_off = "REST Power Off" 856741f740SMichael Walshboot_count = 0 860bbd860fSMichael Walsh 870bbd860fSMichael Walsh 880bbd860fSMichael Walsh############################################################################### 890bbd860fSMichael Walshdef plug_in_setup(): 900bbd860fSMichael Walsh 910bbd860fSMichael Walsh r""" 920bbd860fSMichael Walsh Initialize all plug-in environment variables for use by the plug-in 930bbd860fSMichael Walsh programs. 940bbd860fSMichael Walsh """ 950bbd860fSMichael Walsh 966741f740SMichael Walsh boot_pass, boot_fail = boot_results.return_total_pass_fail() 970bbd860fSMichael Walsh if boot_pass > 1: 980bbd860fSMichael Walsh test_really_running = 1 990bbd860fSMichael Walsh else: 1000bbd860fSMichael Walsh test_really_running = 0 1010bbd860fSMichael Walsh 1020bbd860fSMichael Walsh seconds = time.time() 1030bbd860fSMichael Walsh loc_time = time.localtime(seconds) 1040bbd860fSMichael Walsh time_string = time.strftime("%y%m%d.%H%M%S.", loc_time) 1050bbd860fSMichael Walsh 1066741f740SMichael Walsh ffdc_prefix = openbmc_nickname + "." + time_string 1070bbd860fSMichael Walsh 1086741f740SMichael Walsh BuiltIn().set_global_variable("${test_really_running}", 1096741f740SMichael Walsh test_really_running) 1106741f740SMichael Walsh BuiltIn().set_global_variable("${boot_type_desc}", next_boot) 1116741f740SMichael Walsh BuiltIn().set_global_variable("${master_pid}", master_pid) 1120bbd860fSMichael Walsh BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path) 11355302295SMichael Walsh BuiltIn().set_global_variable("${STATUS_DIR_PATH}", status_dir_path) 1144c9a6453SMichael Walsh BuiltIn().set_global_variable("${BASE_TOOL_DIR_PATH}", base_tool_dir_path) 1154c9a6453SMichael Walsh BuiltIn().set_global_variable("${FFDC_LIST_FILE_PATH}", 1164c9a6453SMichael Walsh ffdc_list_file_path) 1176741f740SMichael Walsh BuiltIn().set_global_variable("${FFDC_DIR_PATH_STYLE}", 1186741f740SMichael Walsh ffdc_dir_path_style) 1196741f740SMichael Walsh BuiltIn().set_global_variable("${FFDC_CHECK}", 1206741f740SMichael Walsh ffdc_check) 1216741f740SMichael Walsh BuiltIn().set_global_variable("${boot_pass}", boot_pass) 1226741f740SMichael Walsh BuiltIn().set_global_variable("${boot_fail}", boot_fail) 1236741f740SMichael Walsh BuiltIn().set_global_variable("${boot_success}", boot_success) 1246741f740SMichael Walsh BuiltIn().set_global_variable("${ffdc_prefix}", ffdc_prefix) 1254c9a6453SMichael Walsh 1260bbd860fSMichael Walsh # For each program parameter, set the corresponding AUTOBOOT_ environment 1270bbd860fSMichael Walsh # variable value. Also, set an AUTOBOOT_ environment variable for every 1280bbd860fSMichael Walsh # element in additional_values. 1290bbd860fSMichael Walsh additional_values = ["boot_type_desc", "boot_success", "boot_pass", 1300bbd860fSMichael Walsh "boot_fail", "test_really_running", "program_pid", 1314c9a6453SMichael Walsh "master_pid", "ffdc_prefix", "ffdc_dir_path", 13255302295SMichael Walsh "status_dir_path", "base_tool_dir_path", 13355302295SMichael Walsh "ffdc_list_file_path"] 1340bbd860fSMichael Walsh 1350bbd860fSMichael Walsh plug_in_vars = parm_list + additional_values 1360bbd860fSMichael Walsh 1370bbd860fSMichael Walsh for var_name in plug_in_vars: 1380bbd860fSMichael Walsh var_value = BuiltIn().get_variable_value("${" + var_name + "}") 1390bbd860fSMichael Walsh var_name = var_name.upper() 1400bbd860fSMichael Walsh if var_value is None: 1410bbd860fSMichael Walsh var_value = "" 1426741f740SMichael Walsh os.environ["AUTOBOOT_" + var_name] = str(var_value) 1430bbd860fSMichael Walsh 1440bbd860fSMichael Walsh if debug: 1456741f740SMichael Walsh shell_rc, out_buf = \ 1466741f740SMichael Walsh gc.cmd_fnc_u("printenv | egrep AUTOBOOT_ | sort -u") 1470bbd860fSMichael Walsh 1480bbd860fSMichael Walsh############################################################################### 1490bbd860fSMichael Walsh 1500bbd860fSMichael Walsh 1510bbd860fSMichael Walsh############################################################################### 1526741f740SMichael Walshdef setup(): 1530bbd860fSMichael Walsh 1540bbd860fSMichael Walsh r""" 1556741f740SMichael Walsh Do general program setup tasks. 1560bbd860fSMichael Walsh """ 1570bbd860fSMichael Walsh 1586741f740SMichael Walsh global cp_setup_called 1590bbd860fSMichael Walsh 1606741f740SMichael Walsh grp.rqprintn() 1616741f740SMichael Walsh 1626741f740SMichael Walsh validate_parms() 1636741f740SMichael Walsh 1646741f740SMichael Walsh grp.rqprint_pgm_header() 1656741f740SMichael Walsh 1666741f740SMichael Walsh plug_in_setup() 1676741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 1686741f740SMichael Walsh call_point='setup') 1696741f740SMichael Walsh if rc != 0: 1706741f740SMichael Walsh error_message = "Plug-in setup failed.\n" 1716741f740SMichael Walsh grp.rprint_error_report(error_message) 1726741f740SMichael Walsh BuiltIn().fail(error_message) 1736741f740SMichael Walsh # Setting cp_setup_called lets our Teardown know that it needs to call 1746741f740SMichael Walsh # the cleanup plug-in call point. 1756741f740SMichael Walsh cp_setup_called = 1 1766741f740SMichael Walsh 1776741f740SMichael Walsh # Keyword "FFDC" will fail if TEST_MESSAGE is not set. 1786741f740SMichael Walsh BuiltIn().set_global_variable("${TEST_MESSAGE}", "${EMPTY}") 1796741f740SMichael Walsh 1806741f740SMichael Walsh grp.rdprint_var(boot_table, 1) 1816741f740SMichael Walsh grp.rdprint_var(boot_lists) 1820bbd860fSMichael Walsh 1830bbd860fSMichael Walsh############################################################################### 1840bbd860fSMichael Walsh 1850bbd860fSMichael Walsh 1860bbd860fSMichael Walsh############################################################################### 1876741f740SMichael Walshdef validate_parms(): 1880bbd860fSMichael Walsh 1890bbd860fSMichael Walsh r""" 1906741f740SMichael Walsh Validate all program parameters. 1910bbd860fSMichael Walsh """ 1920bbd860fSMichael Walsh 1936741f740SMichael Walsh grp.rqprintn() 1940bbd860fSMichael Walsh 1956741f740SMichael Walsh grv.rvalid_value("openbmc_host") 1966741f740SMichael Walsh grv.rvalid_value("openbmc_username") 1976741f740SMichael Walsh grv.rvalid_value("openbmc_password") 1986741f740SMichael Walsh if os_host != "": 1996741f740SMichael Walsh grv.rvalid_value("os_username") 2006741f740SMichael Walsh grv.rvalid_value("os_password") 2010bbd860fSMichael Walsh 2026741f740SMichael Walsh if pdu_host != "": 2036741f740SMichael Walsh grv.rvalid_value("pdu_username") 2046741f740SMichael Walsh grv.rvalid_value("pdu_password") 2056741f740SMichael Walsh grv.rvalid_integer("pdu_slot_no") 2066741f740SMichael Walsh if openbmc_serial_host != "": 2076741f740SMichael Walsh grv.rvalid_integer("openbmc_serial_port") 2086741f740SMichael Walsh grv.rvalid_integer("max_num_tests") 2096741f740SMichael Walsh grv.rvalid_value("openbmc_model") 2106741f740SMichael Walsh grv.rvalid_integer("boot_pass") 2116741f740SMichael Walsh grv.rvalid_integer("boot_fail") 2126741f740SMichael Walsh 2136741f740SMichael Walsh plug_in_packages_list = grpi.rvalidate_plug_ins(plug_in_dir_paths) 2146741f740SMichael Walsh BuiltIn().set_global_variable("${plug_in_packages_list}", 2156741f740SMichael Walsh plug_in_packages_list) 2166741f740SMichael Walsh 2176741f740SMichael Walsh if len(boot_list) == 0 and len(boot_stack) == 0: 2186741f740SMichael Walsh error_message = "You must provide either a value for either the" +\ 2196741f740SMichael Walsh " boot_list or the boot_stack parm.\n" 2206741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 2216741f740SMichael Walsh 2226741f740SMichael Walsh valid_boot_list(boot_list, valid_boot_types) 2236741f740SMichael Walsh valid_boot_list(boot_stack, valid_boot_types) 2246741f740SMichael Walsh 2256741f740SMichael Walsh return 2260bbd860fSMichael Walsh 2270bbd860fSMichael Walsh############################################################################### 2280bbd860fSMichael Walsh 2290bbd860fSMichael Walsh 2300bbd860fSMichael Walsh############################################################################### 2316741f740SMichael Walshdef my_get_state(): 2320bbd860fSMichael Walsh 2330bbd860fSMichael Walsh r""" 2346741f740SMichael Walsh Get the system state plus a little bit of wrapping. 2350bbd860fSMichael Walsh """ 2360bbd860fSMichael Walsh 2376741f740SMichael Walsh global state 2386741f740SMichael Walsh 2396741f740SMichael Walsh req_states = ['epoch_seconds'] + st.default_req_states 2406741f740SMichael Walsh 2416741f740SMichael Walsh grp.rqprint_timen("Getting system state.") 2426741f740SMichael Walsh if test_mode: 2436741f740SMichael Walsh state['epoch_seconds'] = int(time.time()) 2446741f740SMichael Walsh else: 2456741f740SMichael Walsh state = st.get_state(req_states=req_states, quiet=0) 2466741f740SMichael Walsh grp.rprint_var(state) 247341c21ebSMichael Walsh 248341c21ebSMichael Walsh############################################################################### 249341c21ebSMichael Walsh 250341c21ebSMichael Walsh 251341c21ebSMichael Walsh############################################################################### 2526741f740SMichael Walshdef select_boot(): 253341c21ebSMichael Walsh 254341c21ebSMichael Walsh r""" 255341c21ebSMichael Walsh Select a boot test to be run based on our current state and return the 256341c21ebSMichael Walsh chosen boot type. 257341c21ebSMichael Walsh 258341c21ebSMichael Walsh Description of arguments: 2596741f740SMichael Walsh state The state of the machine. 260341c21ebSMichael Walsh """ 261341c21ebSMichael Walsh 26230dadae2SMichael Walsh global boot_stack 26330dadae2SMichael Walsh 2646741f740SMichael Walsh grp.rprint_timen("Selecting a boot test.") 2656741f740SMichael Walsh 2666741f740SMichael Walsh my_get_state() 2676741f740SMichael Walsh 2686741f740SMichael Walsh stack_popped = 0 2696741f740SMichael Walsh if len(boot_stack) > 0: 2706741f740SMichael Walsh stack_popped = 1 2716741f740SMichael Walsh grp.rprint_dashes() 2726741f740SMichael Walsh grp.rprint_var(boot_stack) 2736741f740SMichael Walsh grp.rprint_dashes() 2746741f740SMichael Walsh boot_candidate = boot_stack.pop() 2756741f740SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['start']): 2766741f740SMichael Walsh grp.rprint_timen("The machine state is valid for a '" + 2776741f740SMichael Walsh boot_candidate + "' boot test.") 2786741f740SMichael Walsh grp.rprint_dashes() 2796741f740SMichael Walsh grp.rprint_var(boot_stack) 2806741f740SMichael Walsh grp.rprint_dashes() 2816741f740SMichael Walsh return boot_candidate 282341c21ebSMichael Walsh else: 2836741f740SMichael Walsh grp.rprint_timen("The machine state is not valid for a '" + 2846741f740SMichael Walsh boot_candidate + "' boot test.") 2856741f740SMichael Walsh boot_stack.append(boot_candidate) 2866741f740SMichael Walsh popped_boot = boot_candidate 2876741f740SMichael Walsh 2886741f740SMichael Walsh # Loop through your list selecting a boot_candidates 2896741f740SMichael Walsh boot_candidates = [] 2906741f740SMichael Walsh for boot_candidate in boot_list: 2916741f740SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['start']): 2926741f740SMichael Walsh if stack_popped: 2936741f740SMichael Walsh if st.compare_states(boot_table[boot_candidate]['end'], 2946741f740SMichael Walsh boot_table[popped_boot]['start']): 2956741f740SMichael Walsh boot_candidates.append(boot_candidate) 296341c21ebSMichael Walsh else: 2976741f740SMichael Walsh boot_candidates.append(boot_candidate) 2986741f740SMichael Walsh 2996741f740SMichael Walsh if len(boot_candidates) == 0: 3006741f740SMichael Walsh grp.rprint_timen("The user's boot list contained no boot tests" + 3016741f740SMichael Walsh " which are valid for the current machine state.") 3026741f740SMichael Walsh boot_candidate = default_power_on 3036741f740SMichael Walsh if not st.compare_states(state, boot_table[default_power_on]['start']): 3046741f740SMichael Walsh boot_candidate = default_power_off 3056741f740SMichael Walsh boot_candidates.append(boot_candidate) 3066741f740SMichael Walsh grp.rprint_timen("Using default '" + boot_candidate + 3076741f740SMichael Walsh "' boot type to transtion to valid state.") 3086741f740SMichael Walsh 3096741f740SMichael Walsh grp.rdprint_var(boot_candidates) 3106741f740SMichael Walsh 3116741f740SMichael Walsh # Randomly select a boot from the candidate list. 3126741f740SMichael Walsh boot = random.choice(boot_candidates) 313341c21ebSMichael Walsh 314341c21ebSMichael Walsh return boot 3150bbd860fSMichael Walsh 3160bbd860fSMichael Walsh############################################################################### 31755302295SMichael Walsh 31855302295SMichael Walsh 31955302295SMichael Walsh############################################################################### 320341c21ebSMichael Walshdef print_last_boots(): 321341c21ebSMichael Walsh 322341c21ebSMichael Walsh r""" 323341c21ebSMichael Walsh Print the last ten boots done with their time stamps. 324341c21ebSMichael Walsh """ 325341c21ebSMichael Walsh 326341c21ebSMichael Walsh # indent 0, 90 chars wide, linefeed, char is "=" 327341c21ebSMichael Walsh grp.rqprint_dashes(0, 90) 328341c21ebSMichael Walsh grp.rqprintn("Last 10 boots:\n") 329341c21ebSMichael Walsh 330341c21ebSMichael Walsh for boot_entry in last_ten: 331341c21ebSMichael Walsh grp.rqprint(boot_entry) 332341c21ebSMichael Walsh grp.rqprint_dashes(0, 90) 333341c21ebSMichael Walsh 334341c21ebSMichael Walsh############################################################################### 335341c21ebSMichael Walsh 336341c21ebSMichael Walsh 337341c21ebSMichael Walsh############################################################################### 338341c21ebSMichael Walshdef print_defect_report(): 339341c21ebSMichael Walsh 340341c21ebSMichael Walsh r""" 341341c21ebSMichael Walsh Print a defect report. 342341c21ebSMichael Walsh """ 343341c21ebSMichael Walsh 344341c21ebSMichael Walsh grp.rqprintn() 345341c21ebSMichael Walsh # indent=0, width=90, linefeed=1, char="=" 346341c21ebSMichael Walsh grp.rqprint_dashes(0, 90, 1, "=") 347341c21ebSMichael Walsh grp.rqprintn("Copy this data to the defect:\n") 348341c21ebSMichael Walsh 349341c21ebSMichael Walsh grp.rqpvars(*parm_list) 350341c21ebSMichael Walsh 351341c21ebSMichael Walsh grp.rqprintn() 352341c21ebSMichael Walsh 353341c21ebSMichael Walsh print_last_boots() 354341c21ebSMichael Walsh grp.rqprintn() 355341c21ebSMichael Walsh grp.rqpvar(state) 356341c21ebSMichael Walsh 357341c21ebSMichael Walsh # At some point I'd like to have the 'Call FFDC Methods' return a list 358341c21ebSMichael Walsh # of files it has collected. In that case, the following "ls" command 359341c21ebSMichael Walsh # would no longer be needed. For now, however, glob shows the files 360341c21ebSMichael Walsh # named in FFDC_LIST_FILE_PATH so I will refrain from printing those 361341c21ebSMichael Walsh # out (so we don't see duplicates in the list). 362341c21ebSMichael Walsh 363341c21ebSMichael Walsh LOG_PREFIX = BuiltIn().get_variable_value("${LOG_PREFIX}") 364341c21ebSMichael Walsh 365341c21ebSMichael Walsh output = '\n'.join(glob.glob(LOG_PREFIX + '*')) 366341c21ebSMichael Walsh try: 3676741f740SMichael Walsh ffdc_list = open(ffdc_list_file_path, 'r') 368341c21ebSMichael Walsh except IOError: 369341c21ebSMichael Walsh ffdc_list = "" 370341c21ebSMichael Walsh 371341c21ebSMichael Walsh grp.rqprintn() 372341c21ebSMichael Walsh grp.rqprintn("FFDC data files:") 373341c21ebSMichael Walsh if status_file_path != "": 374341c21ebSMichael Walsh grp.rqprintn(status_file_path) 375341c21ebSMichael Walsh 376341c21ebSMichael Walsh grp.rqprintn(output) 377341c21ebSMichael Walsh # grp.rqprintn(ffdc_list) 378341c21ebSMichael Walsh grp.rqprintn() 379341c21ebSMichael Walsh 380341c21ebSMichael Walsh grp.rqprint_dashes(0, 90, 1, "=") 381341c21ebSMichael Walsh 382341c21ebSMichael Walsh############################################################################### 3836741f740SMichael Walsh 3846741f740SMichael Walsh 3856741f740SMichael Walsh############################################################################### 3866741f740SMichael Walshdef my_ffdc(): 3876741f740SMichael Walsh 3886741f740SMichael Walsh r""" 3896741f740SMichael Walsh Collect FFDC data. 3906741f740SMichael Walsh """ 3916741f740SMichael Walsh 3926741f740SMichael Walsh global state 3936741f740SMichael Walsh 3946741f740SMichael Walsh plug_in_setup() 3956741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 3966741f740SMichael Walsh call_point='ffdc', stop_on_plug_in_failure=1) 3976741f740SMichael Walsh 3986741f740SMichael Walsh AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX'] 3996741f740SMichael Walsh 4006741f740SMichael Walsh # FFDC_LOG_PATH is used by "FFDC" keyword. 4016741f740SMichael Walsh BuiltIn().set_global_variable("${FFDC_LOG_PATH}", ffdc_dir_path) 4026741f740SMichael Walsh 4036741f740SMichael Walsh cmd_buf = ["FFDC", "ffdc_prefix=" + AUTOBOOT_FFDC_PREFIX] 4046741f740SMichael Walsh grp.rpissuing_keyword(cmd_buf) 4056741f740SMichael Walsh BuiltIn().run_keyword(*cmd_buf) 4066741f740SMichael Walsh 4076741f740SMichael Walsh my_get_state() 4086741f740SMichael Walsh 4096741f740SMichael Walsh print_defect_report() 4106741f740SMichael Walsh 4116741f740SMichael Walsh############################################################################### 4126741f740SMichael Walsh 4136741f740SMichael Walsh 4146741f740SMichael Walsh############################################################################### 4156741f740SMichael Walshdef print_test_start_message(boot_keyword): 4166741f740SMichael Walsh 4176741f740SMichael Walsh r""" 4186741f740SMichael Walsh Print a message indicating what boot test is about to run. 4196741f740SMichael Walsh 4206741f740SMichael Walsh Description of arguments: 4216741f740SMichael Walsh boot_keyword The name of the boot which is to be run 4226741f740SMichael Walsh (e.g. "BMC Power On"). 4236741f740SMichael Walsh """ 4246741f740SMichael Walsh 4256741f740SMichael Walsh global last_ten 4266741f740SMichael Walsh 4276741f740SMichael Walsh doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".") 4286741f740SMichael Walsh grp.rqprint(doing_msg) 4296741f740SMichael Walsh 4306741f740SMichael Walsh last_ten.append(doing_msg) 4316741f740SMichael Walsh 4326741f740SMichael Walsh if len(last_ten) > 10: 4336741f740SMichael Walsh del last_ten[0] 4346741f740SMichael Walsh 4356741f740SMichael Walsh############################################################################### 4366741f740SMichael Walsh 4376741f740SMichael Walsh 4386741f740SMichael Walsh############################################################################### 4396741f740SMichael Walshdef run_boot(boot): 4406741f740SMichael Walsh 4416741f740SMichael Walsh r""" 4426741f740SMichael Walsh Run the specified boot. 4436741f740SMichael Walsh 4446741f740SMichael Walsh Description of arguments: 4456741f740SMichael Walsh boot The name of the boot test to be performed. 4466741f740SMichael Walsh """ 4476741f740SMichael Walsh 4486741f740SMichael Walsh global state 4496741f740SMichael Walsh 4506741f740SMichael Walsh print_test_start_message(boot) 4516741f740SMichael Walsh 4526741f740SMichael Walsh plug_in_setup() 4536741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 4546741f740SMichael Walsh grpi.rprocess_plug_in_packages(call_point="pre_boot") 4556741f740SMichael Walsh if rc != 0: 4566741f740SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" +\ 4576741f740SMichael Walsh gp.sprint_var(rc, 1) 4586741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 4596741f740SMichael Walsh 4606741f740SMichael Walsh if test_mode: 4616741f740SMichael Walsh # In test mode, we'll pretend the boot worked by assigning its 4626741f740SMichael Walsh # required end state to the default state value. 46330dadae2SMichael Walsh state = st.strip_anchor_state(boot_table[boot]['end']) 4646741f740SMichael Walsh else: 4656741f740SMichael Walsh # Assertion: We trust that the state data was made fresh by the 4666741f740SMichael Walsh # caller. 4676741f740SMichael Walsh 4686741f740SMichael Walsh grp.rprintn() 4696741f740SMichael Walsh 4706741f740SMichael Walsh if boot_table[boot]['method_type'] == "keyword": 4710b93fbf8SMichael Walsh rk.my_run_keywords(boot_table[boot].get('lib_file_path', ''), 4720b93fbf8SMichael Walsh boot_table[boot]['method']) 4736741f740SMichael Walsh 4746741f740SMichael Walsh if boot_table[boot]['bmc_reboot']: 4756741f740SMichael Walsh st.wait_for_comm_cycle(int(state['epoch_seconds'])) 47630dadae2SMichael Walsh plug_in_setup() 47730dadae2SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 47830dadae2SMichael Walsh grpi.rprocess_plug_in_packages(call_point="post_reboot") 47930dadae2SMichael Walsh if rc != 0: 4800b93fbf8SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" 4810b93fbf8SMichael Walsh error_message += gp.sprint_var(rc, 1) 48230dadae2SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 4836741f740SMichael Walsh else: 4846741f740SMichael Walsh match_state = st.anchor_state(state) 4856741f740SMichael Walsh del match_state['epoch_seconds'] 4866741f740SMichael Walsh # Wait for the state to change in any way. 4876741f740SMichael Walsh st.wait_state(match_state, wait_time=state_change_timeout, 4886741f740SMichael Walsh interval="3 seconds", invert=1) 4896741f740SMichael Walsh 4906741f740SMichael Walsh grp.rprintn() 4916741f740SMichael Walsh if boot_table[boot]['end']['chassis'] == "Off": 4926741f740SMichael Walsh boot_timeout = power_off_timeout 4936741f740SMichael Walsh else: 4946741f740SMichael Walsh boot_timeout = power_on_timeout 4956741f740SMichael Walsh st.wait_state(boot_table[boot]['end'], wait_time=boot_timeout, 4966741f740SMichael Walsh interval="3 seconds") 4976741f740SMichael Walsh 4986741f740SMichael Walsh plug_in_setup() 4996741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 5006741f740SMichael Walsh grpi.rprocess_plug_in_packages(call_point="post_boot") 5016741f740SMichael Walsh if rc != 0: 5026741f740SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" +\ 5036741f740SMichael Walsh gp.sprint_var(rc, 1) 5046741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 5056741f740SMichael Walsh 5066741f740SMichael Walsh############################################################################### 5076741f740SMichael Walsh 5086741f740SMichael Walsh 5096741f740SMichael Walsh############################################################################### 5106741f740SMichael Walshdef test_loop_body(): 5116741f740SMichael Walsh 5126741f740SMichael Walsh r""" 5136741f740SMichael Walsh The main loop body for the loop in main_py. 5146741f740SMichael Walsh 5156741f740SMichael Walsh Description of arguments: 5166741f740SMichael Walsh boot_count The iteration number (starts at 1). 5176741f740SMichael Walsh """ 5186741f740SMichael Walsh 5196741f740SMichael Walsh global boot_count 5206741f740SMichael Walsh global state 5216741f740SMichael Walsh global next_boot 5226741f740SMichael Walsh global boot_success 5236741f740SMichael Walsh 5246741f740SMichael Walsh grp.rqprintn() 5256741f740SMichael Walsh 5266741f740SMichael Walsh boot_count += 1 5276741f740SMichael Walsh 5286741f740SMichael Walsh next_boot = select_boot() 5296741f740SMichael Walsh 5306741f740SMichael Walsh grp.rqprint_timen("Starting boot " + str(boot_count) + ".") 5316741f740SMichael Walsh 5326741f740SMichael Walsh # Clear the ffdc_list_file_path file. Plug-ins may now write to it. 5336741f740SMichael Walsh try: 5346741f740SMichael Walsh os.remove(ffdc_list_file_path) 5356741f740SMichael Walsh except OSError: 5366741f740SMichael Walsh pass 5376741f740SMichael Walsh 5386741f740SMichael Walsh cmd_buf = ["run_boot", next_boot] 5396741f740SMichael Walsh boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf) 5406741f740SMichael Walsh if boot_status == "FAIL": 5416741f740SMichael Walsh grp.rprint(msg) 5426741f740SMichael Walsh 5436741f740SMichael Walsh grp.rqprintn() 5446741f740SMichael Walsh if boot_status == "PASS": 5456741f740SMichael Walsh boot_success = 1 5466741f740SMichael Walsh grp.rqprint_timen("BOOT_SUCCESS: \"" + next_boot + "\" succeeded.") 5476741f740SMichael Walsh else: 5486741f740SMichael Walsh boot_success = 0 5496741f740SMichael Walsh grp.rqprint_timen("BOOT_FAILED: \"" + next_boot + "\" failed.") 5506741f740SMichael Walsh 5516741f740SMichael Walsh boot_results.update(next_boot, boot_status) 5526741f740SMichael Walsh 5536741f740SMichael Walsh plug_in_setup() 5546741f740SMichael Walsh # NOTE: A post_test_case call point failure is NOT counted as a boot 5556741f740SMichael Walsh # failure. 5566741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 5576741f740SMichael Walsh call_point='post_test_case', stop_on_plug_in_failure=1) 5586741f740SMichael Walsh 5596741f740SMichael Walsh plug_in_setup() 5606741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 5616741f740SMichael Walsh call_point='ffdc_check', shell_rc=0x00000200, 5626741f740SMichael Walsh stop_on_plug_in_failure=1, stop_on_non_zero_rc=1) 5636741f740SMichael Walsh if boot_status != "PASS" or ffdc_check == "All" or shell_rc == 0x00000200: 5646741f740SMichael Walsh cmd_buf = ["my_ffdc"] 5656741f740SMichael Walsh grp.rpissuing_keyword(cmd_buf) 5666741f740SMichael Walsh BuiltIn().run_keyword_and_continue_on_failure(*cmd_buf) 5676741f740SMichael Walsh 568*952f9b09SMichael Walsh boot_results.print_report() 569*952f9b09SMichael Walsh grp.rqprint_timen("Finished boot " + str(boot_count) + ".") 570*952f9b09SMichael Walsh 5716741f740SMichael Walsh plug_in_setup() 5726741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 5736741f740SMichael Walsh call_point='stop_check') 5746741f740SMichael Walsh if rc != 0: 5756741f740SMichael Walsh error_message = "Stopping as requested by user.\n" 5766741f740SMichael Walsh grp.rprint_error_report(error_message) 5776741f740SMichael Walsh BuiltIn().fail(error_message) 5786741f740SMichael Walsh 5796741f740SMichael Walsh return True 5806741f740SMichael Walsh 5816741f740SMichael Walsh############################################################################### 5826741f740SMichael Walsh 5836741f740SMichael Walsh 5846741f740SMichael Walsh############################################################################### 5856741f740SMichael Walshdef program_teardown(): 5866741f740SMichael Walsh 5876741f740SMichael Walsh r""" 5886741f740SMichael Walsh Clean up after this program. 5896741f740SMichael Walsh """ 5906741f740SMichael Walsh 5916741f740SMichael Walsh if cp_setup_called: 5926741f740SMichael Walsh plug_in_setup() 5936741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 5946741f740SMichael Walsh call_point='cleanup', stop_on_plug_in_failure=1) 5956741f740SMichael Walsh 5960b93fbf8SMichael Walsh # Save boot_results object to a file in case it is needed again. 5970b93fbf8SMichael Walsh grp.rprint_timen("Saving boot_results to the following path.") 5980b93fbf8SMichael Walsh grp.rprint_var(boot_results_file_path) 5990b93fbf8SMichael Walsh pickle.dump(boot_results, open(boot_results_file_path, 'wb'), 6000b93fbf8SMichael Walsh pickle.HIGHEST_PROTOCOL) 6010b93fbf8SMichael Walsh 6026741f740SMichael Walsh############################################################################### 6036741f740SMichael Walsh 6046741f740SMichael Walsh 6056741f740SMichael Walsh############################################################################### 6066741f740SMichael Walshdef main_py(): 6076741f740SMichael Walsh 6086741f740SMichael Walsh r""" 6096741f740SMichael Walsh Do main program processing. 6106741f740SMichael Walsh """ 6116741f740SMichael Walsh 6126741f740SMichael Walsh setup() 6136741f740SMichael Walsh 6146741f740SMichael Walsh # Process caller's boot_stack. 6156741f740SMichael Walsh while (len(boot_stack) > 0): 6166741f740SMichael Walsh test_loop_body() 6176741f740SMichael Walsh 61830dadae2SMichael Walsh grp.rprint_timen("Finished processing stack.") 61930dadae2SMichael Walsh 6206741f740SMichael Walsh # Process caller's boot_list. 6216741f740SMichael Walsh if len(boot_list) > 0: 6226741f740SMichael Walsh for ix in range(1, max_num_tests + 1): 6236741f740SMichael Walsh test_loop_body() 6246741f740SMichael Walsh 6256741f740SMichael Walsh grp.rqprint_timen("Completed all requested boot tests.") 6266741f740SMichael Walsh 6276741f740SMichael Walsh############################################################################### 628