blob: f2d2e0932328d95d92a6c7213dd62862e320be1d [file] [log] [blame]
Michael Walsh769c2a12016-12-13 15:45:17 -06001#!/usr/bin/env python
2
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
16
Michael Walsh769c2a12016-12-13 15:45:17 -060017def ffdc(ffdc_dir_path=None,
Michael Walshe844e9a2017-04-20 16:51:10 -050018 ffdc_prefix=None,
19 ffdc_function_list=""):
Michael Walsh769c2a12016-12-13 15:45:17 -060020 r"""
21 Gather First Failure Data Capture (FFDC).
22
23 This includes:
24 - Set global FFDC_TIME.
25 - Create FFDC work space directory.
26 - Write test info details.
27 - Call BMC methods to write/collect FFDC data.
28
29 Description of arguments:
Michael Walshe844e9a2017-04-20 16:51:10 -050030 ffdc_dir_path The dir path where FFDC data should be put.
31 ffdc_prefix The prefix to be given to each FFDC file name
32 generated.
33 ffdc_function_list A colon-delimited list of all the types of FFDC data
34 you wish to have collected. A blank value means that
35 all possible kinds of FFDC are to be collected. See
36 FFDC_METHOD_CALL object in lib/openbmc_ffdc_list.py
37 for possible choices.
Michael Walsh769c2a12016-12-13 15:45:17 -060038 """
39
Michael Walshe4a093d2017-10-30 15:03:18 -050040 ffdc_file_list = []
41
George Keishing3f7f12c2017-03-02 06:14:41 -060042 # Check if Ping and SSH connection is alive
43 OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
George Keishing3f7f12c2017-03-02 06:14:41 -060044
Michael Walsh2bfc48e2018-10-24 15:23:17 -050045 state = st.get_state(req_states=['ping', 'uptime', 'rest'])
Michael Walshe4a093d2017-10-30 15:03:18 -050046 gp.qprint_var(state)
47 if not int(state['ping']):
48 gp.print_error("BMC is not ping-able. Terminating FFDC collection.\n")
49 return ffdc_file_list
50
Michael Walsh2bfc48e2018-10-24 15:23:17 -050051 if not int(state['rest']):
52 gp.print_error("REST commands to the BMC are failing."
53 + " Terminating FFDC collection.\n")
54 return ffdc_file_list
55
Michael Walshe4a093d2017-10-30 15:03:18 -050056 if state['uptime'] == "":
Michael Walsh2bfc48e2018-10-24 15:23:17 -050057 gp.print_error("BMC is not communicating via ssh. Terminating FFDC"
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050058 + " collection.\n")
Michael Walshe4a093d2017-10-30 15:03:18 -050059 return ffdc_file_list
60
61 gp.qprint_timen("Collecting FFDC.")
Michael Walsh769c2a12016-12-13 15:45:17 -060062
Michael Walsh769c2a12016-12-13 15:45:17 -060063 # Get default values for arguments.
64 ffdc_dir_path, ffdc_prefix = set_ffdc_defaults(ffdc_dir_path, ffdc_prefix)
Michael Walshe4a093d2017-10-30 15:03:18 -050065 gp.qprint_var(ffdc_dir_path)
66 gp.qprint_var(ffdc_prefix)
Michael Walsh769c2a12016-12-13 15:45:17 -060067
68 # LOG_PREFIX is used by subordinate functions.
69 LOG_PREFIX = ffdc_dir_path + ffdc_prefix
70 BuiltIn().set_global_variable("${LOG_PREFIX}", LOG_PREFIX)
71
72 cmd_buf = ["Create Directory", ffdc_dir_path]
Michael Walshedb5c942019-03-28 12:40:50 -050073 gp.qprint_issuing(cmd_buf)
Michael Walsh769c2a12016-12-13 15:45:17 -060074 status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
75 if status != "PASS":
Michael Walshedb5c942019-03-28 12:40:50 -050076 error_message = gp.sprint_error_report("Create Directory failed"
77 + " with the following"
78 + " error:\n" + output)
Michael Walsh769c2a12016-12-13 15:45:17 -060079 BuiltIn().fail(error_message)
80
81 # FFDC_FILE_PATH is used by Header Message.
82 FFDC_FILE_PATH = ffdc_dir_path + ffdc_prefix + "BMC_general.txt"
83 BuiltIn().set_global_variable("${FFDC_FILE_PATH}", FFDC_FILE_PATH)
84
Michael Walshe4a093d2017-10-30 15:03:18 -050085 status, ffdc_file_list = grk.run_key("Header Message")
86 status, ffdc_file_sub_list = \
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050087 grk.run_key_u("Call FFDC Methods ffdc_function_list="
88 + ffdc_function_list)
Michael Walsh769c2a12016-12-13 15:45:17 -060089
Michael Walshe4a093d2017-10-30 15:03:18 -050090 # Combine lists, remove duplicates and sort.
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050091 ffdc_file_list = sorted(set(ffdc_file_list + ffdc_file_sub_list))
Michael Walsh769c2a12016-12-13 15:45:17 -060092
Michael Walshe4a093d2017-10-30 15:03:18 -050093 gp.qprint_timen("Finished collecting FFDC.")
94
95 return ffdc_file_list
Michael Walsh769c2a12016-12-13 15:45:17 -060096
Michael Walsh769c2a12016-12-13 15:45:17 -060097
Michael Walsh769c2a12016-12-13 15:45:17 -060098def set_ffdc_defaults(ffdc_dir_path=None,
99 ffdc_prefix=None):
Michael Walsh769c2a12016-12-13 15:45:17 -0600100 r"""
101 Set a default value for ffdc_dir_path and ffdc_prefix if they don't
102 already have values. Return both values.
103
104 Description of arguments:
105 ffdc_dir_path The dir path where FFDC data should be put.
106 ffdc_prefix The prefix to be given to each FFDC file name generated.
107
108 NOTE: If global variable ffdc_dir_path_style is set to ${1}, this function
109 will create default values in a newer way. Otherwise, its behavior
110 will remain unchanged.
111 """
112
Michael Walshfa9f70f2017-04-21 16:00:18 -0500113 # Note: Several subordinate functions like 'Get Test Dir and Name' and
114 # 'Header Message' expect global variable FFDC_TIME to be set.
115 cmd_buf = ["Get Current Time Stamp"]
Michael Walshedb5c942019-03-28 12:40:50 -0500116 gp.dprint_issuing(cmd_buf)
Michael Walshfa9f70f2017-04-21 16:00:18 -0500117 FFDC_TIME = BuiltIn().run_keyword(*cmd_buf)
118 BuiltIn().set_global_variable("${FFDC_TIME}", FFDC_TIME)
119
Michael Walsha0364ae2017-01-10 11:24:42 -0600120 ffdc_dir_path_style = BuiltIn().get_variable_value(
121 "${ffdc_dir_path_style}")
Michael Walsh769c2a12016-12-13 15:45:17 -0600122
123 if ffdc_dir_path is None:
124 if ffdc_dir_path_style:
125 try:
126 ffdc_dir_path = os.environ['FFDC_DIR_PATH']
127 except KeyError:
128 ffdc_dir_path = os.path.dirname(
129 BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
130 else:
George Keishing58a13f52017-06-21 14:04:42 -0500131 FFDC_LOG_PATH = os.getcwd() + "/logs/"
Michael Walsh769c2a12016-12-13 15:45:17 -0600132 if FFDC_LOG_PATH is None:
133 FFDC_LOG_PATH = ""
134 if FFDC_LOG_PATH == "":
135 FFDC_LOG_PATH = os.path.dirname(
136 BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
137 error_message = gv.svalid_value(FFDC_LOG_PATH,
138 var_name="FFDC_LOG_PATH")
139 if error_message != "":
Michael Walshedb5c942019-03-28 12:40:50 -0500140 error_message = gp.sprint_error_report(error_message)
Michael Walsh769c2a12016-12-13 15:45:17 -0600141 BuiltIn().fail(error_message)
142 FFDC_LOG_PATH = os.path.normpath(FFDC_LOG_PATH) + os.sep
143
144 cmd_buf = ["Get Test Dir and Name"]
Michael Walshedb5c942019-03-28 12:40:50 -0500145 gp.print_issuing(cmd_buf)
Michael Walsh769c2a12016-12-13 15:45:17 -0600146 suitename, testname = BuiltIn().run_keyword(*cmd_buf)
147
148 ffdc_dir_path = FFDC_LOG_PATH + suitename + "/" + testname + "/"
149
150 # Add trailing slash.
151 ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep
152
153 if ffdc_prefix is None:
154 FFDC_TIME = BuiltIn().get_variable_value("${FFDC_TIME}")
155 if ffdc_prefix is None:
156 if ffdc_dir_path_style:
157 OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
Michael Walsha0364ae2017-01-10 11:24:42 -0600158 OPENBMC_NICKNAME = BuiltIn().get_variable_value(
159 "${OPENBMC_NICKNAME}", default=OPENBMC_HOST)
160 ffdc_prefix = OPENBMC_NICKNAME + "." + FFDC_TIME[2:8] + "." +\
Michael Walsh769c2a12016-12-13 15:45:17 -0600161 FFDC_TIME[8:14] + "."
162 else:
163 ffdc_prefix = FFDC_TIME + "_"
164
Michael Walshfa9f70f2017-04-21 16:00:18 -0500165 BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path)
166 BuiltIn().set_global_variable("${FFDC_PREFIX}", ffdc_prefix)
167
Michael Walsh769c2a12016-12-13 15:45:17 -0600168 return ffdc_dir_path, ffdc_prefix