blob: 8b6040a4a1f262e9dacb75fdad663aba319ecf13 [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)
Michael Walsh903e0b22017-09-19 17:00:33 -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.
330 shell_rc, out_buf = gc.cmd_fnc_u("which process_plug_in_packages.py" +
331 " ssh_pw validate_plug_ins.py", quiet=1,
332 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
Michael Walsh11cfc8c2017-03-31 09:40:55 -0500424 selected_PDU_boots = list(set(boot_list + boot_stack) &
425 set(boot_lists['PDU_reboot']))
426
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()
483 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.")
489 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()
512 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']):
Michael Walshb5839d02017-04-12 16:11:20 -0500525 gp.qprint_timen("The machine state is valid for a '" +
526 boot_candidate + "' boot test.")
527 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:
Michael Walshb5839d02017-04-12 16:11:20 -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:
Michael Walshb5839d02017-04-12 16:11:20 -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)
Michael Walshb5839d02017-04-12 16:11:20 -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.
624 ffdc_file_list = list(set(ffdc_file_list + plug_in_ffdc_list))
625 ffdc_file_list.sort()
626
627 if status_file_path != "":
628 ffdc_file_list.insert(0, status_file_path)
629
630 # Convert the list to a printable list.
631 printable_ffdc_file_list = "\n".join(ffdc_file_list)
Michael Walsh341c21e2017-01-17 16:25:20 -0600632
Michael Walsh68a61162017-04-25 11:54:06 -0500633 # Open ffdc_file_list for writing. We will write a complete list of
634 # FFDC files to it for possible use by plug-ins like cp_stop_check.
635 ffdc_list_file = open(ffdc_list_file_path, 'w')
Michael Walshb2e53ec2017-10-30 15:04:36 -0500636 ffdc_list_file.write(printable_ffdc_file_list + "\n")
637 ffdc_list_file.close()
638
639 indent = 0
640 width = 90
641 linefeed = 1
642 char = "="
Michael Walsh68a61162017-04-25 11:54:06 -0500643
644 gp.qprintn()
Michael Walshb2e53ec2017-10-30 15:04:36 -0500645 gp.qprint_dashes(indent, width, linefeed, char)
Michael Walsh68a61162017-04-25 11:54:06 -0500646 gp.qprintn("Copy this data to the defect:\n")
647
Michael Walshe0cf8d72017-05-17 13:20:46 -0500648 if len(more_header_info) > 0:
Michael Walshff340002017-08-29 11:18:27 -0500649 gp.qprintn(more_header_info)
Michael Walshdc80d672017-05-09 12:58:32 -0500650 gp.qpvars(host_name, host_ip, openbmc_nickname, openbmc_host,
651 openbmc_host_name, openbmc_ip, openbmc_username,
652 openbmc_password, os_host, os_host_name, os_ip, os_username,
653 os_password, pdu_host, pdu_host_name, pdu_ip, pdu_username,
654 pdu_password, pdu_slot_no, openbmc_serial_host,
655 openbmc_serial_host_name, openbmc_serial_ip, openbmc_serial_port)
Michael Walsh68a61162017-04-25 11:54:06 -0500656
657 gp.qprintn()
Michael Walsh68a61162017-04-25 11:54:06 -0500658 print_last_boots()
659 gp.qprintn()
660 gp.qprint_var(state)
Michael Walshb5839d02017-04-12 16:11:20 -0500661 gp.qprintn()
662 gp.qprintn("FFDC data files:")
Michael Walshb2e53ec2017-10-30 15:04:36 -0500663 gp.qprintn(printable_ffdc_file_list)
Michael Walshb5839d02017-04-12 16:11:20 -0500664 gp.qprintn()
Michael Walsh341c21e2017-01-17 16:25:20 -0600665
Michael Walsh600876d2017-05-30 17:58:58 -0500666 if len(ffdc_summary_info) > 0:
Michael Walshff340002017-08-29 11:18:27 -0500667 gp.qprintn(ffdc_summary_info)
Michael Walsh600876d2017-05-30 17:58:58 -0500668
Michael Walshb2e53ec2017-10-30 15:04:36 -0500669 gp.qprint_dashes(indent, width, linefeed, char)
Michael Walsh68a61162017-04-25 11:54:06 -0500670
Michael Walsh6741f742017-02-20 16:16:38 -0600671
Michael Walsh6741f742017-02-20 16:16:38 -0600672def my_ffdc():
Michael Walsh6741f742017-02-20 16:16:38 -0600673 r"""
674 Collect FFDC data.
675 """
676
677 global state
678
679 plug_in_setup()
680 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500681 call_point='ffdc', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600682
683 AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX']
Michael Walshb2e53ec2017-10-30 15:04:36 -0500684 status, ffdc_file_list = grk.run_key_u("FFDC ffdc_prefix=" +
685 AUTOBOOT_FFDC_PREFIX +
686 " ffdc_function_list=" +
687 ffdc_function_list, ignore=1)
Michael Walsh83f4bc72017-04-20 16:49:43 -0500688 if status != 'PASS':
Michael Walshff340002017-08-29 11:18:27 -0500689 gp.qprint_error("Call to ffdc failed.\n")
Michael Walsh6741f742017-02-20 16:16:38 -0600690
691 my_get_state()
692
Michael Walshb2e53ec2017-10-30 15:04:36 -0500693 print_defect_report(ffdc_file_list)
Michael Walsh6741f742017-02-20 16:16:38 -0600694
Michael Walsh6741f742017-02-20 16:16:38 -0600695
Michael Walsh6741f742017-02-20 16:16:38 -0600696def print_test_start_message(boot_keyword):
Michael Walsh6741f742017-02-20 16:16:38 -0600697 r"""
698 Print a message indicating what boot test is about to run.
699
700 Description of arguments:
701 boot_keyword The name of the boot which is to be run
702 (e.g. "BMC Power On").
703 """
704
705 global last_ten
Sunil M325eb542017-08-10 07:09:43 -0500706 global boot_start_time
Michael Walsh6741f742017-02-20 16:16:38 -0600707
708 doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".")
Sunil M325eb542017-08-10 07:09:43 -0500709
710 # Set boot_start_time for use by plug-ins.
711 boot_start_time = doing_msg[1:33]
712 gp.qprint_var(boot_start_time)
713
Michael Walshb5839d02017-04-12 16:11:20 -0500714 gp.qprint(doing_msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600715
716 last_ten.append(doing_msg)
717
718 if len(last_ten) > 10:
719 del last_ten[0]
720
Michael Walsh6741f742017-02-20 16:16:38 -0600721
Michael Walsh6741f742017-02-20 16:16:38 -0600722def run_boot(boot):
Michael Walsh6741f742017-02-20 16:16:38 -0600723 r"""
724 Run the specified boot.
725
726 Description of arguments:
727 boot The name of the boot test to be performed.
728 """
729
730 global state
731
732 print_test_start_message(boot)
733
734 plug_in_setup()
735 rc, shell_rc, failed_plug_in_name = \
736 grpi.rprocess_plug_in_packages(call_point="pre_boot")
737 if rc != 0:
738 error_message = "Plug-in failed with non-zero return code.\n" +\
739 gp.sprint_var(rc, 1)
740 BuiltIn().fail(gp.sprint_error(error_message))
741
742 if test_mode:
743 # In test mode, we'll pretend the boot worked by assigning its
744 # required end state to the default state value.
Michael Walsh30dadae2017-02-27 14:25:52 -0600745 state = st.strip_anchor_state(boot_table[boot]['end'])
Michael Walsh6741f742017-02-20 16:16:38 -0600746 else:
747 # Assertion: We trust that the state data was made fresh by the
748 # caller.
749
Michael Walshb5839d02017-04-12 16:11:20 -0500750 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600751
752 if boot_table[boot]['method_type'] == "keyword":
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600753 rk.my_run_keywords(boot_table[boot].get('lib_file_path', ''),
Michael Walshb5839d02017-04-12 16:11:20 -0500754 boot_table[boot]['method'],
755 quiet=quiet)
Michael Walsh6741f742017-02-20 16:16:38 -0600756
757 if boot_table[boot]['bmc_reboot']:
758 st.wait_for_comm_cycle(int(state['epoch_seconds']))
Michael Walsh30dadae2017-02-27 14:25:52 -0600759 plug_in_setup()
760 rc, shell_rc, failed_plug_in_name = \
761 grpi.rprocess_plug_in_packages(call_point="post_reboot")
762 if rc != 0:
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600763 error_message = "Plug-in failed with non-zero return code.\n"
764 error_message += gp.sprint_var(rc, 1)
Michael Walsh30dadae2017-02-27 14:25:52 -0600765 BuiltIn().fail(gp.sprint_error(error_message))
Michael Walsh6741f742017-02-20 16:16:38 -0600766 else:
767 match_state = st.anchor_state(state)
768 del match_state['epoch_seconds']
769 # Wait for the state to change in any way.
770 st.wait_state(match_state, wait_time=state_change_timeout,
Michael Walsh600876d2017-05-30 17:58:58 -0500771 interval="10 seconds", invert=1)
Michael Walsh6741f742017-02-20 16:16:38 -0600772
Michael Walshb5839d02017-04-12 16:11:20 -0500773 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600774 if boot_table[boot]['end']['chassis'] == "Off":
775 boot_timeout = power_off_timeout
776 else:
777 boot_timeout = power_on_timeout
778 st.wait_state(boot_table[boot]['end'], wait_time=boot_timeout,
Michael Walsh600876d2017-05-30 17:58:58 -0500779 interval="10 seconds")
Michael Walsh6741f742017-02-20 16:16:38 -0600780
781 plug_in_setup()
782 rc, shell_rc, failed_plug_in_name = \
783 grpi.rprocess_plug_in_packages(call_point="post_boot")
784 if rc != 0:
785 error_message = "Plug-in failed with non-zero return code.\n" +\
786 gp.sprint_var(rc, 1)
787 BuiltIn().fail(gp.sprint_error(error_message))
788
Michael Walsh6741f742017-02-20 16:16:38 -0600789
Michael Walsh6741f742017-02-20 16:16:38 -0600790def test_loop_body():
Michael Walsh6741f742017-02-20 16:16:38 -0600791 r"""
792 The main loop body for the loop in main_py.
793
794 Description of arguments:
795 boot_count The iteration number (starts at 1).
796 """
797
798 global boot_count
799 global state
800 global next_boot
801 global boot_success
Sunil M325eb542017-08-10 07:09:43 -0500802 global boot_end_time
Michael Walsh6741f742017-02-20 16:16:38 -0600803
Michael Walshb5839d02017-04-12 16:11:20 -0500804 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600805
806 next_boot = select_boot()
Michael Walshb5839d02017-04-12 16:11:20 -0500807 if next_boot == "":
808 return True
Michael Walsh6741f742017-02-20 16:16:38 -0600809
Michael Walshb5839d02017-04-12 16:11:20 -0500810 boot_count += 1
811 gp.qprint_timen("Starting boot " + str(boot_count) + ".")
Michael Walsh6741f742017-02-20 16:16:38 -0600812
Michael Walshe0cf8d72017-05-17 13:20:46 -0500813 pre_boot_plug_in_setup()
Michael Walsh6741f742017-02-20 16:16:38 -0600814
815 cmd_buf = ["run_boot", next_boot]
816 boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
817 if boot_status == "FAIL":
Michael Walshb5839d02017-04-12 16:11:20 -0500818 gp.qprint(msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600819
Michael Walshb5839d02017-04-12 16:11:20 -0500820 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600821 if boot_status == "PASS":
822 boot_success = 1
Michael Walshff340002017-08-29 11:18:27 -0500823 completion_msg = gp.sprint_timen("BOOT_SUCCESS: \"" + next_boot +
824 "\" succeeded.")
Michael Walsh6741f742017-02-20 16:16:38 -0600825 else:
826 boot_success = 0
Michael Walshff340002017-08-29 11:18:27 -0500827 completion_msg = gp.sprint_timen("BOOT_FAILED: \"" + next_boot +
828 "\" failed.")
Sunil M325eb542017-08-10 07:09:43 -0500829
830 # Set boot_end_time for use by plug-ins.
831 boot_end_time = completion_msg[1:33]
832 gp.qprint_var(boot_end_time)
833
834 gp.qprint(completion_msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600835
836 boot_results.update(next_boot, boot_status)
837
838 plug_in_setup()
839 # NOTE: A post_test_case call point failure is NOT counted as a boot
840 # failure.
841 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500842 call_point='post_test_case', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600843
844 plug_in_setup()
845 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
846 call_point='ffdc_check', shell_rc=0x00000200,
847 stop_on_plug_in_failure=1, stop_on_non_zero_rc=1)
848 if boot_status != "PASS" or ffdc_check == "All" or shell_rc == 0x00000200:
Michael Walsh83f4bc72017-04-20 16:49:43 -0500849 status, ret_values = grk.run_key_u("my_ffdc", ignore=1)
850 if status != 'PASS':
Michael Walshff340002017-08-29 11:18:27 -0500851 gp.qprint_error("Call to my_ffdc failed.\n")
Michael Walsh6741f742017-02-20 16:16:38 -0600852
Michael Walshaabef1e2017-09-20 15:16:17 -0500853 if delete_errlogs:
854 # We need to purge error logs between boots or they build up.
855 grk.run_key("Delete Error logs", ignore=1)
Michael Walshd139f282017-04-04 18:00:23 -0500856
Michael Walsh952f9b02017-03-09 13:11:14 -0600857 boot_results.print_report()
Michael Walshb5839d02017-04-12 16:11:20 -0500858 gp.qprint_timen("Finished boot " + str(boot_count) + ".")
Michael Walsh952f9b02017-03-09 13:11:14 -0600859
Michael Walsh6741f742017-02-20 16:16:38 -0600860 plug_in_setup()
861 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500862 call_point='stop_check', shell_rc=0x00000200, stop_on_non_zero_rc=1)
863 if shell_rc == 0x00000200:
864 message = "Stopping as requested by user.\n"
865 gp.print_time(message)
866 BuiltIn().fail(message)
Michael Walsh6741f742017-02-20 16:16:38 -0600867
Michael Walshd139f282017-04-04 18:00:23 -0500868 # This should help prevent ConnectionErrors.
Michael Walsh0960b382017-06-22 16:23:37 -0500869 grk.run_key_u("Close All Connections")
Michael Walshd139f282017-04-04 18:00:23 -0500870
Michael Walsh6741f742017-02-20 16:16:38 -0600871 return True
872
Michael Walsh6741f742017-02-20 16:16:38 -0600873
Michael Walsh83f4bc72017-04-20 16:49:43 -0500874def obmc_boot_test_teardown():
Michael Walsh6741f742017-02-20 16:16:38 -0600875 r"""
Michael Walshc9116812017-03-10 14:23:06 -0600876 Clean up after the Main keyword.
Michael Walsh6741f742017-02-20 16:16:38 -0600877 """
878
879 if cp_setup_called:
880 plug_in_setup()
881 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500882 call_point='cleanup', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600883
Michael Walsh600876d2017-05-30 17:58:58 -0500884 if 'boot_results_file_path' in globals():
885 # Save boot_results object to a file in case it is needed again.
886 gp.qprint_timen("Saving boot_results to the following path.")
887 gp.qprint_var(boot_results_file_path)
888 pickle.dump(boot_results, open(boot_results_file_path, 'wb'),
889 pickle.HIGHEST_PROTOCOL)
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600890
Michael Walshff340002017-08-29 11:18:27 -0500891 global save_stack
892 # Restore any global values saved on the save_stack.
893 for parm_name in main_func_parm_list:
894 # Get the parm_value if it was saved on the stack.
895 try:
896 parm_value = save_stack.pop(parm_name)
897 except:
898 # If it was not saved, no further action is required.
899 continue
900
901 # Restore the saved value.
902 cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
903 "}\", parm_value)"
904 gp.dpissuing(cmd_buf)
905 exec(cmd_buf)
906
907 gp.dprintn(save_stack.sprint_obj())
908
Michael Walsh6741f742017-02-20 16:16:38 -0600909
Michael Walshc9116812017-03-10 14:23:06 -0600910def test_teardown():
Michael Walshc9116812017-03-10 14:23:06 -0600911 r"""
912 Clean up after this test case.
913 """
914
915 gp.qprintn()
916 cmd_buf = ["Print Error",
917 "A keyword timeout occurred ending this program.\n"]
918 BuiltIn().run_keyword_if_timeout_occurred(*cmd_buf)
919
Michael Walshb5839d02017-04-12 16:11:20 -0500920 grp.rqprint_pgm_footer()
921
Michael Walshc9116812017-03-10 14:23:06 -0600922
Michael Walshff340002017-08-29 11:18:27 -0500923def obmc_boot_test_py(loc_boot_stack=None,
924 loc_stack_mode=None,
925 loc_quiet=None):
Michael Walsh6741f742017-02-20 16:16:38 -0600926 r"""
927 Do main program processing.
928 """
929
Michael Walshff340002017-08-29 11:18:27 -0500930 global save_stack
931
932 # Process function parms.
933 for parm_name in main_func_parm_list:
934 # Get parm's value.
935 cmd_buf = "parm_value = loc_" + parm_name
936 exec(cmd_buf)
937 gp.dpvar(parm_name)
938 gp.dpvar(parm_value)
939
940 if parm_value is None:
941 # Parm was not specified by the calling function so set it to its
942 # corresponding global value.
943 cmd_buf = "loc_" + parm_name + " = BuiltIn().get_variable_value" +\
944 "(\"${" + parm_name + "}\")"
945 gp.dpissuing(cmd_buf)
946 exec(cmd_buf)
947 else:
948 # Save the global value on a stack.
949 cmd_buf = "save_stack.push(BuiltIn().get_variable_value(\"${" +\
950 parm_name + "}\"), \"" + parm_name + "\")"
951 gp.dpissuing(cmd_buf)
952 exec(cmd_buf)
953
954 # Set the global value to the passed value.
955 cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
956 "}\", loc_" + parm_name + ")"
957 gp.dpissuing(cmd_buf)
958 exec(cmd_buf)
959
960 gp.dprintn(save_stack.sprint_obj())
Michael Walshb5839d02017-04-12 16:11:20 -0500961
Michael Walsh6741f742017-02-20 16:16:38 -0600962 setup()
963
Michael Walshcd9fbfd2017-09-19 12:00:08 -0500964 init_boot_pass, init_boot_fail = boot_results.return_total_pass_fail()
965
Michael Walsha20da402017-03-31 16:27:45 -0500966 if ffdc_only:
967 gp.qprint_timen("Caller requested ffdc_only.")
Michael Walshe0cf8d72017-05-17 13:20:46 -0500968 pre_boot_plug_in_setup()
Michael Walsh83f4bc72017-04-20 16:49:43 -0500969 grk.run_key_u("my_ffdc")
Michael Walsh764d2f82017-04-27 16:01:08 -0500970 return
Michael Walsha20da402017-03-31 16:27:45 -0500971
Michael Walsh6741f742017-02-20 16:16:38 -0600972 # Process caller's boot_stack.
973 while (len(boot_stack) > 0):
974 test_loop_body()
975
Michael Walshb5839d02017-04-12 16:11:20 -0500976 gp.qprint_timen("Finished processing stack.")
Michael Walsh30dadae2017-02-27 14:25:52 -0600977
Michael Walsh6741f742017-02-20 16:16:38 -0600978 # Process caller's boot_list.
979 if len(boot_list) > 0:
980 for ix in range(1, max_num_tests + 1):
981 test_loop_body()
982
Michael Walshb5839d02017-04-12 16:11:20 -0500983 gp.qprint_timen("Completed all requested boot tests.")
984
985 boot_pass, boot_fail = boot_results.return_total_pass_fail()
Michael Walshcd9fbfd2017-09-19 12:00:08 -0500986 new_fail = boot_fail - init_boot_fail
987 if new_fail > boot_fail_threshold:
Michael Walshb5839d02017-04-12 16:11:20 -0500988 error_message = "Boot failures exceed the boot failure" +\
989 " threshold:\n" +\
Michael Walshcd9fbfd2017-09-19 12:00:08 -0500990 gp.sprint_var(new_fail) +\
Michael Walshb5839d02017-04-12 16:11:20 -0500991 gp.sprint_var(boot_fail_threshold)
992 BuiltIn().fail(gp.sprint_error(error_message))