blob: 77eaa7ae8ecb347361b69ffce09d5e61b5f38329 [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 Walsh45ca6e42017-09-14 17:29:12 -0500479def valid_state():
480
481 r"""
482 Verify that our state dictionary contains no blank values. If we don't get
483 valid state data, we cannot continue to work.
484 """
485
486 if st.compare_states(state, st.invalid_state_match, 'or'):
487 error_message = "The state dictionary contains blank fields which" +\
488 " is illegal.\n" + gp.sprint_var(state)
489 BuiltIn().fail(gp.sprint_error(error_message))
490
491###############################################################################
492
493
494###############################################################################
Michael Walsh6741f742017-02-20 16:16:38 -0600495def select_boot():
Michael Walsh341c21e2017-01-17 16:25:20 -0600496
497 r"""
498 Select a boot test to be run based on our current state and return the
499 chosen boot type.
500
501 Description of arguments:
Michael Walsh6741f742017-02-20 16:16:38 -0600502 state The state of the machine.
Michael Walsh341c21e2017-01-17 16:25:20 -0600503 """
504
Michael Walsh30dadae2017-02-27 14:25:52 -0600505 global boot_stack
506
Michael Walshb5839d02017-04-12 16:11:20 -0500507 gp.qprint_timen("Selecting a boot test.")
Michael Walsh6741f742017-02-20 16:16:38 -0600508
509 my_get_state()
Michael Walsh45ca6e42017-09-14 17:29:12 -0500510 valid_state()
Michael Walsh6741f742017-02-20 16:16:38 -0600511
512 stack_popped = 0
513 if len(boot_stack) > 0:
514 stack_popped = 1
Michael Walshb5839d02017-04-12 16:11:20 -0500515 gp.qprint_dashes()
516 gp.qprint_var(boot_stack)
517 gp.qprint_dashes()
518 skip_boot_printed = 0
519 while len(boot_stack) > 0:
520 boot_candidate = boot_stack.pop()
521 if stack_mode == 'normal':
522 break
523 else:
524 if st.compare_states(state, boot_table[boot_candidate]['end']):
525 if not skip_boot_printed:
Michael Walshff340002017-08-29 11:18:27 -0500526 gp.qprint_var(stack_mode)
527 gp.qprintn()
528 gp.qprint_timen("Skipping the following boot tests" +
529 " which are unnecessary since their" +
530 " required end states match the" +
531 " current machine state:")
Michael Walshb5839d02017-04-12 16:11:20 -0500532 skip_boot_printed = 1
Michael Walshff340002017-08-29 11:18:27 -0500533 gp.qprint_var(boot_candidate)
Michael Walshb5839d02017-04-12 16:11:20 -0500534 boot_candidate = ""
535 if boot_candidate == "":
536 gp.qprint_dashes()
537 gp.qprint_var(boot_stack)
538 gp.qprint_dashes()
539 return boot_candidate
Michael Walsh6741f742017-02-20 16:16:38 -0600540 if st.compare_states(state, boot_table[boot_candidate]['start']):
Michael Walshb5839d02017-04-12 16:11:20 -0500541 gp.qprint_timen("The machine state is valid for a '" +
542 boot_candidate + "' boot test.")
543 gp.qprint_dashes()
544 gp.qprint_var(boot_stack)
545 gp.qprint_dashes()
Michael Walsh6741f742017-02-20 16:16:38 -0600546 return boot_candidate
Michael Walsh341c21e2017-01-17 16:25:20 -0600547 else:
Michael Walshb5839d02017-04-12 16:11:20 -0500548 gp.qprint_timen("The machine state does not match the required" +
549 " starting state for a '" + boot_candidate +
550 "' boot test:")
Michael Walshff340002017-08-29 11:18:27 -0500551 gp.qprint_varx("boot_table[" + boot_candidate + "][start]",
552 boot_table[boot_candidate]['start'], 1)
Michael Walsh6741f742017-02-20 16:16:38 -0600553 boot_stack.append(boot_candidate)
554 popped_boot = boot_candidate
555
556 # Loop through your list selecting a boot_candidates
557 boot_candidates = []
558 for boot_candidate in boot_list:
559 if st.compare_states(state, boot_table[boot_candidate]['start']):
560 if stack_popped:
561 if st.compare_states(boot_table[boot_candidate]['end'],
562 boot_table[popped_boot]['start']):
563 boot_candidates.append(boot_candidate)
564 else:
565 boot_candidates.append(boot_candidate)
566
567 if len(boot_candidates) == 0:
Michael Walshb5839d02017-04-12 16:11:20 -0500568 gp.qprint_timen("The user's boot list contained no boot tests" +
569 " which are valid for the current machine state.")
Michael Walsh6741f742017-02-20 16:16:38 -0600570 boot_candidate = default_power_on
571 if not st.compare_states(state, boot_table[default_power_on]['start']):
572 boot_candidate = default_power_off
573 boot_candidates.append(boot_candidate)
Michael Walshb5839d02017-04-12 16:11:20 -0500574 gp.qprint_timen("Using default '" + boot_candidate +
575 "' boot type to transition to valid state.")
Michael Walsh6741f742017-02-20 16:16:38 -0600576
Michael Walshb5839d02017-04-12 16:11:20 -0500577 gp.dprint_var(boot_candidates)
Michael Walsh6741f742017-02-20 16:16:38 -0600578
579 # Randomly select a boot from the candidate list.
580 boot = random.choice(boot_candidates)
Michael Walsh341c21e2017-01-17 16:25:20 -0600581
582 return boot
Michael Walsh0bbd8602016-11-22 11:31:49 -0600583
584###############################################################################
Michael Walsh55302292017-01-10 11:43:02 -0600585
586
587###############################################################################
Michael Walsh341c21e2017-01-17 16:25:20 -0600588def print_last_boots():
589
590 r"""
591 Print the last ten boots done with their time stamps.
592 """
593
594 # indent 0, 90 chars wide, linefeed, char is "="
Michael Walshb5839d02017-04-12 16:11:20 -0500595 gp.qprint_dashes(0, 90)
596 gp.qprintn("Last 10 boots:\n")
Michael Walsh341c21e2017-01-17 16:25:20 -0600597
598 for boot_entry in last_ten:
599 grp.rqprint(boot_entry)
Michael Walshb5839d02017-04-12 16:11:20 -0500600 gp.qprint_dashes(0, 90)
Michael Walsh341c21e2017-01-17 16:25:20 -0600601
602###############################################################################
603
604
605###############################################################################
Michael Walsh341c21e2017-01-17 16:25:20 -0600606def print_defect_report():
607
608 r"""
609 Print a defect report.
610 """
611
Michael Walsh600876d2017-05-30 17:58:58 -0500612 # Making deliberate choice to NOT run plug_in_setup(). We don't want
613 # ffdc_prefix updated.
614 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
615 call_point='ffdc_report', stop_on_plug_in_failure=0)
616
Michael Walsh341c21e2017-01-17 16:25:20 -0600617 # At some point I'd like to have the 'Call FFDC Methods' return a list
618 # of files it has collected. In that case, the following "ls" command
619 # would no longer be needed. For now, however, glob shows the files
620 # named in FFDC_LIST_FILE_PATH so I will refrain from printing those
621 # out (so we don't see duplicates in the list).
622
Michael Walshe0cf8d72017-05-17 13:20:46 -0500623 # Get additional header data which may have been created by ffdc plug-ins.
624 # Also, delete the individual header files to cleanup.
625 cmd_buf = "file_list=$(cat " + ffdc_report_list_path + " 2>/dev/null)" +\
626 " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\
627 " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :"
628 shell_rc, more_header_info = gc.cmd_fnc_u(cmd_buf, print_output=0,
629 show_err=0)
630
Michael Walsh600876d2017-05-30 17:58:58 -0500631 # Get additional header data which may have been created by ffdc plug-ins.
632 # Also, delete the individual header files to cleanup.
633 cmd_buf = "file_list=$(cat " + ffdc_summary_list_path + " 2>/dev/null)" +\
634 " ; [ ! -z \"${file_list}\" ] && cat ${file_list}" +\
635 " 2>/dev/null ; rm -rf ${file_list} 2>/dev/null || :"
636 shell_rc, ffdc_summary_info = gc.cmd_fnc_u(cmd_buf, print_output=0,
637 show_err=0)
638
Michael Walsh341c21e2017-01-17 16:25:20 -0600639 LOG_PREFIX = BuiltIn().get_variable_value("${LOG_PREFIX}")
640
Michael Walshe0cf8d72017-05-17 13:20:46 -0500641 output = '\n'.join(sorted(glob.glob(LOG_PREFIX + '*')))
Michael Walsh341c21e2017-01-17 16:25:20 -0600642 try:
Michael Walsh6741f742017-02-20 16:16:38 -0600643 ffdc_list = open(ffdc_list_file_path, 'r')
Michael Walsh341c21e2017-01-17 16:25:20 -0600644 except IOError:
645 ffdc_list = ""
646
Michael Walsh68a61162017-04-25 11:54:06 -0500647 # Open ffdc_file_list for writing. We will write a complete list of
648 # FFDC files to it for possible use by plug-ins like cp_stop_check.
649 ffdc_list_file = open(ffdc_list_file_path, 'w')
650
651 gp.qprintn()
652 # indent=0, width=90, linefeed=1, char="="
653 gp.qprint_dashes(0, 90, 1, "=")
654 gp.qprintn("Copy this data to the defect:\n")
655
Michael Walshe0cf8d72017-05-17 13:20:46 -0500656 if len(more_header_info) > 0:
Michael Walshff340002017-08-29 11:18:27 -0500657 gp.qprintn(more_header_info)
Michael Walshdc80d672017-05-09 12:58:32 -0500658 gp.qpvars(host_name, host_ip, openbmc_nickname, openbmc_host,
659 openbmc_host_name, openbmc_ip, openbmc_username,
660 openbmc_password, os_host, os_host_name, os_ip, os_username,
661 os_password, pdu_host, pdu_host_name, pdu_ip, pdu_username,
662 pdu_password, pdu_slot_no, openbmc_serial_host,
663 openbmc_serial_host_name, openbmc_serial_ip, openbmc_serial_port)
Michael Walsh68a61162017-04-25 11:54:06 -0500664
665 gp.qprintn()
666
667 print_last_boots()
668 gp.qprintn()
669 gp.qprint_var(state)
670
Michael Walshb5839d02017-04-12 16:11:20 -0500671 gp.qprintn()
672 gp.qprintn("FFDC data files:")
Michael Walsh341c21e2017-01-17 16:25:20 -0600673 if status_file_path != "":
Michael Walshb5839d02017-04-12 16:11:20 -0500674 gp.qprintn(status_file_path)
Michael Walsh68a61162017-04-25 11:54:06 -0500675 ffdc_list_file.write(status_file_path + "\n")
Michael Walsh341c21e2017-01-17 16:25:20 -0600676
Michael Walshb5839d02017-04-12 16:11:20 -0500677 gp.qprintn(output)
678 # gp.qprintn(ffdc_list)
679 gp.qprintn()
Michael Walsh341c21e2017-01-17 16:25:20 -0600680
Michael Walsh600876d2017-05-30 17:58:58 -0500681 if len(ffdc_summary_info) > 0:
Michael Walshff340002017-08-29 11:18:27 -0500682 gp.qprintn(ffdc_summary_info)
Michael Walsh600876d2017-05-30 17:58:58 -0500683
Michael Walshb5839d02017-04-12 16:11:20 -0500684 gp.qprint_dashes(0, 90, 1, "=")
Michael Walsh341c21e2017-01-17 16:25:20 -0600685
Michael Walsh68a61162017-04-25 11:54:06 -0500686 ffdc_list_file.write(output + "\n")
687 ffdc_list_file.close()
688
Michael Walsh341c21e2017-01-17 16:25:20 -0600689###############################################################################
Michael Walsh6741f742017-02-20 16:16:38 -0600690
691
692###############################################################################
693def my_ffdc():
694
695 r"""
696 Collect FFDC data.
697 """
698
699 global state
700
701 plug_in_setup()
702 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500703 call_point='ffdc', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600704
705 AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX']
Michael Walsh83f4bc72017-04-20 16:49:43 -0500706 status, ret_values = grk.run_key_u("FFDC ffdc_prefix=" +
707 AUTOBOOT_FFDC_PREFIX +
708 " ffdc_function_list=" +
709 ffdc_function_list, ignore=1)
710 if status != 'PASS':
Michael Walshff340002017-08-29 11:18:27 -0500711 gp.qprint_error("Call to ffdc failed.\n")
Michael Walsh6741f742017-02-20 16:16:38 -0600712
713 my_get_state()
714
715 print_defect_report()
716
717###############################################################################
718
719
720###############################################################################
721def print_test_start_message(boot_keyword):
722
723 r"""
724 Print a message indicating what boot test is about to run.
725
726 Description of arguments:
727 boot_keyword The name of the boot which is to be run
728 (e.g. "BMC Power On").
729 """
730
731 global last_ten
Sunil M325eb542017-08-10 07:09:43 -0500732 global boot_start_time
Michael Walsh6741f742017-02-20 16:16:38 -0600733
734 doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".")
Sunil M325eb542017-08-10 07:09:43 -0500735
736 # Set boot_start_time for use by plug-ins.
737 boot_start_time = doing_msg[1:33]
738 gp.qprint_var(boot_start_time)
739
Michael Walshb5839d02017-04-12 16:11:20 -0500740 gp.qprint(doing_msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600741
742 last_ten.append(doing_msg)
743
744 if len(last_ten) > 10:
745 del last_ten[0]
746
747###############################################################################
748
749
750###############################################################################
751def run_boot(boot):
752
753 r"""
754 Run the specified boot.
755
756 Description of arguments:
757 boot The name of the boot test to be performed.
758 """
759
760 global state
761
762 print_test_start_message(boot)
763
764 plug_in_setup()
765 rc, shell_rc, failed_plug_in_name = \
766 grpi.rprocess_plug_in_packages(call_point="pre_boot")
767 if rc != 0:
768 error_message = "Plug-in failed with non-zero return code.\n" +\
769 gp.sprint_var(rc, 1)
770 BuiltIn().fail(gp.sprint_error(error_message))
771
772 if test_mode:
773 # In test mode, we'll pretend the boot worked by assigning its
774 # required end state to the default state value.
Michael Walsh30dadae2017-02-27 14:25:52 -0600775 state = st.strip_anchor_state(boot_table[boot]['end'])
Michael Walsh6741f742017-02-20 16:16:38 -0600776 else:
777 # Assertion: We trust that the state data was made fresh by the
778 # caller.
779
Michael Walshb5839d02017-04-12 16:11:20 -0500780 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600781
782 if boot_table[boot]['method_type'] == "keyword":
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600783 rk.my_run_keywords(boot_table[boot].get('lib_file_path', ''),
Michael Walshb5839d02017-04-12 16:11:20 -0500784 boot_table[boot]['method'],
785 quiet=quiet)
Michael Walsh6741f742017-02-20 16:16:38 -0600786
787 if boot_table[boot]['bmc_reboot']:
788 st.wait_for_comm_cycle(int(state['epoch_seconds']))
Michael Walsh30dadae2017-02-27 14:25:52 -0600789 plug_in_setup()
790 rc, shell_rc, failed_plug_in_name = \
791 grpi.rprocess_plug_in_packages(call_point="post_reboot")
792 if rc != 0:
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600793 error_message = "Plug-in failed with non-zero return code.\n"
794 error_message += gp.sprint_var(rc, 1)
Michael Walsh30dadae2017-02-27 14:25:52 -0600795 BuiltIn().fail(gp.sprint_error(error_message))
Michael Walsh6741f742017-02-20 16:16:38 -0600796 else:
797 match_state = st.anchor_state(state)
798 del match_state['epoch_seconds']
799 # Wait for the state to change in any way.
800 st.wait_state(match_state, wait_time=state_change_timeout,
Michael Walsh600876d2017-05-30 17:58:58 -0500801 interval="10 seconds", invert=1)
Michael Walsh6741f742017-02-20 16:16:38 -0600802
Michael Walshb5839d02017-04-12 16:11:20 -0500803 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600804 if boot_table[boot]['end']['chassis'] == "Off":
805 boot_timeout = power_off_timeout
806 else:
807 boot_timeout = power_on_timeout
808 st.wait_state(boot_table[boot]['end'], wait_time=boot_timeout,
Michael Walsh600876d2017-05-30 17:58:58 -0500809 interval="10 seconds")
Michael Walsh6741f742017-02-20 16:16:38 -0600810
811 plug_in_setup()
812 rc, shell_rc, failed_plug_in_name = \
813 grpi.rprocess_plug_in_packages(call_point="post_boot")
814 if rc != 0:
815 error_message = "Plug-in failed with non-zero return code.\n" +\
816 gp.sprint_var(rc, 1)
817 BuiltIn().fail(gp.sprint_error(error_message))
818
819###############################################################################
820
821
822###############################################################################
823def test_loop_body():
824
825 r"""
826 The main loop body for the loop in main_py.
827
828 Description of arguments:
829 boot_count The iteration number (starts at 1).
830 """
831
832 global boot_count
833 global state
834 global next_boot
835 global boot_success
Sunil M325eb542017-08-10 07:09:43 -0500836 global boot_end_time
Michael Walsh6741f742017-02-20 16:16:38 -0600837
Michael Walshb5839d02017-04-12 16:11:20 -0500838 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600839
840 next_boot = select_boot()
Michael Walshb5839d02017-04-12 16:11:20 -0500841 if next_boot == "":
842 return True
Michael Walsh6741f742017-02-20 16:16:38 -0600843
Michael Walshb5839d02017-04-12 16:11:20 -0500844 boot_count += 1
845 gp.qprint_timen("Starting boot " + str(boot_count) + ".")
Michael Walsh6741f742017-02-20 16:16:38 -0600846
Michael Walshe0cf8d72017-05-17 13:20:46 -0500847 pre_boot_plug_in_setup()
Michael Walsh6741f742017-02-20 16:16:38 -0600848
849 cmd_buf = ["run_boot", next_boot]
850 boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
851 if boot_status == "FAIL":
Michael Walshb5839d02017-04-12 16:11:20 -0500852 gp.qprint(msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600853
Michael Walshb5839d02017-04-12 16:11:20 -0500854 gp.qprintn()
Michael Walsh6741f742017-02-20 16:16:38 -0600855 if boot_status == "PASS":
856 boot_success = 1
Michael Walshff340002017-08-29 11:18:27 -0500857 completion_msg = gp.sprint_timen("BOOT_SUCCESS: \"" + next_boot +
858 "\" succeeded.")
Michael Walsh6741f742017-02-20 16:16:38 -0600859 else:
860 boot_success = 0
Michael Walshff340002017-08-29 11:18:27 -0500861 completion_msg = gp.sprint_timen("BOOT_FAILED: \"" + next_boot +
862 "\" failed.")
Sunil M325eb542017-08-10 07:09:43 -0500863
864 # Set boot_end_time for use by plug-ins.
865 boot_end_time = completion_msg[1:33]
866 gp.qprint_var(boot_end_time)
867
868 gp.qprint(completion_msg)
Michael Walsh6741f742017-02-20 16:16:38 -0600869
870 boot_results.update(next_boot, boot_status)
871
872 plug_in_setup()
873 # NOTE: A post_test_case call point failure is NOT counted as a boot
874 # failure.
875 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500876 call_point='post_test_case', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600877
878 plug_in_setup()
879 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
880 call_point='ffdc_check', shell_rc=0x00000200,
881 stop_on_plug_in_failure=1, stop_on_non_zero_rc=1)
882 if boot_status != "PASS" or ffdc_check == "All" or shell_rc == 0x00000200:
Michael Walsh83f4bc72017-04-20 16:49:43 -0500883 status, ret_values = grk.run_key_u("my_ffdc", ignore=1)
884 if status != 'PASS':
Michael Walshff340002017-08-29 11:18:27 -0500885 gp.qprint_error("Call to my_ffdc failed.\n")
Michael Walsh6741f742017-02-20 16:16:38 -0600886
Michael Walshd139f282017-04-04 18:00:23 -0500887 # We need to purge error logs between boots or they build up.
Michael Walshb5839d02017-04-12 16:11:20 -0500888 grk.run_key("Delete Error logs", ignore=1)
Michael Walshd139f282017-04-04 18:00:23 -0500889
Michael Walsh952f9b02017-03-09 13:11:14 -0600890 boot_results.print_report()
Michael Walshb5839d02017-04-12 16:11:20 -0500891 gp.qprint_timen("Finished boot " + str(boot_count) + ".")
Michael Walsh952f9b02017-03-09 13:11:14 -0600892
Michael Walsh6741f742017-02-20 16:16:38 -0600893 plug_in_setup()
894 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
895 call_point='stop_check')
896 if rc != 0:
897 error_message = "Stopping as requested by user.\n"
898 grp.rprint_error_report(error_message)
899 BuiltIn().fail(error_message)
900
Michael Walshd139f282017-04-04 18:00:23 -0500901 # This should help prevent ConnectionErrors.
Michael Walsh0960b382017-06-22 16:23:37 -0500902 grk.run_key_u("Close All Connections")
Michael Walshd139f282017-04-04 18:00:23 -0500903
Michael Walsh6741f742017-02-20 16:16:38 -0600904 return True
905
906###############################################################################
907
908
909###############################################################################
Michael Walsh83f4bc72017-04-20 16:49:43 -0500910def obmc_boot_test_teardown():
Michael Walsh6741f742017-02-20 16:16:38 -0600911
912 r"""
Michael Walshc9116812017-03-10 14:23:06 -0600913 Clean up after the Main keyword.
Michael Walsh6741f742017-02-20 16:16:38 -0600914 """
915
916 if cp_setup_called:
917 plug_in_setup()
918 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
Michael Walsh600876d2017-05-30 17:58:58 -0500919 call_point='cleanup', stop_on_plug_in_failure=0)
Michael Walsh6741f742017-02-20 16:16:38 -0600920
Michael Walsh600876d2017-05-30 17:58:58 -0500921 if 'boot_results_file_path' in globals():
922 # Save boot_results object to a file in case it is needed again.
923 gp.qprint_timen("Saving boot_results to the following path.")
924 gp.qprint_var(boot_results_file_path)
925 pickle.dump(boot_results, open(boot_results_file_path, 'wb'),
926 pickle.HIGHEST_PROTOCOL)
Michael Walsh0b93fbf2017-03-02 14:42:41 -0600927
Michael Walshff340002017-08-29 11:18:27 -0500928 global save_stack
929 # Restore any global values saved on the save_stack.
930 for parm_name in main_func_parm_list:
931 # Get the parm_value if it was saved on the stack.
932 try:
933 parm_value = save_stack.pop(parm_name)
934 except:
935 # If it was not saved, no further action is required.
936 continue
937
938 # Restore the saved value.
939 cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
940 "}\", parm_value)"
941 gp.dpissuing(cmd_buf)
942 exec(cmd_buf)
943
944 gp.dprintn(save_stack.sprint_obj())
945
Michael Walsh6741f742017-02-20 16:16:38 -0600946###############################################################################
947
948
949###############################################################################
Michael Walshc9116812017-03-10 14:23:06 -0600950def test_teardown():
951
952 r"""
953 Clean up after this test case.
954 """
955
956 gp.qprintn()
957 cmd_buf = ["Print Error",
958 "A keyword timeout occurred ending this program.\n"]
959 BuiltIn().run_keyword_if_timeout_occurred(*cmd_buf)
960
Michael Walshb5839d02017-04-12 16:11:20 -0500961 grp.rqprint_pgm_footer()
962
Michael Walshc9116812017-03-10 14:23:06 -0600963###############################################################################
964
965
966###############################################################################
Michael Walshff340002017-08-29 11:18:27 -0500967def obmc_boot_test_py(loc_boot_stack=None,
968 loc_stack_mode=None,
969 loc_quiet=None):
Michael Walsh6741f742017-02-20 16:16:38 -0600970
971 r"""
972 Do main program processing.
973 """
974
Michael Walshff340002017-08-29 11:18:27 -0500975 global save_stack
976
977 # Process function parms.
978 for parm_name in main_func_parm_list:
979 # Get parm's value.
980 cmd_buf = "parm_value = loc_" + parm_name
981 exec(cmd_buf)
982 gp.dpvar(parm_name)
983 gp.dpvar(parm_value)
984
985 if parm_value is None:
986 # Parm was not specified by the calling function so set it to its
987 # corresponding global value.
988 cmd_buf = "loc_" + parm_name + " = BuiltIn().get_variable_value" +\
989 "(\"${" + parm_name + "}\")"
990 gp.dpissuing(cmd_buf)
991 exec(cmd_buf)
992 else:
993 # Save the global value on a stack.
994 cmd_buf = "save_stack.push(BuiltIn().get_variable_value(\"${" +\
995 parm_name + "}\"), \"" + parm_name + "\")"
996 gp.dpissuing(cmd_buf)
997 exec(cmd_buf)
998
999 # Set the global value to the passed value.
1000 cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
1001 "}\", loc_" + parm_name + ")"
1002 gp.dpissuing(cmd_buf)
1003 exec(cmd_buf)
1004
1005 gp.dprintn(save_stack.sprint_obj())
Michael Walshb5839d02017-04-12 16:11:20 -05001006
Michael Walsh6741f742017-02-20 16:16:38 -06001007 setup()
1008
Michael Walsha20da402017-03-31 16:27:45 -05001009 if ffdc_only:
1010 gp.qprint_timen("Caller requested ffdc_only.")
Michael Walshe0cf8d72017-05-17 13:20:46 -05001011 pre_boot_plug_in_setup()
Michael Walsh83f4bc72017-04-20 16:49:43 -05001012 grk.run_key_u("my_ffdc")
Michael Walsh764d2f82017-04-27 16:01:08 -05001013 return
Michael Walsha20da402017-03-31 16:27:45 -05001014
Michael Walsh6741f742017-02-20 16:16:38 -06001015 # Process caller's boot_stack.
1016 while (len(boot_stack) > 0):
1017 test_loop_body()
1018
Michael Walshb5839d02017-04-12 16:11:20 -05001019 gp.qprint_timen("Finished processing stack.")
Michael Walsh30dadae2017-02-27 14:25:52 -06001020
Michael Walsh6741f742017-02-20 16:16:38 -06001021 # Process caller's boot_list.
1022 if len(boot_list) > 0:
1023 for ix in range(1, max_num_tests + 1):
1024 test_loop_body()
1025
Michael Walshb5839d02017-04-12 16:11:20 -05001026 gp.qprint_timen("Completed all requested boot tests.")
1027
1028 boot_pass, boot_fail = boot_results.return_total_pass_fail()
1029 if boot_fail > boot_fail_threshold:
1030 error_message = "Boot failures exceed the boot failure" +\
1031 " threshold:\n" +\
1032 gp.sprint_var(boot_fail) +\
1033 gp.sprint_var(boot_fail_threshold)
1034 BuiltIn().fail(gp.sprint_error(error_message))
Michael Walsh6741f742017-02-20 16:16:38 -06001035
1036###############################################################################