blob: 8c76f8431e158e237111a725db2ea983ef514911 [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
49state = st.return_default_state()
50cp_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
72###############################################################################
Michael Walsh0ad0f7f2017-05-04 14:39:58 -050073def process_host(host,
74 host_var_name=""):
75
76 r"""
77 Process a host by getting the associated host name and IP address and
78 setting them in global variables.
79
80 If the caller does not pass the host_var_name, this function will try to
81 figure out the name of the variable used by the caller for the host parm.
82 Callers are advised to explicitly specify the host_var_name when calling
83 with an exec command. In such cases, the get_arg_name cannot figure out
84 the host variable name.
85
86 This function will then create similar global variable names by
87 removing "_host" and appending "_host_name" or "_ip" to the host variable
88 name.
89
90 Example:
91
92 If a call is made like this:
93 process_host(openbmc_host)
94
95 Global variables openbmc_host_name and openbmc_ip will be set.
96
97 Description of argument(s):
98 host A host name or IP. The name of the variable used should
99 have a suffix of "_host".
100 host_var_name The name of the variable being used as the host parm.
101 """
102
103 if host_var_name == "":
104 host_var_name = gp.get_arg_name(0, 1, stack_frame_ix=2)
105
106 host_name_var_name = re.sub("host", "host_name", host_var_name)
107 ip_var_name = re.sub("host", "ip", host_var_name)
108 cmd_buf = "global " + host_name_var_name + ", " + ip_var_name + " ; " +\
109 host_name_var_name + ", " + ip_var_name + " = gm.get_host_name_ip('" +\
110 host + "')"
111 exec(cmd_buf)
112
113###############################################################################
114
115
116###############################################################################
Michael Walshb5839d02017-04-12 16:11:20 -0500117def process_pgm_parms():
118
119 r"""
120 Process the program parameters by assigning them all to corresponding
121 globals. Also, set some global values that depend on program parameters.
122 """
123
124 # Program parameter processing.
125 # Assign all program parms to python variables which are global to this
126 # module.
127
128 global parm_list
129 parm_list = BuiltIn().get_variable_value("${parm_list}")
130 # The following subset of parms should be processed as integers.
131 int_list = ['max_num_tests', 'boot_pass', 'boot_fail', 'ffdc_only',
Michael Walshaabef1e2017-09-20 15:16:17 -0500132 'boot_fail_threshold', 'delete_errlogs', 'quiet', 'test_mode',
133 'debug']
Michael Walshb5839d02017-04-12 16:11:20 -0500134 for parm in parm_list:
135 if parm in int_list:
136 sub_cmd = "int(BuiltIn().get_variable_value(\"${" + parm +\
137 "}\", \"0\"))"
138 else:
139 sub_cmd = "BuiltIn().get_variable_value(\"${" + parm + "}\")"
140 cmd_buf = "global " + parm + " ; " + parm + " = " + sub_cmd
Michael Walshff340002017-08-29 11:18:27 -0500141 gp.dpissuing(cmd_buf)
Michael Walshb5839d02017-04-12 16:11:20 -0500142 exec(cmd_buf)
Michael Walsh0ad0f7f2017-05-04 14:39:58 -0500143 if re.match(r".*_host$", parm):
144 cmd_buf = "process_host(" + parm + ", '" + parm + "')"
145 exec(cmd_buf)
146 if re.match(r".*_password$", parm):
147 # Register the value of any parm whose name ends in _password.
148 # This will cause the print functions to replace passwords with
149 # asterisks in the output.
150 cmd_buf = "gp.register_passwords(" + parm + ")"
151 exec(cmd_buf)
Michael Walshb5839d02017-04-12 16:11:20 -0500152
153 global ffdc_dir_path_style
154 global boot_list
155 global boot_stack
156 global boot_results_file_path
157 global boot_results
158 global ffdc_list_file_path
Michael Walshe0cf8d72017-05-17 13:20:46 -0500159 global ffdc_report_list_path
Michael Walsh600876d2017-05-30 17:58:58 -0500160 global ffdc_summary_list_path
Michael Walshb5839d02017-04-12 16:11:20 -0500161
162 if ffdc_dir_path_style == "":
163 ffdc_dir_path_style = int(os.environ.get('FFDC_DIR_PATH_STYLE', '0'))
164
165 # Convert these program parms to lists for easier processing..
166 boot_list = filter(None, boot_list.split(":"))
167 boot_stack = filter(None, boot_stack.split(":"))
168
Michael Walsh903e0b22017-09-19 17:00:33 -0500169 cleanup_boot_results_file()
170 boot_results_file_path = create_boot_results_file_path(pgm_name,
171 openbmc_nickname,
172 master_pid)
Michael Walshb5839d02017-04-12 16:11:20 -0500173
174 if os.path.isfile(boot_results_file_path):
175 # We've been called before in this run so we'll load the saved
176 # boot_results object.
177 boot_results = pickle.load(open(boot_results_file_path, 'rb'))
178 else:
179 boot_results = boot_results(boot_table, boot_pass, boot_fail)
180
181 ffdc_list_file_path = base_tool_dir_path + openbmc_nickname +\
182 "/FFDC_FILE_LIST"
Michael Walshe0cf8d72017-05-17 13:20:46 -0500183 ffdc_report_list_path = base_tool_dir_path + openbmc_nickname +\
184 "/FFDC_REPORT_FILE_LIST"
Michael Walshb5839d02017-04-12 16:11:20 -0500185
Michael Walsh600876d2017-05-30 17:58:58 -0500186 ffdc_summary_list_path = base_tool_dir_path + openbmc_nickname +\
187 "/FFDC_SUMMARY_FILE_LIST"
188
Michael Walshb5839d02017-04-12 16:11:20 -0500189###############################################################################
190
191
192###############################################################################
Michael Walsh85678942017-03-27 14:34:22 -0500193def initial_plug_in_setup():
194
195 r"""
196 Initialize all plug-in environment variables which do not change for the
197 duration of the program.
198
199 """
200
201 global LOG_LEVEL
202 BuiltIn().set_log_level("NONE")
203
204 BuiltIn().set_global_variable("${master_pid}", master_pid)
205 BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path)
206 BuiltIn().set_global_variable("${STATUS_DIR_PATH}", status_dir_path)
207 BuiltIn().set_global_variable("${BASE_TOOL_DIR_PATH}", base_tool_dir_path)
208 BuiltIn().set_global_variable("${FFDC_LIST_FILE_PATH}",
209 ffdc_list_file_path)
Michael Walshe0cf8d72017-05-17 13:20:46 -0500210 BuiltIn().set_global_variable("${FFDC_REPORT_LIST_PATH}",
211 ffdc_report_list_path)
Michael Walsh600876d2017-05-30 17:58:58 -0500212 BuiltIn().set_global_variable("${FFDC_SUMMARY_LIST_PATH}",
213 ffdc_summary_list_path)
Michael Walsh85678942017-03-27 14:34:22 -0500214
215 BuiltIn().set_global_variable("${FFDC_DIR_PATH_STYLE}",
216 ffdc_dir_path_style)
217 BuiltIn().set_global_variable("${FFDC_CHECK}",
218 ffdc_check)
219
220 # For each program parameter, set the corresponding AUTOBOOT_ environment
221 # variable value. Also, set an AUTOBOOT_ environment variable for every
222 # element in additional_values.
223 additional_values = ["program_pid", "master_pid", "ffdc_dir_path",
224 "status_dir_path", "base_tool_dir_path",
Michael Walsh600876d2017-05-30 17:58:58 -0500225 "ffdc_list_file_path", "ffdc_report_list_path",
226 "ffdc_summary_list_path"]
Michael Walsh85678942017-03-27 14:34:22 -0500227
228 plug_in_vars = parm_list + additional_values
229
230 for var_name in plug_in_vars:
231 var_value = BuiltIn().get_variable_value("${" + var_name + "}")
232 var_name = var_name.upper()
233 if var_value is None:
234 var_value = ""
235 os.environ["AUTOBOOT_" + var_name] = str(var_value)
236
237 BuiltIn().set_log_level(LOG_LEVEL)
238
Michael Walsh68a61162017-04-25 11:54:06 -0500239 # Make sure the ffdc list directory exists.
240 ffdc_list_dir_path = os.path.dirname(ffdc_list_file_path) + os.sep
241 if not os.path.exists(ffdc_list_dir_path):
242 os.makedirs(ffdc_list_dir_path)
Michael Walsh85678942017-03-27 14:34:22 -0500243
244###############################################################################
245
Michael Walsh0bbd8602016-11-22 11:31:49 -0600246
247###############################################################################
Michael Walsh0bbd8602016-11-22 11:31:49 -0600248def plug_in_setup():
249
250 r"""
Michael Walsh85678942017-03-27 14:34:22 -0500251 Initialize all changing plug-in environment variables for use by the
252 plug-in programs.
Michael Walsh0bbd8602016-11-22 11:31:49 -0600253 """
254
Michael Walsh85678942017-03-27 14:34:22 -0500255 global LOG_LEVEL
256 global test_really_running
257
258 BuiltIn().set_log_level("NONE")
259
Michael Walsh6741f742017-02-20 16:16:38 -0600260 boot_pass, boot_fail = boot_results.return_total_pass_fail()
Michael Walsh0bbd8602016-11-22 11:31:49 -0600261 if boot_pass > 1:
262 test_really_running = 1
263 else:
264 test_really_running = 0
265
Michael Walsh6741f742017-02-20 16:16:38 -0600266 BuiltIn().set_global_variable("${test_really_running}",
267 test_really_running)
268 BuiltIn().set_global_variable("${boot_type_desc}", next_boot)
Michael Walsh6741f742017-02-20 16:16:38 -0600269 BuiltIn().set_global_variable("${boot_pass}", boot_pass)
270 BuiltIn().set_global_variable("${boot_fail}", boot_fail)
271 BuiltIn().set_global_variable("${boot_success}", boot_success)
272 BuiltIn().set_global_variable("${ffdc_prefix}", ffdc_prefix)
Sunil M325eb542017-08-10 07:09:43 -0500273 BuiltIn().set_global_variable("${boot_start_time}", boot_start_time)
274 BuiltIn().set_global_variable("${boot_end_time}", boot_end_time)
Michael Walsh4c9a6452016-12-13 16:03:11 -0600275
Michael Walsh0bbd8602016-11-22 11:31:49 -0600276 # For each program parameter, set the corresponding AUTOBOOT_ environment
277 # variable value. Also, set an AUTOBOOT_ environment variable for every
278 # element in additional_values.
279 additional_values = ["boot_type_desc", "boot_success", "boot_pass",
Sunil M325eb542017-08-10 07:09:43 -0500280 "boot_fail", "test_really_running", "ffdc_prefix",
281 "boot_start_time", "boot_end_time"]
Michael Walsh0bbd8602016-11-22 11:31:49 -0600282
Michael Walsh85678942017-03-27 14:34:22 -0500283 plug_in_vars = additional_values
Michael Walsh0bbd8602016-11-22 11:31:49 -0600284
285 for var_name in plug_in_vars:
286 var_value = BuiltIn().get_variable_value("${" + var_name + "}")
287 var_name = var_name.upper()
288 if var_value is None:
289 var_value = ""
Michael Walsh6741f742017-02-20 16:16:38 -0600290 os.environ["AUTOBOOT_" + var_name] = str(var_value)
Michael Walsh0bbd8602016-11-22 11:31:49 -0600291
Michael Walsh0bbd8602016-11-22 11:31:49 -0600292 if debug:
Michael Walsh6741f742017-02-20 16:16:38 -0600293 shell_rc, out_buf = \
294 gc.cmd_fnc_u("printenv | egrep AUTOBOOT_ | sort -u")
Michael Walsh0bbd8602016-11-22 11:31:49 -0600295
Michael Walsh85678942017-03-27 14:34:22 -0500296 BuiltIn().set_log_level(LOG_LEVEL)
297
Michael Walsh0bbd8602016-11-22 11:31:49 -0600298###############################################################################
299
300
301###############################################################################
Michael Walshe0cf8d72017-05-17 13:20:46 -0500302def pre_boot_plug_in_setup():
303
304 # Clear the ffdc_list_file_path file. Plug-ins may now write to it.
305 try:
306 os.remove(ffdc_list_file_path)
307 except OSError:
308 pass
309
310 # Clear the ffdc_report_list_path file. Plug-ins may now write to it.
311 try:
312 os.remove(ffdc_report_list_path)
313 except OSError:
314 pass
315
Michael Walsh600876d2017-05-30 17:58:58 -0500316 # Clear the ffdc_summary_list_path file. Plug-ins may now write to it.
317 try:
318 os.remove(ffdc_summary_list_path)
319 except OSError:
320 pass
321
Michael Walshe1974b92017-08-03 13:39:51 -0500322 global ffdc_prefix
323
324 seconds = time.time()
325 loc_time = time.localtime(seconds)
326 time_string = time.strftime("%y%m%d.%H%M%S.", loc_time)
327
328 ffdc_prefix = openbmc_nickname + "." + time_string
329
Michael Walshe0cf8d72017-05-17 13:20:46 -0500330###############################################################################
331
332
333###############################################################################
Michael Walsh6741f742017-02-20 16:16:38 -0600334def setup():
Michael Walsh0bbd8602016-11-22 11:31:49 -0600335
336 r"""
Michael Walsh6741f742017-02-20 16:16:38 -0600337 Do general program setup tasks.
Michael Walsh0bbd8602016-11-22 11:31:49 -0600338 """
339
Michael Walsh6741f742017-02-20 16:16:38 -0600340 global cp_setup_called
Michael Walsh0bbd8602016-11-22 11:31:49 -0600341
Michael Walshb5839d02017-04-12 16:11:20 -0500342 gp.qprintn()
343
Michael Walsh83f4bc72017-04-20 16:49:43 -0500344 robot_pgm_dir_path = os.path.dirname(__file__) + os.sep
345 repo_bin_path = robot_pgm_dir_path.replace("/lib/", "/bin/")
Michael Walshd061c042017-05-23 14:46:57 -0500346 # If we can't find process_plug_in_packages.py, ssh_pw or
347 # validate_plug_ins.py, then we don't have our repo bin in PATH.
348 shell_rc, out_buf = gc.cmd_fnc_u("which process_plug_in_packages.py" +
349 " ssh_pw validate_plug_ins.py", quiet=1,
350 print_output=0, show_err=0)
Michael Walshb5839d02017-04-12 16:11:20 -0500351 if shell_rc != 0:
Michael Walsh83f4bc72017-04-20 16:49:43 -0500352 os.environ['PATH'] = repo_bin_path + ":" + os.environ.get('PATH', "")
353 # Likewise, our repo lib subdir needs to be in sys.path and PYTHONPATH.
354 if robot_pgm_dir_path not in sys.path:
355 sys.path.append(robot_pgm_dir_path)
356 PYTHONPATH = os.environ.get("PYTHONPATH", "")
357 if PYTHONPATH == "":
358 os.environ['PYTHONPATH'] = robot_pgm_dir_path
359 else:
360 os.environ['PYTHONPATH'] = robot_pgm_dir_path + ":" + PYTHONPATH
Michael Walsh6741f742017-02-20 16:16:38 -0600361
362 validate_parms()
363
364 grp.rqprint_pgm_header()
365
Michael Walshfdc5ced2017-08-17 13:15:15 -0500366 grk.run_key("Set BMC Power Policy RESTORE_LAST_STATE")
Michael Walsh11cfc8c2017-03-31 09:40:55 -0500367
Michael Walsh85678942017-03-27 14:34:22 -0500368 initial_plug_in_setup()
369
Michael Walsh6741f742017-02-20 16:16:38 -0600370 plug_in_setup()
371 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
372 call_point='setup')
373 if rc != 0:
374 error_message = "Plug-in setup failed.\n"
375 grp.rprint_error_report(error_message)
376 BuiltIn().fail(error_message)
377 # Setting cp_setup_called lets our Teardown know that it needs to call
378 # the cleanup plug-in call point.
379 cp_setup_called = 1
380
381 # Keyword "FFDC" will fail if TEST_MESSAGE is not set.
382 BuiltIn().set_global_variable("${TEST_MESSAGE}", "${EMPTY}")
Michael Walsh85678942017-03-27 14:34:22 -0500383 # FFDC_LOG_PATH is used by "FFDC" keyword.
384 BuiltIn().set_global_variable("${FFDC_LOG_PATH}", ffdc_dir_path)
Michael Walsh6741f742017-02-20 16:16:38 -0600385
Michael Walshdc80d672017-05-09 12:58:32 -0500386 # Also printed by FFDC.
387 global host_name
388 global host_ip
389 host = socket.gethostname()
390 host_name, host_ip = gm.get_host_name_ip(host)
391
Michael Walshb5839d02017-04-12 16:11:20 -0500392 gp.dprint_var(boot_table, 1)
393 gp.dprint_var(boot_lists)
Michael Walsh0bbd8602016-11-22 11:31:49 -0600394
395###############################################################################
396
397
398###############################################################################
Michael Walsh6741f742017-02-20 16:16:38 -0600399def validate_parms():
Michael Walsh0bbd8602016-11-22 11:31:49 -0600400
401 r"""
Michael Walsh6741f742017-02-20 16:16:38 -0600402 Validate all program parameters.
Michael Walsh0bbd8602016-11-22 11:31:49 -0600403 """
404
Michael Walshb5839d02017-04-12 16:11:20 -0500405 process_pgm_parms()
Michael Walsh0bbd8602016-11-22 11:31:49 -0600406
Michael Walshb5839d02017-04-12 16:11:20 -0500407 gp.qprintn()
408
409 global openbmc_model
Michael Walsh6741f742017-02-20 16:16:38 -0600410 grv.rvalid_value("openbmc_host")
411 grv.rvalid_value("openbmc_username")
412 grv.rvalid_value("openbmc_password")
413 if os_host != "":
414 grv.rvalid_value("os_username")
415 grv.rvalid_value("os_password")
Michael Walsh0bbd8602016-11-22 11:31:49 -0600416
Michael Walsh6741f742017-02-20 16:16:38 -0600417 if pdu_host != "":
418 grv.rvalid_value("pdu_username")
419 grv.rvalid_value("pdu_password")
Michael Walsh85678942017-03-27 14:34:22 -0500420 grv.rvalid_integer("pdu_slot_no")
Michael Walsh6741f742017-02-20 16:16:38 -0600421 if openbmc_serial_host != "":
422 grv.rvalid_integer("openbmc_serial_port")
Michael Walshb5839d02017-04-12 16:11:20 -0500423 if openbmc_model == "":
424 status, ret_values =\
425 grk.run_key_u("Get BMC System Model")
426 openbmc_model = ret_values
427 BuiltIn().set_global_variable("${openbmc_model}", openbmc_model)
Michael Walsh6741f742017-02-20 16:16:38 -0600428 grv.rvalid_value("openbmc_model")
Michael Walshb5839d02017-04-12 16:11:20 -0500429 grv.rvalid_integer("max_num_tests")
Michael Walsh6741f742017-02-20 16:16:38 -0600430 grv.rvalid_integer("boot_pass")
431 grv.rvalid_integer("boot_fail")
432
433 plug_in_packages_list = grpi.rvalidate_plug_ins(plug_in_dir_paths)
434 BuiltIn().set_global_variable("${plug_in_packages_list}",
435 plug_in_packages_list)
436
Michael Walshb5839d02017-04-12 16:11:20 -0500437 grv.rvalid_value("stack_mode", valid_values=['normal', 'skip'])
Michael Walsha20da402017-03-31 16:27:45 -0500438 if len(boot_list) == 0 and len(boot_stack) == 0 and not ffdc_only:
Michael Walsh6741f742017-02-20 16:16:38 -0600439 error_message = "You must provide either a value for either the" +\
440 " boot_list or the boot_stack parm.\n"
441 BuiltIn().fail(gp.sprint_error(error_message))
442
443 valid_boot_list(boot_list, valid_boot_types)
444 valid_boot_list(boot_stack, valid_boot_types)
445
Michael Walsh11cfc8c2017-03-31 09:40:55 -0500446 selected_PDU_boots = list(set(boot_list + boot_stack) &
447 set(boot_lists['PDU_reboot']))
448
449 if len(selected_PDU_boots) > 0 and pdu_host == "":
450 error_message = "You have selected the following boots which" +\
451 " require a PDU host but no value for pdu_host:\n"
452 error_message += gp.sprint_var(selected_PDU_boots)
453 error_message += gp.sprint_var(pdu_host, 2)
454 BuiltIn().fail(gp.sprint_error(error_message))
455
Michael Walsh6741f742017-02-20 16:16:38 -0600456 return
Michael Walsh0bbd8602016-11-22 11:31:49 -0600457
458###############################################################################
459
460
461###############################################################################
Michael Walsh6741f742017-02-20 16:16:38 -0600462def my_get_state():
Michael Walsh0bbd8602016-11-22 11:31:49 -0600463
464 r"""
Michael Walsh6741f742017-02-20 16:16:38 -0600465 Get the system state plus a little bit of wrapping.
Michael Walsh0bbd8602016-11-22 11:31:49 -0600466 """
467
Michael Walsh6741f742017-02-20 16:16:38 -0600468 global state
469
470 req_states = ['epoch_seconds'] + st.default_req_states
471
Michael Walshb5839d02017-04-12 16:11:20 -0500472 gp.qprint_timen("Getting system state.")
Michael Walsh6741f742017-02-20 16:16:38 -0600473 if test_mode:
474 state['epoch_seconds'] = int(time.time())
475 else:
Michael Walshb5839d02017-04-12 16:11:20 -0500476 state = st.get_state(req_states=req_states, quiet=quiet)
477 gp.qprint_var(state)
Michael Walsh341c21e2017-01-17 16:25:20 -0600478
479###############################################################################
480
481
482###############################################################################
Michael Walsh45ca6e42017-09-14 17:29:12 -0500483def valid_state():
484
485 r"""
486 Verify that our state dictionary contains no blank values. If we don't get
487 valid state data, we cannot continue to work.
488 """
489
490 if st.compare_states(state, st.invalid_state_match, 'or'):
491 error_message = "The state dictionary contains blank fields which" +\
492 " is illegal.\n" + gp.sprint_var(state)
493 BuiltIn().fail(gp.sprint_error(error_message))
494
495###############################################################################
496
497
498###############################################################################
Michael Walsh6741f742017-02-20 16:16:38 -0600499def select_boot():
Michael Walsh341c21e2017-01-17 16:25:20 -0600500
501 r"""
502 Select a boot test to be run based on our current state and return the
503 chosen boot type.
504
505 Description of arguments:
Michael Walsh6741f742017-02-20 16:16:38 -0600506 state The state of the machine.
Michael Walsh341c21e2017-01-17 16:25:20 -0600507 """
508
Michael Walsh30dadae2017-02-27 14:25:52 -0600509 global boot_stack
510
Michael Walshb5839d02017-04-12 16:11:20 -0500511 gp.qprint_timen("Selecting a boot test.")
Michael Walsh6741f742017-02-20 16:16:38 -0600512
513 my_get_state()
Michael Walsh45ca6e42017-09-14 17:29:12 -0500514 valid_state()
Michael Walsh6741f742017-02-20 16:16:38 -0600515
516 stack_popped = 0
517 if len(boot_stack) > 0:
518 stack_popped = 1
Michael Walshb5839d02017-04-12 16:11:20 -0500519 gp.qprint_dashes()
520 gp.qprint_var(boot_stack)
521 gp.qprint_dashes()
522 skip_boot_printed = 0
523 while len(boot_stack) > 0:
524 boot_candidate = boot_stack.pop()
525 if stack_mode == 'normal':
526 break
527 else:
528 if st.compare_states(state, boot_table[boot_candidate]['end']):
529 if not skip_boot_printed:
Michael Walshff340002017-08-29 11:18:27 -0500530 gp.qprint_var(stack_mode)
531 gp.qprintn()
532 gp.qprint_timen("Skipping the following boot tests" +
533 " which are unnecessary since their" +
534 " required end states match the" +
535 " current machine state:")
Michael Walshb5839d02017-04-12 16:11:20 -0500536 skip_boot_printed = 1
Michael Walshff340002017-08-29 11:18:27 -0500537 gp.qprint_var(boot_candidate)
Michael Walshb5839d02017-04-12 16:11:20 -0500538 boot_candidate = ""
539 if boot_candidate == "":
540 gp.qprint_dashes()
541 gp.qprint_var(boot_stack)
542 gp.qprint_dashes()
543 return boot_candidate
Michael Walsh6741f742017-02-20 16:16:38 -0600544 if st.compare_states(state, boot_table[boot_candidate]['start']):
Michael Walshb5839d02017-04-12 16:11:20 -0500545 gp.qprint_timen("The machine state is valid for a '" +
546 boot_candidate + "' boot test.")
547 gp.qprint_dashes()
548 gp.qprint_var(boot_stack)
549 gp.qprint_dashes()
Michael Walsh6741f742017-02-20 16:16:38 -0600550 return boot_candidate
Michael Walsh341c21e2017-01-17 16:25:20 -0600551 else:
Michael Walshb5839d02017-04-12 16:11:20 -0500552 gp.qprint_timen("The machine state does not match the required" +
553 " starting state for a '" + boot_candidate +
554 "' boot test:")
Michael Walshff340002017-08-29 11:18:27 -0500555 gp.qprint_varx("boot_table[" + boot_candidate + "][start]",
556 boot_table[boot_candidate]['start'], 1)
Michael Walsh6741f742017-02-20 16:16:38 -0600557 boot_stack.append(boot_candidate)
558 popped_boot = boot_candidate
559
560 # Loop through your list selecting a boot_candidates
561 boot_candidates = []
562 for boot_candidate in boot_list:
563 if st.compare_states(state, boot_table[boot_candidate]['start']):
564 if stack_popped:
565 if st.compare_states(boot_table[boot_candidate]['end'],
566 boot_table[popped_boot]['start']):
567 boot_candidates.append(boot_candidate)
568 else:
569 boot_candidates.append(boot_candidate)
570
571 if len(boot_candidates) == 0:
Michael Walshb5839d02017-04-12 16:11:20 -0500572 gp.qprint_timen("The user's boot list contained no boot tests" +
573 " which are valid for the current machine state.")
Michael Walsh6741f742017-02-20 16:16:38 -0600574 boot_candidate = default_power_on
575 if not st.compare_states(state, boot_table[default_power_on]['start']):
576 boot_candidate = default_power_off
577 boot_candidates.append(boot_candidate)
Michael Walshb5839d02017-04-12 16:11:20 -0500578 gp.qprint_timen("Using default '" + boot_candidate +
579 "' boot type to transition to valid state.")
Michael Walsh6741f742017-02-20 16:16:38 -0600580
Michael Walshb5839d02017-04-12 16:11:20 -0500581 gp.dprint_var(boot_candidates)
Michael Walsh6741f742017-02-20 16:16:38 -0600582
583 # Randomly select a boot from the candidate list.
584 boot = random.choice(boot_candidates)
Michael Walsh341c21e2017-01-17 16:25:20 -0600585
586 return boot
Michael Walsh0bbd8602016-11-22 11:31:49 -0600587
588###############################################################################
Michael Walsh55302292017-01-10 11:43:02 -0600589
590
591###############################################################################
Michael Walsh341c21e2017-01-17 16:25:20 -0600592def print_last_boots():
593
594 r"""
595 Print the last ten boots done with their time stamps.
596 """
597
598 # indent 0, 90 chars wide, linefeed, char is "="
Michael Walshb5839d02017-04-12 16:11:20 -0500599 gp.qprint_dashes(0, 90)
600 gp.qprintn("Last 10 boots:\n")
Michael Walsh341c21e2017-01-17 16:25:20 -0600601
602 for boot_entry in last_ten:
603 grp.rqprint(boot_entry)
Michael Walshb5839d02017-04-12 16:11:20 -0500604 gp.qprint_dashes(0, 90)
Michael Walsh341c21e2017-01-17 16:25:20 -0600605
606###############################################################################
607
608
609###############################################################################
Michael Walsh341c21e2017-01-17 16:25:20 -0600610def print_defect_report():
611
612 r"""
613 Print a defect report.
614 """
615
Michael Walsh600876d2017-05-30 17:58:58 -0500616 # Making deliberate choice to NOT run plug_in_setup(). We don't want
617 # ffdc_prefix updated.
618 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
619 call_point='ffdc_report', stop_on_plug_in_failure=0)
620
Michael Walsh341c21e2017-01-17 16:25:20 -0600621 # At some point I'd like to have the 'Call FFDC Methods' return a list
622 # of files it has collected. In that case, the following "ls" command
623 # would no longer be needed. For now, however, glob shows the files
624 # named in FFDC_LIST_FILE_PATH so I will refrain from printing those
625 # out (so we don't see duplicates in the list).
626
Michael Walshe0cf8d72017-05-17 13:20:46 -0500627 # Get additional header data which may have been created by ffdc plug-ins.
628 # Also, delete the individual header files to cleanup.
629 cmd_buf = "file_list=$(cat " + ffdc_report_list_path + " 2>/dev/null)" +\
630 " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\
631 " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :"
632 shell_rc, more_header_info = gc.cmd_fnc_u(cmd_buf, print_output=0,
633 show_err=0)
634
Michael Walsh600876d2017-05-30 17:58:58 -0500635 # Get additional header data which may have been created by ffdc plug-ins.
636 # Also, delete the individual header files to cleanup.
637 cmd_buf = "file_list=$(cat " + ffdc_summary_list_path + " 2>/dev/null)" +\
638 " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\
639 " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :"
640 shell_rc, ffdc_summary_info = gc.cmd_fnc_u(cmd_buf, print_output=0,
641 show_err=0)
642
Michael Walsh341c21e2017-01-17 16:25:20 -0600643 LOG_PREFIX = BuiltIn().get_variable_value("${LOG_PREFIX}")
644
Michael Walshe0cf8d72017-05-17 13:20:46 -0500645 output = '\n'.join(sorted(glob.glob(LOG_PREFIX + '*')))
Michael Walsh341c21e2017-01-17 16:25:20 -0600646 try:
Michael Walsh6741f742017-02-20 16:16:38 -0600647 ffdc_list = open(ffdc_list_file_path, 'r')
Michael Walsh341c21e2017-01-17 16:25:20 -0600648 except IOError:
649 ffdc_list = ""
650
Michael Walsh68a61162017-04-25 11:54:06 -0500651 # Open ffdc_file_list for writing. We will write a complete list of
652 # FFDC files to it for possible use by plug-ins like cp_stop_check.
653 ffdc_list_file = open(ffdc_list_file_path, 'w')
654
655 gp.qprintn()
656 # indent=0, width=90, linefeed=1, char="="
657 gp.qprint_dashes(0, 90, 1, "=")
658 gp.qprintn("Copy this data to the defect:\n")
659
Michael Walshe0cf8d72017-05-17 13:20:46 -0500660 if len(more_header_info) > 0:
Michael Walshff340002017-08-29 11:18:27 -0500661 gp.qprintn(more_header_info)
Michael Walshdc80d672017-05-09 12:58:32 -0500662 gp.qpvars(host_name, host_ip, openbmc_nickname, openbmc_host,
663 openbmc_host_name, openbmc_ip, openbmc_username,
664 openbmc_password, os_host, os_host_name, os_ip, os_username,
665 os_password, pdu_host, pdu_host_name, pdu_ip, pdu_username,
666 pdu_password, pdu_slot_no, openbmc_serial_host,
667 openbmc_serial_host_name, openbmc_serial_ip, openbmc_serial_port)
Michael Walsh68a61162017-04-25 11:54:06 -0500668
669 gp.qprintn()
670
671 print_last_boots()
672 gp.qprintn()
673 gp.qprint_var(state)
674
Michael Walshb5839d02017-04-12 16:11:20 -0500675 gp.qprintn()
676 gp.qprintn("FFDC data files:")
Michael Walsh341c21e2017-01-17 16:25:20 -0600677 if status_file_path != "":
Michael Walshb5839d02017-04-12 16:11:20 -0500678 gp.qprintn(status_file_path)
Michael Walsh68a61162017-04-25 11:54:06 -0500679 ffdc_list_file.write(status_file_path + "\n")
Michael Walsh341c21e2017-01-17 16:25:20 -0600680
Michael Walshb5839d02017-04-12 16:11:20 -0500681 gp.qprintn(output)
682 # gp.qprintn(ffdc_list)
683 gp.qprintn()
Michael Walsh341c21e2017-01-17 16:25:20 -0600684
Michael Walsh600876d2017-05-30 17:58:58 -0500685 if len(ffdc_summary_info) > 0:
Michael Walshff340002017-08-29 11:18:27 -0500686 gp.qprintn(ffdc_summary_info)
Michael Walsh600876d2017-05-30 17:58:58 -0500687
Michael Walshb5839d02017-04-12 16:11:20 -0500688 gp.qprint_dashes(0, 90, 1, "=")
Michael Walsh341c21e2017-01-17 16:25:20 -0600689
Michael Walsh68a61162017-04-25 11:54:06 -0500690 ffdc_list_file.write(output + "\n")
691 ffdc_list_file.close()
692
Michael Walsh341c21e2017-01-17 16:25:20 -0600693###############################################################################
Michael Walsh6741f742017-02-20 16:16:38 -0600694
695
696###############################################################################
697def my_ffdc():
698
699 r"""
700 Collect FFDC data.
701 """
702
703 global state
704
705 plug_in_setup()
706 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500707 call_point='ffdc', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600708
709 AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX']
Michael Walsh83f4bc72017-04-20 16:49:43 -0500710 status, ret_values = grk.run_key_u("FFDC ffdc_prefix=" +
711 AUTOBOOT_FFDC_PREFIX +
712 " ffdc_function_list=" +
713 ffdc_function_list, ignore=1)
714 if status != 'PASS':
Michael Walshff340002017-08-29 11:18:27 -0500715 gp.qprint_error("Call to ffdc failed.\n")
Michael Walsh6741f742017-02-20 16:16:38 -0600716
717 my_get_state()
718
719 print_defect_report()
720
721###############################################################################
722
723
724###############################################################################
725def print_test_start_message(boot_keyword):
726
727 r"""
728 Print a message indicating what boot test is about to run.
729
730 Description of arguments:
731 boot_keyword The name of the boot which is to be run
732 (e.g. "BMC Power On").
733 """
734
735 global last_ten
Sunil M325eb542017-08-10 07:09:43 -0500736 global boot_start_time
Michael Walsh6741f742017-02-20 16:16:38 -0600737
738 doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".")
Sunil M325eb542017-08-10 07:09:43 -0500739
740 # Set boot_start_time for use by plug-ins.
741 boot_start_time = doing_msg[1:33]
742 gp.qprint_var(boot_start_time)
743
Michael Walshb5839d02017-04-12 16:11:20 -0500744 gp.qprint(doing_msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600745
746 last_ten.append(doing_msg)
747
748 if len(last_ten) > 10:
749 del last_ten[0]
750
751###############################################################################
752
753
754###############################################################################
755def run_boot(boot):
756
757 r"""
758 Run the specified boot.
759
760 Description of arguments:
761 boot The name of the boot test to be performed.
762 """
763
764 global state
765
766 print_test_start_message(boot)
767
768 plug_in_setup()
769 rc, shell_rc, failed_plug_in_name = \
770 grpi.rprocess_plug_in_packages(call_point="pre_boot")
771 if rc != 0:
772 error_message = "Plug-in failed with non-zero return code.\n" +\
773 gp.sprint_var(rc, 1)
774 BuiltIn().fail(gp.sprint_error(error_message))
775
776 if test_mode:
777 # In test mode, we'll pretend the boot worked by assigning its
778 # required end state to the default state value.
Michael Walsh30dadae2017-02-27 14:25:52 -0600779 state = st.strip_anchor_state(boot_table[boot]['end'])
Michael Walsh6741f742017-02-20 16:16:38 -0600780 else:
781 # Assertion: We trust that the state data was made fresh by the
782 # caller.
783
Michael Walshb5839d02017-04-12 16:11:20 -0500784 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600785
786 if boot_table[boot]['method_type'] == "keyword":
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600787 rk.my_run_keywords(boot_table[boot].get('lib_file_path', ''),
Michael Walshb5839d02017-04-12 16:11:20 -0500788 boot_table[boot]['method'],
789 quiet=quiet)
Michael Walsh6741f742017-02-20 16:16:38 -0600790
791 if boot_table[boot]['bmc_reboot']:
792 st.wait_for_comm_cycle(int(state['epoch_seconds']))
Michael Walsh30dadae2017-02-27 14:25:52 -0600793 plug_in_setup()
794 rc, shell_rc, failed_plug_in_name = \
795 grpi.rprocess_plug_in_packages(call_point="post_reboot")
796 if rc != 0:
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600797 error_message = "Plug-in failed with non-zero return code.\n"
798 error_message += gp.sprint_var(rc, 1)
Michael Walsh30dadae2017-02-27 14:25:52 -0600799 BuiltIn().fail(gp.sprint_error(error_message))
Michael Walsh6741f742017-02-20 16:16:38 -0600800 else:
801 match_state = st.anchor_state(state)
802 del match_state['epoch_seconds']
803 # Wait for the state to change in any way.
804 st.wait_state(match_state, wait_time=state_change_timeout,
Michael Walsh600876d2017-05-30 17:58:58 -0500805 interval="10 seconds", invert=1)
Michael Walsh6741f742017-02-20 16:16:38 -0600806
Michael Walshb5839d02017-04-12 16:11:20 -0500807 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600808 if boot_table[boot]['end']['chassis'] == "Off":
809 boot_timeout = power_off_timeout
810 else:
811 boot_timeout = power_on_timeout
812 st.wait_state(boot_table[boot]['end'], wait_time=boot_timeout,
Michael Walsh600876d2017-05-30 17:58:58 -0500813 interval="10 seconds")
Michael Walsh6741f742017-02-20 16:16:38 -0600814
815 plug_in_setup()
816 rc, shell_rc, failed_plug_in_name = \
817 grpi.rprocess_plug_in_packages(call_point="post_boot")
818 if rc != 0:
819 error_message = "Plug-in failed with non-zero return code.\n" +\
820 gp.sprint_var(rc, 1)
821 BuiltIn().fail(gp.sprint_error(error_message))
822
823###############################################################################
824
825
826###############################################################################
827def test_loop_body():
828
829 r"""
830 The main loop body for the loop in main_py.
831
832 Description of arguments:
833 boot_count The iteration number (starts at 1).
834 """
835
836 global boot_count
837 global state
838 global next_boot
839 global boot_success
Sunil M325eb542017-08-10 07:09:43 -0500840 global boot_end_time
Michael Walsh6741f742017-02-20 16:16:38 -0600841
Michael Walshb5839d02017-04-12 16:11:20 -0500842 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600843
844 next_boot = select_boot()
Michael Walshb5839d02017-04-12 16:11:20 -0500845 if next_boot == "":
846 return True
Michael Walsh6741f742017-02-20 16:16:38 -0600847
Michael Walshb5839d02017-04-12 16:11:20 -0500848 boot_count += 1
849 gp.qprint_timen("Starting boot " + str(boot_count) + ".")
Michael Walsh6741f742017-02-20 16:16:38 -0600850
Michael Walshe0cf8d72017-05-17 13:20:46 -0500851 pre_boot_plug_in_setup()
Michael Walsh6741f742017-02-20 16:16:38 -0600852
853 cmd_buf = ["run_boot", next_boot]
854 boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
855 if boot_status == "FAIL":
Michael Walshb5839d02017-04-12 16:11:20 -0500856 gp.qprint(msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600857
Michael Walshb5839d02017-04-12 16:11:20 -0500858 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600859 if boot_status == "PASS":
860 boot_success = 1
Michael Walshff340002017-08-29 11:18:27 -0500861 completion_msg = gp.sprint_timen("BOOT_SUCCESS: \"" + next_boot +
862 "\" succeeded.")
Michael Walsh6741f742017-02-20 16:16:38 -0600863 else:
864 boot_success = 0
Michael Walshff340002017-08-29 11:18:27 -0500865 completion_msg = gp.sprint_timen("BOOT_FAILED: \"" + next_boot +
866 "\" failed.")
Sunil M325eb542017-08-10 07:09:43 -0500867
868 # Set boot_end_time for use by plug-ins.
869 boot_end_time = completion_msg[1:33]
870 gp.qprint_var(boot_end_time)
871
872 gp.qprint(completion_msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600873
874 boot_results.update(next_boot, boot_status)
875
876 plug_in_setup()
877 # NOTE: A post_test_case call point failure is NOT counted as a boot
878 # failure.
879 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500880 call_point='post_test_case', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600881
882 plug_in_setup()
883 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
884 call_point='ffdc_check', shell_rc=0x00000200,
885 stop_on_plug_in_failure=1, stop_on_non_zero_rc=1)
886 if boot_status != "PASS" or ffdc_check == "All" or shell_rc == 0x00000200:
Michael Walsh83f4bc72017-04-20 16:49:43 -0500887 status, ret_values = grk.run_key_u("my_ffdc", ignore=1)
888 if status != 'PASS':
Michael Walshff340002017-08-29 11:18:27 -0500889 gp.qprint_error("Call to my_ffdc failed.\n")
Michael Walsh6741f742017-02-20 16:16:38 -0600890
Michael Walshaabef1e2017-09-20 15:16:17 -0500891 if delete_errlogs:
892 # We need to purge error logs between boots or they build up.
893 grk.run_key("Delete Error logs", ignore=1)
Michael Walshd139f282017-04-04 18:00:23 -0500894
Michael Walsh952f9b02017-03-09 13:11:14 -0600895 boot_results.print_report()
Michael Walshb5839d02017-04-12 16:11:20 -0500896 gp.qprint_timen("Finished boot " + str(boot_count) + ".")
Michael Walsh952f9b02017-03-09 13:11:14 -0600897
Michael Walsh6741f742017-02-20 16:16:38 -0600898 plug_in_setup()
899 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
900 call_point='stop_check')
901 if rc != 0:
902 error_message = "Stopping as requested by user.\n"
903 grp.rprint_error_report(error_message)
904 BuiltIn().fail(error_message)
905
Michael Walshd139f282017-04-04 18:00:23 -0500906 # This should help prevent ConnectionErrors.
Michael Walsh0960b382017-06-22 16:23:37 -0500907 grk.run_key_u("Close All Connections")
Michael Walshd139f282017-04-04 18:00:23 -0500908
Michael Walsh6741f742017-02-20 16:16:38 -0600909 return True
910
911###############################################################################
912
913
914###############################################################################
Michael Walsh83f4bc72017-04-20 16:49:43 -0500915def obmc_boot_test_teardown():
Michael Walsh6741f742017-02-20 16:16:38 -0600916
917 r"""
Michael Walshc9116812017-03-10 14:23:06 -0600918 Clean up after the Main keyword.
Michael Walsh6741f742017-02-20 16:16:38 -0600919 """
920
921 if cp_setup_called:
922 plug_in_setup()
923 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500924 call_point='cleanup', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600925
Michael Walsh600876d2017-05-30 17:58:58 -0500926 if 'boot_results_file_path' in globals():
927 # Save boot_results object to a file in case it is needed again.
928 gp.qprint_timen("Saving boot_results to the following path.")
929 gp.qprint_var(boot_results_file_path)
930 pickle.dump(boot_results, open(boot_results_file_path, 'wb'),
931 pickle.HIGHEST_PROTOCOL)
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600932
Michael Walshff340002017-08-29 11:18:27 -0500933 global save_stack
934 # Restore any global values saved on the save_stack.
935 for parm_name in main_func_parm_list:
936 # Get the parm_value if it was saved on the stack.
937 try:
938 parm_value = save_stack.pop(parm_name)
939 except:
940 # If it was not saved, no further action is required.
941 continue
942
943 # Restore the saved value.
944 cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
945 "}\", parm_value)"
946 gp.dpissuing(cmd_buf)
947 exec(cmd_buf)
948
949 gp.dprintn(save_stack.sprint_obj())
950
Michael Walsh6741f742017-02-20 16:16:38 -0600951###############################################################################
952
953
954###############################################################################
Michael Walshc9116812017-03-10 14:23:06 -0600955def test_teardown():
956
957 r"""
958 Clean up after this test case.
959 """
960
961 gp.qprintn()
962 cmd_buf = ["Print Error",
963 "A keyword timeout occurred ending this program.\n"]
964 BuiltIn().run_keyword_if_timeout_occurred(*cmd_buf)
965
Michael Walshb5839d02017-04-12 16:11:20 -0500966 grp.rqprint_pgm_footer()
967
Michael Walshc9116812017-03-10 14:23:06 -0600968###############################################################################
969
970
971###############################################################################
Michael Walshff340002017-08-29 11:18:27 -0500972def obmc_boot_test_py(loc_boot_stack=None,
973 loc_stack_mode=None,
974 loc_quiet=None):
Michael Walsh6741f742017-02-20 16:16:38 -0600975
976 r"""
977 Do main program processing.
978 """
979
Michael Walshff340002017-08-29 11:18:27 -0500980 global save_stack
981
982 # Process function parms.
983 for parm_name in main_func_parm_list:
984 # Get parm's value.
985 cmd_buf = "parm_value = loc_" + parm_name
986 exec(cmd_buf)
987 gp.dpvar(parm_name)
988 gp.dpvar(parm_value)
989
990 if parm_value is None:
991 # Parm was not specified by the calling function so set it to its
992 # corresponding global value.
993 cmd_buf = "loc_" + parm_name + " = BuiltIn().get_variable_value" +\
994 "(\"${" + parm_name + "}\")"
995 gp.dpissuing(cmd_buf)
996 exec(cmd_buf)
997 else:
998 # Save the global value on a stack.
999 cmd_buf = "save_stack.push(BuiltIn().get_variable_value(\"${" +\
1000 parm_name + "}\"), \"" + parm_name + "\")"
1001 gp.dpissuing(cmd_buf)
1002 exec(cmd_buf)
1003
1004 # Set the global value to the passed value.
1005 cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
1006 "}\", loc_" + parm_name + ")"
1007 gp.dpissuing(cmd_buf)
1008 exec(cmd_buf)
1009
1010 gp.dprintn(save_stack.sprint_obj())
Michael Walshb5839d02017-04-12 16:11:20 -05001011
Michael Walsh6741f742017-02-20 16:16:38 -06001012 setup()
1013
Michael Walshcd9fbfd2017-09-19 12:00:08 -05001014 init_boot_pass, init_boot_fail = boot_results.return_total_pass_fail()
1015
Michael Walsha20da402017-03-31 16:27:45 -05001016 if ffdc_only:
1017 gp.qprint_timen("Caller requested ffdc_only.")
Michael Walshe0cf8d72017-05-17 13:20:46 -05001018 pre_boot_plug_in_setup()
Michael Walsh83f4bc72017-04-20 16:49:43 -05001019 grk.run_key_u("my_ffdc")
Michael Walsh764d2f82017-04-27 16:01:08 -05001020 return
Michael Walsha20da402017-03-31 16:27:45 -05001021
Michael Walsh6741f742017-02-20 16:16:38 -06001022 # Process caller's boot_stack.
1023 while (len(boot_stack) > 0):
1024 test_loop_body()
1025
Michael Walshb5839d02017-04-12 16:11:20 -05001026 gp.qprint_timen("Finished processing stack.")
Michael Walsh30dadae2017-02-27 14:25:52 -06001027
Michael Walsh6741f742017-02-20 16:16:38 -06001028 # Process caller's boot_list.
1029 if len(boot_list) > 0:
1030 for ix in range(1, max_num_tests + 1):
1031 test_loop_body()
1032
Michael Walshb5839d02017-04-12 16:11:20 -05001033 gp.qprint_timen("Completed all requested boot tests.")
1034
1035 boot_pass, boot_fail = boot_results.return_total_pass_fail()
Michael Walshcd9fbfd2017-09-19 12:00:08 -05001036 new_fail = boot_fail - init_boot_fail
1037 if new_fail > boot_fail_threshold:
Michael Walshb5839d02017-04-12 16:11:20 -05001038 error_message = "Boot failures exceed the boot failure" +\
1039 " threshold:\n" +\
Michael Walshcd9fbfd2017-09-19 12:00:08 -05001040 gp.sprint_var(new_fail) +\
Michael Walshb5839d02017-04-12 16:11:20 -05001041 gp.sprint_var(boot_fail_threshold)
1042 BuiltIn().fail(gp.sprint_error(error_message))
Michael Walsh6741f742017-02-20 16:16:38 -06001043
1044###############################################################################