blob: eaca19f9174715cdfbdcb5bf9eeb2c3f509ba45f [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_robot_print as grp
11import gen_valid as gv
Michael Walshe844e9a2017-04-20 16:51:10 -050012import gen_robot_keyword as grk
Michael Walshe4a093d2017-10-30 15:03:18 -050013import state as st
Michael Walsh769c2a12016-12-13 15:45:17 -060014
15from robot.libraries.BuiltIn import BuiltIn
16
17
Michael Walsh769c2a12016-12-13 15:45:17 -060018def ffdc(ffdc_dir_path=None,
Michael Walshe844e9a2017-04-20 16:51:10 -050019 ffdc_prefix=None,
20 ffdc_function_list=""):
Michael Walsh769c2a12016-12-13 15:45:17 -060021 r"""
22 Gather First Failure Data Capture (FFDC).
23
24 This includes:
25 - Set global FFDC_TIME.
26 - Create FFDC work space directory.
27 - Write test info details.
28 - Call BMC methods to write/collect FFDC data.
29
30 Description of arguments:
Michael Walshe844e9a2017-04-20 16:51:10 -050031 ffdc_dir_path The dir path where FFDC data should be put.
32 ffdc_prefix The prefix to be given to each FFDC file name
33 generated.
34 ffdc_function_list A colon-delimited list of all the types of FFDC data
35 you wish to have collected. A blank value means that
36 all possible kinds of FFDC are to be collected. See
37 FFDC_METHOD_CALL object in lib/openbmc_ffdc_list.py
38 for possible choices.
Michael Walsh769c2a12016-12-13 15:45:17 -060039 """
40
Michael Walshe4a093d2017-10-30 15:03:18 -050041 ffdc_file_list = []
42
George Keishing3f7f12c2017-03-02 06:14:41 -060043 # Check if Ping and SSH connection is alive
44 OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
George Keishing3f7f12c2017-03-02 06:14:41 -060045
Michael Walshe4a093d2017-10-30 15:03:18 -050046 state = st.get_state(req_states=['ping', 'uptime'])
47 gp.qprint_var(state)
48 if not int(state['ping']):
49 gp.print_error("BMC is not ping-able. Terminating FFDC collection.\n")
50 return ffdc_file_list
51
52 if state['uptime'] == "":
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050053 gp.print_error("BMC is not communicating. Terminating FFDC"
54 + " collection.\n")
Michael Walshe4a093d2017-10-30 15:03:18 -050055 return ffdc_file_list
56
57 gp.qprint_timen("Collecting FFDC.")
Michael Walsh769c2a12016-12-13 15:45:17 -060058
Michael Walsh769c2a12016-12-13 15:45:17 -060059 # Get default values for arguments.
60 ffdc_dir_path, ffdc_prefix = set_ffdc_defaults(ffdc_dir_path, ffdc_prefix)
Michael Walshe4a093d2017-10-30 15:03:18 -050061 gp.qprint_var(ffdc_dir_path)
62 gp.qprint_var(ffdc_prefix)
Michael Walsh769c2a12016-12-13 15:45:17 -060063
64 # LOG_PREFIX is used by subordinate functions.
65 LOG_PREFIX = ffdc_dir_path + ffdc_prefix
66 BuiltIn().set_global_variable("${LOG_PREFIX}", LOG_PREFIX)
67
68 cmd_buf = ["Create Directory", ffdc_dir_path]
Michael Walshe4a093d2017-10-30 15:03:18 -050069 grp.rqpissuing_keyword(cmd_buf)
Michael Walsh769c2a12016-12-13 15:45:17 -060070 status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
71 if status != "PASS":
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050072 error_message = grp.sprint_error_report("Create Directory failed"
73 + " with the following"
74 + " error:\n" + output)
Michael Walsh769c2a12016-12-13 15:45:17 -060075 BuiltIn().fail(error_message)
76
77 # FFDC_FILE_PATH is used by Header Message.
78 FFDC_FILE_PATH = ffdc_dir_path + ffdc_prefix + "BMC_general.txt"
79 BuiltIn().set_global_variable("${FFDC_FILE_PATH}", FFDC_FILE_PATH)
80
Michael Walshe4a093d2017-10-30 15:03:18 -050081 status, ffdc_file_list = grk.run_key("Header Message")
82 status, ffdc_file_sub_list = \
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050083 grk.run_key_u("Call FFDC Methods ffdc_function_list="
84 + ffdc_function_list)
Michael Walsh769c2a12016-12-13 15:45:17 -060085
Michael Walshe4a093d2017-10-30 15:03:18 -050086 # Combine lists, remove duplicates and sort.
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050087 ffdc_file_list = sorted(set(ffdc_file_list + ffdc_file_sub_list))
Michael Walsh769c2a12016-12-13 15:45:17 -060088
Michael Walshe4a093d2017-10-30 15:03:18 -050089 gp.qprint_timen("Finished collecting FFDC.")
90
91 return ffdc_file_list
Michael Walsh769c2a12016-12-13 15:45:17 -060092
Michael Walsh769c2a12016-12-13 15:45:17 -060093
Michael Walsh769c2a12016-12-13 15:45:17 -060094def set_ffdc_defaults(ffdc_dir_path=None,
95 ffdc_prefix=None):
Michael Walsh769c2a12016-12-13 15:45:17 -060096 r"""
97 Set a default value for ffdc_dir_path and ffdc_prefix if they don't
98 already have values. Return both values.
99
100 Description of arguments:
101 ffdc_dir_path The dir path where FFDC data should be put.
102 ffdc_prefix The prefix to be given to each FFDC file name generated.
103
104 NOTE: If global variable ffdc_dir_path_style is set to ${1}, this function
105 will create default values in a newer way. Otherwise, its behavior
106 will remain unchanged.
107 """
108
Michael Walshfa9f70f2017-04-21 16:00:18 -0500109 # Note: Several subordinate functions like 'Get Test Dir and Name' and
110 # 'Header Message' expect global variable FFDC_TIME to be set.
111 cmd_buf = ["Get Current Time Stamp"]
112 grp.rdpissuing_keyword(cmd_buf)
113 FFDC_TIME = BuiltIn().run_keyword(*cmd_buf)
114 BuiltIn().set_global_variable("${FFDC_TIME}", FFDC_TIME)
115
Michael Walsha0364ae2017-01-10 11:24:42 -0600116 ffdc_dir_path_style = BuiltIn().get_variable_value(
117 "${ffdc_dir_path_style}")
Michael Walsh769c2a12016-12-13 15:45:17 -0600118
119 if ffdc_dir_path is None:
120 if ffdc_dir_path_style:
121 try:
122 ffdc_dir_path = os.environ['FFDC_DIR_PATH']
123 except KeyError:
124 ffdc_dir_path = os.path.dirname(
125 BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
126 else:
George Keishing58a13f52017-06-21 14:04:42 -0500127 FFDC_LOG_PATH = os.getcwd() + "/logs/"
Michael Walsh769c2a12016-12-13 15:45:17 -0600128 if FFDC_LOG_PATH is None:
129 FFDC_LOG_PATH = ""
130 if FFDC_LOG_PATH == "":
131 FFDC_LOG_PATH = os.path.dirname(
132 BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
133 error_message = gv.svalid_value(FFDC_LOG_PATH,
134 var_name="FFDC_LOG_PATH")
135 if error_message != "":
136 error_message = grp.sprint_error_report(error_message)
137 BuiltIn().fail(error_message)
138 FFDC_LOG_PATH = os.path.normpath(FFDC_LOG_PATH) + os.sep
139
140 cmd_buf = ["Get Test Dir and Name"]
141 grp.rpissuing_keyword(cmd_buf)
142 suitename, testname = BuiltIn().run_keyword(*cmd_buf)
143
144 ffdc_dir_path = FFDC_LOG_PATH + suitename + "/" + testname + "/"
145
146 # Add trailing slash.
147 ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep
148
149 if ffdc_prefix is None:
150 FFDC_TIME = BuiltIn().get_variable_value("${FFDC_TIME}")
151 if ffdc_prefix is None:
152 if ffdc_dir_path_style:
153 OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
Michael Walsha0364ae2017-01-10 11:24:42 -0600154 OPENBMC_NICKNAME = BuiltIn().get_variable_value(
155 "${OPENBMC_NICKNAME}", default=OPENBMC_HOST)
156 ffdc_prefix = OPENBMC_NICKNAME + "." + FFDC_TIME[2:8] + "." +\
Michael Walsh769c2a12016-12-13 15:45:17 -0600157 FFDC_TIME[8:14] + "."
158 else:
159 ffdc_prefix = FFDC_TIME + "_"
160
Michael Walshfa9f70f2017-04-21 16:00:18 -0500161 BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path)
162 BuiltIn().set_global_variable("${FFDC_PREFIX}", ffdc_prefix)
163
Michael Walsh769c2a12016-12-13 15:45:17 -0600164 return ffdc_dir_path, ffdc_prefix