blob: 78f596c87538ab3e8b7876fe47368b7d1eed6bf9 [file] [log] [blame]
George Keishinge7e91712021-09-03 11:28:44 -05001#!/usr/bin/env python3
Michael Walsh769c2a12016-12-13 15:45:17 -06002
3r"""
4This module is the python counterpart to openbmc_ffdc.robot..
5"""
6
7import os
8
Michael Walshe4a093d2017-10-30 15:03:18 -05009import gen_print as gp
Michael Walsh769c2a12016-12-13 15:45:17 -060010import gen_valid as gv
Michael Walshe844e9a2017-04-20 16:51:10 -050011import gen_robot_keyword as grk
Michael Walshe4a093d2017-10-30 15:03:18 -050012import state as st
Michael Walsh769c2a12016-12-13 15:45:17 -060013
14from robot.libraries.BuiltIn import BuiltIn
15
Michael Shepose1775172021-02-11 16:59:08 -060016redfish_support_trans_state = int(os.environ.get('REDFISH_SUPPORT_TRANS_STATE', 0)) or \
17 int(BuiltIn().get_variable_value("${REDFISH_SUPPORT_TRANS_STATE}", default=0))
18
Michael Walsh769c2a12016-12-13 15:45:17 -060019
Michael Walsh769c2a12016-12-13 15:45:17 -060020def ffdc(ffdc_dir_path=None,
Michael Walshe844e9a2017-04-20 16:51:10 -050021 ffdc_prefix=None,
Michael Walshda8b3942020-03-23 10:39:52 -050022 ffdc_function_list="",
23 comm_check=True):
Michael Walsh769c2a12016-12-13 15:45:17 -060024 r"""
25 Gather First Failure Data Capture (FFDC).
26
27 This includes:
28 - Set global FFDC_TIME.
29 - Create FFDC work space directory.
30 - Write test info details.
31 - Call BMC methods to write/collect FFDC data.
32
33 Description of arguments:
Michael Walshda8b3942020-03-23 10:39:52 -050034 ffdc_dir_path The dir path where FFDC data should be put.
35 ffdc_prefix The prefix to be given to each FFDC file name generated.
36 ffdc_function_list A colon-delimited list of all the types of FFDC data you wish to have
37 collected. A blank value means that all possible kinds of FFDC are to be
38 collected. See FFDC_METHOD_CALL object in lib/openbmc_ffdc_list.py for
39 possible choices.
40 comm_check Do a communications check prior to collecting FFDC. If commincation to
41 the BMC can't be established, abort the FFDC collection.
Michael Walsh769c2a12016-12-13 15:45:17 -060042 """
43
Michael Walshe4a093d2017-10-30 15:03:18 -050044 ffdc_file_list = []
45
George Keishing3f7f12c2017-03-02 06:14:41 -060046 # Check if Ping and SSH connection is alive
47 OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
George Keishing3f7f12c2017-03-02 06:14:41 -060048
Michael Walshda8b3942020-03-23 10:39:52 -050049 if comm_check:
Michael Shepose1775172021-02-11 16:59:08 -060050 if not redfish_support_trans_state:
51 interface = 'rest'
52 else:
53 interface = 'redfish'
54
55 state = st.get_state(req_states=['ping', 'uptime', interface])
Michael Walshda8b3942020-03-23 10:39:52 -050056 gp.qprint_var(state)
57 if not int(state['ping']):
58 gp.print_error("BMC is not ping-able. Terminating FFDC collection.\n")
59 return ffdc_file_list
Michael Walshe4a093d2017-10-30 15:03:18 -050060
Michael Shepose1775172021-02-11 16:59:08 -060061 if not int(state[interface]):
George Keishingb1b6f132022-02-15 01:30:29 -060062 gp.print_error("%s commands to the BMC are failing." % interface)
Michael Walsh2bfc48e2018-10-24 15:23:17 -050063
Michael Walshda8b3942020-03-23 10:39:52 -050064 if state['uptime'] == "":
George Keishingb1b6f132022-02-15 01:30:29 -060065 gp.print_error("BMC is not communicating via ssh.\n")
66
67 # If SSH and Redfish connection doesn't works, abort.
68 if not int(state[interface]) and state['uptime'] == "":
69 gp.print_error("BMC is not communicating via ssh or Redfish. Terminating FFDC"
Michael Walshda8b3942020-03-23 10:39:52 -050070 + " collection.\n")
71 return ffdc_file_list
Michael Walshe4a093d2017-10-30 15:03:18 -050072
73 gp.qprint_timen("Collecting FFDC.")
Michael Walsh769c2a12016-12-13 15:45:17 -060074
Michael Walsh769c2a12016-12-13 15:45:17 -060075 # Get default values for arguments.
76 ffdc_dir_path, ffdc_prefix = set_ffdc_defaults(ffdc_dir_path, ffdc_prefix)
Michael Walshe4a093d2017-10-30 15:03:18 -050077 gp.qprint_var(ffdc_dir_path)
78 gp.qprint_var(ffdc_prefix)
Michael Walsh769c2a12016-12-13 15:45:17 -060079
80 # LOG_PREFIX is used by subordinate functions.
81 LOG_PREFIX = ffdc_dir_path + ffdc_prefix
82 BuiltIn().set_global_variable("${LOG_PREFIX}", LOG_PREFIX)
83
84 cmd_buf = ["Create Directory", ffdc_dir_path]
Michael Walshedb5c942019-03-28 12:40:50 -050085 gp.qprint_issuing(cmd_buf)
Michael Walsh769c2a12016-12-13 15:45:17 -060086 status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
87 if status != "PASS":
Michael Walshedb5c942019-03-28 12:40:50 -050088 error_message = gp.sprint_error_report("Create Directory failed"
89 + " with the following"
90 + " error:\n" + output)
Michael Walsh769c2a12016-12-13 15:45:17 -060091 BuiltIn().fail(error_message)
92
93 # FFDC_FILE_PATH is used by Header Message.
94 FFDC_FILE_PATH = ffdc_dir_path + ffdc_prefix + "BMC_general.txt"
95 BuiltIn().set_global_variable("${FFDC_FILE_PATH}", FFDC_FILE_PATH)
96
Michael Walshfdde2582019-04-18 11:05:11 -050097 status, ffdc_file_list = grk.run_key_u("Header Message")
Michael Walshe4a093d2017-10-30 15:03:18 -050098 status, ffdc_file_sub_list = \
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050099 grk.run_key_u("Call FFDC Methods ffdc_function_list="
100 + ffdc_function_list)
Michael Walsh769c2a12016-12-13 15:45:17 -0600101
Michael Walshe4a093d2017-10-30 15:03:18 -0500102 # Combine lists, remove duplicates and sort.
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500103 ffdc_file_list = sorted(set(ffdc_file_list + ffdc_file_sub_list))
Michael Walsh769c2a12016-12-13 15:45:17 -0600104
Michael Walshe4a093d2017-10-30 15:03:18 -0500105 gp.qprint_timen("Finished collecting FFDC.")
106
107 return ffdc_file_list
Michael Walsh769c2a12016-12-13 15:45:17 -0600108
Michael Walsh769c2a12016-12-13 15:45:17 -0600109
Michael Walsh769c2a12016-12-13 15:45:17 -0600110def set_ffdc_defaults(ffdc_dir_path=None,
111 ffdc_prefix=None):
Michael Walsh769c2a12016-12-13 15:45:17 -0600112 r"""
113 Set a default value for ffdc_dir_path and ffdc_prefix if they don't
114 already have values. Return both values.
115
116 Description of arguments:
117 ffdc_dir_path The dir path where FFDC data should be put.
118 ffdc_prefix The prefix to be given to each FFDC file name generated.
119
120 NOTE: If global variable ffdc_dir_path_style is set to ${1}, this function
121 will create default values in a newer way. Otherwise, its behavior
122 will remain unchanged.
123 """
124
Michael Walshfa9f70f2017-04-21 16:00:18 -0500125 # Note: Several subordinate functions like 'Get Test Dir and Name' and
126 # 'Header Message' expect global variable FFDC_TIME to be set.
127 cmd_buf = ["Get Current Time Stamp"]
Michael Walshedb5c942019-03-28 12:40:50 -0500128 gp.dprint_issuing(cmd_buf)
Michael Walshfa9f70f2017-04-21 16:00:18 -0500129 FFDC_TIME = BuiltIn().run_keyword(*cmd_buf)
130 BuiltIn().set_global_variable("${FFDC_TIME}", FFDC_TIME)
131
Michael Walsha0364ae2017-01-10 11:24:42 -0600132 ffdc_dir_path_style = BuiltIn().get_variable_value(
133 "${ffdc_dir_path_style}")
Michael Walsh769c2a12016-12-13 15:45:17 -0600134
135 if ffdc_dir_path is None:
136 if ffdc_dir_path_style:
137 try:
138 ffdc_dir_path = os.environ['FFDC_DIR_PATH']
139 except KeyError:
140 ffdc_dir_path = os.path.dirname(
141 BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
142 else:
George Keishing58a13f52017-06-21 14:04:42 -0500143 FFDC_LOG_PATH = os.getcwd() + "/logs/"
Michael Walsh769c2a12016-12-13 15:45:17 -0600144 if FFDC_LOG_PATH is None:
145 FFDC_LOG_PATH = ""
146 if FFDC_LOG_PATH == "":
147 FFDC_LOG_PATH = os.path.dirname(
148 BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
Michael Walshec01a6f2019-08-01 12:43:20 -0500149 error_message = gv.valid_value(FFDC_LOG_PATH,
150 var_name="FFDC_LOG_PATH")
Michael Walsh769c2a12016-12-13 15:45:17 -0600151 if error_message != "":
Michael Walshedb5c942019-03-28 12:40:50 -0500152 error_message = gp.sprint_error_report(error_message)
Michael Walsh769c2a12016-12-13 15:45:17 -0600153 BuiltIn().fail(error_message)
154 FFDC_LOG_PATH = os.path.normpath(FFDC_LOG_PATH) + os.sep
155
156 cmd_buf = ["Get Test Dir and Name"]
Michael Walshedb5c942019-03-28 12:40:50 -0500157 gp.print_issuing(cmd_buf)
Michael Walsh769c2a12016-12-13 15:45:17 -0600158 suitename, testname = BuiltIn().run_keyword(*cmd_buf)
159
160 ffdc_dir_path = FFDC_LOG_PATH + suitename + "/" + testname + "/"
161
162 # Add trailing slash.
163 ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep
164
165 if ffdc_prefix is None:
166 FFDC_TIME = BuiltIn().get_variable_value("${FFDC_TIME}")
167 if ffdc_prefix is None:
168 if ffdc_dir_path_style:
169 OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
Michael Walsha0364ae2017-01-10 11:24:42 -0600170 OPENBMC_NICKNAME = BuiltIn().get_variable_value(
171 "${OPENBMC_NICKNAME}", default=OPENBMC_HOST)
172 ffdc_prefix = OPENBMC_NICKNAME + "." + FFDC_TIME[2:8] + "." +\
Michael Walsh769c2a12016-12-13 15:45:17 -0600173 FFDC_TIME[8:14] + "."
174 else:
175 ffdc_prefix = FFDC_TIME + "_"
176
Michael Walshfa9f70f2017-04-21 16:00:18 -0500177 BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path)
178 BuiltIn().set_global_variable("${FFDC_PREFIX}", ffdc_prefix)
179
Michael Walsh769c2a12016-12-13 15:45:17 -0600180 return ffdc_dir_path, ffdc_prefix