blob: 97461c185fb385e08c313b6583651a718bd5e90b [file] [log] [blame]
Michael Walsh0bbd8602016-11-22 11:31:49 -06001#!/usr/bin/env python
2
3r"""
4This module is the python counterpart to obmc_boot_test.
5"""
6
Michael Walsh0b93fbf2017-03-02 14:42:41 -06007import os
8import imp
9import time
10import glob
11import random
Michael Walsh0ad0f7f2017-05-04 14:39:58 -050012import re
Michael Walsh0b93fbf2017-03-02 14:42:41 -060013import cPickle as pickle
Michael Walshdc80d672017-05-09 12:58:32 -050014import socket
Michael Walsh0b93fbf2017-03-02 14:42:41 -060015
16from robot.utils import DotDict
17from robot.libraries.BuiltIn import BuiltIn
18
Michael Walsh6741f742017-02-20 16:16:38 -060019from boot_data import *
Michael Walshc9116812017-03-10 14:23:06 -060020import gen_print as gp
Michael Walsh0bbd8602016-11-22 11:31:49 -060021import gen_robot_print as grp
Michael Walsh55302292017-01-10 11:43:02 -060022import gen_robot_plug_in as grpi
Michael Walsh6741f742017-02-20 16:16:38 -060023import gen_robot_valid as grv
24import gen_misc as gm
25import gen_cmd as gc
Michael Walshb5839d02017-04-12 16:11:20 -050026import gen_robot_keyword as grk
Michael Walsh55302292017-01-10 11:43:02 -060027import state as st
Michael Walshff340002017-08-29 11:18:27 -050028import var_stack as vs
Michael Walsh0bbd8602016-11-22 11:31:49 -060029
Michael Walsh0b93fbf2017-03-02 14:42:41 -060030base_path = os.path.dirname(os.path.dirname(
31 imp.find_module("gen_robot_print")[1])) +\
Michael Walshc9116812017-03-10 14:23:06 -060032 os.sep
Michael Walsh0b93fbf2017-03-02 14:42:41 -060033sys.path.append(base_path + "extended/")
34import run_keyword as rk
Michael Walsh0bbd8602016-11-22 11:31:49 -060035
Michael Walshe1e26442017-03-06 17:50:07 -060036# Setting master_pid correctly influences the behavior of plug-ins like
37# DB_Logging
38program_pid = os.getpid()
39master_pid = os.environ.get('AUTOBOOT_MASTER_PID', program_pid)
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050040pgm_name = re.sub('\\.py$', '', os.path.basename(__file__))
Michael Walshe1e26442017-03-06 17:50:07 -060041
Michael Walshb5839d02017-04-12 16:11:20 -050042# Set up boot data structures.
43boot_table = create_boot_table()
44valid_boot_types = create_valid_boot_list(boot_table)
Michael Walsh0b93fbf2017-03-02 14:42:41 -060045
Michael Walsh6741f742017-02-20 16:16:38 -060046boot_lists = read_boot_lists()
47last_ten = []
Michael Walsh6741f742017-02-20 16:16:38 -060048
Michael Walsh7dc885b2018-03-14 17:51:59 -050049state = st.return_state_constant('default_state')
Michael Walsh6741f742017-02-20 16:16:38 -060050cp_setup_called = 0
51next_boot = ""
52base_tool_dir_path = os.path.normpath(os.environ.get(
53 'AUTOBOOT_BASE_TOOL_DIR_PATH', "/tmp")) + os.sep
Michael Walshb5839d02017-04-12 16:11:20 -050054
Michael Walsh6741f742017-02-20 16:16:38 -060055ffdc_dir_path = os.path.normpath(os.environ.get('FFDC_DIR_PATH', '')) + os.sep
Michael Walsh6741f742017-02-20 16:16:38 -060056boot_success = 0
Michael Walsh6741f742017-02-20 16:16:38 -060057status_dir_path = os.environ.get('STATUS_DIR_PATH', "")
58if status_dir_path != "":
59 status_dir_path = os.path.normpath(status_dir_path) + os.sep
Michael Walsh0b93fbf2017-03-02 14:42:41 -060060default_power_on = "REST Power On"
61default_power_off = "REST Power Off"
Michael Walsh6741f742017-02-20 16:16:38 -060062boot_count = 0
Michael Walsh0bbd8602016-11-22 11:31:49 -060063
Michael Walsh85678942017-03-27 14:34:22 -050064LOG_LEVEL = BuiltIn().get_variable_value("${LOG_LEVEL}")
Michael Walshe1974b92017-08-03 13:39:51 -050065ffdc_prefix = ""
Sunil M325eb542017-08-10 07:09:43 -050066boot_start_time = ""
67boot_end_time = ""
Michael Walshff340002017-08-29 11:18:27 -050068save_stack = vs.var_stack('save_stack')
69main_func_parm_list = ['boot_stack', 'stack_mode', 'quiet']
Michael Walsh85678942017-03-27 14:34:22 -050070
71
Michael Walsh0ad0f7f2017-05-04 14:39:58 -050072def process_host(host,
73 host_var_name=""):
Michael Walsh0ad0f7f2017-05-04 14:39:58 -050074 r"""
75 Process a host by getting the associated host name and IP address and
76 setting them in global variables.
77
78 If the caller does not pass the host_var_name, this function will try to
79 figure out the name of the variable used by the caller for the host parm.
80 Callers are advised to explicitly specify the host_var_name when calling
81 with an exec command. In such cases, the get_arg_name cannot figure out
82 the host variable name.
83
84 This function will then create similar global variable names by
85 removing "_host" and appending "_host_name" or "_ip" to the host variable
86 name.
87
88 Example:
89
90 If a call is made like this:
91 process_host(openbmc_host)
92
93 Global variables openbmc_host_name and openbmc_ip will be set.
94
95 Description of argument(s):
96 host A host name or IP. The name of the variable used should
97 have a suffix of "_host".
98 host_var_name The name of the variable being used as the host parm.
99 """
100
101 if host_var_name == "":
102 host_var_name = gp.get_arg_name(0, 1, stack_frame_ix=2)
103
104 host_name_var_name = re.sub("host", "host_name", host_var_name)
105 ip_var_name = re.sub("host", "ip", host_var_name)
106 cmd_buf = "global " + host_name_var_name + ", " + ip_var_name + " ; " +\
107 host_name_var_name + ", " + ip_var_name + " = gm.get_host_name_ip('" +\
108 host + "')"
109 exec(cmd_buf)
110
Michael Walsh0ad0f7f2017-05-04 14:39:58 -0500111
Michael Walshb5839d02017-04-12 16:11:20 -0500112def process_pgm_parms():
Michael Walshb5839d02017-04-12 16:11:20 -0500113 r"""
114 Process the program parameters by assigning them all to corresponding
115 globals. Also, set some global values that depend on program parameters.
116 """
117
118 # Program parameter processing.
119 # Assign all program parms to python variables which are global to this
120 # module.
121
122 global parm_list
123 parm_list = BuiltIn().get_variable_value("${parm_list}")
124 # The following subset of parms should be processed as integers.
125 int_list = ['max_num_tests', 'boot_pass', 'boot_fail', 'ffdc_only',
Michael Walshaabef1e2017-09-20 15:16:17 -0500126 'boot_fail_threshold', 'delete_errlogs', 'quiet', 'test_mode',
127 'debug']
Michael Walshb5839d02017-04-12 16:11:20 -0500128 for parm in parm_list:
129 if parm in int_list:
130 sub_cmd = "int(BuiltIn().get_variable_value(\"${" + parm +\
131 "}\", \"0\"))"
132 else:
133 sub_cmd = "BuiltIn().get_variable_value(\"${" + parm + "}\")"
134 cmd_buf = "global " + parm + " ; " + parm + " = " + sub_cmd
Michael Walshff340002017-08-29 11:18:27 -0500135 gp.dpissuing(cmd_buf)
Michael Walshb5839d02017-04-12 16:11:20 -0500136 exec(cmd_buf)
Michael Walsh0ad0f7f2017-05-04 14:39:58 -0500137 if re.match(r".*_host$", parm):
138 cmd_buf = "process_host(" + parm + ", '" + parm + "')"
139 exec(cmd_buf)
140 if re.match(r".*_password$", parm):
141 # Register the value of any parm whose name ends in _password.
142 # This will cause the print functions to replace passwords with
143 # asterisks in the output.
144 cmd_buf = "gp.register_passwords(" + parm + ")"
145 exec(cmd_buf)
Michael Walshb5839d02017-04-12 16:11:20 -0500146
147 global ffdc_dir_path_style
148 global boot_list
149 global boot_stack
150 global boot_results_file_path
151 global boot_results
152 global ffdc_list_file_path
Michael Walshe0cf8d72017-05-17 13:20:46 -0500153 global ffdc_report_list_path
Michael Walsh600876d2017-05-30 17:58:58 -0500154 global ffdc_summary_list_path
Michael Walshb5839d02017-04-12 16:11:20 -0500155
156 if ffdc_dir_path_style == "":
157 ffdc_dir_path_style = int(os.environ.get('FFDC_DIR_PATH_STYLE', '0'))
158
159 # Convert these program parms to lists for easier processing..
160 boot_list = filter(None, boot_list.split(":"))
161 boot_stack = filter(None, boot_stack.split(":"))
162
Michael Walsh903e0b22017-09-19 17:00:33 -0500163 cleanup_boot_results_file()
164 boot_results_file_path = create_boot_results_file_path(pgm_name,
165 openbmc_nickname,
166 master_pid)
Michael Walshb5839d02017-04-12 16:11:20 -0500167
168 if os.path.isfile(boot_results_file_path):
169 # We've been called before in this run so we'll load the saved
170 # boot_results object.
171 boot_results = pickle.load(open(boot_results_file_path, 'rb'))
172 else:
173 boot_results = boot_results(boot_table, boot_pass, boot_fail)
174
175 ffdc_list_file_path = base_tool_dir_path + openbmc_nickname +\
176 "/FFDC_FILE_LIST"
Michael Walshe0cf8d72017-05-17 13:20:46 -0500177 ffdc_report_list_path = base_tool_dir_path + openbmc_nickname +\
178 "/FFDC_REPORT_FILE_LIST"
Michael Walshb5839d02017-04-12 16:11:20 -0500179
Michael Walsh600876d2017-05-30 17:58:58 -0500180 ffdc_summary_list_path = base_tool_dir_path + openbmc_nickname +\
181 "/FFDC_SUMMARY_FILE_LIST"
182
Michael Walshb5839d02017-04-12 16:11:20 -0500183
Michael Walsh85678942017-03-27 14:34:22 -0500184def initial_plug_in_setup():
Michael Walsh85678942017-03-27 14:34:22 -0500185 r"""
186 Initialize all plug-in environment variables which do not change for the
187 duration of the program.
188
189 """
190
191 global LOG_LEVEL
192 BuiltIn().set_log_level("NONE")
193
194 BuiltIn().set_global_variable("${master_pid}", master_pid)
195 BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path)
196 BuiltIn().set_global_variable("${STATUS_DIR_PATH}", status_dir_path)
197 BuiltIn().set_global_variable("${BASE_TOOL_DIR_PATH}", base_tool_dir_path)
198 BuiltIn().set_global_variable("${FFDC_LIST_FILE_PATH}",
199 ffdc_list_file_path)
Michael Walshe0cf8d72017-05-17 13:20:46 -0500200 BuiltIn().set_global_variable("${FFDC_REPORT_LIST_PATH}",
201 ffdc_report_list_path)
Michael Walsh600876d2017-05-30 17:58:58 -0500202 BuiltIn().set_global_variable("${FFDC_SUMMARY_LIST_PATH}",
203 ffdc_summary_list_path)
Michael Walsh85678942017-03-27 14:34:22 -0500204
205 BuiltIn().set_global_variable("${FFDC_DIR_PATH_STYLE}",
206 ffdc_dir_path_style)
207 BuiltIn().set_global_variable("${FFDC_CHECK}",
208 ffdc_check)
209
210 # For each program parameter, set the corresponding AUTOBOOT_ environment
211 # variable value. Also, set an AUTOBOOT_ environment variable for every
212 # element in additional_values.
213 additional_values = ["program_pid", "master_pid", "ffdc_dir_path",
214 "status_dir_path", "base_tool_dir_path",
Michael Walsh600876d2017-05-30 17:58:58 -0500215 "ffdc_list_file_path", "ffdc_report_list_path",
216 "ffdc_summary_list_path"]
Michael Walsh85678942017-03-27 14:34:22 -0500217
218 plug_in_vars = parm_list + additional_values
219
220 for var_name in plug_in_vars:
221 var_value = BuiltIn().get_variable_value("${" + var_name + "}")
222 var_name = var_name.upper()
223 if var_value is None:
224 var_value = ""
225 os.environ["AUTOBOOT_" + var_name] = str(var_value)
226
227 BuiltIn().set_log_level(LOG_LEVEL)
228
Michael Walsh68a61162017-04-25 11:54:06 -0500229 # Make sure the ffdc list directory exists.
230 ffdc_list_dir_path = os.path.dirname(ffdc_list_file_path) + os.sep
231 if not os.path.exists(ffdc_list_dir_path):
232 os.makedirs(ffdc_list_dir_path)
Michael Walsh85678942017-03-27 14:34:22 -0500233
Michael Walsh85678942017-03-27 14:34:22 -0500234
Michael Walsh0bbd8602016-11-22 11:31:49 -0600235def plug_in_setup():
Michael Walsh0bbd8602016-11-22 11:31:49 -0600236 r"""
Michael Walsh85678942017-03-27 14:34:22 -0500237 Initialize all changing plug-in environment variables for use by the
238 plug-in programs.
Michael Walsh0bbd8602016-11-22 11:31:49 -0600239 """
240
Michael Walsh85678942017-03-27 14:34:22 -0500241 global LOG_LEVEL
242 global test_really_running
243
244 BuiltIn().set_log_level("NONE")
245
Michael Walsh6741f742017-02-20 16:16:38 -0600246 boot_pass, boot_fail = boot_results.return_total_pass_fail()
Michael Walsh0bbd8602016-11-22 11:31:49 -0600247 if boot_pass > 1:
248 test_really_running = 1
249 else:
250 test_really_running = 0
251
Michael Walsh6741f742017-02-20 16:16:38 -0600252 BuiltIn().set_global_variable("${test_really_running}",
253 test_really_running)
254 BuiltIn().set_global_variable("${boot_type_desc}", next_boot)
Michael Walsh6741f742017-02-20 16:16:38 -0600255 BuiltIn().set_global_variable("${boot_pass}", boot_pass)
256 BuiltIn().set_global_variable("${boot_fail}", boot_fail)
257 BuiltIn().set_global_variable("${boot_success}", boot_success)
258 BuiltIn().set_global_variable("${ffdc_prefix}", ffdc_prefix)
Sunil M325eb542017-08-10 07:09:43 -0500259 BuiltIn().set_global_variable("${boot_start_time}", boot_start_time)
260 BuiltIn().set_global_variable("${boot_end_time}", boot_end_time)
Michael Walsh4c9a6452016-12-13 16:03:11 -0600261
Michael Walsh0bbd8602016-11-22 11:31:49 -0600262 # For each program parameter, set the corresponding AUTOBOOT_ environment
263 # variable value. Also, set an AUTOBOOT_ environment variable for every
264 # element in additional_values.
265 additional_values = ["boot_type_desc", "boot_success", "boot_pass",
Sunil M325eb542017-08-10 07:09:43 -0500266 "boot_fail", "test_really_running", "ffdc_prefix",
267 "boot_start_time", "boot_end_time"]
Michael Walsh0bbd8602016-11-22 11:31:49 -0600268
Michael Walsh85678942017-03-27 14:34:22 -0500269 plug_in_vars = additional_values
Michael Walsh0bbd8602016-11-22 11:31:49 -0600270
271 for var_name in plug_in_vars:
272 var_value = BuiltIn().get_variable_value("${" + var_name + "}")
273 var_name = var_name.upper()
274 if var_value is None:
275 var_value = ""
Michael Walsh6741f742017-02-20 16:16:38 -0600276 os.environ["AUTOBOOT_" + var_name] = str(var_value)
Michael Walsh0bbd8602016-11-22 11:31:49 -0600277
Michael Walsh0bbd8602016-11-22 11:31:49 -0600278 if debug:
Michael Walsh6741f742017-02-20 16:16:38 -0600279 shell_rc, out_buf = \
280 gc.cmd_fnc_u("printenv | egrep AUTOBOOT_ | sort -u")
Michael Walsh0bbd8602016-11-22 11:31:49 -0600281
Michael Walsh85678942017-03-27 14:34:22 -0500282 BuiltIn().set_log_level(LOG_LEVEL)
283
Michael Walsh0bbd8602016-11-22 11:31:49 -0600284
Michael Walshe0cf8d72017-05-17 13:20:46 -0500285def pre_boot_plug_in_setup():
286
287 # Clear the ffdc_list_file_path file. Plug-ins may now write to it.
288 try:
289 os.remove(ffdc_list_file_path)
290 except OSError:
291 pass
292
293 # Clear the ffdc_report_list_path file. Plug-ins may now write to it.
294 try:
295 os.remove(ffdc_report_list_path)
296 except OSError:
297 pass
298
Michael Walsh600876d2017-05-30 17:58:58 -0500299 # Clear the ffdc_summary_list_path file. Plug-ins may now write to it.
300 try:
301 os.remove(ffdc_summary_list_path)
302 except OSError:
303 pass
304
Michael Walshe1974b92017-08-03 13:39:51 -0500305 global ffdc_prefix
306
307 seconds = time.time()
308 loc_time = time.localtime(seconds)
309 time_string = time.strftime("%y%m%d.%H%M%S.", loc_time)
310
311 ffdc_prefix = openbmc_nickname + "." + time_string
312
Michael Walshe0cf8d72017-05-17 13:20:46 -0500313
Michael Walsh6741f742017-02-20 16:16:38 -0600314def setup():
Michael Walsh0bbd8602016-11-22 11:31:49 -0600315 r"""
Michael Walsh6741f742017-02-20 16:16:38 -0600316 Do general program setup tasks.
Michael Walsh0bbd8602016-11-22 11:31:49 -0600317 """
318
Michael Walsh6741f742017-02-20 16:16:38 -0600319 global cp_setup_called
Michael Walsh81816742017-09-27 11:02:29 -0500320 global transitional_boot_selected
Michael Walsh0bbd8602016-11-22 11:31:49 -0600321
Michael Walshb5839d02017-04-12 16:11:20 -0500322 gp.qprintn()
323
Michael Walsh81816742017-09-27 11:02:29 -0500324 transitional_boot_selected = False
325
Michael Walsh83f4bc72017-04-20 16:49:43 -0500326 robot_pgm_dir_path = os.path.dirname(__file__) + os.sep
327 repo_bin_path = robot_pgm_dir_path.replace("/lib/", "/bin/")
Michael Walshd061c042017-05-23 14:46:57 -0500328 # If we can't find process_plug_in_packages.py, ssh_pw or
329 # validate_plug_ins.py, then we don't have our repo bin in PATH.
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500330 shell_rc, out_buf = gc.cmd_fnc_u("which process_plug_in_packages.py"
331 + " ssh_pw validate_plug_ins.py", quiet=1,
Michael Walshd061c042017-05-23 14:46:57 -0500332 print_output=0, show_err=0)
Michael Walshb5839d02017-04-12 16:11:20 -0500333 if shell_rc != 0:
Michael Walsh83f4bc72017-04-20 16:49:43 -0500334 os.environ['PATH'] = repo_bin_path + ":" + os.environ.get('PATH', "")
335 # Likewise, our repo lib subdir needs to be in sys.path and PYTHONPATH.
336 if robot_pgm_dir_path not in sys.path:
337 sys.path.append(robot_pgm_dir_path)
338 PYTHONPATH = os.environ.get("PYTHONPATH", "")
339 if PYTHONPATH == "":
340 os.environ['PYTHONPATH'] = robot_pgm_dir_path
341 else:
342 os.environ['PYTHONPATH'] = robot_pgm_dir_path + ":" + PYTHONPATH
Michael Walsh6741f742017-02-20 16:16:38 -0600343
344 validate_parms()
345
346 grp.rqprint_pgm_header()
347
George Keishingefc3ff22017-12-12 11:49:25 -0600348 grk.run_key("Set BMC Power Policy ALWAYS_POWER_OFF")
Michael Walsh11cfc8c2017-03-31 09:40:55 -0500349
Michael Walsh85678942017-03-27 14:34:22 -0500350 initial_plug_in_setup()
351
Michael Walsh6741f742017-02-20 16:16:38 -0600352 plug_in_setup()
353 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
354 call_point='setup')
355 if rc != 0:
356 error_message = "Plug-in setup failed.\n"
357 grp.rprint_error_report(error_message)
358 BuiltIn().fail(error_message)
359 # Setting cp_setup_called lets our Teardown know that it needs to call
360 # the cleanup plug-in call point.
361 cp_setup_called = 1
362
363 # Keyword "FFDC" will fail if TEST_MESSAGE is not set.
364 BuiltIn().set_global_variable("${TEST_MESSAGE}", "${EMPTY}")
Michael Walsh85678942017-03-27 14:34:22 -0500365 # FFDC_LOG_PATH is used by "FFDC" keyword.
366 BuiltIn().set_global_variable("${FFDC_LOG_PATH}", ffdc_dir_path)
Michael Walsh6741f742017-02-20 16:16:38 -0600367
Michael Walshdc80d672017-05-09 12:58:32 -0500368 # Also printed by FFDC.
369 global host_name
370 global host_ip
371 host = socket.gethostname()
372 host_name, host_ip = gm.get_host_name_ip(host)
373
Michael Walshb5839d02017-04-12 16:11:20 -0500374 gp.dprint_var(boot_table, 1)
375 gp.dprint_var(boot_lists)
Michael Walsh0bbd8602016-11-22 11:31:49 -0600376
Michael Walsh0bbd8602016-11-22 11:31:49 -0600377
Michael Walsh6741f742017-02-20 16:16:38 -0600378def validate_parms():
Michael Walsh0bbd8602016-11-22 11:31:49 -0600379 r"""
Michael Walsh6741f742017-02-20 16:16:38 -0600380 Validate all program parameters.
Michael Walsh0bbd8602016-11-22 11:31:49 -0600381 """
382
Michael Walshb5839d02017-04-12 16:11:20 -0500383 process_pgm_parms()
Michael Walsh0bbd8602016-11-22 11:31:49 -0600384
Michael Walshb5839d02017-04-12 16:11:20 -0500385 gp.qprintn()
386
387 global openbmc_model
Michael Walsh6741f742017-02-20 16:16:38 -0600388 grv.rvalid_value("openbmc_host")
389 grv.rvalid_value("openbmc_username")
390 grv.rvalid_value("openbmc_password")
391 if os_host != "":
392 grv.rvalid_value("os_username")
393 grv.rvalid_value("os_password")
Michael Walsh0bbd8602016-11-22 11:31:49 -0600394
Michael Walsh6741f742017-02-20 16:16:38 -0600395 if pdu_host != "":
396 grv.rvalid_value("pdu_username")
397 grv.rvalid_value("pdu_password")
Michael Walsh85678942017-03-27 14:34:22 -0500398 grv.rvalid_integer("pdu_slot_no")
Michael Walsh6741f742017-02-20 16:16:38 -0600399 if openbmc_serial_host != "":
400 grv.rvalid_integer("openbmc_serial_port")
Michael Walshb5839d02017-04-12 16:11:20 -0500401 if openbmc_model == "":
402 status, ret_values =\
403 grk.run_key_u("Get BMC System Model")
404 openbmc_model = ret_values
405 BuiltIn().set_global_variable("${openbmc_model}", openbmc_model)
Michael Walsh6741f742017-02-20 16:16:38 -0600406 grv.rvalid_value("openbmc_model")
Michael Walshb5839d02017-04-12 16:11:20 -0500407 grv.rvalid_integer("max_num_tests")
Michael Walsh6741f742017-02-20 16:16:38 -0600408 grv.rvalid_integer("boot_pass")
409 grv.rvalid_integer("boot_fail")
410
411 plug_in_packages_list = grpi.rvalidate_plug_ins(plug_in_dir_paths)
412 BuiltIn().set_global_variable("${plug_in_packages_list}",
413 plug_in_packages_list)
414
Michael Walshb5839d02017-04-12 16:11:20 -0500415 grv.rvalid_value("stack_mode", valid_values=['normal', 'skip'])
Michael Walsha20da402017-03-31 16:27:45 -0500416 if len(boot_list) == 0 and len(boot_stack) == 0 and not ffdc_only:
Michael Walsh6741f742017-02-20 16:16:38 -0600417 error_message = "You must provide either a value for either the" +\
418 " boot_list or the boot_stack parm.\n"
419 BuiltIn().fail(gp.sprint_error(error_message))
420
421 valid_boot_list(boot_list, valid_boot_types)
422 valid_boot_list(boot_stack, valid_boot_types)
423
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500424 selected_PDU_boots = list(set(boot_list + boot_stack)
425 & set(boot_lists['PDU_reboot']))
Michael Walsh11cfc8c2017-03-31 09:40:55 -0500426
427 if len(selected_PDU_boots) > 0 and pdu_host == "":
428 error_message = "You have selected the following boots which" +\
429 " require a PDU host but no value for pdu_host:\n"
430 error_message += gp.sprint_var(selected_PDU_boots)
431 error_message += gp.sprint_var(pdu_host, 2)
432 BuiltIn().fail(gp.sprint_error(error_message))
433
Michael Walsh6741f742017-02-20 16:16:38 -0600434 return
Michael Walsh0bbd8602016-11-22 11:31:49 -0600435
Michael Walsh0bbd8602016-11-22 11:31:49 -0600436
Michael Walsh6741f742017-02-20 16:16:38 -0600437def my_get_state():
Michael Walsh0bbd8602016-11-22 11:31:49 -0600438 r"""
Michael Walsh6741f742017-02-20 16:16:38 -0600439 Get the system state plus a little bit of wrapping.
Michael Walsh0bbd8602016-11-22 11:31:49 -0600440 """
441
Michael Walsh6741f742017-02-20 16:16:38 -0600442 global state
443
444 req_states = ['epoch_seconds'] + st.default_req_states
445
Michael Walshb5839d02017-04-12 16:11:20 -0500446 gp.qprint_timen("Getting system state.")
Michael Walsh6741f742017-02-20 16:16:38 -0600447 if test_mode:
448 state['epoch_seconds'] = int(time.time())
449 else:
Michael Walshb5839d02017-04-12 16:11:20 -0500450 state = st.get_state(req_states=req_states, quiet=quiet)
451 gp.qprint_var(state)
Michael Walsh341c21e2017-01-17 16:25:20 -0600452
Michael Walsh341c21e2017-01-17 16:25:20 -0600453
Michael Walsh45ca6e42017-09-14 17:29:12 -0500454def valid_state():
Michael Walsh45ca6e42017-09-14 17:29:12 -0500455 r"""
456 Verify that our state dictionary contains no blank values. If we don't get
457 valid state data, we cannot continue to work.
458 """
459
460 if st.compare_states(state, st.invalid_state_match, 'or'):
461 error_message = "The state dictionary contains blank fields which" +\
462 " is illegal.\n" + gp.sprint_var(state)
463 BuiltIn().fail(gp.sprint_error(error_message))
464
Michael Walsh45ca6e42017-09-14 17:29:12 -0500465
Michael Walsh6741f742017-02-20 16:16:38 -0600466def select_boot():
Michael Walsh341c21e2017-01-17 16:25:20 -0600467 r"""
468 Select a boot test to be run based on our current state and return the
469 chosen boot type.
470
471 Description of arguments:
Michael Walsh6741f742017-02-20 16:16:38 -0600472 state The state of the machine.
Michael Walsh341c21e2017-01-17 16:25:20 -0600473 """
474
Michael Walsh81816742017-09-27 11:02:29 -0500475 global transitional_boot_selected
Michael Walsh30dadae2017-02-27 14:25:52 -0600476 global boot_stack
477
Michael Walshb5839d02017-04-12 16:11:20 -0500478 gp.qprint_timen("Selecting a boot test.")
Michael Walsh6741f742017-02-20 16:16:38 -0600479
Michael Walsh81816742017-09-27 11:02:29 -0500480 if transitional_boot_selected and not boot_success:
481 prior_boot = next_boot
482 boot_candidate = boot_stack.pop()
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500483 gp.qprint_timen("The prior '" + next_boot + "' was chosen to"
484 + " transition to a valid state for '" + boot_candidate
485 + "' which was at the top of the boot_stack. Since"
486 + " the '" + next_boot + "' failed, the '"
487 + boot_candidate + "' has been removed from the stack"
488 + " to avoid and endless failure loop.")
Michael Walsh81816742017-09-27 11:02:29 -0500489 if len(boot_stack) == 0:
490 return ""
491
Michael Walsh6741f742017-02-20 16:16:38 -0600492 my_get_state()
Michael Walsh45ca6e42017-09-14 17:29:12 -0500493 valid_state()
Michael Walsh6741f742017-02-20 16:16:38 -0600494
Michael Walsh81816742017-09-27 11:02:29 -0500495 transitional_boot_selected = False
Michael Walsh6741f742017-02-20 16:16:38 -0600496 stack_popped = 0
497 if len(boot_stack) > 0:
498 stack_popped = 1
Michael Walshb5839d02017-04-12 16:11:20 -0500499 gp.qprint_dashes()
500 gp.qprint_var(boot_stack)
501 gp.qprint_dashes()
502 skip_boot_printed = 0
503 while len(boot_stack) > 0:
504 boot_candidate = boot_stack.pop()
505 if stack_mode == 'normal':
506 break
507 else:
508 if st.compare_states(state, boot_table[boot_candidate]['end']):
509 if not skip_boot_printed:
Michael Walshff340002017-08-29 11:18:27 -0500510 gp.qprint_var(stack_mode)
511 gp.qprintn()
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500512 gp.qprint_timen("Skipping the following boot tests"
513 + " which are unnecessary since their"
514 + " required end states match the"
515 + " current machine state:")
Michael Walshb5839d02017-04-12 16:11:20 -0500516 skip_boot_printed = 1
Michael Walshff340002017-08-29 11:18:27 -0500517 gp.qprint_var(boot_candidate)
Michael Walshb5839d02017-04-12 16:11:20 -0500518 boot_candidate = ""
519 if boot_candidate == "":
520 gp.qprint_dashes()
521 gp.qprint_var(boot_stack)
522 gp.qprint_dashes()
523 return boot_candidate
Michael Walsh6741f742017-02-20 16:16:38 -0600524 if st.compare_states(state, boot_table[boot_candidate]['start']):
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500525 gp.qprint_timen("The machine state is valid for a '"
526 + boot_candidate + "' boot test.")
Michael Walshb5839d02017-04-12 16:11:20 -0500527 gp.qprint_dashes()
528 gp.qprint_var(boot_stack)
529 gp.qprint_dashes()
Michael Walsh6741f742017-02-20 16:16:38 -0600530 return boot_candidate
Michael Walsh341c21e2017-01-17 16:25:20 -0600531 else:
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500532 gp.qprint_timen("The machine state does not match the required"
533 + " starting state for a '" + boot_candidate
534 + "' boot test:")
Michael Walshff340002017-08-29 11:18:27 -0500535 gp.qprint_varx("boot_table[" + boot_candidate + "][start]",
536 boot_table[boot_candidate]['start'], 1)
Michael Walsh6741f742017-02-20 16:16:38 -0600537 boot_stack.append(boot_candidate)
Michael Walsh81816742017-09-27 11:02:29 -0500538 transitional_boot_selected = True
Michael Walsh6741f742017-02-20 16:16:38 -0600539 popped_boot = boot_candidate
540
541 # Loop through your list selecting a boot_candidates
542 boot_candidates = []
543 for boot_candidate in boot_list:
544 if st.compare_states(state, boot_table[boot_candidate]['start']):
545 if stack_popped:
546 if st.compare_states(boot_table[boot_candidate]['end'],
Gunnar Mills096cd562018-03-26 10:19:12 -0500547 boot_table[popped_boot]['start']):
Michael Walsh6741f742017-02-20 16:16:38 -0600548 boot_candidates.append(boot_candidate)
549 else:
550 boot_candidates.append(boot_candidate)
551
552 if len(boot_candidates) == 0:
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500553 gp.qprint_timen("The user's boot list contained no boot tests"
554 + " which are valid for the current machine state.")
Michael Walsh6741f742017-02-20 16:16:38 -0600555 boot_candidate = default_power_on
556 if not st.compare_states(state, boot_table[default_power_on]['start']):
557 boot_candidate = default_power_off
558 boot_candidates.append(boot_candidate)
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500559 gp.qprint_timen("Using default '" + boot_candidate
560 + "' boot type to transition to valid state.")
Michael Walsh6741f742017-02-20 16:16:38 -0600561
Michael Walshb5839d02017-04-12 16:11:20 -0500562 gp.dprint_var(boot_candidates)
Michael Walsh6741f742017-02-20 16:16:38 -0600563
564 # Randomly select a boot from the candidate list.
565 boot = random.choice(boot_candidates)
Michael Walsh341c21e2017-01-17 16:25:20 -0600566
567 return boot
Michael Walsh0bbd8602016-11-22 11:31:49 -0600568
Michael Walsh55302292017-01-10 11:43:02 -0600569
Michael Walsh341c21e2017-01-17 16:25:20 -0600570def print_last_boots():
Michael Walsh341c21e2017-01-17 16:25:20 -0600571 r"""
572 Print the last ten boots done with their time stamps.
573 """
574
575 # indent 0, 90 chars wide, linefeed, char is "="
Michael Walshb5839d02017-04-12 16:11:20 -0500576 gp.qprint_dashes(0, 90)
577 gp.qprintn("Last 10 boots:\n")
Michael Walsh341c21e2017-01-17 16:25:20 -0600578
579 for boot_entry in last_ten:
580 grp.rqprint(boot_entry)
Michael Walshb5839d02017-04-12 16:11:20 -0500581 gp.qprint_dashes(0, 90)
Michael Walsh341c21e2017-01-17 16:25:20 -0600582
Michael Walsh341c21e2017-01-17 16:25:20 -0600583
Michael Walshb2e53ec2017-10-30 15:04:36 -0500584def print_defect_report(ffdc_file_list):
Michael Walsh341c21e2017-01-17 16:25:20 -0600585 r"""
586 Print a defect report.
Michael Walshb2e53ec2017-10-30 15:04:36 -0500587
588 Description of argument(s):
589 ffdc_file_list A list of files which were collected by our ffdc functions.
Michael Walsh341c21e2017-01-17 16:25:20 -0600590 """
591
Michael Walsh600876d2017-05-30 17:58:58 -0500592 # Making deliberate choice to NOT run plug_in_setup(). We don't want
593 # ffdc_prefix updated.
594 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
595 call_point='ffdc_report', stop_on_plug_in_failure=0)
596
Michael Walshe0cf8d72017-05-17 13:20:46 -0500597 # Get additional header data which may have been created by ffdc plug-ins.
598 # Also, delete the individual header files to cleanup.
599 cmd_buf = "file_list=$(cat " + ffdc_report_list_path + " 2>/dev/null)" +\
600 " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\
601 " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :"
602 shell_rc, more_header_info = gc.cmd_fnc_u(cmd_buf, print_output=0,
603 show_err=0)
604
Michael Walshb2e53ec2017-10-30 15:04:36 -0500605 # Get additional summary data which may have been created by ffdc plug-ins.
Michael Walsh600876d2017-05-30 17:58:58 -0500606 # Also, delete the individual header files to cleanup.
607 cmd_buf = "file_list=$(cat " + ffdc_summary_list_path + " 2>/dev/null)" +\
608 " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\
609 " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :"
610 shell_rc, ffdc_summary_info = gc.cmd_fnc_u(cmd_buf, print_output=0,
611 show_err=0)
612
Michael Walshb2e53ec2017-10-30 15:04:36 -0500613 # ffdc_list_file_path contains a list of any ffdc files created by plug-
614 # ins, etc. Read that data into a list.
Michael Walsh341c21e2017-01-17 16:25:20 -0600615 try:
Michael Walshb2e53ec2017-10-30 15:04:36 -0500616 plug_in_ffdc_list = \
617 open(ffdc_list_file_path, 'r').read().rstrip("\n").split("\n")
618 plug_in_ffdc_list = filter(None, plug_in_ffdc_list)
Michael Walsh341c21e2017-01-17 16:25:20 -0600619 except IOError:
Michael Walshb2e53ec2017-10-30 15:04:36 -0500620 plug_in_ffdc_list = []
621
622 # Combine the files from plug_in_ffdc_list with the ffdc_file_list passed
623 # in. Eliminate duplicates and sort the list.
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500624 ffdc_file_list = sorted(set(ffdc_file_list + plug_in_ffdc_list))
Michael Walshb2e53ec2017-10-30 15:04:36 -0500625
626 if status_file_path != "":
627 ffdc_file_list.insert(0, status_file_path)
628
629 # Convert the list to a printable list.
630 printable_ffdc_file_list = "\n".join(ffdc_file_list)
Michael Walsh341c21e2017-01-17 16:25:20 -0600631
Michael Walsh68a61162017-04-25 11:54:06 -0500632 # Open ffdc_file_list for writing. We will write a complete list of
633 # FFDC files to it for possible use by plug-ins like cp_stop_check.
634 ffdc_list_file = open(ffdc_list_file_path, 'w')
Michael Walshb2e53ec2017-10-30 15:04:36 -0500635 ffdc_list_file.write(printable_ffdc_file_list + "\n")
636 ffdc_list_file.close()
637
638 indent = 0
639 width = 90
640 linefeed = 1
641 char = "="
Michael Walsh68a61162017-04-25 11:54:06 -0500642
643 gp.qprintn()
Michael Walshb2e53ec2017-10-30 15:04:36 -0500644 gp.qprint_dashes(indent, width, linefeed, char)
Michael Walsh68a61162017-04-25 11:54:06 -0500645 gp.qprintn("Copy this data to the defect:\n")
646
Michael Walshe0cf8d72017-05-17 13:20:46 -0500647 if len(more_header_info) > 0:
Michael Walshff340002017-08-29 11:18:27 -0500648 gp.qprintn(more_header_info)
Michael Walshdc80d672017-05-09 12:58:32 -0500649 gp.qpvars(host_name, host_ip, openbmc_nickname, openbmc_host,
650 openbmc_host_name, openbmc_ip, openbmc_username,
651 openbmc_password, os_host, os_host_name, os_ip, os_username,
652 os_password, pdu_host, pdu_host_name, pdu_ip, pdu_username,
653 pdu_password, pdu_slot_no, openbmc_serial_host,
654 openbmc_serial_host_name, openbmc_serial_ip, openbmc_serial_port)
Michael Walsh68a61162017-04-25 11:54:06 -0500655
656 gp.qprintn()
Michael Walsh68a61162017-04-25 11:54:06 -0500657 print_last_boots()
658 gp.qprintn()
659 gp.qprint_var(state)
Michael Walshb5839d02017-04-12 16:11:20 -0500660 gp.qprintn()
661 gp.qprintn("FFDC data files:")
Michael Walshb2e53ec2017-10-30 15:04:36 -0500662 gp.qprintn(printable_ffdc_file_list)
Michael Walshb5839d02017-04-12 16:11:20 -0500663 gp.qprintn()
Michael Walsh341c21e2017-01-17 16:25:20 -0600664
Michael Walsh600876d2017-05-30 17:58:58 -0500665 if len(ffdc_summary_info) > 0:
Michael Walshff340002017-08-29 11:18:27 -0500666 gp.qprintn(ffdc_summary_info)
Michael Walsh600876d2017-05-30 17:58:58 -0500667
Michael Walshb2e53ec2017-10-30 15:04:36 -0500668 gp.qprint_dashes(indent, width, linefeed, char)
Michael Walsh68a61162017-04-25 11:54:06 -0500669
Michael Walsh6741f742017-02-20 16:16:38 -0600670
Michael Walsh6741f742017-02-20 16:16:38 -0600671def my_ffdc():
Michael Walsh6741f742017-02-20 16:16:38 -0600672 r"""
673 Collect FFDC data.
674 """
675
676 global state
677
678 plug_in_setup()
679 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500680 call_point='ffdc', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600681
682 AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX']
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500683 status, ffdc_file_list = grk.run_key_u("FFDC ffdc_prefix="
684 + AUTOBOOT_FFDC_PREFIX
685 + " ffdc_function_list="
686 + ffdc_function_list, ignore=1)
Michael Walsh83f4bc72017-04-20 16:49:43 -0500687 if status != 'PASS':
Michael Walshff340002017-08-29 11:18:27 -0500688 gp.qprint_error("Call to ffdc failed.\n")
Michael Walsh6741f742017-02-20 16:16:38 -0600689
690 my_get_state()
691
Michael Walshb2e53ec2017-10-30 15:04:36 -0500692 print_defect_report(ffdc_file_list)
Michael Walsh6741f742017-02-20 16:16:38 -0600693
Michael Walsh6741f742017-02-20 16:16:38 -0600694
Michael Walsh6741f742017-02-20 16:16:38 -0600695def print_test_start_message(boot_keyword):
Michael Walsh6741f742017-02-20 16:16:38 -0600696 r"""
697 Print a message indicating what boot test is about to run.
698
699 Description of arguments:
700 boot_keyword The name of the boot which is to be run
701 (e.g. "BMC Power On").
702 """
703
704 global last_ten
Sunil M325eb542017-08-10 07:09:43 -0500705 global boot_start_time
Michael Walsh6741f742017-02-20 16:16:38 -0600706
707 doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".")
Sunil M325eb542017-08-10 07:09:43 -0500708
709 # Set boot_start_time for use by plug-ins.
710 boot_start_time = doing_msg[1:33]
711 gp.qprint_var(boot_start_time)
712
Michael Walshb5839d02017-04-12 16:11:20 -0500713 gp.qprint(doing_msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600714
715 last_ten.append(doing_msg)
716
717 if len(last_ten) > 10:
718 del last_ten[0]
719
Michael Walsh6741f742017-02-20 16:16:38 -0600720
Michael Walsh6741f742017-02-20 16:16:38 -0600721def run_boot(boot):
Michael Walsh6741f742017-02-20 16:16:38 -0600722 r"""
723 Run the specified boot.
724
725 Description of arguments:
726 boot The name of the boot test to be performed.
727 """
728
729 global state
730
731 print_test_start_message(boot)
732
733 plug_in_setup()
734 rc, shell_rc, failed_plug_in_name = \
735 grpi.rprocess_plug_in_packages(call_point="pre_boot")
736 if rc != 0:
737 error_message = "Plug-in failed with non-zero return code.\n" +\
738 gp.sprint_var(rc, 1)
739 BuiltIn().fail(gp.sprint_error(error_message))
740
741 if test_mode:
742 # In test mode, we'll pretend the boot worked by assigning its
743 # required end state to the default state value.
Michael Walsh30dadae2017-02-27 14:25:52 -0600744 state = st.strip_anchor_state(boot_table[boot]['end'])
Michael Walsh6741f742017-02-20 16:16:38 -0600745 else:
746 # Assertion: We trust that the state data was made fresh by the
747 # caller.
748
Michael Walshb5839d02017-04-12 16:11:20 -0500749 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600750
751 if boot_table[boot]['method_type'] == "keyword":
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600752 rk.my_run_keywords(boot_table[boot].get('lib_file_path', ''),
Michael Walshb5839d02017-04-12 16:11:20 -0500753 boot_table[boot]['method'],
754 quiet=quiet)
Michael Walsh6741f742017-02-20 16:16:38 -0600755
756 if boot_table[boot]['bmc_reboot']:
757 st.wait_for_comm_cycle(int(state['epoch_seconds']))
Michael Walsh30dadae2017-02-27 14:25:52 -0600758 plug_in_setup()
759 rc, shell_rc, failed_plug_in_name = \
760 grpi.rprocess_plug_in_packages(call_point="post_reboot")
761 if rc != 0:
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600762 error_message = "Plug-in failed with non-zero return code.\n"
763 error_message += gp.sprint_var(rc, 1)
Michael Walsh30dadae2017-02-27 14:25:52 -0600764 BuiltIn().fail(gp.sprint_error(error_message))
Michael Walsh6741f742017-02-20 16:16:38 -0600765 else:
766 match_state = st.anchor_state(state)
767 del match_state['epoch_seconds']
768 # Wait for the state to change in any way.
769 st.wait_state(match_state, wait_time=state_change_timeout,
Michael Walsh600876d2017-05-30 17:58:58 -0500770 interval="10 seconds", invert=1)
Michael Walsh6741f742017-02-20 16:16:38 -0600771
Michael Walshb5839d02017-04-12 16:11:20 -0500772 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600773 if boot_table[boot]['end']['chassis'] == "Off":
774 boot_timeout = power_off_timeout
775 else:
776 boot_timeout = power_on_timeout
777 st.wait_state(boot_table[boot]['end'], wait_time=boot_timeout,
Michael Walsh600876d2017-05-30 17:58:58 -0500778 interval="10 seconds")
Michael Walsh6741f742017-02-20 16:16:38 -0600779
780 plug_in_setup()
781 rc, shell_rc, failed_plug_in_name = \
782 grpi.rprocess_plug_in_packages(call_point="post_boot")
783 if rc != 0:
784 error_message = "Plug-in failed with non-zero return code.\n" +\
785 gp.sprint_var(rc, 1)
786 BuiltIn().fail(gp.sprint_error(error_message))
787
Michael Walsh6741f742017-02-20 16:16:38 -0600788
Michael Walsh6741f742017-02-20 16:16:38 -0600789def test_loop_body():
Michael Walsh6741f742017-02-20 16:16:38 -0600790 r"""
791 The main loop body for the loop in main_py.
792
793 Description of arguments:
794 boot_count The iteration number (starts at 1).
795 """
796
797 global boot_count
798 global state
799 global next_boot
800 global boot_success
Sunil M325eb542017-08-10 07:09:43 -0500801 global boot_end_time
Michael Walsh6741f742017-02-20 16:16:38 -0600802
Michael Walshb5839d02017-04-12 16:11:20 -0500803 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600804
805 next_boot = select_boot()
Michael Walshb5839d02017-04-12 16:11:20 -0500806 if next_boot == "":
807 return True
Michael Walsh6741f742017-02-20 16:16:38 -0600808
Michael Walshb5839d02017-04-12 16:11:20 -0500809 boot_count += 1
810 gp.qprint_timen("Starting boot " + str(boot_count) + ".")
Michael Walsh6741f742017-02-20 16:16:38 -0600811
Michael Walshe0cf8d72017-05-17 13:20:46 -0500812 pre_boot_plug_in_setup()
Michael Walsh6741f742017-02-20 16:16:38 -0600813
814 cmd_buf = ["run_boot", next_boot]
815 boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
816 if boot_status == "FAIL":
Michael Walshb5839d02017-04-12 16:11:20 -0500817 gp.qprint(msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600818
Michael Walshb5839d02017-04-12 16:11:20 -0500819 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600820 if boot_status == "PASS":
821 boot_success = 1
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500822 completion_msg = gp.sprint_timen("BOOT_SUCCESS: \"" + next_boot
823 + "\" succeeded.")
Michael Walsh6741f742017-02-20 16:16:38 -0600824 else:
825 boot_success = 0
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500826 completion_msg = gp.sprint_timen("BOOT_FAILED: \"" + next_boot
827 + "\" failed.")
Sunil M325eb542017-08-10 07:09:43 -0500828
829 # Set boot_end_time for use by plug-ins.
830 boot_end_time = completion_msg[1:33]
831 gp.qprint_var(boot_end_time)
832
833 gp.qprint(completion_msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600834
835 boot_results.update(next_boot, boot_status)
836
837 plug_in_setup()
838 # NOTE: A post_test_case call point failure is NOT counted as a boot
839 # failure.
840 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500841 call_point='post_test_case', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600842
843 plug_in_setup()
844 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
845 call_point='ffdc_check', shell_rc=0x00000200,
846 stop_on_plug_in_failure=1, stop_on_non_zero_rc=1)
847 if boot_status != "PASS" or ffdc_check == "All" or shell_rc == 0x00000200:
Michael Walsh83f4bc72017-04-20 16:49:43 -0500848 status, ret_values = grk.run_key_u("my_ffdc", ignore=1)
849 if status != 'PASS':
Michael Walshff340002017-08-29 11:18:27 -0500850 gp.qprint_error("Call to my_ffdc failed.\n")
Michael Walsh6741f742017-02-20 16:16:38 -0600851
Michael Walshaabef1e2017-09-20 15:16:17 -0500852 if delete_errlogs:
853 # We need to purge error logs between boots or they build up.
854 grk.run_key("Delete Error logs", ignore=1)
Michael Walshd139f282017-04-04 18:00:23 -0500855
Michael Walsh952f9b02017-03-09 13:11:14 -0600856 boot_results.print_report()
Michael Walshb5839d02017-04-12 16:11:20 -0500857 gp.qprint_timen("Finished boot " + str(boot_count) + ".")
Michael Walsh952f9b02017-03-09 13:11:14 -0600858
Michael Walsh6741f742017-02-20 16:16:38 -0600859 plug_in_setup()
860 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500861 call_point='stop_check', shell_rc=0x00000200, stop_on_non_zero_rc=1)
862 if shell_rc == 0x00000200:
863 message = "Stopping as requested by user.\n"
864 gp.print_time(message)
865 BuiltIn().fail(message)
Michael Walsh6741f742017-02-20 16:16:38 -0600866
Michael Walshd139f282017-04-04 18:00:23 -0500867 # This should help prevent ConnectionErrors.
Michael Walsh0960b382017-06-22 16:23:37 -0500868 grk.run_key_u("Close All Connections")
Michael Walshd139f282017-04-04 18:00:23 -0500869
Michael Walsh6741f742017-02-20 16:16:38 -0600870 return True
871
Michael Walsh6741f742017-02-20 16:16:38 -0600872
Michael Walsh83f4bc72017-04-20 16:49:43 -0500873def obmc_boot_test_teardown():
Michael Walsh6741f742017-02-20 16:16:38 -0600874 r"""
Michael Walshc9116812017-03-10 14:23:06 -0600875 Clean up after the Main keyword.
Michael Walsh6741f742017-02-20 16:16:38 -0600876 """
877
878 if cp_setup_called:
879 plug_in_setup()
880 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500881 call_point='cleanup', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600882
Michael Walsh600876d2017-05-30 17:58:58 -0500883 if 'boot_results_file_path' in globals():
884 # Save boot_results object to a file in case it is needed again.
885 gp.qprint_timen("Saving boot_results to the following path.")
886 gp.qprint_var(boot_results_file_path)
887 pickle.dump(boot_results, open(boot_results_file_path, 'wb'),
888 pickle.HIGHEST_PROTOCOL)
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600889
Michael Walshff340002017-08-29 11:18:27 -0500890 global save_stack
891 # Restore any global values saved on the save_stack.
892 for parm_name in main_func_parm_list:
893 # Get the parm_value if it was saved on the stack.
894 try:
895 parm_value = save_stack.pop(parm_name)
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500896 except BaseException:
Michael Walshff340002017-08-29 11:18:27 -0500897 # If it was not saved, no further action is required.
898 continue
899
900 # Restore the saved value.
901 cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
902 "}\", parm_value)"
903 gp.dpissuing(cmd_buf)
904 exec(cmd_buf)
905
906 gp.dprintn(save_stack.sprint_obj())
907
Michael Walsh6741f742017-02-20 16:16:38 -0600908
Michael Walshc9116812017-03-10 14:23:06 -0600909def test_teardown():
Michael Walshc9116812017-03-10 14:23:06 -0600910 r"""
911 Clean up after this test case.
912 """
913
914 gp.qprintn()
915 cmd_buf = ["Print Error",
916 "A keyword timeout occurred ending this program.\n"]
917 BuiltIn().run_keyword_if_timeout_occurred(*cmd_buf)
918
Michael Walshb5839d02017-04-12 16:11:20 -0500919 grp.rqprint_pgm_footer()
920
Michael Walshc9116812017-03-10 14:23:06 -0600921
Michael Walshff340002017-08-29 11:18:27 -0500922def obmc_boot_test_py(loc_boot_stack=None,
923 loc_stack_mode=None,
924 loc_quiet=None):
Michael Walsh6741f742017-02-20 16:16:38 -0600925 r"""
926 Do main program processing.
927 """
928
Michael Walshff340002017-08-29 11:18:27 -0500929 global save_stack
930
931 # Process function parms.
932 for parm_name in main_func_parm_list:
933 # Get parm's value.
934 cmd_buf = "parm_value = loc_" + parm_name
935 exec(cmd_buf)
936 gp.dpvar(parm_name)
937 gp.dpvar(parm_value)
938
939 if parm_value is None:
940 # Parm was not specified by the calling function so set it to its
941 # corresponding global value.
942 cmd_buf = "loc_" + parm_name + " = BuiltIn().get_variable_value" +\
943 "(\"${" + parm_name + "}\")"
944 gp.dpissuing(cmd_buf)
945 exec(cmd_buf)
946 else:
947 # Save the global value on a stack.
948 cmd_buf = "save_stack.push(BuiltIn().get_variable_value(\"${" +\
949 parm_name + "}\"), \"" + parm_name + "\")"
950 gp.dpissuing(cmd_buf)
951 exec(cmd_buf)
952
953 # Set the global value to the passed value.
954 cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
955 "}\", loc_" + parm_name + ")"
956 gp.dpissuing(cmd_buf)
957 exec(cmd_buf)
958
959 gp.dprintn(save_stack.sprint_obj())
Michael Walshb5839d02017-04-12 16:11:20 -0500960
Michael Walsh6741f742017-02-20 16:16:38 -0600961 setup()
962
Michael Walshcd9fbfd2017-09-19 12:00:08 -0500963 init_boot_pass, init_boot_fail = boot_results.return_total_pass_fail()
964
Michael Walsha20da402017-03-31 16:27:45 -0500965 if ffdc_only:
966 gp.qprint_timen("Caller requested ffdc_only.")
Michael Walshe0cf8d72017-05-17 13:20:46 -0500967 pre_boot_plug_in_setup()
Michael Walsh83f4bc72017-04-20 16:49:43 -0500968 grk.run_key_u("my_ffdc")
Michael Walsh764d2f82017-04-27 16:01:08 -0500969 return
Michael Walsha20da402017-03-31 16:27:45 -0500970
Michael Walsh6741f742017-02-20 16:16:38 -0600971 # Process caller's boot_stack.
972 while (len(boot_stack) > 0):
973 test_loop_body()
974
Michael Walshb5839d02017-04-12 16:11:20 -0500975 gp.qprint_timen("Finished processing stack.")
Michael Walsh30dadae2017-02-27 14:25:52 -0600976
Michael Walsh6741f742017-02-20 16:16:38 -0600977 # Process caller's boot_list.
978 if len(boot_list) > 0:
979 for ix in range(1, max_num_tests + 1):
980 test_loop_body()
981
Michael Walshb5839d02017-04-12 16:11:20 -0500982 gp.qprint_timen("Completed all requested boot tests.")
983
984 boot_pass, boot_fail = boot_results.return_total_pass_fail()
Michael Walshcd9fbfd2017-09-19 12:00:08 -0500985 new_fail = boot_fail - init_boot_fail
986 if new_fail > boot_fail_threshold:
Michael Walshb5839d02017-04-12 16:11:20 -0500987 error_message = "Boot failures exceed the boot failure" +\
988 " threshold:\n" +\
Michael Walshcd9fbfd2017-09-19 12:00:08 -0500989 gp.sprint_var(new_fail) +\
Michael Walshb5839d02017-04-12 16:11:20 -0500990 gp.sprint_var(boot_fail_threshold)
991 BuiltIn().fail(gp.sprint_error(error_message))