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 130b93fbf8SMichael Walshimport cPickle as pickle 14dc80d67dSMichael Walshimport socket 150b93fbf8SMichael Walsh 160b93fbf8SMichael Walshfrom robot.utils import DotDict 170b93fbf8SMichael Walshfrom robot.libraries.BuiltIn import BuiltIn 180b93fbf8SMichael Walsh 196741f740SMichael Walshfrom boot_data import * 20c9116811SMichael Walshimport gen_print as gp 210bbd860fSMichael Walshimport gen_robot_print as grp 2255302295SMichael Walshimport gen_robot_plug_in as grpi 236741f740SMichael Walshimport gen_robot_valid as grv 246741f740SMichael Walshimport gen_misc as gm 256741f740SMichael Walshimport gen_cmd as gc 26b5839d00SMichael Walshimport gen_robot_keyword as grk 2755302295SMichael Walshimport state as st 280bbd860fSMichael Walsh 290b93fbf8SMichael Walshbase_path = os.path.dirname(os.path.dirname( 300b93fbf8SMichael Walsh imp.find_module("gen_robot_print")[1])) +\ 310b93fbf8SMichael Walsh os.sep 320b93fbf8SMichael Walshsys.path.append(base_path + "extended/") 330b93fbf8SMichael Walshimport run_keyword as rk 340bbd860fSMichael Walsh 35e1e26448SMichael Walsh# Setting master_pid correctly influences the behavior of plug-ins like 36e1e26448SMichael Walsh# DB_Logging 37e1e26448SMichael Walshprogram_pid = os.getpid() 38e1e26448SMichael Walshmaster_pid = os.environ.get('AUTOBOOT_MASTER_PID', program_pid) 39e1e26448SMichael Walsh 40b5839d00SMichael Walsh# Set up boot data structures. 41b5839d00SMichael Walshboot_table = create_boot_table() 42b5839d00SMichael Walshvalid_boot_types = create_valid_boot_list(boot_table) 430b93fbf8SMichael Walsh 446741f740SMichael Walshboot_lists = read_boot_lists() 456741f740SMichael Walshlast_ten = [] 466741f740SMichael Walsh 476741f740SMichael Walshstate = st.return_default_state() 486741f740SMichael Walshcp_setup_called = 0 496741f740SMichael Walshnext_boot = "" 506741f740SMichael Walshbase_tool_dir_path = os.path.normpath(os.environ.get( 516741f740SMichael Walsh 'AUTOBOOT_BASE_TOOL_DIR_PATH', "/tmp")) + os.sep 52b5839d00SMichael Walsh 536741f740SMichael Walshffdc_dir_path = os.path.normpath(os.environ.get('FFDC_DIR_PATH', '')) + os.sep 546741f740SMichael Walshboot_success = 0 556741f740SMichael Walshstatus_dir_path = os.environ.get('STATUS_DIR_PATH', "") 566741f740SMichael Walshif status_dir_path != "": 576741f740SMichael Walsh status_dir_path = os.path.normpath(status_dir_path) + os.sep 580b93fbf8SMichael Walshdefault_power_on = "REST Power On" 590b93fbf8SMichael Walshdefault_power_off = "REST Power Off" 606741f740SMichael Walshboot_count = 0 610bbd860fSMichael Walsh 6285678948SMichael WalshLOG_LEVEL = BuiltIn().get_variable_value("${LOG_LEVEL}") 6385678948SMichael Walsh 6485678948SMichael Walsh 6585678948SMichael Walsh############################################################################### 660ad0f7f8SMichael Walshdef process_host(host, 670ad0f7f8SMichael Walsh host_var_name=""): 680ad0f7f8SMichael Walsh 690ad0f7f8SMichael Walsh r""" 700ad0f7f8SMichael Walsh Process a host by getting the associated host name and IP address and 710ad0f7f8SMichael Walsh setting them in global variables. 720ad0f7f8SMichael Walsh 730ad0f7f8SMichael Walsh If the caller does not pass the host_var_name, this function will try to 740ad0f7f8SMichael Walsh figure out the name of the variable used by the caller for the host parm. 750ad0f7f8SMichael Walsh Callers are advised to explicitly specify the host_var_name when calling 760ad0f7f8SMichael Walsh with an exec command. In such cases, the get_arg_name cannot figure out 770ad0f7f8SMichael Walsh the host variable name. 780ad0f7f8SMichael Walsh 790ad0f7f8SMichael Walsh This function will then create similar global variable names by 800ad0f7f8SMichael Walsh removing "_host" and appending "_host_name" or "_ip" to the host variable 810ad0f7f8SMichael Walsh name. 820ad0f7f8SMichael Walsh 830ad0f7f8SMichael Walsh Example: 840ad0f7f8SMichael Walsh 850ad0f7f8SMichael Walsh If a call is made like this: 860ad0f7f8SMichael Walsh process_host(openbmc_host) 870ad0f7f8SMichael Walsh 880ad0f7f8SMichael Walsh Global variables openbmc_host_name and openbmc_ip will be set. 890ad0f7f8SMichael Walsh 900ad0f7f8SMichael Walsh Description of argument(s): 910ad0f7f8SMichael Walsh host A host name or IP. The name of the variable used should 920ad0f7f8SMichael Walsh have a suffix of "_host". 930ad0f7f8SMichael Walsh host_var_name The name of the variable being used as the host parm. 940ad0f7f8SMichael Walsh """ 950ad0f7f8SMichael Walsh 960ad0f7f8SMichael Walsh if host_var_name == "": 970ad0f7f8SMichael Walsh host_var_name = gp.get_arg_name(0, 1, stack_frame_ix=2) 980ad0f7f8SMichael Walsh 990ad0f7f8SMichael Walsh host_name_var_name = re.sub("host", "host_name", host_var_name) 1000ad0f7f8SMichael Walsh ip_var_name = re.sub("host", "ip", host_var_name) 1010ad0f7f8SMichael Walsh cmd_buf = "global " + host_name_var_name + ", " + ip_var_name + " ; " +\ 1020ad0f7f8SMichael Walsh host_name_var_name + ", " + ip_var_name + " = gm.get_host_name_ip('" +\ 1030ad0f7f8SMichael Walsh host + "')" 1040ad0f7f8SMichael Walsh exec(cmd_buf) 1050ad0f7f8SMichael Walsh 1060ad0f7f8SMichael Walsh############################################################################### 1070ad0f7f8SMichael Walsh 1080ad0f7f8SMichael Walsh 1090ad0f7f8SMichael Walsh############################################################################### 110b5839d00SMichael Walshdef process_pgm_parms(): 111b5839d00SMichael Walsh 112b5839d00SMichael Walsh r""" 113b5839d00SMichael Walsh Process the program parameters by assigning them all to corresponding 114b5839d00SMichael Walsh globals. Also, set some global values that depend on program parameters. 115b5839d00SMichael Walsh """ 116b5839d00SMichael Walsh 117b5839d00SMichael Walsh # Program parameter processing. 118b5839d00SMichael Walsh # Assign all program parms to python variables which are global to this 119b5839d00SMichael Walsh # module. 120b5839d00SMichael Walsh 121b5839d00SMichael Walsh global parm_list 122b5839d00SMichael Walsh parm_list = BuiltIn().get_variable_value("${parm_list}") 123b5839d00SMichael Walsh # The following subset of parms should be processed as integers. 124b5839d00SMichael Walsh int_list = ['max_num_tests', 'boot_pass', 'boot_fail', 'ffdc_only', 125b5839d00SMichael Walsh 'boot_fail_threshold', 'quiet', 'test_mode', 'debug'] 126b5839d00SMichael Walsh for parm in parm_list: 127b5839d00SMichael Walsh if parm in int_list: 128b5839d00SMichael Walsh sub_cmd = "int(BuiltIn().get_variable_value(\"${" + parm +\ 129b5839d00SMichael Walsh "}\", \"0\"))" 130b5839d00SMichael Walsh else: 131b5839d00SMichael Walsh sub_cmd = "BuiltIn().get_variable_value(\"${" + parm + "}\")" 132b5839d00SMichael Walsh cmd_buf = "global " + parm + " ; " + parm + " = " + sub_cmd 133b5839d00SMichael Walsh exec(cmd_buf) 1340ad0f7f8SMichael Walsh if re.match(r".*_host$", parm): 1350ad0f7f8SMichael Walsh cmd_buf = "process_host(" + parm + ", '" + parm + "')" 1360ad0f7f8SMichael Walsh exec(cmd_buf) 1370ad0f7f8SMichael Walsh if re.match(r".*_password$", parm): 1380ad0f7f8SMichael Walsh # Register the value of any parm whose name ends in _password. 1390ad0f7f8SMichael Walsh # This will cause the print functions to replace passwords with 1400ad0f7f8SMichael Walsh # asterisks in the output. 1410ad0f7f8SMichael Walsh cmd_buf = "gp.register_passwords(" + parm + ")" 1420ad0f7f8SMichael Walsh exec(cmd_buf) 143b5839d00SMichael Walsh 144b5839d00SMichael Walsh global ffdc_dir_path_style 145b5839d00SMichael Walsh global boot_list 146b5839d00SMichael Walsh global boot_stack 147b5839d00SMichael Walsh global boot_results_file_path 148b5839d00SMichael Walsh global boot_results 149b5839d00SMichael Walsh global ffdc_list_file_path 150e0cf8d70SMichael Walsh global ffdc_report_list_path 151600876daSMichael Walsh global ffdc_summary_list_path 152b5839d00SMichael Walsh 153b5839d00SMichael Walsh if ffdc_dir_path_style == "": 154b5839d00SMichael Walsh ffdc_dir_path_style = int(os.environ.get('FFDC_DIR_PATH_STYLE', '0')) 155b5839d00SMichael Walsh 156b5839d00SMichael Walsh # Convert these program parms to lists for easier processing.. 157b5839d00SMichael Walsh boot_list = filter(None, boot_list.split(":")) 158b5839d00SMichael Walsh boot_stack = filter(None, boot_stack.split(":")) 159b5839d00SMichael Walsh 160b5839d00SMichael Walsh boot_results_file_path = "/tmp/" + openbmc_nickname + ":pid_" +\ 161b5839d00SMichael Walsh str(master_pid) + ":boot_results" 162b5839d00SMichael Walsh 163b5839d00SMichael Walsh if os.path.isfile(boot_results_file_path): 164b5839d00SMichael Walsh # We've been called before in this run so we'll load the saved 165b5839d00SMichael Walsh # boot_results object. 166b5839d00SMichael Walsh boot_results = pickle.load(open(boot_results_file_path, 'rb')) 167b5839d00SMichael Walsh else: 168b5839d00SMichael Walsh boot_results = boot_results(boot_table, boot_pass, boot_fail) 169b5839d00SMichael Walsh 170b5839d00SMichael Walsh ffdc_list_file_path = base_tool_dir_path + openbmc_nickname +\ 171b5839d00SMichael Walsh "/FFDC_FILE_LIST" 172e0cf8d70SMichael Walsh ffdc_report_list_path = base_tool_dir_path + openbmc_nickname +\ 173e0cf8d70SMichael Walsh "/FFDC_REPORT_FILE_LIST" 174b5839d00SMichael Walsh 175600876daSMichael Walsh ffdc_summary_list_path = base_tool_dir_path + openbmc_nickname +\ 176600876daSMichael Walsh "/FFDC_SUMMARY_FILE_LIST" 177600876daSMichael Walsh 178b5839d00SMichael Walsh############################################################################### 179b5839d00SMichael Walsh 180b5839d00SMichael Walsh 181b5839d00SMichael Walsh############################################################################### 18285678948SMichael Walshdef initial_plug_in_setup(): 18385678948SMichael Walsh 18485678948SMichael Walsh r""" 18585678948SMichael Walsh Initialize all plug-in environment variables which do not change for the 18685678948SMichael Walsh duration of the program. 18785678948SMichael Walsh 18885678948SMichael Walsh """ 18985678948SMichael Walsh 19085678948SMichael Walsh global LOG_LEVEL 19185678948SMichael Walsh BuiltIn().set_log_level("NONE") 19285678948SMichael Walsh 19385678948SMichael Walsh BuiltIn().set_global_variable("${master_pid}", master_pid) 19485678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path) 19585678948SMichael Walsh BuiltIn().set_global_variable("${STATUS_DIR_PATH}", status_dir_path) 19685678948SMichael Walsh BuiltIn().set_global_variable("${BASE_TOOL_DIR_PATH}", base_tool_dir_path) 19785678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_LIST_FILE_PATH}", 19885678948SMichael Walsh ffdc_list_file_path) 199e0cf8d70SMichael Walsh BuiltIn().set_global_variable("${FFDC_REPORT_LIST_PATH}", 200e0cf8d70SMichael Walsh ffdc_report_list_path) 201600876daSMichael Walsh BuiltIn().set_global_variable("${FFDC_SUMMARY_LIST_PATH}", 202600876daSMichael Walsh ffdc_summary_list_path) 20385678948SMichael Walsh 20485678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_DIR_PATH_STYLE}", 20585678948SMichael Walsh ffdc_dir_path_style) 20685678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_CHECK}", 20785678948SMichael Walsh ffdc_check) 20885678948SMichael Walsh 20985678948SMichael Walsh # For each program parameter, set the corresponding AUTOBOOT_ environment 21085678948SMichael Walsh # variable value. Also, set an AUTOBOOT_ environment variable for every 21185678948SMichael Walsh # element in additional_values. 21285678948SMichael Walsh additional_values = ["program_pid", "master_pid", "ffdc_dir_path", 21385678948SMichael Walsh "status_dir_path", "base_tool_dir_path", 214600876daSMichael Walsh "ffdc_list_file_path", "ffdc_report_list_path", 215600876daSMichael Walsh "ffdc_summary_list_path"] 21685678948SMichael Walsh 21785678948SMichael Walsh plug_in_vars = parm_list + additional_values 21885678948SMichael Walsh 21985678948SMichael Walsh for var_name in plug_in_vars: 22085678948SMichael Walsh var_value = BuiltIn().get_variable_value("${" + var_name + "}") 22185678948SMichael Walsh var_name = var_name.upper() 22285678948SMichael Walsh if var_value is None: 22385678948SMichael Walsh var_value = "" 22485678948SMichael Walsh os.environ["AUTOBOOT_" + var_name] = str(var_value) 22585678948SMichael Walsh 22685678948SMichael Walsh BuiltIn().set_log_level(LOG_LEVEL) 22785678948SMichael Walsh 22868a61162SMichael Walsh # Make sure the ffdc list directory exists. 22968a61162SMichael Walsh ffdc_list_dir_path = os.path.dirname(ffdc_list_file_path) + os.sep 23068a61162SMichael Walsh if not os.path.exists(ffdc_list_dir_path): 23168a61162SMichael Walsh os.makedirs(ffdc_list_dir_path) 23285678948SMichael Walsh 23385678948SMichael Walsh############################################################################### 23485678948SMichael Walsh 2350bbd860fSMichael Walsh 2360bbd860fSMichael Walsh############################################################################### 2370bbd860fSMichael Walshdef plug_in_setup(): 2380bbd860fSMichael Walsh 2390bbd860fSMichael Walsh r""" 24085678948SMichael Walsh Initialize all changing plug-in environment variables for use by the 24185678948SMichael Walsh plug-in programs. 2420bbd860fSMichael Walsh """ 2430bbd860fSMichael Walsh 24485678948SMichael Walsh global LOG_LEVEL 24585678948SMichael Walsh global test_really_running 24685678948SMichael Walsh 24785678948SMichael Walsh BuiltIn().set_log_level("NONE") 24885678948SMichael Walsh 2496741f740SMichael Walsh boot_pass, boot_fail = boot_results.return_total_pass_fail() 2500bbd860fSMichael Walsh if boot_pass > 1: 2510bbd860fSMichael Walsh test_really_running = 1 2520bbd860fSMichael Walsh else: 2530bbd860fSMichael Walsh test_really_running = 0 2540bbd860fSMichael Walsh 2550bbd860fSMichael Walsh seconds = time.time() 2560bbd860fSMichael Walsh loc_time = time.localtime(seconds) 2570bbd860fSMichael Walsh time_string = time.strftime("%y%m%d.%H%M%S.", loc_time) 2580bbd860fSMichael Walsh 2596741f740SMichael Walsh ffdc_prefix = openbmc_nickname + "." + time_string 2600bbd860fSMichael Walsh 2616741f740SMichael Walsh BuiltIn().set_global_variable("${test_really_running}", 2626741f740SMichael Walsh test_really_running) 2636741f740SMichael Walsh BuiltIn().set_global_variable("${boot_type_desc}", next_boot) 2646741f740SMichael Walsh BuiltIn().set_global_variable("${boot_pass}", boot_pass) 2656741f740SMichael Walsh BuiltIn().set_global_variable("${boot_fail}", boot_fail) 2666741f740SMichael Walsh BuiltIn().set_global_variable("${boot_success}", boot_success) 2676741f740SMichael Walsh BuiltIn().set_global_variable("${ffdc_prefix}", ffdc_prefix) 2684c9a6453SMichael Walsh 2690bbd860fSMichael Walsh # For each program parameter, set the corresponding AUTOBOOT_ environment 2700bbd860fSMichael Walsh # variable value. Also, set an AUTOBOOT_ environment variable for every 2710bbd860fSMichael Walsh # element in additional_values. 2720bbd860fSMichael Walsh additional_values = ["boot_type_desc", "boot_success", "boot_pass", 27385678948SMichael Walsh "boot_fail", "test_really_running", "ffdc_prefix"] 2740bbd860fSMichael Walsh 27585678948SMichael Walsh plug_in_vars = additional_values 2760bbd860fSMichael Walsh 2770bbd860fSMichael Walsh for var_name in plug_in_vars: 2780bbd860fSMichael Walsh var_value = BuiltIn().get_variable_value("${" + var_name + "}") 2790bbd860fSMichael Walsh var_name = var_name.upper() 2800bbd860fSMichael Walsh if var_value is None: 2810bbd860fSMichael Walsh var_value = "" 2826741f740SMichael Walsh os.environ["AUTOBOOT_" + var_name] = str(var_value) 2830bbd860fSMichael Walsh 2840bbd860fSMichael Walsh if debug: 2856741f740SMichael Walsh shell_rc, out_buf = \ 2866741f740SMichael Walsh gc.cmd_fnc_u("printenv | egrep AUTOBOOT_ | sort -u") 2870bbd860fSMichael Walsh 28885678948SMichael Walsh BuiltIn().set_log_level(LOG_LEVEL) 28985678948SMichael Walsh 2900bbd860fSMichael Walsh############################################################################### 2910bbd860fSMichael Walsh 2920bbd860fSMichael Walsh 2930bbd860fSMichael Walsh############################################################################### 294e0cf8d70SMichael Walshdef pre_boot_plug_in_setup(): 295e0cf8d70SMichael Walsh 296e0cf8d70SMichael Walsh # Clear the ffdc_list_file_path file. Plug-ins may now write to it. 297e0cf8d70SMichael Walsh try: 298e0cf8d70SMichael Walsh os.remove(ffdc_list_file_path) 299e0cf8d70SMichael Walsh except OSError: 300e0cf8d70SMichael Walsh pass 301e0cf8d70SMichael Walsh 302e0cf8d70SMichael Walsh # Clear the ffdc_report_list_path file. Plug-ins may now write to it. 303e0cf8d70SMichael Walsh try: 304e0cf8d70SMichael Walsh os.remove(ffdc_report_list_path) 305e0cf8d70SMichael Walsh except OSError: 306e0cf8d70SMichael Walsh pass 307e0cf8d70SMichael Walsh 308600876daSMichael Walsh # Clear the ffdc_summary_list_path file. Plug-ins may now write to it. 309600876daSMichael Walsh try: 310600876daSMichael Walsh os.remove(ffdc_summary_list_path) 311600876daSMichael Walsh except OSError: 312600876daSMichael Walsh pass 313600876daSMichael Walsh 314e0cf8d70SMichael Walsh############################################################################### 315e0cf8d70SMichael Walsh 316e0cf8d70SMichael Walsh 317e0cf8d70SMichael Walsh############################################################################### 3186741f740SMichael Walshdef setup(): 3190bbd860fSMichael Walsh 3200bbd860fSMichael Walsh r""" 3216741f740SMichael Walsh Do general program setup tasks. 3220bbd860fSMichael Walsh """ 3230bbd860fSMichael Walsh 3246741f740SMichael Walsh global cp_setup_called 3250bbd860fSMichael Walsh 326b5839d00SMichael Walsh gp.qprintn() 327b5839d00SMichael Walsh 32883f4bc77SMichael Walsh robot_pgm_dir_path = os.path.dirname(__file__) + os.sep 32983f4bc77SMichael Walsh repo_bin_path = robot_pgm_dir_path.replace("/lib/", "/bin/") 330d061c043SMichael Walsh # If we can't find process_plug_in_packages.py, ssh_pw or 331d061c043SMichael Walsh # validate_plug_ins.py, then we don't have our repo bin in PATH. 332d061c043SMichael Walsh shell_rc, out_buf = gc.cmd_fnc_u("which process_plug_in_packages.py" + 333d061c043SMichael Walsh " ssh_pw validate_plug_ins.py", quiet=1, 334d061c043SMichael Walsh print_output=0, show_err=0) 335b5839d00SMichael Walsh if shell_rc != 0: 33683f4bc77SMichael Walsh os.environ['PATH'] = repo_bin_path + ":" + os.environ.get('PATH', "") 33783f4bc77SMichael Walsh # Likewise, our repo lib subdir needs to be in sys.path and PYTHONPATH. 33883f4bc77SMichael Walsh if robot_pgm_dir_path not in sys.path: 33983f4bc77SMichael Walsh sys.path.append(robot_pgm_dir_path) 34083f4bc77SMichael Walsh PYTHONPATH = os.environ.get("PYTHONPATH", "") 34183f4bc77SMichael Walsh if PYTHONPATH == "": 34283f4bc77SMichael Walsh os.environ['PYTHONPATH'] = robot_pgm_dir_path 34383f4bc77SMichael Walsh else: 34483f4bc77SMichael Walsh os.environ['PYTHONPATH'] = robot_pgm_dir_path + ":" + PYTHONPATH 3456741f740SMichael Walsh 3466741f740SMichael Walsh validate_parms() 3476741f740SMichael Walsh 3486741f740SMichael Walsh grp.rqprint_pgm_header() 3496741f740SMichael Walsh 350b5839d00SMichael Walsh grk.run_key("Set BMC Power Policy RESTORE_LAST_STATE") 35111cfc8c0SMichael Walsh 35285678948SMichael Walsh initial_plug_in_setup() 35385678948SMichael Walsh 3546741f740SMichael Walsh plug_in_setup() 3556741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 3566741f740SMichael Walsh call_point='setup') 3576741f740SMichael Walsh if rc != 0: 3586741f740SMichael Walsh error_message = "Plug-in setup failed.\n" 3596741f740SMichael Walsh grp.rprint_error_report(error_message) 3606741f740SMichael Walsh BuiltIn().fail(error_message) 3616741f740SMichael Walsh # Setting cp_setup_called lets our Teardown know that it needs to call 3626741f740SMichael Walsh # the cleanup plug-in call point. 3636741f740SMichael Walsh cp_setup_called = 1 3646741f740SMichael Walsh 3656741f740SMichael Walsh # Keyword "FFDC" will fail if TEST_MESSAGE is not set. 3666741f740SMichael Walsh BuiltIn().set_global_variable("${TEST_MESSAGE}", "${EMPTY}") 36785678948SMichael Walsh # FFDC_LOG_PATH is used by "FFDC" keyword. 36885678948SMichael Walsh BuiltIn().set_global_variable("${FFDC_LOG_PATH}", ffdc_dir_path) 3696741f740SMichael Walsh 370dc80d67dSMichael Walsh # Also printed by FFDC. 371dc80d67dSMichael Walsh global host_name 372dc80d67dSMichael Walsh global host_ip 373dc80d67dSMichael Walsh host = socket.gethostname() 374dc80d67dSMichael Walsh host_name, host_ip = gm.get_host_name_ip(host) 375dc80d67dSMichael Walsh 376b5839d00SMichael Walsh gp.dprint_var(boot_table, 1) 377b5839d00SMichael Walsh gp.dprint_var(boot_lists) 3780bbd860fSMichael Walsh 3790bbd860fSMichael Walsh############################################################################### 3800bbd860fSMichael Walsh 3810bbd860fSMichael Walsh 3820bbd860fSMichael Walsh############################################################################### 3836741f740SMichael Walshdef validate_parms(): 3840bbd860fSMichael Walsh 3850bbd860fSMichael Walsh r""" 3866741f740SMichael Walsh Validate all program parameters. 3870bbd860fSMichael Walsh """ 3880bbd860fSMichael Walsh 389b5839d00SMichael Walsh process_pgm_parms() 3900bbd860fSMichael Walsh 391b5839d00SMichael Walsh gp.qprintn() 392b5839d00SMichael Walsh 393b5839d00SMichael Walsh global openbmc_model 3946741f740SMichael Walsh grv.rvalid_value("openbmc_host") 3956741f740SMichael Walsh grv.rvalid_value("openbmc_username") 3966741f740SMichael Walsh grv.rvalid_value("openbmc_password") 3976741f740SMichael Walsh if os_host != "": 3986741f740SMichael Walsh grv.rvalid_value("os_username") 3996741f740SMichael Walsh grv.rvalid_value("os_password") 4000bbd860fSMichael Walsh 4016741f740SMichael Walsh if pdu_host != "": 4026741f740SMichael Walsh grv.rvalid_value("pdu_username") 4036741f740SMichael Walsh grv.rvalid_value("pdu_password") 4046741f740SMichael Walsh grv.rvalid_integer("pdu_slot_no") 4056741f740SMichael Walsh if openbmc_serial_host != "": 4066741f740SMichael Walsh grv.rvalid_integer("openbmc_serial_port") 407b5839d00SMichael Walsh if openbmc_model == "": 408b5839d00SMichael Walsh status, ret_values =\ 409b5839d00SMichael Walsh grk.run_key_u("Get BMC System Model") 410b5839d00SMichael Walsh openbmc_model = ret_values 411b5839d00SMichael Walsh BuiltIn().set_global_variable("${openbmc_model}", openbmc_model) 4126741f740SMichael Walsh grv.rvalid_value("openbmc_model") 413b5839d00SMichael Walsh grv.rvalid_integer("max_num_tests") 4146741f740SMichael Walsh grv.rvalid_integer("boot_pass") 4156741f740SMichael Walsh grv.rvalid_integer("boot_fail") 4166741f740SMichael Walsh 4176741f740SMichael Walsh plug_in_packages_list = grpi.rvalidate_plug_ins(plug_in_dir_paths) 4186741f740SMichael Walsh BuiltIn().set_global_variable("${plug_in_packages_list}", 4196741f740SMichael Walsh plug_in_packages_list) 4206741f740SMichael Walsh 421b5839d00SMichael Walsh grv.rvalid_value("stack_mode", valid_values=['normal', 'skip']) 422a20da401SMichael Walsh if len(boot_list) == 0 and len(boot_stack) == 0 and not ffdc_only: 4236741f740SMichael Walsh error_message = "You must provide either a value for either the" +\ 4246741f740SMichael Walsh " boot_list or the boot_stack parm.\n" 4256741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 4266741f740SMichael Walsh 4276741f740SMichael Walsh valid_boot_list(boot_list, valid_boot_types) 4286741f740SMichael Walsh valid_boot_list(boot_stack, valid_boot_types) 4296741f740SMichael Walsh 43011cfc8c0SMichael Walsh selected_PDU_boots = list(set(boot_list + boot_stack) & 43111cfc8c0SMichael Walsh set(boot_lists['PDU_reboot'])) 43211cfc8c0SMichael Walsh 43311cfc8c0SMichael Walsh if len(selected_PDU_boots) > 0 and pdu_host == "": 43411cfc8c0SMichael Walsh error_message = "You have selected the following boots which" +\ 43511cfc8c0SMichael Walsh " require a PDU host but no value for pdu_host:\n" 43611cfc8c0SMichael Walsh error_message += gp.sprint_var(selected_PDU_boots) 43711cfc8c0SMichael Walsh error_message += gp.sprint_var(pdu_host, 2) 43811cfc8c0SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 43911cfc8c0SMichael Walsh 4406741f740SMichael Walsh return 4410bbd860fSMichael Walsh 4420bbd860fSMichael Walsh############################################################################### 4430bbd860fSMichael Walsh 4440bbd860fSMichael Walsh 4450bbd860fSMichael Walsh############################################################################### 4466741f740SMichael Walshdef my_get_state(): 4470bbd860fSMichael Walsh 4480bbd860fSMichael Walsh r""" 4496741f740SMichael Walsh Get the system state plus a little bit of wrapping. 4500bbd860fSMichael Walsh """ 4510bbd860fSMichael Walsh 4526741f740SMichael Walsh global state 4536741f740SMichael Walsh 4546741f740SMichael Walsh req_states = ['epoch_seconds'] + st.default_req_states 4556741f740SMichael Walsh 456b5839d00SMichael Walsh gp.qprint_timen("Getting system state.") 4576741f740SMichael Walsh if test_mode: 4586741f740SMichael Walsh state['epoch_seconds'] = int(time.time()) 4596741f740SMichael Walsh else: 460b5839d00SMichael Walsh state = st.get_state(req_states=req_states, quiet=quiet) 461b5839d00SMichael Walsh gp.qprint_var(state) 462341c21ebSMichael Walsh 463341c21ebSMichael Walsh############################################################################### 464341c21ebSMichael Walsh 465341c21ebSMichael Walsh 466341c21ebSMichael Walsh############################################################################### 4676741f740SMichael Walshdef select_boot(): 468341c21ebSMichael Walsh 469341c21ebSMichael Walsh r""" 470341c21ebSMichael Walsh Select a boot test to be run based on our current state and return the 471341c21ebSMichael Walsh chosen boot type. 472341c21ebSMichael Walsh 473341c21ebSMichael Walsh Description of arguments: 4746741f740SMichael Walsh state The state of the machine. 475341c21ebSMichael Walsh """ 476341c21ebSMichael Walsh 47730dadae2SMichael Walsh global boot_stack 47830dadae2SMichael Walsh 479b5839d00SMichael Walsh gp.qprint_timen("Selecting a boot test.") 4806741f740SMichael Walsh 4816741f740SMichael Walsh my_get_state() 4826741f740SMichael Walsh 4836741f740SMichael Walsh stack_popped = 0 4846741f740SMichael Walsh if len(boot_stack) > 0: 4856741f740SMichael Walsh stack_popped = 1 486b5839d00SMichael Walsh gp.qprint_dashes() 487b5839d00SMichael Walsh gp.qprint_var(boot_stack) 488b5839d00SMichael Walsh gp.qprint_dashes() 489b5839d00SMichael Walsh skip_boot_printed = 0 490b5839d00SMichael Walsh while len(boot_stack) > 0: 4916741f740SMichael Walsh boot_candidate = boot_stack.pop() 492b5839d00SMichael Walsh if stack_mode == 'normal': 493b5839d00SMichael Walsh break 494b5839d00SMichael Walsh else: 495b5839d00SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['end']): 496b5839d00SMichael Walsh if not skip_boot_printed: 497b5839d00SMichael Walsh gp.print_var(stack_mode) 498b5839d00SMichael Walsh gp.printn() 499b5839d00SMichael Walsh gp.print_timen("Skipping the following boot tests" + 500b5839d00SMichael Walsh " which are unnecessary since their" + 501b5839d00SMichael Walsh " required end states match the" + 502b5839d00SMichael Walsh " current machine state:") 503b5839d00SMichael Walsh skip_boot_printed = 1 504b5839d00SMichael Walsh gp.print_var(boot_candidate) 505b5839d00SMichael Walsh boot_candidate = "" 506b5839d00SMichael Walsh if boot_candidate == "": 507b5839d00SMichael Walsh gp.qprint_dashes() 508b5839d00SMichael Walsh gp.qprint_var(boot_stack) 509b5839d00SMichael Walsh gp.qprint_dashes() 510b5839d00SMichael Walsh return boot_candidate 5116741f740SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['start']): 512b5839d00SMichael Walsh gp.qprint_timen("The machine state is valid for a '" + 5136741f740SMichael Walsh boot_candidate + "' boot test.") 514b5839d00SMichael Walsh gp.qprint_dashes() 515b5839d00SMichael Walsh gp.qprint_var(boot_stack) 516b5839d00SMichael Walsh gp.qprint_dashes() 5176741f740SMichael Walsh return boot_candidate 518341c21ebSMichael Walsh else: 519b5839d00SMichael Walsh gp.qprint_timen("The machine state does not match the required" + 520b5839d00SMichael Walsh " starting state for a '" + boot_candidate + 521b5839d00SMichael Walsh "' boot test:") 522b5839d00SMichael Walsh gp.print_varx("boot_table[" + boot_candidate + "][start]", 523b5839d00SMichael Walsh boot_table[boot_candidate]['start'], 1) 5246741f740SMichael Walsh boot_stack.append(boot_candidate) 5256741f740SMichael Walsh popped_boot = boot_candidate 5266741f740SMichael Walsh 5276741f740SMichael Walsh # Loop through your list selecting a boot_candidates 5286741f740SMichael Walsh boot_candidates = [] 5296741f740SMichael Walsh for boot_candidate in boot_list: 5306741f740SMichael Walsh if st.compare_states(state, boot_table[boot_candidate]['start']): 5316741f740SMichael Walsh if stack_popped: 5326741f740SMichael Walsh if st.compare_states(boot_table[boot_candidate]['end'], 5336741f740SMichael Walsh boot_table[popped_boot]['start']): 5346741f740SMichael Walsh boot_candidates.append(boot_candidate) 535341c21ebSMichael Walsh else: 5366741f740SMichael Walsh boot_candidates.append(boot_candidate) 5376741f740SMichael Walsh 5386741f740SMichael Walsh if len(boot_candidates) == 0: 539b5839d00SMichael Walsh gp.qprint_timen("The user's boot list contained no boot tests" + 5406741f740SMichael Walsh " which are valid for the current machine state.") 5416741f740SMichael Walsh boot_candidate = default_power_on 5426741f740SMichael Walsh if not st.compare_states(state, boot_table[default_power_on]['start']): 5436741f740SMichael Walsh boot_candidate = default_power_off 5446741f740SMichael Walsh boot_candidates.append(boot_candidate) 545b5839d00SMichael Walsh gp.qprint_timen("Using default '" + boot_candidate + 546b5839d00SMichael Walsh "' boot type to transition to valid state.") 5476741f740SMichael Walsh 548b5839d00SMichael Walsh gp.dprint_var(boot_candidates) 5496741f740SMichael Walsh 5506741f740SMichael Walsh # Randomly select a boot from the candidate list. 5516741f740SMichael Walsh boot = random.choice(boot_candidates) 552341c21ebSMichael Walsh 553341c21ebSMichael Walsh return boot 5540bbd860fSMichael Walsh 5550bbd860fSMichael Walsh############################################################################### 55655302295SMichael Walsh 55755302295SMichael Walsh 55855302295SMichael Walsh############################################################################### 559341c21ebSMichael Walshdef print_last_boots(): 560341c21ebSMichael Walsh 561341c21ebSMichael Walsh r""" 562341c21ebSMichael Walsh Print the last ten boots done with their time stamps. 563341c21ebSMichael Walsh """ 564341c21ebSMichael Walsh 565341c21ebSMichael Walsh # indent 0, 90 chars wide, linefeed, char is "=" 566b5839d00SMichael Walsh gp.qprint_dashes(0, 90) 567b5839d00SMichael Walsh gp.qprintn("Last 10 boots:\n") 568341c21ebSMichael Walsh 569341c21ebSMichael Walsh for boot_entry in last_ten: 570341c21ebSMichael Walsh grp.rqprint(boot_entry) 571b5839d00SMichael Walsh gp.qprint_dashes(0, 90) 572341c21ebSMichael Walsh 573341c21ebSMichael Walsh############################################################################### 574341c21ebSMichael Walsh 575341c21ebSMichael Walsh 576341c21ebSMichael Walsh############################################################################### 577341c21ebSMichael Walshdef print_defect_report(): 578341c21ebSMichael Walsh 579341c21ebSMichael Walsh r""" 580341c21ebSMichael Walsh Print a defect report. 581341c21ebSMichael Walsh """ 582341c21ebSMichael Walsh 583600876daSMichael Walsh # Making deliberate choice to NOT run plug_in_setup(). We don't want 584600876daSMichael Walsh # ffdc_prefix updated. 585600876daSMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 586600876daSMichael Walsh call_point='ffdc_report', stop_on_plug_in_failure=0) 587600876daSMichael Walsh 588341c21ebSMichael Walsh # At some point I'd like to have the 'Call FFDC Methods' return a list 589341c21ebSMichael Walsh # of files it has collected. In that case, the following "ls" command 590341c21ebSMichael Walsh # would no longer be needed. For now, however, glob shows the files 591341c21ebSMichael Walsh # named in FFDC_LIST_FILE_PATH so I will refrain from printing those 592341c21ebSMichael Walsh # out (so we don't see duplicates in the list). 593341c21ebSMichael Walsh 594e0cf8d70SMichael Walsh # Get additional header data which may have been created by ffdc plug-ins. 595e0cf8d70SMichael Walsh # Also, delete the individual header files to cleanup. 596e0cf8d70SMichael Walsh cmd_buf = "file_list=$(cat " + ffdc_report_list_path + " 2>/dev/null)" +\ 597e0cf8d70SMichael Walsh " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\ 598e0cf8d70SMichael Walsh " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :" 599e0cf8d70SMichael Walsh shell_rc, more_header_info = gc.cmd_fnc_u(cmd_buf, print_output=0, 600e0cf8d70SMichael Walsh show_err=0) 601e0cf8d70SMichael Walsh 602600876daSMichael Walsh # Get additional header data which may have been created by ffdc plug-ins. 603600876daSMichael Walsh # Also, delete the individual header files to cleanup. 604600876daSMichael Walsh cmd_buf = "file_list=$(cat " + ffdc_summary_list_path + " 2>/dev/null)" +\ 605600876daSMichael Walsh " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\ 606600876daSMichael Walsh " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :" 607600876daSMichael Walsh shell_rc, ffdc_summary_info = gc.cmd_fnc_u(cmd_buf, print_output=0, 608600876daSMichael Walsh show_err=0) 609600876daSMichael Walsh 610341c21ebSMichael Walsh LOG_PREFIX = BuiltIn().get_variable_value("${LOG_PREFIX}") 611341c21ebSMichael Walsh 612e0cf8d70SMichael Walsh output = '\n'.join(sorted(glob.glob(LOG_PREFIX + '*'))) 613341c21ebSMichael Walsh try: 6146741f740SMichael Walsh ffdc_list = open(ffdc_list_file_path, 'r') 615341c21ebSMichael Walsh except IOError: 616341c21ebSMichael Walsh ffdc_list = "" 617341c21ebSMichael Walsh 61868a61162SMichael Walsh # Open ffdc_file_list for writing. We will write a complete list of 61968a61162SMichael Walsh # FFDC files to it for possible use by plug-ins like cp_stop_check. 62068a61162SMichael Walsh ffdc_list_file = open(ffdc_list_file_path, 'w') 62168a61162SMichael Walsh 62268a61162SMichael Walsh gp.qprintn() 62368a61162SMichael Walsh # indent=0, width=90, linefeed=1, char="=" 62468a61162SMichael Walsh gp.qprint_dashes(0, 90, 1, "=") 62568a61162SMichael Walsh gp.qprintn("Copy this data to the defect:\n") 62668a61162SMichael Walsh 627e0cf8d70SMichael Walsh if len(more_header_info) > 0: 628e0cf8d70SMichael Walsh gp.printn(more_header_info) 629dc80d67dSMichael Walsh gp.qpvars(host_name, host_ip, openbmc_nickname, openbmc_host, 630dc80d67dSMichael Walsh openbmc_host_name, openbmc_ip, openbmc_username, 631dc80d67dSMichael Walsh openbmc_password, os_host, os_host_name, os_ip, os_username, 632dc80d67dSMichael Walsh os_password, pdu_host, pdu_host_name, pdu_ip, pdu_username, 633dc80d67dSMichael Walsh pdu_password, pdu_slot_no, openbmc_serial_host, 634dc80d67dSMichael Walsh openbmc_serial_host_name, openbmc_serial_ip, openbmc_serial_port) 63568a61162SMichael Walsh 63668a61162SMichael Walsh gp.qprintn() 63768a61162SMichael Walsh 63868a61162SMichael Walsh print_last_boots() 63968a61162SMichael Walsh gp.qprintn() 64068a61162SMichael Walsh gp.qprint_var(state) 64168a61162SMichael Walsh 642b5839d00SMichael Walsh gp.qprintn() 643b5839d00SMichael Walsh gp.qprintn("FFDC data files:") 644341c21ebSMichael Walsh if status_file_path != "": 645b5839d00SMichael Walsh gp.qprintn(status_file_path) 64668a61162SMichael Walsh ffdc_list_file.write(status_file_path + "\n") 647341c21ebSMichael Walsh 648b5839d00SMichael Walsh gp.qprintn(output) 649b5839d00SMichael Walsh # gp.qprintn(ffdc_list) 650b5839d00SMichael Walsh gp.qprintn() 651341c21ebSMichael Walsh 652600876daSMichael Walsh if len(ffdc_summary_info) > 0: 653600876daSMichael Walsh gp.printn(ffdc_summary_info) 654600876daSMichael Walsh 655b5839d00SMichael Walsh gp.qprint_dashes(0, 90, 1, "=") 656341c21ebSMichael Walsh 65768a61162SMichael Walsh ffdc_list_file.write(output + "\n") 65868a61162SMichael Walsh ffdc_list_file.close() 65968a61162SMichael Walsh 660341c21ebSMichael Walsh############################################################################### 6616741f740SMichael Walsh 6626741f740SMichael Walsh 6636741f740SMichael Walsh############################################################################### 6646741f740SMichael Walshdef my_ffdc(): 6656741f740SMichael Walsh 6666741f740SMichael Walsh r""" 6676741f740SMichael Walsh Collect FFDC data. 6686741f740SMichael Walsh """ 6696741f740SMichael Walsh 6706741f740SMichael Walsh global state 6716741f740SMichael Walsh 6726741f740SMichael Walsh plug_in_setup() 6736741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 674600876daSMichael Walsh call_point='ffdc', stop_on_plug_in_failure=0) 6756741f740SMichael Walsh 6766741f740SMichael Walsh AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX'] 67783f4bc77SMichael Walsh status, ret_values = grk.run_key_u("FFDC ffdc_prefix=" + 67883f4bc77SMichael Walsh AUTOBOOT_FFDC_PREFIX + 67983f4bc77SMichael Walsh " ffdc_function_list=" + 68083f4bc77SMichael Walsh ffdc_function_list, ignore=1) 68183f4bc77SMichael Walsh if status != 'PASS': 6823328caffSMichael Walsh gp.print_error("Call to ffdc failed.\n") 6836741f740SMichael Walsh 6846741f740SMichael Walsh my_get_state() 6856741f740SMichael Walsh 6866741f740SMichael Walsh print_defect_report() 6876741f740SMichael Walsh 6886741f740SMichael Walsh############################################################################### 6896741f740SMichael Walsh 6906741f740SMichael Walsh 6916741f740SMichael Walsh############################################################################### 6926741f740SMichael Walshdef print_test_start_message(boot_keyword): 6936741f740SMichael Walsh 6946741f740SMichael Walsh r""" 6956741f740SMichael Walsh Print a message indicating what boot test is about to run. 6966741f740SMichael Walsh 6976741f740SMichael Walsh Description of arguments: 6986741f740SMichael Walsh boot_keyword The name of the boot which is to be run 6996741f740SMichael Walsh (e.g. "BMC Power On"). 7006741f740SMichael Walsh """ 7016741f740SMichael Walsh 7026741f740SMichael Walsh global last_ten 7036741f740SMichael Walsh 7046741f740SMichael Walsh doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".") 705b5839d00SMichael Walsh gp.qprint(doing_msg) 7066741f740SMichael Walsh 7076741f740SMichael Walsh last_ten.append(doing_msg) 7086741f740SMichael Walsh 7096741f740SMichael Walsh if len(last_ten) > 10: 7106741f740SMichael Walsh del last_ten[0] 7116741f740SMichael Walsh 7126741f740SMichael Walsh############################################################################### 7136741f740SMichael Walsh 7146741f740SMichael Walsh 7156741f740SMichael Walsh############################################################################### 7166741f740SMichael Walshdef run_boot(boot): 7176741f740SMichael Walsh 7186741f740SMichael Walsh r""" 7196741f740SMichael Walsh Run the specified boot. 7206741f740SMichael Walsh 7216741f740SMichael Walsh Description of arguments: 7226741f740SMichael Walsh boot The name of the boot test to be performed. 7236741f740SMichael Walsh """ 7246741f740SMichael Walsh 7256741f740SMichael Walsh global state 7266741f740SMichael Walsh 7276741f740SMichael Walsh print_test_start_message(boot) 7286741f740SMichael Walsh 7296741f740SMichael Walsh plug_in_setup() 7306741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 7316741f740SMichael Walsh grpi.rprocess_plug_in_packages(call_point="pre_boot") 7326741f740SMichael Walsh if rc != 0: 7336741f740SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" +\ 7346741f740SMichael Walsh gp.sprint_var(rc, 1) 7356741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 7366741f740SMichael Walsh 7376741f740SMichael Walsh if test_mode: 7386741f740SMichael Walsh # In test mode, we'll pretend the boot worked by assigning its 7396741f740SMichael Walsh # required end state to the default state value. 74030dadae2SMichael Walsh state = st.strip_anchor_state(boot_table[boot]['end']) 7416741f740SMichael Walsh else: 7426741f740SMichael Walsh # Assertion: We trust that the state data was made fresh by the 7436741f740SMichael Walsh # caller. 7446741f740SMichael Walsh 745b5839d00SMichael Walsh gp.qprintn() 7466741f740SMichael Walsh 7476741f740SMichael Walsh if boot_table[boot]['method_type'] == "keyword": 7480b93fbf8SMichael Walsh rk.my_run_keywords(boot_table[boot].get('lib_file_path', ''), 749b5839d00SMichael Walsh boot_table[boot]['method'], 750b5839d00SMichael Walsh quiet=quiet) 7516741f740SMichael Walsh 7526741f740SMichael Walsh if boot_table[boot]['bmc_reboot']: 7536741f740SMichael Walsh st.wait_for_comm_cycle(int(state['epoch_seconds'])) 75430dadae2SMichael Walsh plug_in_setup() 75530dadae2SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 75630dadae2SMichael Walsh grpi.rprocess_plug_in_packages(call_point="post_reboot") 75730dadae2SMichael Walsh if rc != 0: 7580b93fbf8SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" 7590b93fbf8SMichael Walsh error_message += gp.sprint_var(rc, 1) 76030dadae2SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 7616741f740SMichael Walsh else: 7626741f740SMichael Walsh match_state = st.anchor_state(state) 7636741f740SMichael Walsh del match_state['epoch_seconds'] 7646741f740SMichael Walsh # Wait for the state to change in any way. 7656741f740SMichael Walsh st.wait_state(match_state, wait_time=state_change_timeout, 766600876daSMichael Walsh interval="10 seconds", invert=1) 7676741f740SMichael Walsh 768b5839d00SMichael Walsh gp.qprintn() 7696741f740SMichael Walsh if boot_table[boot]['end']['chassis'] == "Off": 7706741f740SMichael Walsh boot_timeout = power_off_timeout 7716741f740SMichael Walsh else: 7726741f740SMichael Walsh boot_timeout = power_on_timeout 7736741f740SMichael Walsh st.wait_state(boot_table[boot]['end'], wait_time=boot_timeout, 774600876daSMichael Walsh interval="10 seconds") 7756741f740SMichael Walsh 7766741f740SMichael Walsh plug_in_setup() 7776741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = \ 7786741f740SMichael Walsh grpi.rprocess_plug_in_packages(call_point="post_boot") 7796741f740SMichael Walsh if rc != 0: 7806741f740SMichael Walsh error_message = "Plug-in failed with non-zero return code.\n" +\ 7816741f740SMichael Walsh gp.sprint_var(rc, 1) 7826741f740SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 7836741f740SMichael Walsh 7846741f740SMichael Walsh############################################################################### 7856741f740SMichael Walsh 7866741f740SMichael Walsh 7876741f740SMichael Walsh############################################################################### 7886741f740SMichael Walshdef test_loop_body(): 7896741f740SMichael Walsh 7906741f740SMichael Walsh r""" 7916741f740SMichael Walsh The main loop body for the loop in main_py. 7926741f740SMichael Walsh 7936741f740SMichael Walsh Description of arguments: 7946741f740SMichael Walsh boot_count The iteration number (starts at 1). 7956741f740SMichael Walsh """ 7966741f740SMichael Walsh 7976741f740SMichael Walsh global boot_count 7986741f740SMichael Walsh global state 7996741f740SMichael Walsh global next_boot 8006741f740SMichael Walsh global boot_success 8016741f740SMichael Walsh 802b5839d00SMichael Walsh gp.qprintn() 8036741f740SMichael Walsh 8046741f740SMichael Walsh next_boot = select_boot() 805b5839d00SMichael Walsh if next_boot == "": 806b5839d00SMichael Walsh return True 8076741f740SMichael Walsh 808b5839d00SMichael Walsh boot_count += 1 809b5839d00SMichael Walsh gp.qprint_timen("Starting boot " + str(boot_count) + ".") 8106741f740SMichael Walsh 811e0cf8d70SMichael Walsh pre_boot_plug_in_setup() 8126741f740SMichael Walsh 8136741f740SMichael Walsh cmd_buf = ["run_boot", next_boot] 8146741f740SMichael Walsh boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf) 8156741f740SMichael Walsh if boot_status == "FAIL": 816b5839d00SMichael Walsh gp.qprint(msg) 8176741f740SMichael Walsh 818b5839d00SMichael Walsh gp.qprintn() 8196741f740SMichael Walsh if boot_status == "PASS": 8206741f740SMichael Walsh boot_success = 1 821b5839d00SMichael Walsh gp.qprint_timen("BOOT_SUCCESS: \"" + next_boot + "\" succeeded.") 8226741f740SMichael Walsh else: 8236741f740SMichael Walsh boot_success = 0 824b5839d00SMichael Walsh gp.qprint_timen("BOOT_FAILED: \"" + next_boot + "\" failed.") 8256741f740SMichael Walsh 8266741f740SMichael Walsh boot_results.update(next_boot, boot_status) 8276741f740SMichael Walsh 8286741f740SMichael Walsh plug_in_setup() 8296741f740SMichael Walsh # NOTE: A post_test_case call point failure is NOT counted as a boot 8306741f740SMichael Walsh # failure. 8316741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 832600876daSMichael Walsh call_point='post_test_case', stop_on_plug_in_failure=0) 8336741f740SMichael Walsh 8346741f740SMichael Walsh plug_in_setup() 8356741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 8366741f740SMichael Walsh call_point='ffdc_check', shell_rc=0x00000200, 8376741f740SMichael Walsh stop_on_plug_in_failure=1, stop_on_non_zero_rc=1) 8386741f740SMichael Walsh if boot_status != "PASS" or ffdc_check == "All" or shell_rc == 0x00000200: 83983f4bc77SMichael Walsh status, ret_values = grk.run_key_u("my_ffdc", ignore=1) 84083f4bc77SMichael Walsh if status != 'PASS': 8413328caffSMichael Walsh gp.print_error("Call to my_ffdc failed.\n") 8426741f740SMichael Walsh 843d139f286SMichael Walsh # We need to purge error logs between boots or they build up. 844b5839d00SMichael Walsh grk.run_key("Delete Error logs", ignore=1) 845d139f286SMichael Walsh 846952f9b09SMichael Walsh boot_results.print_report() 847b5839d00SMichael Walsh gp.qprint_timen("Finished boot " + str(boot_count) + ".") 848952f9b09SMichael Walsh 8496741f740SMichael Walsh plug_in_setup() 8506741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 8516741f740SMichael Walsh call_point='stop_check') 8526741f740SMichael Walsh if rc != 0: 8536741f740SMichael Walsh error_message = "Stopping as requested by user.\n" 8546741f740SMichael Walsh grp.rprint_error_report(error_message) 8556741f740SMichael Walsh BuiltIn().fail(error_message) 8566741f740SMichael Walsh 857d139f286SMichael Walsh # This should help prevent ConnectionErrors. 858*0960b384SMichael Walsh grk.run_key_u("Close All Connections") 859d139f286SMichael Walsh 8606741f740SMichael Walsh return True 8616741f740SMichael Walsh 8626741f740SMichael Walsh############################################################################### 8636741f740SMichael Walsh 8646741f740SMichael Walsh 8656741f740SMichael Walsh############################################################################### 86683f4bc77SMichael Walshdef obmc_boot_test_teardown(): 8676741f740SMichael Walsh 8686741f740SMichael Walsh r""" 869c9116811SMichael Walsh Clean up after the Main keyword. 8706741f740SMichael Walsh """ 8716741f740SMichael Walsh 8726741f740SMichael Walsh if cp_setup_called: 8736741f740SMichael Walsh plug_in_setup() 8746741f740SMichael Walsh rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages( 875600876daSMichael Walsh call_point='cleanup', stop_on_plug_in_failure=0) 8766741f740SMichael Walsh 877600876daSMichael Walsh if 'boot_results_file_path' in globals(): 8780b93fbf8SMichael Walsh # Save boot_results object to a file in case it is needed again. 879b5839d00SMichael Walsh gp.qprint_timen("Saving boot_results to the following path.") 880b5839d00SMichael Walsh gp.qprint_var(boot_results_file_path) 8810b93fbf8SMichael Walsh pickle.dump(boot_results, open(boot_results_file_path, 'wb'), 8820b93fbf8SMichael Walsh pickle.HIGHEST_PROTOCOL) 8830b93fbf8SMichael Walsh 8846741f740SMichael Walsh############################################################################### 8856741f740SMichael Walsh 8866741f740SMichael Walsh 8876741f740SMichael Walsh############################################################################### 888c9116811SMichael Walshdef test_teardown(): 889c9116811SMichael Walsh 890c9116811SMichael Walsh r""" 891c9116811SMichael Walsh Clean up after this test case. 892c9116811SMichael Walsh """ 893c9116811SMichael Walsh 894c9116811SMichael Walsh gp.qprintn() 895c9116811SMichael Walsh cmd_buf = ["Print Error", 896c9116811SMichael Walsh "A keyword timeout occurred ending this program.\n"] 897c9116811SMichael Walsh BuiltIn().run_keyword_if_timeout_occurred(*cmd_buf) 898c9116811SMichael Walsh 899b5839d00SMichael Walsh grp.rqprint_pgm_footer() 900b5839d00SMichael Walsh 901c9116811SMichael Walsh############################################################################### 902c9116811SMichael Walsh 903c9116811SMichael Walsh 904c9116811SMichael Walsh############################################################################### 90583f4bc77SMichael Walshdef obmc_boot_test_py(alt_boot_stack=None): 9066741f740SMichael Walsh 9076741f740SMichael Walsh r""" 9086741f740SMichael Walsh Do main program processing. 9096741f740SMichael Walsh """ 9106741f740SMichael Walsh 911b5839d00SMichael Walsh if alt_boot_stack is not None: 912b5839d00SMichael Walsh BuiltIn().set_global_variable("${boot_stack}", alt_boot_stack) 913b5839d00SMichael Walsh 9146741f740SMichael Walsh setup() 9156741f740SMichael Walsh 916a20da401SMichael Walsh if ffdc_only: 917a20da401SMichael Walsh gp.qprint_timen("Caller requested ffdc_only.") 918e0cf8d70SMichael Walsh pre_boot_plug_in_setup() 91983f4bc77SMichael Walsh grk.run_key_u("my_ffdc") 920764d2f83SMichael Walsh return 921a20da401SMichael Walsh 9226741f740SMichael Walsh # Process caller's boot_stack. 9236741f740SMichael Walsh while (len(boot_stack) > 0): 9246741f740SMichael Walsh test_loop_body() 9256741f740SMichael Walsh 926b5839d00SMichael Walsh gp.qprint_timen("Finished processing stack.") 92730dadae2SMichael Walsh 9286741f740SMichael Walsh # Process caller's boot_list. 9296741f740SMichael Walsh if len(boot_list) > 0: 9306741f740SMichael Walsh for ix in range(1, max_num_tests + 1): 9316741f740SMichael Walsh test_loop_body() 9326741f740SMichael Walsh 933b5839d00SMichael Walsh gp.qprint_timen("Completed all requested boot tests.") 934b5839d00SMichael Walsh 935b5839d00SMichael Walsh boot_pass, boot_fail = boot_results.return_total_pass_fail() 936b5839d00SMichael Walsh if boot_fail > boot_fail_threshold: 937b5839d00SMichael Walsh error_message = "Boot failures exceed the boot failure" +\ 938b5839d00SMichael Walsh " threshold:\n" +\ 939b5839d00SMichael Walsh gp.sprint_var(boot_fail) +\ 940b5839d00SMichael Walsh gp.sprint_var(boot_fail_threshold) 941b5839d00SMichael Walsh BuiltIn().fail(gp.sprint_error(error_message)) 9426741f740SMichael Walsh 9436741f740SMichael Walsh############################################################################### 944