blob: 4ee66d1ab41758bb85e23a7d12e0be8e61095cf9 [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)
40
Michael Walshb5839d02017-04-12 16:11:20 -050041# Set up boot data structures.
42boot_table = create_boot_table()
43valid_boot_types = create_valid_boot_list(boot_table)
Michael Walsh0b93fbf2017-03-02 14:42:41 -060044
Michael Walsh6741f742017-02-20 16:16:38 -060045boot_lists = read_boot_lists()
46last_ten = []
Michael Walsh6741f742017-02-20 16:16:38 -060047
48state = st.return_default_state()
49cp_setup_called = 0
50next_boot = ""
51base_tool_dir_path = os.path.normpath(os.environ.get(
52 'AUTOBOOT_BASE_TOOL_DIR_PATH', "/tmp")) + os.sep
Michael Walshb5839d02017-04-12 16:11:20 -050053
Michael Walsh6741f742017-02-20 16:16:38 -060054ffdc_dir_path = os.path.normpath(os.environ.get('FFDC_DIR_PATH', '')) + os.sep
Michael Walsh6741f742017-02-20 16:16:38 -060055boot_success = 0
Michael Walsh6741f742017-02-20 16:16:38 -060056status_dir_path = os.environ.get('STATUS_DIR_PATH', "")
57if status_dir_path != "":
58 status_dir_path = os.path.normpath(status_dir_path) + os.sep
Michael Walsh0b93fbf2017-03-02 14:42:41 -060059default_power_on = "REST Power On"
60default_power_off = "REST Power Off"
Michael Walsh6741f742017-02-20 16:16:38 -060061boot_count = 0
Michael Walsh0bbd8602016-11-22 11:31:49 -060062
Michael Walsh85678942017-03-27 14:34:22 -050063LOG_LEVEL = BuiltIn().get_variable_value("${LOG_LEVEL}")
Michael Walshe1974b92017-08-03 13:39:51 -050064ffdc_prefix = ""
Sunil M325eb542017-08-10 07:09:43 -050065boot_start_time = ""
66boot_end_time = ""
Michael Walshff340002017-08-29 11:18:27 -050067save_stack = vs.var_stack('save_stack')
68main_func_parm_list = ['boot_stack', 'stack_mode', 'quiet']
Michael Walsh85678942017-03-27 14:34:22 -050069
70
71###############################################################################
Michael Walsh0ad0f7f2017-05-04 14:39:58 -050072def process_host(host,
73 host_var_name=""):
74
75 r"""
76 Process a host by getting the associated host name and IP address and
77 setting them in global variables.
78
79 If the caller does not pass the host_var_name, this function will try to
80 figure out the name of the variable used by the caller for the host parm.
81 Callers are advised to explicitly specify the host_var_name when calling
82 with an exec command. In such cases, the get_arg_name cannot figure out
83 the host variable name.
84
85 This function will then create similar global variable names by
86 removing "_host" and appending "_host_name" or "_ip" to the host variable
87 name.
88
89 Example:
90
91 If a call is made like this:
92 process_host(openbmc_host)
93
94 Global variables openbmc_host_name and openbmc_ip will be set.
95
96 Description of argument(s):
97 host A host name or IP. The name of the variable used should
98 have a suffix of "_host".
99 host_var_name The name of the variable being used as the host parm.
100 """
101
102 if host_var_name == "":
103 host_var_name = gp.get_arg_name(0, 1, stack_frame_ix=2)
104
105 host_name_var_name = re.sub("host", "host_name", host_var_name)
106 ip_var_name = re.sub("host", "ip", host_var_name)
107 cmd_buf = "global " + host_name_var_name + ", " + ip_var_name + " ; " +\
108 host_name_var_name + ", " + ip_var_name + " = gm.get_host_name_ip('" +\
109 host + "')"
110 exec(cmd_buf)
111
112###############################################################################
113
114
115###############################################################################
Michael Walshb5839d02017-04-12 16:11:20 -0500116def process_pgm_parms():
117
118 r"""
119 Process the program parameters by assigning them all to corresponding
120 globals. Also, set some global values that depend on program parameters.
121 """
122
123 # Program parameter processing.
124 # Assign all program parms to python variables which are global to this
125 # module.
126
127 global parm_list
128 parm_list = BuiltIn().get_variable_value("${parm_list}")
129 # The following subset of parms should be processed as integers.
130 int_list = ['max_num_tests', 'boot_pass', 'boot_fail', 'ffdc_only',
131 'boot_fail_threshold', 'quiet', 'test_mode', 'debug']
132 for parm in parm_list:
133 if parm in int_list:
134 sub_cmd = "int(BuiltIn().get_variable_value(\"${" + parm +\
135 "}\", \"0\"))"
136 else:
137 sub_cmd = "BuiltIn().get_variable_value(\"${" + parm + "}\")"
138 cmd_buf = "global " + parm + " ; " + parm + " = " + sub_cmd
Michael Walshff340002017-08-29 11:18:27 -0500139 gp.dpissuing(cmd_buf)
Michael Walshb5839d02017-04-12 16:11:20 -0500140 exec(cmd_buf)
Michael Walsh0ad0f7f2017-05-04 14:39:58 -0500141 if re.match(r".*_host$", parm):
142 cmd_buf = "process_host(" + parm + ", '" + parm + "')"
143 exec(cmd_buf)
144 if re.match(r".*_password$", parm):
145 # Register the value of any parm whose name ends in _password.
146 # This will cause the print functions to replace passwords with
147 # asterisks in the output.
148 cmd_buf = "gp.register_passwords(" + parm + ")"
149 exec(cmd_buf)
Michael Walshb5839d02017-04-12 16:11:20 -0500150
151 global ffdc_dir_path_style
152 global boot_list
153 global boot_stack
154 global boot_results_file_path
155 global boot_results
156 global ffdc_list_file_path
Michael Walshe0cf8d72017-05-17 13:20:46 -0500157 global ffdc_report_list_path
Michael Walsh600876d2017-05-30 17:58:58 -0500158 global ffdc_summary_list_path
Michael Walshb5839d02017-04-12 16:11:20 -0500159
160 if ffdc_dir_path_style == "":
161 ffdc_dir_path_style = int(os.environ.get('FFDC_DIR_PATH_STYLE', '0'))
162
163 # Convert these program parms to lists for easier processing..
164 boot_list = filter(None, boot_list.split(":"))
165 boot_stack = filter(None, boot_stack.split(":"))
166
167 boot_results_file_path = "/tmp/" + openbmc_nickname + ":pid_" +\
168 str(master_pid) + ":boot_results"
169
170 if os.path.isfile(boot_results_file_path):
171 # We've been called before in this run so we'll load the saved
172 # boot_results object.
173 boot_results = pickle.load(open(boot_results_file_path, 'rb'))
174 else:
175 boot_results = boot_results(boot_table, boot_pass, boot_fail)
176
177 ffdc_list_file_path = base_tool_dir_path + openbmc_nickname +\
178 "/FFDC_FILE_LIST"
Michael Walshe0cf8d72017-05-17 13:20:46 -0500179 ffdc_report_list_path = base_tool_dir_path + openbmc_nickname +\
180 "/FFDC_REPORT_FILE_LIST"
Michael Walshb5839d02017-04-12 16:11:20 -0500181
Michael Walsh600876d2017-05-30 17:58:58 -0500182 ffdc_summary_list_path = base_tool_dir_path + openbmc_nickname +\
183 "/FFDC_SUMMARY_FILE_LIST"
184
Michael Walshb5839d02017-04-12 16:11:20 -0500185###############################################################################
186
187
188###############################################################################
Michael Walsh85678942017-03-27 14:34:22 -0500189def initial_plug_in_setup():
190
191 r"""
192 Initialize all plug-in environment variables which do not change for the
193 duration of the program.
194
195 """
196
197 global LOG_LEVEL
198 BuiltIn().set_log_level("NONE")
199
200 BuiltIn().set_global_variable("${master_pid}", master_pid)
201 BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path)
202 BuiltIn().set_global_variable("${STATUS_DIR_PATH}", status_dir_path)
203 BuiltIn().set_global_variable("${BASE_TOOL_DIR_PATH}", base_tool_dir_path)
204 BuiltIn().set_global_variable("${FFDC_LIST_FILE_PATH}",
205 ffdc_list_file_path)
Michael Walshe0cf8d72017-05-17 13:20:46 -0500206 BuiltIn().set_global_variable("${FFDC_REPORT_LIST_PATH}",
207 ffdc_report_list_path)
Michael Walsh600876d2017-05-30 17:58:58 -0500208 BuiltIn().set_global_variable("${FFDC_SUMMARY_LIST_PATH}",
209 ffdc_summary_list_path)
Michael Walsh85678942017-03-27 14:34:22 -0500210
211 BuiltIn().set_global_variable("${FFDC_DIR_PATH_STYLE}",
212 ffdc_dir_path_style)
213 BuiltIn().set_global_variable("${FFDC_CHECK}",
214 ffdc_check)
215
216 # For each program parameter, set the corresponding AUTOBOOT_ environment
217 # variable value. Also, set an AUTOBOOT_ environment variable for every
218 # element in additional_values.
219 additional_values = ["program_pid", "master_pid", "ffdc_dir_path",
220 "status_dir_path", "base_tool_dir_path",
Michael Walsh600876d2017-05-30 17:58:58 -0500221 "ffdc_list_file_path", "ffdc_report_list_path",
222 "ffdc_summary_list_path"]
Michael Walsh85678942017-03-27 14:34:22 -0500223
224 plug_in_vars = parm_list + additional_values
225
226 for var_name in plug_in_vars:
227 var_value = BuiltIn().get_variable_value("${" + var_name + "}")
228 var_name = var_name.upper()
229 if var_value is None:
230 var_value = ""
231 os.environ["AUTOBOOT_" + var_name] = str(var_value)
232
233 BuiltIn().set_log_level(LOG_LEVEL)
234
Michael Walsh68a61162017-04-25 11:54:06 -0500235 # Make sure the ffdc list directory exists.
236 ffdc_list_dir_path = os.path.dirname(ffdc_list_file_path) + os.sep
237 if not os.path.exists(ffdc_list_dir_path):
238 os.makedirs(ffdc_list_dir_path)
Michael Walsh85678942017-03-27 14:34:22 -0500239
240###############################################################################
241
Michael Walsh0bbd8602016-11-22 11:31:49 -0600242
243###############################################################################
Michael Walsh0bbd8602016-11-22 11:31:49 -0600244def plug_in_setup():
245
246 r"""
Michael Walsh85678942017-03-27 14:34:22 -0500247 Initialize all changing plug-in environment variables for use by the
248 plug-in programs.
Michael Walsh0bbd8602016-11-22 11:31:49 -0600249 """
250
Michael Walsh85678942017-03-27 14:34:22 -0500251 global LOG_LEVEL
252 global test_really_running
253
254 BuiltIn().set_log_level("NONE")
255
Michael Walsh6741f742017-02-20 16:16:38 -0600256 boot_pass, boot_fail = boot_results.return_total_pass_fail()
Michael Walsh0bbd8602016-11-22 11:31:49 -0600257 if boot_pass > 1:
258 test_really_running = 1
259 else:
260 test_really_running = 0
261
Michael Walsh6741f742017-02-20 16:16:38 -0600262 BuiltIn().set_global_variable("${test_really_running}",
263 test_really_running)
264 BuiltIn().set_global_variable("${boot_type_desc}", next_boot)
Michael Walsh6741f742017-02-20 16:16:38 -0600265 BuiltIn().set_global_variable("${boot_pass}", boot_pass)
266 BuiltIn().set_global_variable("${boot_fail}", boot_fail)
267 BuiltIn().set_global_variable("${boot_success}", boot_success)
268 BuiltIn().set_global_variable("${ffdc_prefix}", ffdc_prefix)
Sunil M325eb542017-08-10 07:09:43 -0500269 BuiltIn().set_global_variable("${boot_start_time}", boot_start_time)
270 BuiltIn().set_global_variable("${boot_end_time}", boot_end_time)
Michael Walsh4c9a6452016-12-13 16:03:11 -0600271
Michael Walsh0bbd8602016-11-22 11:31:49 -0600272 # For each program parameter, set the corresponding AUTOBOOT_ environment
273 # variable value. Also, set an AUTOBOOT_ environment variable for every
274 # element in additional_values.
275 additional_values = ["boot_type_desc", "boot_success", "boot_pass",
Sunil M325eb542017-08-10 07:09:43 -0500276 "boot_fail", "test_really_running", "ffdc_prefix",
277 "boot_start_time", "boot_end_time"]
Michael Walsh0bbd8602016-11-22 11:31:49 -0600278
Michael Walsh85678942017-03-27 14:34:22 -0500279 plug_in_vars = additional_values
Michael Walsh0bbd8602016-11-22 11:31:49 -0600280
281 for var_name in plug_in_vars:
282 var_value = BuiltIn().get_variable_value("${" + var_name + "}")
283 var_name = var_name.upper()
284 if var_value is None:
285 var_value = ""
Michael Walsh6741f742017-02-20 16:16:38 -0600286 os.environ["AUTOBOOT_" + var_name] = str(var_value)
Michael Walsh0bbd8602016-11-22 11:31:49 -0600287
Michael Walsh0bbd8602016-11-22 11:31:49 -0600288 if debug:
Michael Walsh6741f742017-02-20 16:16:38 -0600289 shell_rc, out_buf = \
290 gc.cmd_fnc_u("printenv | egrep AUTOBOOT_ | sort -u")
Michael Walsh0bbd8602016-11-22 11:31:49 -0600291
Michael Walsh85678942017-03-27 14:34:22 -0500292 BuiltIn().set_log_level(LOG_LEVEL)
293
Michael Walsh0bbd8602016-11-22 11:31:49 -0600294###############################################################################
295
296
297###############################################################################
Michael Walshe0cf8d72017-05-17 13:20:46 -0500298def pre_boot_plug_in_setup():
299
300 # Clear the ffdc_list_file_path file. Plug-ins may now write to it.
301 try:
302 os.remove(ffdc_list_file_path)
303 except OSError:
304 pass
305
306 # Clear the ffdc_report_list_path file. Plug-ins may now write to it.
307 try:
308 os.remove(ffdc_report_list_path)
309 except OSError:
310 pass
311
Michael Walsh600876d2017-05-30 17:58:58 -0500312 # Clear the ffdc_summary_list_path file. Plug-ins may now write to it.
313 try:
314 os.remove(ffdc_summary_list_path)
315 except OSError:
316 pass
317
Michael Walshe1974b92017-08-03 13:39:51 -0500318 global ffdc_prefix
319
320 seconds = time.time()
321 loc_time = time.localtime(seconds)
322 time_string = time.strftime("%y%m%d.%H%M%S.", loc_time)
323
324 ffdc_prefix = openbmc_nickname + "." + time_string
325
Michael Walshe0cf8d72017-05-17 13:20:46 -0500326###############################################################################
327
328
329###############################################################################
Michael Walsh6741f742017-02-20 16:16:38 -0600330def setup():
Michael Walsh0bbd8602016-11-22 11:31:49 -0600331
332 r"""
Michael Walsh6741f742017-02-20 16:16:38 -0600333 Do general program setup tasks.
Michael Walsh0bbd8602016-11-22 11:31:49 -0600334 """
335
Michael Walsh6741f742017-02-20 16:16:38 -0600336 global cp_setup_called
Michael Walsh0bbd8602016-11-22 11:31:49 -0600337
Michael Walshb5839d02017-04-12 16:11:20 -0500338 gp.qprintn()
339
Michael Walsh83f4bc72017-04-20 16:49:43 -0500340 robot_pgm_dir_path = os.path.dirname(__file__) + os.sep
341 repo_bin_path = robot_pgm_dir_path.replace("/lib/", "/bin/")
Michael Walshd061c042017-05-23 14:46:57 -0500342 # If we can't find process_plug_in_packages.py, ssh_pw or
343 # validate_plug_ins.py, then we don't have our repo bin in PATH.
344 shell_rc, out_buf = gc.cmd_fnc_u("which process_plug_in_packages.py" +
345 " ssh_pw validate_plug_ins.py", quiet=1,
346 print_output=0, show_err=0)
Michael Walshb5839d02017-04-12 16:11:20 -0500347 if shell_rc != 0:
Michael Walsh83f4bc72017-04-20 16:49:43 -0500348 os.environ['PATH'] = repo_bin_path + ":" + os.environ.get('PATH', "")
349 # Likewise, our repo lib subdir needs to be in sys.path and PYTHONPATH.
350 if robot_pgm_dir_path not in sys.path:
351 sys.path.append(robot_pgm_dir_path)
352 PYTHONPATH = os.environ.get("PYTHONPATH", "")
353 if PYTHONPATH == "":
354 os.environ['PYTHONPATH'] = robot_pgm_dir_path
355 else:
356 os.environ['PYTHONPATH'] = robot_pgm_dir_path + ":" + PYTHONPATH
Michael Walsh6741f742017-02-20 16:16:38 -0600357
358 validate_parms()
359
360 grp.rqprint_pgm_header()
361
Michael Walshfdc5ced2017-08-17 13:15:15 -0500362 grk.run_key("Set BMC Power Policy RESTORE_LAST_STATE")
Michael Walsh11cfc8c2017-03-31 09:40:55 -0500363
Michael Walsh85678942017-03-27 14:34:22 -0500364 initial_plug_in_setup()
365
Michael Walsh6741f742017-02-20 16:16:38 -0600366 plug_in_setup()
367 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
368 call_point='setup')
369 if rc != 0:
370 error_message = "Plug-in setup failed.\n"
371 grp.rprint_error_report(error_message)
372 BuiltIn().fail(error_message)
373 # Setting cp_setup_called lets our Teardown know that it needs to call
374 # the cleanup plug-in call point.
375 cp_setup_called = 1
376
377 # Keyword "FFDC" will fail if TEST_MESSAGE is not set.
378 BuiltIn().set_global_variable("${TEST_MESSAGE}", "${EMPTY}")
Michael Walsh85678942017-03-27 14:34:22 -0500379 # FFDC_LOG_PATH is used by "FFDC" keyword.
380 BuiltIn().set_global_variable("${FFDC_LOG_PATH}", ffdc_dir_path)
Michael Walsh6741f742017-02-20 16:16:38 -0600381
Michael Walshdc80d672017-05-09 12:58:32 -0500382 # Also printed by FFDC.
383 global host_name
384 global host_ip
385 host = socket.gethostname()
386 host_name, host_ip = gm.get_host_name_ip(host)
387
Michael Walshb5839d02017-04-12 16:11:20 -0500388 gp.dprint_var(boot_table, 1)
389 gp.dprint_var(boot_lists)
Michael Walsh0bbd8602016-11-22 11:31:49 -0600390
391###############################################################################
392
393
394###############################################################################
Michael Walsh6741f742017-02-20 16:16:38 -0600395def validate_parms():
Michael Walsh0bbd8602016-11-22 11:31:49 -0600396
397 r"""
Michael Walsh6741f742017-02-20 16:16:38 -0600398 Validate all program parameters.
Michael Walsh0bbd8602016-11-22 11:31:49 -0600399 """
400
Michael Walshb5839d02017-04-12 16:11:20 -0500401 process_pgm_parms()
Michael Walsh0bbd8602016-11-22 11:31:49 -0600402
Michael Walshb5839d02017-04-12 16:11:20 -0500403 gp.qprintn()
404
405 global openbmc_model
Michael Walsh6741f742017-02-20 16:16:38 -0600406 grv.rvalid_value("openbmc_host")
407 grv.rvalid_value("openbmc_username")
408 grv.rvalid_value("openbmc_password")
409 if os_host != "":
410 grv.rvalid_value("os_username")
411 grv.rvalid_value("os_password")
Michael Walsh0bbd8602016-11-22 11:31:49 -0600412
Michael Walsh6741f742017-02-20 16:16:38 -0600413 if pdu_host != "":
414 grv.rvalid_value("pdu_username")
415 grv.rvalid_value("pdu_password")
Michael Walsh85678942017-03-27 14:34:22 -0500416 grv.rvalid_integer("pdu_slot_no")
Michael Walsh6741f742017-02-20 16:16:38 -0600417 if openbmc_serial_host != "":
418 grv.rvalid_integer("openbmc_serial_port")
Michael Walshb5839d02017-04-12 16:11:20 -0500419 if openbmc_model == "":
420 status, ret_values =\
421 grk.run_key_u("Get BMC System Model")
422 openbmc_model = ret_values
423 BuiltIn().set_global_variable("${openbmc_model}", openbmc_model)
Michael Walsh6741f742017-02-20 16:16:38 -0600424 grv.rvalid_value("openbmc_model")
Michael Walshb5839d02017-04-12 16:11:20 -0500425 grv.rvalid_integer("max_num_tests")
Michael Walsh6741f742017-02-20 16:16:38 -0600426 grv.rvalid_integer("boot_pass")
427 grv.rvalid_integer("boot_fail")
428
429 plug_in_packages_list = grpi.rvalidate_plug_ins(plug_in_dir_paths)
430 BuiltIn().set_global_variable("${plug_in_packages_list}",
431 plug_in_packages_list)
432
Michael Walshb5839d02017-04-12 16:11:20 -0500433 grv.rvalid_value("stack_mode", valid_values=['normal', 'skip'])
Michael Walsha20da402017-03-31 16:27:45 -0500434 if len(boot_list) == 0 and len(boot_stack) == 0 and not ffdc_only:
Michael Walsh6741f742017-02-20 16:16:38 -0600435 error_message = "You must provide either a value for either the" +\
436 " boot_list or the boot_stack parm.\n"
437 BuiltIn().fail(gp.sprint_error(error_message))
438
439 valid_boot_list(boot_list, valid_boot_types)
440 valid_boot_list(boot_stack, valid_boot_types)
441
Michael Walsh11cfc8c2017-03-31 09:40:55 -0500442 selected_PDU_boots = list(set(boot_list + boot_stack) &
443 set(boot_lists['PDU_reboot']))
444
445 if len(selected_PDU_boots) > 0 and pdu_host == "":
446 error_message = "You have selected the following boots which" +\
447 " require a PDU host but no value for pdu_host:\n"
448 error_message += gp.sprint_var(selected_PDU_boots)
449 error_message += gp.sprint_var(pdu_host, 2)
450 BuiltIn().fail(gp.sprint_error(error_message))
451
Michael Walsh6741f742017-02-20 16:16:38 -0600452 return
Michael Walsh0bbd8602016-11-22 11:31:49 -0600453
454###############################################################################
455
456
457###############################################################################
Michael Walsh6741f742017-02-20 16:16:38 -0600458def my_get_state():
Michael Walsh0bbd8602016-11-22 11:31:49 -0600459
460 r"""
Michael Walsh6741f742017-02-20 16:16:38 -0600461 Get the system state plus a little bit of wrapping.
Michael Walsh0bbd8602016-11-22 11:31:49 -0600462 """
463
Michael Walsh6741f742017-02-20 16:16:38 -0600464 global state
465
466 req_states = ['epoch_seconds'] + st.default_req_states
467
Michael Walshb5839d02017-04-12 16:11:20 -0500468 gp.qprint_timen("Getting system state.")
Michael Walsh6741f742017-02-20 16:16:38 -0600469 if test_mode:
470 state['epoch_seconds'] = int(time.time())
471 else:
Michael Walshb5839d02017-04-12 16:11:20 -0500472 state = st.get_state(req_states=req_states, quiet=quiet)
473 gp.qprint_var(state)
Michael Walsh341c21e2017-01-17 16:25:20 -0600474
475###############################################################################
476
477
478###############################################################################
Michael Walsh6741f742017-02-20 16:16:38 -0600479def select_boot():
Michael Walsh341c21e2017-01-17 16:25:20 -0600480
481 r"""
482 Select a boot test to be run based on our current state and return the
483 chosen boot type.
484
485 Description of arguments:
Michael Walsh6741f742017-02-20 16:16:38 -0600486 state The state of the machine.
Michael Walsh341c21e2017-01-17 16:25:20 -0600487 """
488
Michael Walsh30dadae2017-02-27 14:25:52 -0600489 global boot_stack
490
Michael Walshb5839d02017-04-12 16:11:20 -0500491 gp.qprint_timen("Selecting a boot test.")
Michael Walsh6741f742017-02-20 16:16:38 -0600492
493 my_get_state()
494
495 stack_popped = 0
496 if len(boot_stack) > 0:
497 stack_popped = 1
Michael Walshb5839d02017-04-12 16:11:20 -0500498 gp.qprint_dashes()
499 gp.qprint_var(boot_stack)
500 gp.qprint_dashes()
501 skip_boot_printed = 0
502 while len(boot_stack) > 0:
503 boot_candidate = boot_stack.pop()
504 if stack_mode == 'normal':
505 break
506 else:
507 if st.compare_states(state, boot_table[boot_candidate]['end']):
508 if not skip_boot_printed:
Michael Walshff340002017-08-29 11:18:27 -0500509 gp.qprint_var(stack_mode)
510 gp.qprintn()
511 gp.qprint_timen("Skipping the following boot tests" +
512 " which are unnecessary since their" +
513 " required end states match the" +
514 " current machine state:")
Michael Walshb5839d02017-04-12 16:11:20 -0500515 skip_boot_printed = 1
Michael Walshff340002017-08-29 11:18:27 -0500516 gp.qprint_var(boot_candidate)
Michael Walshb5839d02017-04-12 16:11:20 -0500517 boot_candidate = ""
518 if boot_candidate == "":
519 gp.qprint_dashes()
520 gp.qprint_var(boot_stack)
521 gp.qprint_dashes()
522 return boot_candidate
Michael Walsh6741f742017-02-20 16:16:38 -0600523 if st.compare_states(state, boot_table[boot_candidate]['start']):
Michael Walshb5839d02017-04-12 16:11:20 -0500524 gp.qprint_timen("The machine state is valid for a '" +
525 boot_candidate + "' boot test.")
526 gp.qprint_dashes()
527 gp.qprint_var(boot_stack)
528 gp.qprint_dashes()
Michael Walsh6741f742017-02-20 16:16:38 -0600529 return boot_candidate
Michael Walsh341c21e2017-01-17 16:25:20 -0600530 else:
Michael Walshb5839d02017-04-12 16:11:20 -0500531 gp.qprint_timen("The machine state does not match the required" +
532 " starting state for a '" + boot_candidate +
533 "' boot test:")
Michael Walshff340002017-08-29 11:18:27 -0500534 gp.qprint_varx("boot_table[" + boot_candidate + "][start]",
535 boot_table[boot_candidate]['start'], 1)
Michael Walsh6741f742017-02-20 16:16:38 -0600536 boot_stack.append(boot_candidate)
537 popped_boot = boot_candidate
538
539 # Loop through your list selecting a boot_candidates
540 boot_candidates = []
541 for boot_candidate in boot_list:
542 if st.compare_states(state, boot_table[boot_candidate]['start']):
543 if stack_popped:
544 if st.compare_states(boot_table[boot_candidate]['end'],
545 boot_table[popped_boot]['start']):
546 boot_candidates.append(boot_candidate)
547 else:
548 boot_candidates.append(boot_candidate)
549
550 if len(boot_candidates) == 0:
Michael Walshb5839d02017-04-12 16:11:20 -0500551 gp.qprint_timen("The user's boot list contained no boot tests" +
552 " which are valid for the current machine state.")
Michael Walsh6741f742017-02-20 16:16:38 -0600553 boot_candidate = default_power_on
554 if not st.compare_states(state, boot_table[default_power_on]['start']):
555 boot_candidate = default_power_off
556 boot_candidates.append(boot_candidate)
Michael Walshb5839d02017-04-12 16:11:20 -0500557 gp.qprint_timen("Using default '" + boot_candidate +
558 "' boot type to transition to valid state.")
Michael Walsh6741f742017-02-20 16:16:38 -0600559
Michael Walshb5839d02017-04-12 16:11:20 -0500560 gp.dprint_var(boot_candidates)
Michael Walsh6741f742017-02-20 16:16:38 -0600561
562 # Randomly select a boot from the candidate list.
563 boot = random.choice(boot_candidates)
Michael Walsh341c21e2017-01-17 16:25:20 -0600564
565 return boot
Michael Walsh0bbd8602016-11-22 11:31:49 -0600566
567###############################################################################
Michael Walsh55302292017-01-10 11:43:02 -0600568
569
570###############################################################################
Michael Walsh341c21e2017-01-17 16:25:20 -0600571def print_last_boots():
572
573 r"""
574 Print the last ten boots done with their time stamps.
575 """
576
577 # indent 0, 90 chars wide, linefeed, char is "="
Michael Walshb5839d02017-04-12 16:11:20 -0500578 gp.qprint_dashes(0, 90)
579 gp.qprintn("Last 10 boots:\n")
Michael Walsh341c21e2017-01-17 16:25:20 -0600580
581 for boot_entry in last_ten:
582 grp.rqprint(boot_entry)
Michael Walshb5839d02017-04-12 16:11:20 -0500583 gp.qprint_dashes(0, 90)
Michael Walsh341c21e2017-01-17 16:25:20 -0600584
585###############################################################################
586
587
588###############################################################################
Michael Walsh341c21e2017-01-17 16:25:20 -0600589def print_defect_report():
590
591 r"""
592 Print a defect report.
593 """
594
Michael Walsh600876d2017-05-30 17:58:58 -0500595 # Making deliberate choice to NOT run plug_in_setup(). We don't want
596 # ffdc_prefix updated.
597 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
598 call_point='ffdc_report', stop_on_plug_in_failure=0)
599
Michael Walsh341c21e2017-01-17 16:25:20 -0600600 # At some point I'd like to have the 'Call FFDC Methods' return a list
601 # of files it has collected. In that case, the following "ls" command
602 # would no longer be needed. For now, however, glob shows the files
603 # named in FFDC_LIST_FILE_PATH so I will refrain from printing those
604 # out (so we don't see duplicates in the list).
605
Michael Walshe0cf8d72017-05-17 13:20:46 -0500606 # Get additional header data which may have been created by ffdc plug-ins.
607 # Also, delete the individual header files to cleanup.
608 cmd_buf = "file_list=$(cat " + ffdc_report_list_path + " 2>/dev/null)" +\
609 " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\
610 " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :"
611 shell_rc, more_header_info = gc.cmd_fnc_u(cmd_buf, print_output=0,
612 show_err=0)
613
Michael Walsh600876d2017-05-30 17:58:58 -0500614 # Get additional header data which may have been created by ffdc plug-ins.
615 # Also, delete the individual header files to cleanup.
616 cmd_buf = "file_list=$(cat " + ffdc_summary_list_path + " 2>/dev/null)" +\
617 " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\
618 " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :"
619 shell_rc, ffdc_summary_info = gc.cmd_fnc_u(cmd_buf, print_output=0,
620 show_err=0)
621
Michael Walsh341c21e2017-01-17 16:25:20 -0600622 LOG_PREFIX = BuiltIn().get_variable_value("${LOG_PREFIX}")
623
Michael Walshe0cf8d72017-05-17 13:20:46 -0500624 output = '\n'.join(sorted(glob.glob(LOG_PREFIX + '*')))
Michael Walsh341c21e2017-01-17 16:25:20 -0600625 try:
Michael Walsh6741f742017-02-20 16:16:38 -0600626 ffdc_list = open(ffdc_list_file_path, 'r')
Michael Walsh341c21e2017-01-17 16:25:20 -0600627 except IOError:
628 ffdc_list = ""
629
Michael Walsh68a61162017-04-25 11:54:06 -0500630 # Open ffdc_file_list for writing. We will write a complete list of
631 # FFDC files to it for possible use by plug-ins like cp_stop_check.
632 ffdc_list_file = open(ffdc_list_file_path, 'w')
633
634 gp.qprintn()
635 # indent=0, width=90, linefeed=1, char="="
636 gp.qprint_dashes(0, 90, 1, "=")
637 gp.qprintn("Copy this data to the defect:\n")
638
Michael Walshe0cf8d72017-05-17 13:20:46 -0500639 if len(more_header_info) > 0:
Michael Walshff340002017-08-29 11:18:27 -0500640 gp.qprintn(more_header_info)
Michael Walshdc80d672017-05-09 12:58:32 -0500641 gp.qpvars(host_name, host_ip, openbmc_nickname, openbmc_host,
642 openbmc_host_name, openbmc_ip, openbmc_username,
643 openbmc_password, os_host, os_host_name, os_ip, os_username,
644 os_password, pdu_host, pdu_host_name, pdu_ip, pdu_username,
645 pdu_password, pdu_slot_no, openbmc_serial_host,
646 openbmc_serial_host_name, openbmc_serial_ip, openbmc_serial_port)
Michael Walsh68a61162017-04-25 11:54:06 -0500647
648 gp.qprintn()
649
650 print_last_boots()
651 gp.qprintn()
652 gp.qprint_var(state)
653
Michael Walshb5839d02017-04-12 16:11:20 -0500654 gp.qprintn()
655 gp.qprintn("FFDC data files:")
Michael Walsh341c21e2017-01-17 16:25:20 -0600656 if status_file_path != "":
Michael Walshb5839d02017-04-12 16:11:20 -0500657 gp.qprintn(status_file_path)
Michael Walsh68a61162017-04-25 11:54:06 -0500658 ffdc_list_file.write(status_file_path + "\n")
Michael Walsh341c21e2017-01-17 16:25:20 -0600659
Michael Walshb5839d02017-04-12 16:11:20 -0500660 gp.qprintn(output)
661 # gp.qprintn(ffdc_list)
662 gp.qprintn()
Michael Walsh341c21e2017-01-17 16:25:20 -0600663
Michael Walsh600876d2017-05-30 17:58:58 -0500664 if len(ffdc_summary_info) > 0:
Michael Walshff340002017-08-29 11:18:27 -0500665 gp.qprintn(ffdc_summary_info)
Michael Walsh600876d2017-05-30 17:58:58 -0500666
Michael Walshb5839d02017-04-12 16:11:20 -0500667 gp.qprint_dashes(0, 90, 1, "=")
Michael Walsh341c21e2017-01-17 16:25:20 -0600668
Michael Walsh68a61162017-04-25 11:54:06 -0500669 ffdc_list_file.write(output + "\n")
670 ffdc_list_file.close()
671
Michael Walsh341c21e2017-01-17 16:25:20 -0600672###############################################################################
Michael Walsh6741f742017-02-20 16:16:38 -0600673
674
675###############################################################################
676def my_ffdc():
677
678 r"""
679 Collect FFDC data.
680 """
681
682 global state
683
684 plug_in_setup()
685 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500686 call_point='ffdc', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600687
688 AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX']
Michael Walsh83f4bc72017-04-20 16:49:43 -0500689 status, ret_values = grk.run_key_u("FFDC ffdc_prefix=" +
690 AUTOBOOT_FFDC_PREFIX +
691 " ffdc_function_list=" +
692 ffdc_function_list, ignore=1)
693 if status != 'PASS':
Michael Walshff340002017-08-29 11:18:27 -0500694 gp.qprint_error("Call to ffdc failed.\n")
Michael Walsh6741f742017-02-20 16:16:38 -0600695
696 my_get_state()
697
698 print_defect_report()
699
700###############################################################################
701
702
703###############################################################################
704def print_test_start_message(boot_keyword):
705
706 r"""
707 Print a message indicating what boot test is about to run.
708
709 Description of arguments:
710 boot_keyword The name of the boot which is to be run
711 (e.g. "BMC Power On").
712 """
713
714 global last_ten
Sunil M325eb542017-08-10 07:09:43 -0500715 global boot_start_time
Michael Walsh6741f742017-02-20 16:16:38 -0600716
717 doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".")
Sunil M325eb542017-08-10 07:09:43 -0500718
719 # Set boot_start_time for use by plug-ins.
720 boot_start_time = doing_msg[1:33]
721 gp.qprint_var(boot_start_time)
722
Michael Walshb5839d02017-04-12 16:11:20 -0500723 gp.qprint(doing_msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600724
725 last_ten.append(doing_msg)
726
727 if len(last_ten) > 10:
728 del last_ten[0]
729
730###############################################################################
731
732
733###############################################################################
734def run_boot(boot):
735
736 r"""
737 Run the specified boot.
738
739 Description of arguments:
740 boot The name of the boot test to be performed.
741 """
742
743 global state
744
745 print_test_start_message(boot)
746
747 plug_in_setup()
748 rc, shell_rc, failed_plug_in_name = \
749 grpi.rprocess_plug_in_packages(call_point="pre_boot")
750 if rc != 0:
751 error_message = "Plug-in failed with non-zero return code.\n" +\
752 gp.sprint_var(rc, 1)
753 BuiltIn().fail(gp.sprint_error(error_message))
754
755 if test_mode:
756 # In test mode, we'll pretend the boot worked by assigning its
757 # required end state to the default state value.
Michael Walsh30dadae2017-02-27 14:25:52 -0600758 state = st.strip_anchor_state(boot_table[boot]['end'])
Michael Walsh6741f742017-02-20 16:16:38 -0600759 else:
760 # Assertion: We trust that the state data was made fresh by the
761 # caller.
762
Michael Walshb5839d02017-04-12 16:11:20 -0500763 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600764
765 if boot_table[boot]['method_type'] == "keyword":
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600766 rk.my_run_keywords(boot_table[boot].get('lib_file_path', ''),
Michael Walshb5839d02017-04-12 16:11:20 -0500767 boot_table[boot]['method'],
768 quiet=quiet)
Michael Walsh6741f742017-02-20 16:16:38 -0600769
770 if boot_table[boot]['bmc_reboot']:
771 st.wait_for_comm_cycle(int(state['epoch_seconds']))
Michael Walsh30dadae2017-02-27 14:25:52 -0600772 plug_in_setup()
773 rc, shell_rc, failed_plug_in_name = \
774 grpi.rprocess_plug_in_packages(call_point="post_reboot")
775 if rc != 0:
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600776 error_message = "Plug-in failed with non-zero return code.\n"
777 error_message += gp.sprint_var(rc, 1)
Michael Walsh30dadae2017-02-27 14:25:52 -0600778 BuiltIn().fail(gp.sprint_error(error_message))
Michael Walsh6741f742017-02-20 16:16:38 -0600779 else:
780 match_state = st.anchor_state(state)
781 del match_state['epoch_seconds']
782 # Wait for the state to change in any way.
783 st.wait_state(match_state, wait_time=state_change_timeout,
Michael Walsh600876d2017-05-30 17:58:58 -0500784 interval="10 seconds", invert=1)
Michael Walsh6741f742017-02-20 16:16:38 -0600785
Michael Walshb5839d02017-04-12 16:11:20 -0500786 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600787 if boot_table[boot]['end']['chassis'] == "Off":
788 boot_timeout = power_off_timeout
789 else:
790 boot_timeout = power_on_timeout
791 st.wait_state(boot_table[boot]['end'], wait_time=boot_timeout,
Michael Walsh600876d2017-05-30 17:58:58 -0500792 interval="10 seconds")
Michael Walsh6741f742017-02-20 16:16:38 -0600793
794 plug_in_setup()
795 rc, shell_rc, failed_plug_in_name = \
796 grpi.rprocess_plug_in_packages(call_point="post_boot")
797 if rc != 0:
798 error_message = "Plug-in failed with non-zero return code.\n" +\
799 gp.sprint_var(rc, 1)
800 BuiltIn().fail(gp.sprint_error(error_message))
801
802###############################################################################
803
804
805###############################################################################
806def test_loop_body():
807
808 r"""
809 The main loop body for the loop in main_py.
810
811 Description of arguments:
812 boot_count The iteration number (starts at 1).
813 """
814
815 global boot_count
816 global state
817 global next_boot
818 global boot_success
Sunil M325eb542017-08-10 07:09:43 -0500819 global boot_end_time
Michael Walsh6741f742017-02-20 16:16:38 -0600820
Michael Walshb5839d02017-04-12 16:11:20 -0500821 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600822
823 next_boot = select_boot()
Michael Walshb5839d02017-04-12 16:11:20 -0500824 if next_boot == "":
825 return True
Michael Walsh6741f742017-02-20 16:16:38 -0600826
Michael Walshb5839d02017-04-12 16:11:20 -0500827 boot_count += 1
828 gp.qprint_timen("Starting boot " + str(boot_count) + ".")
Michael Walsh6741f742017-02-20 16:16:38 -0600829
Michael Walshe0cf8d72017-05-17 13:20:46 -0500830 pre_boot_plug_in_setup()
Michael Walsh6741f742017-02-20 16:16:38 -0600831
832 cmd_buf = ["run_boot", next_boot]
833 boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
834 if boot_status == "FAIL":
Michael Walshb5839d02017-04-12 16:11:20 -0500835 gp.qprint(msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600836
Michael Walshb5839d02017-04-12 16:11:20 -0500837 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600838 if boot_status == "PASS":
839 boot_success = 1
Michael Walshff340002017-08-29 11:18:27 -0500840 completion_msg = gp.sprint_timen("BOOT_SUCCESS: \"" + next_boot +
841 "\" succeeded.")
Michael Walsh6741f742017-02-20 16:16:38 -0600842 else:
843 boot_success = 0
Michael Walshff340002017-08-29 11:18:27 -0500844 completion_msg = gp.sprint_timen("BOOT_FAILED: \"" + next_boot +
845 "\" failed.")
Sunil M325eb542017-08-10 07:09:43 -0500846
847 # Set boot_end_time for use by plug-ins.
848 boot_end_time = completion_msg[1:33]
849 gp.qprint_var(boot_end_time)
850
851 gp.qprint(completion_msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600852
853 boot_results.update(next_boot, boot_status)
854
855 plug_in_setup()
856 # NOTE: A post_test_case call point failure is NOT counted as a boot
857 # failure.
858 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500859 call_point='post_test_case', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600860
861 plug_in_setup()
862 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
863 call_point='ffdc_check', shell_rc=0x00000200,
864 stop_on_plug_in_failure=1, stop_on_non_zero_rc=1)
865 if boot_status != "PASS" or ffdc_check == "All" or shell_rc == 0x00000200:
Michael Walsh83f4bc72017-04-20 16:49:43 -0500866 status, ret_values = grk.run_key_u("my_ffdc", ignore=1)
867 if status != 'PASS':
Michael Walshff340002017-08-29 11:18:27 -0500868 gp.qprint_error("Call to my_ffdc failed.\n")
Michael Walsh6741f742017-02-20 16:16:38 -0600869
Michael Walshd139f282017-04-04 18:00:23 -0500870 # We need to purge error logs between boots or they build up.
Michael Walshb5839d02017-04-12 16:11:20 -0500871 grk.run_key("Delete Error logs", ignore=1)
Michael Walshd139f282017-04-04 18:00:23 -0500872
Michael Walsh952f9b02017-03-09 13:11:14 -0600873 boot_results.print_report()
Michael Walshb5839d02017-04-12 16:11:20 -0500874 gp.qprint_timen("Finished boot " + str(boot_count) + ".")
Michael Walsh952f9b02017-03-09 13:11:14 -0600875
Michael Walsh6741f742017-02-20 16:16:38 -0600876 plug_in_setup()
877 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
878 call_point='stop_check')
879 if rc != 0:
880 error_message = "Stopping as requested by user.\n"
881 grp.rprint_error_report(error_message)
882 BuiltIn().fail(error_message)
883
Michael Walshd139f282017-04-04 18:00:23 -0500884 # This should help prevent ConnectionErrors.
Michael Walsh0960b382017-06-22 16:23:37 -0500885 grk.run_key_u("Close All Connections")
Michael Walshd139f282017-04-04 18:00:23 -0500886
Michael Walsh6741f742017-02-20 16:16:38 -0600887 return True
888
889###############################################################################
890
891
892###############################################################################
Michael Walsh83f4bc72017-04-20 16:49:43 -0500893def obmc_boot_test_teardown():
Michael Walsh6741f742017-02-20 16:16:38 -0600894
895 r"""
Michael Walshc9116812017-03-10 14:23:06 -0600896 Clean up after the Main keyword.
Michael Walsh6741f742017-02-20 16:16:38 -0600897 """
898
899 if cp_setup_called:
900 plug_in_setup()
901 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500902 call_point='cleanup', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600903
Michael Walsh600876d2017-05-30 17:58:58 -0500904 if 'boot_results_file_path' in globals():
905 # Save boot_results object to a file in case it is needed again.
906 gp.qprint_timen("Saving boot_results to the following path.")
907 gp.qprint_var(boot_results_file_path)
908 pickle.dump(boot_results, open(boot_results_file_path, 'wb'),
909 pickle.HIGHEST_PROTOCOL)
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600910
Michael Walshff340002017-08-29 11:18:27 -0500911 global save_stack
912 # Restore any global values saved on the save_stack.
913 for parm_name in main_func_parm_list:
914 # Get the parm_value if it was saved on the stack.
915 try:
916 parm_value = save_stack.pop(parm_name)
917 except:
918 # If it was not saved, no further action is required.
919 continue
920
921 # Restore the saved value.
922 cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
923 "}\", parm_value)"
924 gp.dpissuing(cmd_buf)
925 exec(cmd_buf)
926
927 gp.dprintn(save_stack.sprint_obj())
928
Michael Walsh6741f742017-02-20 16:16:38 -0600929###############################################################################
930
931
932###############################################################################
Michael Walshc9116812017-03-10 14:23:06 -0600933def test_teardown():
934
935 r"""
936 Clean up after this test case.
937 """
938
939 gp.qprintn()
940 cmd_buf = ["Print Error",
941 "A keyword timeout occurred ending this program.\n"]
942 BuiltIn().run_keyword_if_timeout_occurred(*cmd_buf)
943
Michael Walshb5839d02017-04-12 16:11:20 -0500944 grp.rqprint_pgm_footer()
945
Michael Walshc9116812017-03-10 14:23:06 -0600946###############################################################################
947
948
949###############################################################################
Michael Walshff340002017-08-29 11:18:27 -0500950def obmc_boot_test_py(loc_boot_stack=None,
951 loc_stack_mode=None,
952 loc_quiet=None):
Michael Walsh6741f742017-02-20 16:16:38 -0600953
954 r"""
955 Do main program processing.
956 """
957
Michael Walshff340002017-08-29 11:18:27 -0500958 global save_stack
959
960 # Process function parms.
961 for parm_name in main_func_parm_list:
962 # Get parm's value.
963 cmd_buf = "parm_value = loc_" + parm_name
964 exec(cmd_buf)
965 gp.dpvar(parm_name)
966 gp.dpvar(parm_value)
967
968 if parm_value is None:
969 # Parm was not specified by the calling function so set it to its
970 # corresponding global value.
971 cmd_buf = "loc_" + parm_name + " = BuiltIn().get_variable_value" +\
972 "(\"${" + parm_name + "}\")"
973 gp.dpissuing(cmd_buf)
974 exec(cmd_buf)
975 else:
976 # Save the global value on a stack.
977 cmd_buf = "save_stack.push(BuiltIn().get_variable_value(\"${" +\
978 parm_name + "}\"), \"" + parm_name + "\")"
979 gp.dpissuing(cmd_buf)
980 exec(cmd_buf)
981
982 # Set the global value to the passed value.
983 cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
984 "}\", loc_" + parm_name + ")"
985 gp.dpissuing(cmd_buf)
986 exec(cmd_buf)
987
988 gp.dprintn(save_stack.sprint_obj())
Michael Walshb5839d02017-04-12 16:11:20 -0500989
Michael Walsh6741f742017-02-20 16:16:38 -0600990 setup()
991
Michael Walsha20da402017-03-31 16:27:45 -0500992 if ffdc_only:
993 gp.qprint_timen("Caller requested ffdc_only.")
Michael Walshe0cf8d72017-05-17 13:20:46 -0500994 pre_boot_plug_in_setup()
Michael Walsh83f4bc72017-04-20 16:49:43 -0500995 grk.run_key_u("my_ffdc")
Michael Walsh764d2f82017-04-27 16:01:08 -0500996 return
Michael Walsha20da402017-03-31 16:27:45 -0500997
Michael Walsh6741f742017-02-20 16:16:38 -0600998 # Process caller's boot_stack.
999 while (len(boot_stack) > 0):
1000 test_loop_body()
1001
Michael Walshb5839d02017-04-12 16:11:20 -05001002 gp.qprint_timen("Finished processing stack.")
Michael Walsh30dadae2017-02-27 14:25:52 -06001003
Michael Walsh6741f742017-02-20 16:16:38 -06001004 # Process caller's boot_list.
1005 if len(boot_list) > 0:
1006 for ix in range(1, max_num_tests + 1):
1007 test_loop_body()
1008
Michael Walshb5839d02017-04-12 16:11:20 -05001009 gp.qprint_timen("Completed all requested boot tests.")
1010
1011 boot_pass, boot_fail = boot_results.return_total_pass_fail()
1012 if boot_fail > boot_fail_threshold:
1013 error_message = "Boot failures exceed the boot failure" +\
1014 " threshold:\n" +\
1015 gp.sprint_var(boot_fail) +\
1016 gp.sprint_var(boot_fail_threshold)
1017 BuiltIn().fail(gp.sprint_error(error_message))
Michael Walsh6741f742017-02-20 16:16:38 -06001018
1019###############################################################################