Changes to obmc_boot_test.robot/obmc_boot_test.py:
- I re-wrote nearly all robot code in python.
Change-Id: Ie68b2714fe107f10486c9b07cc29f4afd2af264c
Signed-off-by: Michael Walsh <micwalsh@us.ibm.com>
diff --git a/extended/obmc_boot_test.robot b/extended/obmc_boot_test.robot
index 8c4714b..3b509bc 100644
--- a/extended/obmc_boot_test.robot
+++ b/extended/obmc_boot_test.robot
@@ -1,23 +1,10 @@
*** Settings ***
Documentation Do random repeated boots based on the state of the BMC machine.
-... The number of repetitions is designated by ${max_num_tests}. Keyword
-... names that are listed in @{AVAIL_BOOTS} become the selection of possible
-... boots for the test.
-Resource ../lib/dvt/obmc_driver_vars.txt
-Resource ../lib/list_utils.robot
-Resource ../lib/openbmc_ffdc.robot
+Library state.py
+Library obmc_boot_test.py
-Library ../lib/gen_robot_print.py
-Library ../lib/gen_misc.py
-Library ../lib/gen_robot_plug_in.py
-Library ../lib/gen_robot_valid.py
-Library ../lib/state.py
-Library ../lib/boot/powerons.py
-Library ../lib/boot/poweroffs.py
-Library ../lib/obmc_boot_test.py
-
-# WITH NAME boot_results
+Resource openbmc_ffdc.robot
*** Variables ***
# Initialize program parameters variables.
@@ -29,11 +16,11 @@
... openbmc_serial_port boot_stack boot_list max_num_tests
... plug_in_dir_paths status_file_path openbmc_model boot_pass boot_fail
... ffdc_dir_path_style ffdc_check state_change_timeout power_on_timeout
-... power_on_timeout test_mode quiet debug
+... power_off_timeout test_mode quiet debug
# Initialize each program parameter.
-${openbmc_nickname} ${EMPTY}
${openbmc_host} ${EMPTY}
+${openbmc_nickname} ${openbmc_host}
${openbmc_username} root
${openbmc_password} 0penBmc
${os_host} ${EMPTY}
@@ -65,25 +52,14 @@
${quiet} 0
${debug} 0
-
-# Plug-in variables.
-${shell_rc} 0x00000000
-${fail_on_plug_in_failure} 1
-${return_on_non_zero_rc} 0
-
-${next_boot} ${EMPTY}
-# State dictionary. Initializing to a realistic state for testing in
-# test_mode.
-
# Flag variables.
-${cp_setup_called} ${0}
# test_really_running is needed by DB_Logging plug-in.
${test_really_running} ${1}
*** Test Cases ***
-Randomized Boot Testing
- [Documentation] Performs random, repeated boots.
- [Tags] Randomized_boot_testing
+General Boot Testing
+ [Documentation] Performs repeated boot tests.
+ [Tags] General_boot_testing
# Call the Main keyword to prevent any dots from appearing in the console
# due to top level keywords.
@@ -94,215 +70,10 @@
Main
[Teardown] Program Teardown
- Setup
+ # This is the "Main" keyword. The advantages of having this keyword vs
+ # just putting the code in the *** Test Cases *** table are:
+ # 1) You won't get a green dot in the output every time you run a keyword.
- :For ${BOOT_COUNT} IN RANGE ${max_num_tests}
- \ Test Loop Body ${BOOT_COUNT}
-
- Rqprint Timen Completed all requested boot tests.
+ Main Py
###############################################################################
-
-
-###############################################################################
-Setup
- [Documentation] Do general program setup tasks.
-
- Validate Parms
-
- Rqprint Pgm Header
-
- Create Boot Results Table
-
- # Preserve the values of boot_pass/boot_fail that were passed in.
- Set Global Variable ${initial_boot_pass} ${boot_pass}
- Set Global Variable ${initial_boot_fail} ${boot_fail}
-
- # Call "setup" plug-ins, if any.
- Plug In Setup
- ${rc} ${shell_rc} ${failed_plug_in_name}= Rprocess Plug In Packages
- ... call_point=setup
- Should Be Equal '${rc}' '${0}'
-
- # Keyword "FFDC" will fail if TEST_MESSAGE is not set.
- Set Global Variable ${TEST_MESSAGE} ${EMPTY}
-
- # Setting cp_setup_called lets our Teardown know that it needs to call
- # the cleanup plug-in call point.
- Set Global Variable ${cp_setup_called} ${1}
-
- Rqprint Timen Getting system state.
- # The state dictionary must be primed before calling Test Loop Body.
- ${temp_state}= Run Keyword If '${test_mode}' == '0' Get State
- ... ELSE Create Dictionary &{default_state}
- Set Global Variable &{state} &{temp_state}
- Rqpvars state
-
-###############################################################################
-
-
-###############################################################################
-Validate Parms
- [Documentation] Validate all program parameters.
-
- Rqprintn
-
- Rvalid Value AVAIL_BOOTS
- Rvalid Value openbmc_host
- Rvalid Value openbmc_username
- Rvalid Value openbmc_password
- # os_host is optional so no validation is being done.
- Run Keyword If '${OS_HOST}' != '${EMPTY}' Run Keywords
- ... Rvalid Value os_username AND
- ... Rvalid Value os_password
- Rvalid Value pdu_host
- Rvalid Value pdu_username
- Rvalid Value pdu_password
- Rvalid Integer pdu_slot_no
- Rvalid Value openbmc_serial_host
- Rvalid Integer openbmc_serial_port
- Rvalid Integer max_num_tests
- Rvalid Value openbmc_model
- Rvalid Integer boot_pass
- Rvalid Integer boot_fail
-
- ${boot_pass_temp}= Convert To Integer ${boot_pass}
- Set Global Variable ${boot_pass} ${boot_pass_temp}
- ${boot_fail_temp}= Convert To Integer ${boot_fail}
- Set Global Variable ${boot_fail} ${boot_fail_temp}
-
- ${temp_arr}= Rvalidate Plug Ins ${plug_in_dir_paths}
- Set Global Variable @{plug_in_packages_list} @{temp_arr}
-
- Run Keyword If '${openbmc_nickname}' == '${EMPTY}'
- ... Set Global Variable ${openbmc_nickname} ${openbmc_host}
-
- Set FFDC Dir Path Style
-
- ${default_state}= Return Default State
- Set Global Variable ${state} ${default_state}
- Set Global Variable ${default_state} ${default_state}
-
-###############################################################################
-
-
-###############################################################################
-Set FFDC Dir Path Style
-
- Run Keyword If '${ffdc_dir_path_style}' != '${EMPTY}' Return from Keyword
-
- ${temp}= Run Keyword and Continue On Failure Get Environment Variable
- ... FFDC_DIR_PATH_STYLE ${0}
-
- Set Global Variable ${ffdc_dir_path_style} ${temp}
-
-###############################################################################
-
-
-###############################################################################
-Program Teardown
- [Documentation] Clean up after this program.
-
- Run Keyword If '${cp_setup_called}' == '1' Run Keywords
- ... Plug In Setup AND
- ... Rprocess Plug In Packages call_point=cleanup
- ... stop_on_plug_in_failure=1
-
- Rqprint Pgm Footer
-
-###############################################################################
-
-
-###############################################################################
-Test Loop Body
- [Documentation] The main loop body for the loop in "main".
- [Arguments] ${BOOT_COUNT}
-
- Rqprintn
- Rqprint Timen Starting boot ${BOOT_COUNT+1} of ${max_num_tests}.
-
- Rqpvars state
-
- ${loc_next_boot}= Select Boot ${state}
- Set Global Variable ${next_boot} ${loc_next_boot}
-
- # Clear this file. Plug-ins may now write to it.
- Remove File ${FFDC_LIST_FILE_PATH}
-
- ${status} ${msg}= Run Keyword And Ignore Error Run Boot ${next_boot}
- Run Keyword If '${status}' == 'FAIL' rprint ${msg}
-
- Rqprintn
- Run Keyword If '${BOOT_STATUS}' == 'PASS' Run Keywords
- ... Set Global Variable ${boot_success} ${1} AND
- ... Rqprint Timen BOOT_SUCCESS: "${next_boot}" succeeded.
- ... ELSE Run Keywords
- ... Set Global Variable ${boot_success} ${0} AND
- ... Rqprint Timen BOOT_FAILED: ${next_boot} failed.
-
- Update Boot Results Table ${next_boot} ${BOOT_STATUS}
-
- # NOTE: A post_test_case call point failure is NOT counted as a boot
- # failure.
- Plug In Setup
- ${rc} ${shell_rc} ${failed_plug_in_name}= Rprocess Plug In Packages
- ... call_point=post_test_case stop_on_plug_in_failure=1
-
- ${rc} ${shell_rc} ${failed_plug_in_name}= Rprocess Plug In Packages
- ... call_point=ffdc_check shell_rc=${0x00000200}
- ... stop_on_plug_in_failure=1 stop_on_non_zero_rc=1
-
- Run Keyword If
- ... '${BOOT_STATUS}' != 'PASS' or '${FFDC_CHECK}' == 'All' or '${shell_rc}' == '${0x00000200}'
- ... Run Keyword and Continue On Failure My FFDC
-
- # Run plug-ins to see if we ought to stop execution.
- Plug In Setup
- ${rc} ${shell_rc} ${failed_plug_in_name}= Rprocess Plug In Packages
- ... call_point=stop_check
- Run Keyword If '${rc}' != '${0}' Run Keywords
- ... Rprint Error Report Stopping as requested by user.
- ... Fail
-
- Print Boot Results Table
- Rqprint Timen Finished boot ${BOOT_COUNT+1} of ${max_num_tests}.
-
- Rqprint Timen Getting system state.
- # The state must be refreshed before calling Test Loop Body again.
- ${temp_state}= Run Keyword If '${test_mode}' == '0' Get State
- ... quiet=${1}
- ... ELSE Create Dictionary &{default_state}
- Set Global Variable &{state} &{temp_state}
- Rqpvars state
-
-###############################################################################
-
-
-###############################################################################
-Run Boot
- [Documentation] Run the selected boot and mark the status when complete.
- [Arguments] ${boot_keyword}
- [Teardown] Set Global Variable ${BOOT_STATUS} ${KEYWORD STATUS}
-
- # boot_keyword The name of the boot to run, which corresponds to the
- # keyword to run. (i.e "BMC Power On")
-
- Print Test Start Message ${boot_keyword}
-
- Plug In Setup
- ${rc} ${shell_rc} ${failed_plug_in_name}= Rprocess Plug In Packages
- ... call_point=pre_boot
- Should Be Equal '${rc}' '${0}'
-
- @{cmd_buf}= Create List ${boot_keyword}
- rqpissuing_keyword ${cmd_buf} ${test_mode}
- Run Keyword If '${test_mode}' == '0' Run Keyword @{cmd_buf}
-
- Plug In Setup
- ${rc} ${shell_rc} ${failed_plug_in_name}= Rprocess Plug In Packages
- ... call_point=post_boot
- Should Be Equal '${rc}' '${0}'
-
-###############################################################################
-
-
diff --git a/lib/obmc_boot_test.py b/lib/obmc_boot_test.py
index 653dde1..d5dabe0 100755
--- a/lib/obmc_boot_test.py
+++ b/lib/obmc_boot_test.py
@@ -4,29 +4,67 @@
This module is the python counterpart to obmc_boot_test.
"""
-from tally_sheet import *
+from boot_data import *
import gen_robot_print as grp
import gen_robot_plug_in as grpi
+import gen_robot_valid as grv
+import gen_misc as gm
+import gen_cmd as gc
import state as st
+import random
import os
import time
-import subprocess
import glob
from robot.utils import DotDict
from robot.libraries.BuiltIn import BuiltIn
-from robot.libraries.OperatingSystem import OperatingSystem
-# Create boot_results_fields for use in creating boot_results.
-boot_results_fields = DotDict([('total', 0), ('pass', 0), ('fail', 0)])
-# Create boot_results which is global to this module.
-boot_results = tally_sheet('boot type',
- boot_results_fields,
- 'boot_test_results')
+# Program parameter processing.
+# Assign all program parms to python variables which are global to this module.
+parm_list = BuiltIn().get_variable_value("${parm_list}")
+int_list = ['max_num_tests', 'boot_pass', 'boot_fail', 'quiet', 'test_mode',
+ 'debug']
+for parm in parm_list:
+ if parm in int_list:
+ sub_cmd = "int(BuiltIn().get_variable_value(\"${" + parm +\
+ "}\", \"0\"))"
+ else:
+ sub_cmd = "BuiltIn().get_variable_value(\"${" + parm + "}\")"
+ cmd_buf = parm + " = " + sub_cmd
+ exec(cmd_buf)
-boot_results.set_sum_fields(['total', 'pass', 'fail'])
-boot_results.set_calc_fields(['total=pass+fail'])
+if ffdc_dir_path_style == "":
+ ffdc_dir_path_style = int(os.environ.get('FFDC_DIR_PATH_STYLE', '0'))
+
+# Set up boot data structures.
+boot_table = create_boot_table()
+valid_boot_types = create_valid_boot_list(boot_table)
+boot_results = boot_results(boot_table, boot_pass, boot_fail)
+boot_lists = read_boot_lists()
+last_ten = []
+# Convert these program parms to more useable lists.
+boot_list = filter(None, boot_list.split(":"))
+boot_stack = filter(None, boot_stack.split(":"))
+
+state = st.return_default_state()
+cp_setup_called = 0
+next_boot = ""
+base_tool_dir_path = os.path.normpath(os.environ.get(
+ 'AUTOBOOT_BASE_TOOL_DIR_PATH', "/tmp")) + os.sep
+ffdc_dir_path = os.path.normpath(os.environ.get('FFDC_DIR_PATH', '')) + os.sep
+ffdc_list_file_path = base_tool_dir_path + openbmc_nickname + "/FFDC_FILE_LIST"
+boot_success = 0
+# Setting master_pid correctly influences the behavior of plug-ins like
+# DB_Logging
+program_pid = os.getpid()
+master_pid = os.environ.get('AUTOBOOT_MASTER_PID', program_pid)
+status_dir_path = os.environ.get('STATUS_DIR_PATH', "")
+if status_dir_path != "":
+ status_dir_path = os.path.normpath(status_dir_path) + os.sep
+default_power_on = "BMC Power On"
+default_power_off = "BMC Power Off"
+boot_count = 0
###############################################################################
@@ -37,66 +75,35 @@
programs.
"""
- boot_pass = int(BuiltIn().get_variable_value("${boot_pass}"))
+ boot_pass, boot_fail = boot_results.return_total_pass_fail()
if boot_pass > 1:
test_really_running = 1
else:
test_really_running = 0
- BuiltIn().set_global_variable("${test_really_running}",
- test_really_running)
-
- next_boot = BuiltIn().get_variable_value("${next_boot}")
- BuiltIn().set_global_variable("${boot_type_desc}", next_boot)
-
- # Setting master_pid correctly influences the behavior of plug-ins like
- # DB_Logging
- program_pid = BuiltIn().get_variable_value("${program_pid}")
- try:
- master_pid = OperatingSystem().get_environment_variable(
- "AUTOBOOT_MASTER_PID")
- except RuntimeError:
- master_pid = program_pid
- if master_pid == "":
- master_pid = program_pid
-
- BuiltIn().set_global_variable("${master_pid}", master_pid)
-
seconds = time.time()
loc_time = time.localtime(seconds)
time_string = time.strftime("%y%m%d.%H%M%S.", loc_time)
- openbmc_nickname = BuiltIn().get_variable_value("${openbmc_nickname}")
- openbmc_host = BuiltIn().get_variable_value("${openbmc_host}")
- if openbmc_nickname == "":
- openbmc_nickname = openbmc_host
- ffdc_prefix = openbmc_nickname
+ ffdc_prefix = openbmc_nickname + "." + time_string
- ffdc_prefix += "." + time_string
-
- try:
- ffdc_dir_path = os.environ['FFDC_DIR_PATH']
- # Add trailing slash.
- ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep
- except KeyError:
- ffdc_dir_path = ""
+ BuiltIn().set_global_variable("${test_really_running}",
+ test_really_running)
+ BuiltIn().set_global_variable("${boot_type_desc}", next_boot)
+ BuiltIn().set_global_variable("${master_pid}", master_pid)
BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path)
-
- status_dir_path = os.environ.get('STATUS_DIR_PATH', "")
- if status_dir_path != "":
- # Add trailing slash.
- status_dir_path = os.path.normpath(status_dir_path) + os.sep
BuiltIn().set_global_variable("${STATUS_DIR_PATH}", status_dir_path)
-
- base_tool_dir_path = os.environ.get('AUTOBOOT_BASE_TOOL_DIR_PATH', "/tmp")
- base_tool_dir_path = os.path.normpath(base_tool_dir_path) + os.sep
BuiltIn().set_global_variable("${BASE_TOOL_DIR_PATH}", base_tool_dir_path)
-
- ffdc_list_file_path = base_tool_dir_path + openbmc_nickname +\
- "/FFDC_FILE_LIST"
-
BuiltIn().set_global_variable("${FFDC_LIST_FILE_PATH}",
ffdc_list_file_path)
+ BuiltIn().set_global_variable("${FFDC_DIR_PATH_STYLE}",
+ ffdc_dir_path_style)
+ BuiltIn().set_global_variable("${FFDC_CHECK}",
+ ffdc_check)
+ BuiltIn().set_global_variable("${boot_pass}", boot_pass)
+ BuiltIn().set_global_variable("${boot_fail}", boot_fail)
+ BuiltIn().set_global_variable("${boot_success}", boot_success)
+ BuiltIn().set_global_variable("${ffdc_prefix}", ffdc_prefix)
# For each program parameter, set the corresponding AUTOBOOT_ environment
# variable value. Also, set an AUTOBOOT_ environment variable for every
@@ -106,9 +113,6 @@
"master_pid", "ffdc_prefix", "ffdc_dir_path",
"status_dir_path", "base_tool_dir_path",
"ffdc_list_file_path"]
- BuiltIn().set_global_variable("${ffdc_prefix}", ffdc_prefix)
-
- parm_list = BuiltIn().get_variable_value("@{parm_list}")
plug_in_vars = parm_list + additional_values
@@ -117,113 +121,175 @@
var_name = var_name.upper()
if var_value is None:
var_value = ""
- OperatingSystem().set_environment_variable(
- "AUTOBOOT_" + var_name, var_value)
+ os.environ["AUTOBOOT_" + var_name] = str(var_value)
- debug = int(BuiltIn().get_variable_value("${debug}"))
if debug:
- cmd_buf = "printenv | egrep AUTOBOOT_ | sort -u"
- grp.rpissuing(cmd_buf)
- sub_proc = subprocess.Popen(cmd_buf, shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- out_buf, err_buf = sub_proc.communicate()
- shell_rc = sub_proc.returncode
- grp.rprint(out_buf)
+ shell_rc, out_buf = \
+ gc.cmd_fnc_u("printenv | egrep AUTOBOOT_ | sort -u")
###############################################################################
###############################################################################
-def create_boot_results_table():
+def setup():
r"""
- Create our boot_results_table.
+ Do general program setup tasks.
"""
- # At some point we'll want to change to reading in our boot types from
- # some external source (e.g. file).
+ global cp_setup_called
- boot_results.add_row('BMC Power On')
- boot_results.add_row('BMC Power Off')
+ grp.rqprintn()
+
+ validate_parms()
+
+ grp.rqprint_pgm_header()
+
+ plug_in_setup()
+ rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
+ call_point='setup')
+ if rc != 0:
+ error_message = "Plug-in setup failed.\n"
+ grp.rprint_error_report(error_message)
+ BuiltIn().fail(error_message)
+ # Setting cp_setup_called lets our Teardown know that it needs to call
+ # the cleanup plug-in call point.
+ cp_setup_called = 1
+
+ # Keyword "FFDC" will fail if TEST_MESSAGE is not set.
+ BuiltIn().set_global_variable("${TEST_MESSAGE}", "${EMPTY}")
+
+ grp.rdprint_var(boot_table, 1)
+ grp.rdprint_var(boot_lists)
###############################################################################
###############################################################################
-def update_boot_results_table(boot_type,
- boot_status):
+def validate_parms():
r"""
- Update our boot_results_table. This includes:
- - Updating the record for the given boot_type by incrementing the pass or
- fail field.
- - Calling the calc method to have the totals, etc. calculated.
- - Updating global variables boot_pass/boot_fail.
-
- Description of arguments:
- boot_type The type of boot just done (e.g. "BMC Power On").
- boot_status The status of the boot just done. This should be equal to
- either "pass" or "fail" (case-insensitive).
+ Validate all program parameters.
"""
- boot_results.inc_row_field(boot_type, boot_status.lower())
- totals_line = boot_results.calc()
+ grp.rqprintn()
- # The caller of obmc_boot_test can pass boot_pass/boot_fail values because
- # the caller may have already done some testing (e.g. "BMC OOB"). For the
- # sake of DB logging done by plug-ins, we want to include these in our
- # overall totals.
- initial_boot_pass = int(BuiltIn().get_variable_value(
- "${initial_boot_pass}"))
- initial_boot_fail = int(BuiltIn().get_variable_value(
- "${initial_boot_fail}"))
+ grv.rvalid_value("openbmc_host")
+ grv.rvalid_value("openbmc_username")
+ grv.rvalid_value("openbmc_password")
+ if os_host != "":
+ grv.rvalid_value("os_username")
+ grv.rvalid_value("os_password")
- BuiltIn().set_global_variable("${boot_pass}",
- totals_line['pass'] + initial_boot_pass)
- BuiltIn().set_global_variable("${boot_fail}",
- totals_line['fail'] + initial_boot_fail)
+ if pdu_host != "":
+ grv.rvalid_value("pdu_username")
+ grv.rvalid_value("pdu_password")
+ grv.rvalid_integer("pdu_slot_no")
+ if openbmc_serial_host != "":
+ grv.rvalid_integer("openbmc_serial_port")
+ grv.rvalid_integer("max_num_tests")
+ grv.rvalid_value("openbmc_model")
+ grv.rvalid_integer("boot_pass")
+ grv.rvalid_integer("boot_fail")
+
+ plug_in_packages_list = grpi.rvalidate_plug_ins(plug_in_dir_paths)
+ BuiltIn().set_global_variable("${plug_in_packages_list}",
+ plug_in_packages_list)
+
+ if len(boot_list) == 0 and len(boot_stack) == 0:
+ error_message = "You must provide either a value for either the" +\
+ " boot_list or the boot_stack parm.\n"
+ BuiltIn().fail(gp.sprint_error(error_message))
+
+ valid_boot_list(boot_list, valid_boot_types)
+ valid_boot_list(boot_stack, valid_boot_types)
+
+ return
###############################################################################
###############################################################################
-def print_boot_results_table(header_footer="\n"):
+def my_get_state():
r"""
- Print the formatted boot_resuls_table to the console.
+ Get the system state plus a little bit of wrapping.
"""
- grp.rqprint(header_footer)
- grp.rqprint(boot_results.sprint_report())
- grp.rqprint(header_footer)
+ global state
+
+ req_states = ['epoch_seconds'] + st.default_req_states
+
+ grp.rqprint_timen("Getting system state.")
+ if test_mode:
+ state['epoch_seconds'] = int(time.time())
+ else:
+ state = st.get_state(req_states=req_states, quiet=0)
+ grp.rprint_var(state)
###############################################################################
###############################################################################
-def select_boot(state):
+def select_boot():
r"""
Select a boot test to be run based on our current state and return the
chosen boot type.
Description of arguments:
- state The state of the machine, which will include the power state..
+ state The state of the machine.
"""
- if 'chassis' in state:
- # New style state.
- if state['chassis'] == 'Off':
- boot = 'BMC Power On'
+ grp.rprint_timen("Selecting a boot test.")
+
+ my_get_state()
+
+ stack_popped = 0
+ if len(boot_stack) > 0:
+ stack_popped = 1
+ grp.rprint_dashes()
+ grp.rprint_var(boot_stack)
+ grp.rprint_dashes()
+ boot_candidate = boot_stack.pop()
+ if st.compare_states(state, boot_table[boot_candidate]['start']):
+ grp.rprint_timen("The machine state is valid for a '" +
+ boot_candidate + "' boot test.")
+ grp.rprint_dashes()
+ grp.rprint_var(boot_stack)
+ grp.rprint_dashes()
+ return boot_candidate
else:
- boot = 'BMC Power Off'
- else:
- # Old style state.
- if state['power'] == 0:
- boot = 'BMC Power On'
- else:
- boot = 'BMC Power Off'
+ grp.rprint_timen("The machine state is not valid for a '" +
+ boot_candidate + "' boot test.")
+ boot_stack.append(boot_candidate)
+ popped_boot = boot_candidate
+
+ # Loop through your list selecting a boot_candidates
+ boot_candidates = []
+ for boot_candidate in boot_list:
+ if st.compare_states(state, boot_table[boot_candidate]['start']):
+ if stack_popped:
+ if st.compare_states(boot_table[boot_candidate]['end'],
+ boot_table[popped_boot]['start']):
+ boot_candidates.append(boot_candidate)
+ else:
+ boot_candidates.append(boot_candidate)
+
+ if len(boot_candidates) == 0:
+ grp.rprint_timen("The user's boot list contained no boot tests" +
+ " which are valid for the current machine state.")
+ boot_candidate = default_power_on
+ if not st.compare_states(state, boot_table[default_power_on]['start']):
+ boot_candidate = default_power_off
+ boot_candidates.append(boot_candidate)
+ grp.rprint_timen("Using default '" + boot_candidate +
+ "' boot type to transtion to valid state.")
+
+ grp.rdprint_var(boot_candidates)
+
+ # Randomly select a boot from the candidate list.
+ boot = random.choice(boot_candidates)
return boot
@@ -231,39 +297,6 @@
###############################################################################
-def my_ffdc():
-
- r"""
- Collect FFDC data.
- """
-
- plug_in_setup()
- rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
- call_point='ffdc', stop_on_plug_in_failure=1)
-
- AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX']
-
- # FFDC_LOG_PATH is used by "FFDC" keyword.
- FFDC_DIR_PATH = BuiltIn().get_variable_value("${FFDC_DIR_PATH}")
- BuiltIn().set_global_variable("${FFDC_LOG_PATH}",
- FFDC_DIR_PATH)
-
- cmd_buf = ["FFDC", "ffdc_prefix=" + AUTOBOOT_FFDC_PREFIX]
- grp.rpissuing_keyword(cmd_buf)
- BuiltIn().run_keyword(*cmd_buf)
-
- state = st.get_state()
- BuiltIn().set_global_variable("${state}",
- state)
-
- cmd_buf = ["Print Defect Report"]
- grp.rpissuing_keyword(cmd_buf)
- BuiltIn().run_keyword(*cmd_buf)
-
-###############################################################################
-
-
-###############################################################################
def print_last_boots():
r"""
@@ -273,7 +306,6 @@
# indent 0, 90 chars wide, linefeed, char is "="
grp.rqprint_dashes(0, 90)
grp.rqprintn("Last 10 boots:\n")
- last_ten = BuiltIn().get_variable_value("${LAST_TEN}")
for boot_entry in last_ten:
grp.rqprint(boot_entry)
@@ -283,29 +315,6 @@
###############################################################################
-def print_test_start_message(boot_keyword):
-
- r"""
- Print a message indicating what boot test is about to run.
-
- Description of arguments:
- boot_keyword The name of the boot which is to be run
- (e.g. "BMC Power On").
- """
-
- doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".")
- grp.rqprint(doing_msg)
-
- last_ten = BuiltIn().get_variable_value("${LAST_TEN}")
- last_ten.append(doing_msg)
-
- if len(last_ten) > 10:
- del last_ten[0]
-
-###############################################################################
-
-
-###############################################################################
def print_defect_report():
r"""
@@ -317,15 +326,12 @@
grp.rqprint_dashes(0, 90, 1, "=")
grp.rqprintn("Copy this data to the defect:\n")
- parm_list = BuiltIn().get_variable_value("${parm_list}")
-
grp.rqpvars(*parm_list)
grp.rqprintn()
print_last_boots()
grp.rqprintn()
- state = BuiltIn().get_variable_value("${state}")
grp.rqpvar(state)
# At some point I'd like to have the 'Call FFDC Methods' return a list
@@ -337,17 +343,11 @@
LOG_PREFIX = BuiltIn().get_variable_value("${LOG_PREFIX}")
output = '\n'.join(glob.glob(LOG_PREFIX + '*'))
-
- FFDC_LIST_FILE_PATH = \
- BuiltIn().get_variable_value("${FFDC_LIST_FILE_PATH}")
-
try:
- ffdc_list = open(FFDC_LIST_FILE_PATH, 'r')
+ ffdc_list = open(ffdc_list_file_path, 'r')
except IOError:
ffdc_list = ""
- status_file_path = BuiltIn().get_variable_value("${status_file_path}")
-
grp.rqprintn()
grp.rqprintn("FFDC data files:")
if status_file_path != "":
@@ -360,3 +360,234 @@
grp.rqprint_dashes(0, 90, 1, "=")
###############################################################################
+
+
+###############################################################################
+def my_ffdc():
+
+ r"""
+ Collect FFDC data.
+ """
+
+ global state
+
+ plug_in_setup()
+ rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
+ call_point='ffdc', stop_on_plug_in_failure=1)
+
+ AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX']
+
+ # FFDC_LOG_PATH is used by "FFDC" keyword.
+ BuiltIn().set_global_variable("${FFDC_LOG_PATH}", ffdc_dir_path)
+
+ cmd_buf = ["FFDC", "ffdc_prefix=" + AUTOBOOT_FFDC_PREFIX]
+ grp.rpissuing_keyword(cmd_buf)
+ BuiltIn().run_keyword(*cmd_buf)
+
+ my_get_state()
+
+ print_defect_report()
+
+###############################################################################
+
+
+###############################################################################
+def print_test_start_message(boot_keyword):
+
+ r"""
+ Print a message indicating what boot test is about to run.
+
+ Description of arguments:
+ boot_keyword The name of the boot which is to be run
+ (e.g. "BMC Power On").
+ """
+
+ global last_ten
+
+ doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".")
+ grp.rqprint(doing_msg)
+
+ last_ten.append(doing_msg)
+
+ if len(last_ten) > 10:
+ del last_ten[0]
+
+###############################################################################
+
+
+###############################################################################
+def run_boot(boot):
+
+ r"""
+ Run the specified boot.
+
+ Description of arguments:
+ boot The name of the boot test to be performed.
+ """
+
+ global state
+
+ print_test_start_message(boot)
+
+ plug_in_setup()
+ rc, shell_rc, failed_plug_in_name = \
+ grpi.rprocess_plug_in_packages(call_point="pre_boot")
+ if rc != 0:
+ error_message = "Plug-in failed with non-zero return code.\n" +\
+ gp.sprint_var(rc, 1)
+ BuiltIn().fail(gp.sprint_error(error_message))
+
+ if test_mode:
+ # In test mode, we'll pretend the boot worked by assigning its
+ # required end state to the default state value.
+ state = boot_table[boot]['end']
+ else:
+ # Assertion: We trust that the state data was made fresh by the
+ # caller.
+
+ grp.rprintn()
+
+ if boot_table[boot]['method_type'] == "keyword":
+ cmd_buf = boot_table[boot]['method'].split(" ")
+ grp.rpissuing_keyword(cmd_buf)
+ BuiltIn().run_keyword(*cmd_buf)
+
+ if boot_table[boot]['bmc_reboot']:
+ st.wait_for_comm_cycle(int(state['epoch_seconds']))
+ else:
+ match_state = st.anchor_state(state)
+ del match_state['epoch_seconds']
+ # Wait for the state to change in any way.
+ st.wait_state(match_state, wait_time=state_change_timeout,
+ interval="3 seconds", invert=1)
+
+ grp.rprintn()
+ if boot_table[boot]['end']['chassis'] == "Off":
+ boot_timeout = power_off_timeout
+ else:
+ boot_timeout = power_on_timeout
+ st.wait_state(boot_table[boot]['end'], wait_time=boot_timeout,
+ interval="3 seconds")
+
+ plug_in_setup()
+ rc, shell_rc, failed_plug_in_name = \
+ grpi.rprocess_plug_in_packages(call_point="post_boot")
+ if rc != 0:
+ error_message = "Plug-in failed with non-zero return code.\n" +\
+ gp.sprint_var(rc, 1)
+ BuiltIn().fail(gp.sprint_error(error_message))
+
+###############################################################################
+
+
+###############################################################################
+def test_loop_body():
+
+ r"""
+ The main loop body for the loop in main_py.
+
+ Description of arguments:
+ boot_count The iteration number (starts at 1).
+ """
+
+ global boot_count
+ global state
+ global next_boot
+ global boot_success
+
+ grp.rqprintn()
+
+ boot_count += 1
+
+ next_boot = select_boot()
+
+ grp.rqprint_timen("Starting boot " + str(boot_count) + ".")
+
+ # Clear the ffdc_list_file_path file. Plug-ins may now write to it.
+ try:
+ os.remove(ffdc_list_file_path)
+ except OSError:
+ pass
+
+ cmd_buf = ["run_boot", next_boot]
+ boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
+ if boot_status == "FAIL":
+ grp.rprint(msg)
+
+ grp.rqprintn()
+ if boot_status == "PASS":
+ boot_success = 1
+ grp.rqprint_timen("BOOT_SUCCESS: \"" + next_boot + "\" succeeded.")
+ else:
+ boot_success = 0
+ grp.rqprint_timen("BOOT_FAILED: \"" + next_boot + "\" failed.")
+
+ boot_results.update(next_boot, boot_status)
+
+ plug_in_setup()
+ # NOTE: A post_test_case call point failure is NOT counted as a boot
+ # failure.
+ rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
+ call_point='post_test_case', stop_on_plug_in_failure=1)
+
+ plug_in_setup()
+ rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
+ call_point='ffdc_check', shell_rc=0x00000200,
+ stop_on_plug_in_failure=1, stop_on_non_zero_rc=1)
+ if boot_status != "PASS" or ffdc_check == "All" or shell_rc == 0x00000200:
+ cmd_buf = ["my_ffdc"]
+ grp.rpissuing_keyword(cmd_buf)
+ BuiltIn().run_keyword_and_continue_on_failure(*cmd_buf)
+
+ plug_in_setup()
+ rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
+ call_point='stop_check')
+ if rc != 0:
+ error_message = "Stopping as requested by user.\n"
+ grp.rprint_error_report(error_message)
+ BuiltIn().fail(error_message)
+
+ boot_results.print_report()
+ grp.rqprint_timen("Finished boot " + str(boot_count) + ".")
+
+ return True
+
+###############################################################################
+
+
+###############################################################################
+def program_teardown():
+
+ r"""
+ Clean up after this program.
+ """
+
+ if cp_setup_called:
+ plug_in_setup()
+ rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
+ call_point='cleanup', stop_on_plug_in_failure=1)
+
+###############################################################################
+
+
+###############################################################################
+def main_py():
+
+ r"""
+ Do main program processing.
+ """
+
+ setup()
+
+ # Process caller's boot_stack.
+ while (len(boot_stack) > 0):
+ test_loop_body()
+
+ # Process caller's boot_list.
+ if len(boot_list) > 0:
+ for ix in range(1, max_num_tests + 1):
+ test_loop_body()
+
+ grp.rqprint_timen("Completed all requested boot tests.")
+
+###############################################################################