1#!/usr/bin/env python 2 3r""" 4This module is the python counterpart to openbmc_ffdc.robot.. 5""" 6 7import os 8 9import gen_print as gp 10import gen_robot_print as grp 11import gen_valid as gv 12import gen_robot_keyword as grk 13import state as st 14 15from robot.libraries.BuiltIn import BuiltIn 16 17 18def ffdc(ffdc_dir_path=None, 19 ffdc_prefix=None, 20 ffdc_function_list=""): 21 22 r""" 23 Gather First Failure Data Capture (FFDC). 24 25 This includes: 26 - Set global FFDC_TIME. 27 - Create FFDC work space directory. 28 - Write test info details. 29 - Call BMC methods to write/collect FFDC data. 30 31 Description of arguments: 32 ffdc_dir_path The dir path where FFDC data should be put. 33 ffdc_prefix The prefix to be given to each FFDC file name 34 generated. 35 ffdc_function_list A colon-delimited list of all the types of FFDC data 36 you wish to have collected. A blank value means that 37 all possible kinds of FFDC are to be collected. See 38 FFDC_METHOD_CALL object in lib/openbmc_ffdc_list.py 39 for possible choices. 40 """ 41 42 ffdc_file_list = [] 43 44 # Check if Ping and SSH connection is alive 45 OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}") 46 47 state = st.get_state(req_states=['ping', 'uptime']) 48 gp.qprint_var(state) 49 if not int(state['ping']): 50 gp.print_error("BMC is not ping-able. Terminating FFDC collection.\n") 51 return ffdc_file_list 52 53 if state['uptime'] == "": 54 gp.print_error("BMC is not communicating. Terminating FFDC" + 55 " collection.\n") 56 return ffdc_file_list 57 58 gp.qprint_timen("Collecting FFDC.") 59 60 # Get default values for arguments. 61 ffdc_dir_path, ffdc_prefix = set_ffdc_defaults(ffdc_dir_path, ffdc_prefix) 62 gp.qprint_var(ffdc_dir_path) 63 gp.qprint_var(ffdc_prefix) 64 65 # LOG_PREFIX is used by subordinate functions. 66 LOG_PREFIX = ffdc_dir_path + ffdc_prefix 67 BuiltIn().set_global_variable("${LOG_PREFIX}", LOG_PREFIX) 68 69 cmd_buf = ["Create Directory", ffdc_dir_path] 70 grp.rqpissuing_keyword(cmd_buf) 71 status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf) 72 if status != "PASS": 73 error_message = grp.sprint_error_report("Create Directory failed" + 74 " with the following" + 75 " error:\n" + output) 76 BuiltIn().fail(error_message) 77 78 # FFDC_FILE_PATH is used by Header Message. 79 FFDC_FILE_PATH = ffdc_dir_path + ffdc_prefix + "BMC_general.txt" 80 BuiltIn().set_global_variable("${FFDC_FILE_PATH}", FFDC_FILE_PATH) 81 82 status, ffdc_file_list = grk.run_key("Header Message") 83 status, ffdc_file_sub_list = \ 84 grk.run_key_u("Call FFDC Methods ffdc_function_list=" + 85 ffdc_function_list) 86 87 # Combine lists, remove duplicates and sort. 88 ffdc_file_list = list(set(ffdc_file_list + ffdc_file_sub_list)) 89 ffdc_file_list.sort() 90 91 gp.qprint_timen("Finished collecting FFDC.") 92 93 return ffdc_file_list 94 95 96def set_ffdc_defaults(ffdc_dir_path=None, 97 ffdc_prefix=None): 98 99 r""" 100 Set a default value for ffdc_dir_path and ffdc_prefix if they don't 101 already have values. Return both values. 102 103 Description of arguments: 104 ffdc_dir_path The dir path where FFDC data should be put. 105 ffdc_prefix The prefix to be given to each FFDC file name generated. 106 107 NOTE: If global variable ffdc_dir_path_style is set to ${1}, this function 108 will create default values in a newer way. Otherwise, its behavior 109 will remain unchanged. 110 """ 111 112 # Note: Several subordinate functions like 'Get Test Dir and Name' and 113 # 'Header Message' expect global variable FFDC_TIME to be set. 114 cmd_buf = ["Get Current Time Stamp"] 115 grp.rdpissuing_keyword(cmd_buf) 116 FFDC_TIME = BuiltIn().run_keyword(*cmd_buf) 117 BuiltIn().set_global_variable("${FFDC_TIME}", FFDC_TIME) 118 119 ffdc_dir_path_style = BuiltIn().get_variable_value( 120 "${ffdc_dir_path_style}") 121 122 if ffdc_dir_path is None: 123 if ffdc_dir_path_style: 124 try: 125 ffdc_dir_path = os.environ['FFDC_DIR_PATH'] 126 except KeyError: 127 ffdc_dir_path = os.path.dirname( 128 BuiltIn().get_variable_value("${LOG_FILE}")) + "/" 129 else: 130 FFDC_LOG_PATH = os.getcwd() + "/logs/" 131 if FFDC_LOG_PATH is None: 132 FFDC_LOG_PATH = "" 133 if FFDC_LOG_PATH == "": 134 FFDC_LOG_PATH = os.path.dirname( 135 BuiltIn().get_variable_value("${LOG_FILE}")) + "/" 136 error_message = gv.svalid_value(FFDC_LOG_PATH, 137 var_name="FFDC_LOG_PATH") 138 if error_message != "": 139 error_message = grp.sprint_error_report(error_message) 140 BuiltIn().fail(error_message) 141 FFDC_LOG_PATH = os.path.normpath(FFDC_LOG_PATH) + os.sep 142 143 cmd_buf = ["Get Test Dir and Name"] 144 grp.rpissuing_keyword(cmd_buf) 145 suitename, testname = BuiltIn().run_keyword(*cmd_buf) 146 147 ffdc_dir_path = FFDC_LOG_PATH + suitename + "/" + testname + "/" 148 149 # Add trailing slash. 150 ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep 151 152 if ffdc_prefix is None: 153 FFDC_TIME = BuiltIn().get_variable_value("${FFDC_TIME}") 154 if ffdc_prefix is None: 155 if ffdc_dir_path_style: 156 OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}") 157 OPENBMC_NICKNAME = BuiltIn().get_variable_value( 158 "${OPENBMC_NICKNAME}", default=OPENBMC_HOST) 159 ffdc_prefix = OPENBMC_NICKNAME + "." + FFDC_TIME[2:8] + "." +\ 160 FFDC_TIME[8:14] + "." 161 else: 162 ffdc_prefix = FFDC_TIME + "_" 163 164 BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path) 165 BuiltIn().set_global_variable("${FFDC_PREFIX}", ffdc_prefix) 166 167 return ffdc_dir_path, ffdc_prefix 168 169