def restore_plug_in_value(default=""):
    r"""
    Return a value from a plug-in save file.

    The name of the value to be restored will be determined by this function
    based on the lvalue being assigned.  Consider the following example:

    my_var1 = restore_plug_in_value(2)

    In this example, this function would look for the "my_var1" file in the
    plug-in save directory, read its value and return it.  If no such file
    exists, the default value of 2 would be returned.

    Description of argument(s):
    default                         The default value to be returned if there
                                    is no plug-in save file for the value in
                                    question.
    """

    # Get the lvalue from the caller's invocation of this function.
    lvalue = gp.get_arg_name(0, -1, stack_frame_ix=2)
    plug_in_save_dir_path = create_plug_in_save_dir()
    save_file_path = plug_in_save_dir_path + lvalue
    if os.path.isfile(save_file_path):
        gp.qprint_timen("Restoring " + lvalue + " value from "
                        + save_file_path + ".")
        return gm.file_to_list(save_file_path, newlines=0, comments=0,
                               trim=1)[0]
    else:
        gp.qprint_timen("Save file " + save_file_path
                        + " does not exist so returning default value.")
        return default
def obmc_boot_test_teardown():
    r"""
    Clean up after the Main keyword.
    """

    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=0)

    if 'boot_results_file_path' in globals():
        # Save boot_results object to a file in case it is needed again.
        gp.qprint_timen("Saving boot_results to the following path.")
        gp.qprint_var(boot_results_file_path)
        pickle.dump(boot_results, open(boot_results_file_path, 'wb'),
                    pickle.HIGHEST_PROTOCOL)

    global save_stack
    # Restore any global values saved on the save_stack.
    for parm_name in main_func_parm_list:
        # Get the parm_value if it was saved on the stack.
        try:
            parm_value = save_stack.pop(parm_name)
        except BaseException:
            # If it was not saved, no further action is required.
            continue

        # Restore the saved value.
        cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
            "}\", parm_value)"
        gp.dpissuing(cmd_buf)
        exec(cmd_buf)

    gp.dprintn(save_stack.sprint_obj())
def exit_not_master():
    r"""
    Exit the program with return code zero if this program was NOT called by the master program.

    There are cases where plug-ins are called by a multi-layered stack:

    master_wrapper
        obmc_boot_test.py
            Example_plug_in/cp_setup

    In a scenario like this, Example_plug_in/cp_setup may be called once directly by master_wrapper (the
    master) and and then called again directly by obmc_boot_test.py (the child).  Some plug-in programs may
    wish to avoid doing any processing on the second such call.  This function will achieve that purpose.

    This function will print a standard message to stdout prior to exiting.
    """

    AUTOBOOT_MASTER_PID = gm.get_mod_global("AUTOBOOT_MASTER_PID")
    AUTOBOOT_PROGRAM_PID = gm.get_mod_global("AUTOBOOT_PROGRAM_PID")

    if AUTOBOOT_MASTER_PID != AUTOBOOT_PROGRAM_PID:
        message = get_plug_in_package_name() + "/" + gp.pgm_name + " is not" \
            + " being called by the master program in the stack so no action" \
            + " will be taken."
        gp.qprint_timen(message)
        gp.qprint_vars(AUTOBOOT_MASTER_PID, AUTOBOOT_PROGRAM_PID)
        exit(0)
def obmc_boot_test_teardown():
    r"""
    Clean up after the Main keyword.
    """

    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=0)

    if 'boot_results_file_path' in globals():
        # Save boot_results object to a file in case it is needed again.
        gp.qprint_timen("Saving boot_results to the following path.")
        gp.qprint_var(boot_results_file_path)
        pickle.dump(boot_results, open(boot_results_file_path, 'wb'),
                    pickle.HIGHEST_PROTOCOL)

    global save_stack
    # Restore any global values saved on the save_stack.
    for parm_name in main_func_parm_list:
        # Get the parm_value if it was saved on the stack.
        try:
            parm_value = save_stack.pop(parm_name)
        except:
            # If it was not saved, no further action is required.
            continue

        # Restore the saved value.
        cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
            "}\", parm_value)"
        gp.dpissuing(cmd_buf)
        exec(cmd_buf)

    gp.dprintn(save_stack.sprint_obj())
Пример #5
0
def restore_plug_in_value(default=""):
    r"""
    Return a value from a plug-in save file.

    The name of the value to be restored will be determined by this function
    based on the lvalue being assigned.  Consider the following example:

    my_var1 = restore_plug_in_value(2)

    In this example, this function would look for the "my_var1" file in the
    plug-in save directory, read its value and return it.  If no such file
    exists, the default value of 2 would be returned.

    Description of argument(s):
    default                         The default value to be returned if there
                                    is no plug-in save file for the value in
                                    question.
    """

    # Get the lvalue from the caller's invocation of this function.
    lvalue = gp.get_arg_name(0, -1, stack_frame_ix=2)
    plug_in_save_dir_path = create_plug_in_save_dir()
    save_file_path = plug_in_save_dir_path + lvalue
    if os.path.isfile(save_file_path):
        gp.qprint_timen("Restoring " + lvalue + " value from " +
                        save_file_path + ".")
        return gm.file_to_list(save_file_path, newlines=0, comments=0,
                               trim=1)[0]
    else:
        gp.qprint_timen("Save file " + save_file_path +
                        " does not exist so returning default value.")
        return default
def restore_plug_in_value(*args, **kwargs):
    r"""
    Return a value from a plug-in save file.

    The args/kwargs are interpreted differently depending on how this function is called.

    Mode 1 - The output of this function is assigned to a variable:

    Example:

    my_var1 = restore_plug_in_value(2)

    In this mode, the lvalue ("my_var1" in this example) will serve as the name of the value to be restored.

    Mode 2 - The output of this function is NOT assigned to a variable:

    Example:

    if restore_plug_in_value('my_var1', 2):
        do_something()

    In this mode, the caller must explicitly provide the name of the value being restored.

    The args/kwargs are interpreted as follows:

    Description of argument(s):
    var_name                        The name of the value to be restored. Only relevant in mode 1 (see
                                    example above).
    default                         The default value to be returned if there is no plug-in save file for the
                                    value in question.
    plug_in_package_name            See compose_plug_in_save_dir_path for details.
    """
    # Process args.
    lvalue = gp.get_arg_name(0, -1, stack_frame_ix=2)
    if lvalue:
        var_name = lvalue
    else:
        var_name, args, kwargs = fa.pop_arg("", *args, **kwargs)
    default, args, kwargs = fa.pop_arg("", *args, **kwargs)
    plug_in_package_name, args, kwargs = fa.pop_arg(None, *args, **kwargs)
    if args or kwargs:
        error_message = "Programmer error - Too many arguments passed for this function."
        raise ValueError(error_message)
    plug_in_save_dir_path = create_plug_in_save_dir(plug_in_package_name)
    save_file_path = plug_in_save_dir_path + var_name
    if os.path.isfile(save_file_path):
        gp.qprint_timen("Restoring " + var_name + " value from " + save_file_path + ".")
        var_value = gm.file_to_list(save_file_path, newlines=0, comments=0, trim=1)[0]
        if type(default) is bool:
            # Convert from string to bool.
            var_value = (var_value == 'True')
        if type(default) is int:
            # Convert from string to int.
            var_value = int(var_value)
    else:
        var_value = default
        gp.qprint_timen("Save file " + save_file_path + " does not exist so returning default value.")

    gp.qprint_varx(var_name, var_value)
    return var_value
def save_plug_in_value(value, plug_in_package_name=None):
    r"""
    Save a value in a plug-in save file.  The value may be retrieved later via
    a call to the restore_plug_in_value function.

    This function will figure out the variable name of the value passed and
    use that name in creating the plug-in save file.

    Example call:

    my_var1 = 5
    save_plug_in_value(my_var1)

    In this example, the value "5" would be saved to the "my_var1" file in the
    plug-in save directory.

    Description of argument(s):
    value                           The value to be saved.
    plug_in_package_name            See compose_plug_in_save_dir_path for
                                    details.
    """

    # Get the name of the variable used as argument one to this function.
    var_name = gp.get_arg_name(0, 1, stack_frame_ix=2)
    plug_in_save_dir_path = create_plug_in_save_dir(plug_in_package_name)
    save_file_path = plug_in_save_dir_path + var_name
    gp.qprint_timen("Saving \"" + var_name + "\" value.")
    gc.shell_cmd("echo '" + str(value) + "' > " + save_file_path)
def save_plug_in_value(value):
    r"""
    Save a value in a plug-in save file.  The value may be retrieved later via
    a call to the restore_plug_in_value function.

    This function will figure out the variable name of the value passed and
    use that name in creating the plug-in save file.

    Example call:

    my_var1 = 5
    save_plug_in_value(my_var1)

    In this example, the value "5" would be saved to the "my_var1" file in the
    plug-in save directory.

    Description of argument(s):
    value                           The value to be saved.
    """

    # Get the name of the variable used as argument one to this function.
    var_name = gp.get_arg_name(0, 1, stack_frame_ix=2)
    plug_in_save_dir_path = create_plug_in_save_dir()
    save_file_path = plug_in_save_dir_path + var_name
    gp.qprint_timen("Saving \"" + var_name + "\" value.")
    gc.shell_cmd("echo '" + str(value) + "' > " + save_file_path)
Пример #9
0
def wait_for_comm_cycle(start_boot_seconds, quiet=None):
    r"""
    Wait for communications to the BMC to stop working and then resume working.
    This function is useful when you have initiated some kind of reboot.

    Description of arguments:
    start_boot_seconds  The time that the boot test started.  The format is the
                        epoch time in seconds, i.e. the number of seconds since
                        1970-01-01 00:00:00 UTC.  This value should be obtained
                        from the BMC so that it is not dependent on any kind of
                        synchronization between this machine and the target BMC
                        This will allow this program to work correctly even in
                        a simulated environment.  This value should be obtained
                        by the caller prior to initiating a reboot.  It can be
                        obtained as follows:
                        state = st.get_state(req_states=['epoch_seconds'])
    """

    quiet = int(gp.get_var_value(quiet, 0))

    # Validate parms.
    error_message = gv.svalid_integer(start_boot_seconds,
                                      var_name="start_boot_seconds")
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    match_state = anchor_state(DotDict([('packet_loss', '100')]))
    # Wait for 100% packet loss trying to ping machine.
    wait_state(match_state, wait_time="8 mins", interval="0 seconds")

    match_state['packet_loss'] = '^0$'
    # Wait for 0% packet loss trying to ping machine.
    wait_state(match_state, wait_time="8 mins", interval="0 seconds")

    # Get the uptime and epoch seconds for comparisons.  We want to be sure
    # that the uptime is less than the elapsed boot time.  Further proof that
    # a reboot has indeed occurred (vs random network instability giving a
    # false positive.
    state = get_state(req_states=['uptime', 'epoch_seconds'], quiet=quiet)

    elapsed_boot_time = int(state['epoch_seconds']) - start_boot_seconds
    gp.qprint_var(elapsed_boot_time)
    if int(float(state['uptime'])) < elapsed_boot_time:
        uptime = state['uptime']
        gp.qprint_var(uptime)
        gp.qprint_timen("The uptime is less than the elapsed boot time," +
                        " as expected.")
    else:
        error_message = "The uptime is greater than the elapsed boot time," +\
                        " which is unexpected:\n" +\
                        gp.sprint_var(start_boot_seconds) +\
                        gp.sprint_var(state)
        BuiltIn().fail(gp.sprint_error(error_message))

    gp.qprint_timen("Verifying that REST API interface is working.")
    match_state = DotDict([('rest', '^1$')])
    state = wait_state(match_state, wait_time="5 mins", interval="2 seconds")
def get_pre_reboot_state():
    r"""
    Get and return a custom state which is comprised of the
    st.default_req_states plus epoch_seconds.
    """

    global state

    req_states = ['epoch_seconds'] + st.default_req_states

    gp.qprint_timen("Get system state.")
    state = st.get_state(req_states=req_states, quiet=0)
    gp.qprint_var(state)
    return state
Пример #11
0
def cleanup_boot_results_file():
    r"""
    Delete all boot results files whose corresponding pids are no longer active.
    """

    # Use create_boot_results_file_path to create a globex to find all of the existing boot results files.
    globex = create_boot_results_file_path("*", "*", "*")
    file_list = sorted(glob.glob(globex))
    for file_path in file_list:
        # Use parse_file_path to extract info from the file path.
        file_dict = vf.parse_file_path(file_path)
        if gm.pid_active(file_dict['master_pid']):
            gp.qprint_timen("Preserving " + file_path + ".")
        else:
            gc.cmd_fnc("rm -f " + file_path)
def my_get_state():
    r"""
    Get the system state plus a little bit of wrapping.
    """

    global state

    req_states = ['epoch_seconds'] + st.default_req_states

    gp.qprint_timen("Getting system state.")
    if test_mode:
        state['epoch_seconds'] = int(time.time())
    else:
        state = st.get_state(req_states=req_states, quiet=quiet)
    gp.qprint_var(state)
def my_get_state():
    r"""
    Get the system state plus a little bit of wrapping.
    """

    global state

    req_states = ['epoch_seconds'] + st.default_req_states

    gp.qprint_timen("Getting system state.")
    if test_mode:
        state['epoch_seconds'] = int(time.time())
    else:
        state = st.get_state(req_states=req_states, quiet=quiet)
    gp.qprint_var(state)
def obmc_boot_test_teardown():
    r"""
    Clean up after the Main keyword.
    """

    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=0)

    if 'boot_results_file_path' in globals():
        # Save boot_results object to a file in case it is needed again.
        gp.qprint_timen("Saving boot_results to the following path.")
        gp.qprint_var(boot_results_file_path)
        pickle.dump(boot_results, open(boot_results_file_path, 'wb'),
                    pickle.HIGHEST_PROTOCOL)
def obmc_boot_test_teardown():

    r"""
    Clean up after the Main keyword.
    """

    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=0)

    if 'boot_results_file_path' in globals():
        # Save boot_results object to a file in case it is needed again.
        gp.qprint_timen("Saving boot_results to the following path.")
        gp.qprint_var(boot_results_file_path)
        pickle.dump(boot_results, open(boot_results_file_path, 'wb'),
                    pickle.HIGHEST_PROTOCOL)
Пример #16
0
def cleanup_boot_results_file():
    r"""
    Delete all boot results files whose corresponding pids are no longer
    active.
    """

    # Use create_boot_results_file_path to create a globex to find all of the
    # existing boot results files.
    globex = create_boot_results_file_path("*", "*", "*")
    file_list = sorted(glob.glob(globex))
    for file_path in file_list:
        # Use parse_file_path to extract info from the file path.
        file_dict = vf.parse_file_path(file_path)
        if gm.pid_active(file_dict['master_pid']):
            gp.qprint_timen("Preserving " + file_path + ".")
        else:
            gc.cmd_fnc("rm -f " + file_path)
def restore_plug_in_value(default="", plug_in_package_name=None):
    r"""
    Return a value from a plug-in save file.

    The name of the value to be restored will be determined by this function
    based on the lvalue being assigned.  Consider the following example:

    my_var1 = restore_plug_in_value(2)

    In this example, this function would look for the "my_var1" file in the
    plug-in save directory, read its value and return it.  If no such file
    exists, the default value of 2 would be returned.

    Description of argument(s):
    default                         The default value to be returned if there
                                    is no plug-in save file for the value in
                                    question.
    plug_in_package_name            See compose_plug_in_save_dir_path for
                                    details.
    """

    # Get the lvalue from the caller's invocation of this function.
    lvalue = gp.get_arg_name(0, -1, stack_frame_ix=2)
    plug_in_save_dir_path = create_plug_in_save_dir(plug_in_package_name)
    save_file_path = plug_in_save_dir_path + lvalue
    if os.path.isfile(save_file_path):
        gp.qprint_timen("Restoring " + lvalue + " value from " +
                        save_file_path + ".")
        value = gm.file_to_list(save_file_path, newlines=0, comments=0,
                                trim=1)[0]
        if type(default) is bool:
            # Convert from string to bool.
            value = (value == 'True')
        if type(default) is int:
            # Convert from string to int.
            value = int(value)
        gp.qprint_varx(lvalue, value)
        return value
    else:
        gp.qprint_timen("Save file " + save_file_path +
                        " does not exist so returning default value.")
        gp.qprint_var(default)
        return default
Пример #18
0
def wait_for_comm_cycle(start_boot_seconds, quiet=None):
    r"""
    Wait for the BMC uptime to be less than elapsed_boot_time.

    This function will tolerate an expected loss of communication to the BMC.
    This function is useful when some kind of reboot has been initiated by the
    caller.

    Description of argument(s):
    start_boot_seconds  The time that the boot test started.  The format is the
                        epoch time in seconds, i.e. the number of seconds since
                        1970-01-01 00:00:00 UTC.  This value should be obtained
                        from the BMC so that it is not dependent on any kind of
                        synchronization between this machine and the target BMC
                        This will allow this program to work correctly even in
                        a simulated environment.  This value should be obtained
                        by the caller prior to initiating a reboot.  It can be
                        obtained as follows:
                        state = st.get_state(req_states=['epoch_seconds'])
    """

    quiet = int(gp.get_var_value(quiet, 0))

    # Validate parms.
    error_message = gv.valid_integer(start_boot_seconds)
    if error_message:
        BuiltIn().fail(gp.sprint_error(error_message))

    # Wait for uptime to be less than elapsed_boot_time.
    set_start_boot_seconds(start_boot_seconds)
    expr = 'int(float(state[\'uptime\'])) < int(state[\'elapsed_boot_time\'])'
    match_state = DotDict([('uptime', '^[0-9\\.]+$'),
                           ('elapsed_boot_time', '^[0-9]+$'),
                           (expressions_key(), [expr])])
    wait_state(match_state, wait_time="12 mins", interval="5 seconds")

    gp.qprint_timen("Verifying that REST/Redfish API interface is working.")
    if not redfish_support_trans_state:
        match_state = DotDict([('rest', '^1$')])
    else:
        match_state = DotDict([('redfish', '^1$')])
    state = wait_state(match_state, wait_time="5 mins", interval="2 seconds")
def save_plug_in_value(var_value=None, plug_in_package_name=None, **kwargs):
    r"""
    Save a value in a plug-in save file.  The value may be retrieved later via a call to the
    restore_plug_in_value function.

    This function will figure out the variable name corresponding to the value passed and use that name in
    creating the plug-in save file.

    The caller may pass the value as a simple variable or as a keyword=value (see examples below).

    Example 1:

    my_var1 = 5
    save_plug_in_value(my_var1)

    In this example, the value "5" would be saved to the "my_var1" file in the plug-in save directory.

    Example 2:

    save_plug_in_value(my_var1=5)

    In this example, the value "5" would be saved to the "my_var1" file in the plug-in save directory.

    Description of argument(s):
    var_value                       The value to be saved.
    plug_in_package_name            See compose_plug_in_save_dir_path for details.
    kwargs                          The first entry may contain a var_name/var_value.  Other entries are
                                    ignored.
    """

    if var_value is None:
        var_name = next(iter(kwargs))
        var_value = kwargs[var_name]
    else:
        # Get the name of the variable used as argument one to this function.
        var_name = gp.get_arg_name(0, 1, stack_frame_ix=2)
    plug_in_save_dir_path = create_plug_in_save_dir(plug_in_package_name)
    save_file_path = plug_in_save_dir_path + var_name
    gp.qprint_timen("Saving \"" + var_name + "\" value.")
    gp.qprint_varx(var_name, var_value)
    gc.shell_cmd("echo '" + str(var_value) + "' > " + save_file_path)
def obmc_boot_test_py(alt_boot_stack=None):

    r"""
    Do main program processing.
    """

    if alt_boot_stack is not None:
        BuiltIn().set_global_variable("${boot_stack}", alt_boot_stack)

    setup()

    if ffdc_only:
        gp.qprint_timen("Caller requested ffdc_only.")
        pre_boot_plug_in_setup()
        grk.run_key_u("my_ffdc")
        return

    # Process caller's boot_stack.
    while (len(boot_stack) > 0):
        test_loop_body()

    gp.qprint_timen("Finished processing stack.")

    # Process caller's boot_list.
    if len(boot_list) > 0:
        for ix in range(1, max_num_tests + 1):
            test_loop_body()

    gp.qprint_timen("Completed all requested boot tests.")

    boot_pass, boot_fail = boot_results.return_total_pass_fail()
    if boot_fail > boot_fail_threshold:
        error_message = "Boot failures exceed the boot failure" +\
                        " threshold:\n" +\
                        gp.sprint_var(boot_fail) +\
                        gp.sprint_var(boot_fail_threshold)
        BuiltIn().fail(gp.sprint_error(error_message))
def obmc_boot_test_py(alt_boot_stack=None):
    r"""
    Do main program processing.
    """

    if alt_boot_stack is not None:
        BuiltIn().set_global_variable("${boot_stack}", alt_boot_stack)

    setup()

    if ffdc_only:
        gp.qprint_timen("Caller requested ffdc_only.")
        pre_boot_plug_in_setup()
        grk.run_key_u("my_ffdc")
        return

    # Process caller's boot_stack.
    while (len(boot_stack) > 0):
        test_loop_body()

    gp.qprint_timen("Finished processing stack.")

    # Process caller's boot_list.
    if len(boot_list) > 0:
        for ix in range(1, max_num_tests + 1):
            test_loop_body()

    gp.qprint_timen("Completed all requested boot tests.")

    boot_pass, boot_fail = boot_results.return_total_pass_fail()
    if boot_fail > boot_fail_threshold:
        error_message = "Boot failures exceed the boot failure" +\
                        " threshold:\n" +\
                        gp.sprint_var(boot_fail) +\
                        gp.sprint_var(boot_fail_threshold)
        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
    global boot_end_time

    gp.qprintn()

    next_boot = select_boot()
    if next_boot == "":
        return True

    boot_count += 1
    gp.qprint_timen("Starting boot " + str(boot_count) + ".")

    pre_boot_plug_in_setup()

    cmd_buf = ["run_boot", next_boot]
    boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
    if boot_status == "FAIL":
        gp.qprint(msg)

    gp.qprintn()
    if boot_status == "PASS":
        boot_success = 1
        completion_msg = gp.sprint_timen("BOOT_SUCCESS: \"" + next_boot +
                                         "\" succeeded.")
    else:
        boot_success = 0
        completion_msg = gp.sprint_timen("BOOT_FAILED: \"" + next_boot +
                                         "\" failed.")

    # Set boot_end_time for use by plug-ins.
    boot_end_time = completion_msg[1:33]
    gp.qprint_var(boot_end_time)

    gp.qprint(completion_msg)

    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=0)

    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:
        status, ret_values = grk.run_key_u("my_ffdc", ignore=1)
        if status != 'PASS':
            gp.qprint_error("Call to my_ffdc failed.\n")

    # We need to purge error logs between boots or they build up.
    grk.run_key("Delete Error logs", ignore=1)

    boot_results.print_report()
    gp.qprint_timen("Finished boot " + str(boot_count) + ".")

    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)

    # This should help prevent ConnectionErrors.
    grk.run_key_u("Close All Connections")

    return True
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.
    """

    global boot_stack

    gp.qprint_timen("Selecting a boot test.")

    my_get_state()

    stack_popped = 0
    if len(boot_stack) > 0:
        stack_popped = 1
        gp.qprint_dashes()
        gp.qprint_var(boot_stack)
        gp.qprint_dashes()
        skip_boot_printed = 0
        while len(boot_stack) > 0:
            boot_candidate = boot_stack.pop()
            if stack_mode == 'normal':
                break
            else:
                if st.compare_states(state, boot_table[boot_candidate]['end']):
                    if not skip_boot_printed:
                        gp.qprint_var(stack_mode)
                        gp.qprintn()
                        gp.qprint_timen("Skipping the following boot tests" +
                                        " which are unnecessary since their" +
                                        " required end states match the" +
                                        " current machine state:")
                        skip_boot_printed = 1
                    gp.qprint_var(boot_candidate)
                    boot_candidate = ""
        if boot_candidate == "":
            gp.qprint_dashes()
            gp.qprint_var(boot_stack)
            gp.qprint_dashes()
            return boot_candidate
        if st.compare_states(state, boot_table[boot_candidate]['start']):
            gp.qprint_timen("The machine state is valid for a '" +
                            boot_candidate + "' boot test.")
            gp.qprint_dashes()
            gp.qprint_var(boot_stack)
            gp.qprint_dashes()
            return boot_candidate
        else:
            gp.qprint_timen("The machine state does not match the required" +
                            " starting state for a '" + boot_candidate +
                            "' boot test:")
            gp.qprint_varx("boot_table[" + boot_candidate + "][start]",
                           boot_table[boot_candidate]['start'], 1)
            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:
        gp.qprint_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)
        gp.qprint_timen("Using default '" + boot_candidate +
                        "' boot type to transition to valid state.")

    gp.dprint_var(boot_candidates)

    # Randomly select a boot from the candidate list.
    boot = random.choice(boot_candidates)

    return boot
def ffdc(ffdc_dir_path=None,
         ffdc_prefix=None,
         ffdc_function_list=""):
    r"""
    Gather First Failure Data Capture (FFDC).

    This includes:
    - Set global FFDC_TIME.
    - Create FFDC work space directory.
    - Write test info details.
    - Call BMC methods to write/collect FFDC data.

    Description of arguments:
    ffdc_dir_path       The dir path where FFDC data should be put.
    ffdc_prefix         The prefix to be given to each FFDC file name
                        generated.
    ffdc_function_list  A colon-delimited list of all the types of FFDC data
                        you wish to have collected.  A blank value means that
                        all possible kinds of FFDC are to be collected.  See
                        FFDC_METHOD_CALL object in lib/openbmc_ffdc_list.py
                        for possible choices.
    """

    ffdc_file_list = []

    # Check if Ping and SSH connection is alive
    OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")

    state = st.get_state(req_states=['ping', 'uptime'])
    gp.qprint_var(state)
    if not int(state['ping']):
        gp.print_error("BMC is not ping-able.  Terminating FFDC collection.\n")
        return ffdc_file_list

    if state['uptime'] == "":
        gp.print_error("BMC is not communicating.  Terminating FFDC"
                       + " collection.\n")
        return ffdc_file_list

    gp.qprint_timen("Collecting FFDC.")

    # Get default values for arguments.
    ffdc_dir_path, ffdc_prefix = set_ffdc_defaults(ffdc_dir_path, ffdc_prefix)
    gp.qprint_var(ffdc_dir_path)
    gp.qprint_var(ffdc_prefix)

    # LOG_PREFIX is used by subordinate functions.
    LOG_PREFIX = ffdc_dir_path + ffdc_prefix
    BuiltIn().set_global_variable("${LOG_PREFIX}", LOG_PREFIX)

    cmd_buf = ["Create Directory", ffdc_dir_path]
    grp.rqpissuing_keyword(cmd_buf)
    status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
    if status != "PASS":
        error_message = grp.sprint_error_report("Create Directory failed"
                                                + " with the following"
                                                + " error:\n" + output)
        BuiltIn().fail(error_message)

    # FFDC_FILE_PATH is used by Header Message.
    FFDC_FILE_PATH = ffdc_dir_path + ffdc_prefix + "BMC_general.txt"
    BuiltIn().set_global_variable("${FFDC_FILE_PATH}", FFDC_FILE_PATH)

    status, ffdc_file_list = grk.run_key("Header Message")
    status, ffdc_file_sub_list = \
        grk.run_key_u("Call FFDC Methods  ffdc_function_list="
                      + ffdc_function_list)

    # Combine lists, remove duplicates and sort.
    ffdc_file_list = sorted(set(ffdc_file_list + ffdc_file_sub_list))

    gp.qprint_timen("Finished collecting FFDC.")

    return ffdc_file_list
Пример #25
0
def ffdc(ffdc_dir_path=None, ffdc_prefix=None, ffdc_function_list=""):
    r"""
    Gather First Failure Data Capture (FFDC).

    This includes:
    - Set global FFDC_TIME.
    - Create FFDC work space directory.
    - Write test info details.
    - Call BMC methods to write/collect FFDC data.

    Description of arguments:
    ffdc_dir_path       The dir path where FFDC data should be put.
    ffdc_prefix         The prefix to be given to each FFDC file name
                        generated.
    ffdc_function_list  A colon-delimited list of all the types of FFDC data
                        you wish to have collected.  A blank value means that
                        all possible kinds of FFDC are to be collected.  See
                        FFDC_METHOD_CALL object in lib/openbmc_ffdc_list.py
                        for possible choices.
    """

    ffdc_file_list = []

    # Check if Ping and SSH connection is alive
    OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")

    state = st.get_state(req_states=['ping', 'uptime', 'rest'])
    gp.qprint_var(state)
    if not int(state['ping']):
        gp.print_error("BMC is not ping-able.  Terminating FFDC collection.\n")
        return ffdc_file_list

    if not int(state['rest']):
        gp.print_error("REST commands to the BMC are failing." +
                       "  Terminating FFDC collection.\n")
        return ffdc_file_list

    if state['uptime'] == "":
        gp.print_error("BMC is not communicating via ssh.  Terminating FFDC" +
                       " collection.\n")
        return ffdc_file_list

    gp.qprint_timen("Collecting FFDC.")

    # Get default values for arguments.
    ffdc_dir_path, ffdc_prefix = set_ffdc_defaults(ffdc_dir_path, ffdc_prefix)
    gp.qprint_var(ffdc_dir_path)
    gp.qprint_var(ffdc_prefix)

    # LOG_PREFIX is used by subordinate functions.
    LOG_PREFIX = ffdc_dir_path + ffdc_prefix
    BuiltIn().set_global_variable("${LOG_PREFIX}", LOG_PREFIX)

    cmd_buf = ["Create Directory", ffdc_dir_path]
    gp.qprint_issuing(cmd_buf)
    status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
    if status != "PASS":
        error_message = gp.sprint_error_report("Create Directory failed" +
                                               " with the following" +
                                               " error:\n" + output)
        BuiltIn().fail(error_message)

    # FFDC_FILE_PATH is used by Header Message.
    FFDC_FILE_PATH = ffdc_dir_path + ffdc_prefix + "BMC_general.txt"
    BuiltIn().set_global_variable("${FFDC_FILE_PATH}", FFDC_FILE_PATH)

    status, ffdc_file_list = grk.run_key_u("Header Message")
    status, ffdc_file_sub_list = \
        grk.run_key_u("Call FFDC Methods  ffdc_function_list="
                      + ffdc_function_list)

    # Combine lists, remove duplicates and sort.
    ffdc_file_list = sorted(set(ffdc_file_list + ffdc_file_sub_list))

    gp.qprint_timen("Finished collecting FFDC.")

    return ffdc_file_list
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.
    """

    global boot_stack

    gp.qprint_timen("Selecting a boot test.")

    my_get_state()

    stack_popped = 0
    if len(boot_stack) > 0:
        stack_popped = 1
        gp.qprint_dashes()
        gp.qprint_var(boot_stack)
        gp.qprint_dashes()
        skip_boot_printed = 0
        while len(boot_stack) > 0:
            boot_candidate = boot_stack.pop()
            if stack_mode == 'normal':
                break
            else:
                if st.compare_states(state, boot_table[boot_candidate]['end']):
                    if not skip_boot_printed:
                        gp.print_var(stack_mode)
                        gp.printn()
                        gp.print_timen("Skipping the following boot tests" +
                                       " which are unnecessary since their" +
                                       " required end states match the" +
                                       " current machine state:")
                        skip_boot_printed = 1
                    gp.print_var(boot_candidate)
                    boot_candidate = ""
        if boot_candidate == "":
            gp.qprint_dashes()
            gp.qprint_var(boot_stack)
            gp.qprint_dashes()
            return boot_candidate
        if st.compare_states(state, boot_table[boot_candidate]['start']):
            gp.qprint_timen("The machine state is valid for a '" +
                            boot_candidate + "' boot test.")
            gp.qprint_dashes()
            gp.qprint_var(boot_stack)
            gp.qprint_dashes()
            return boot_candidate
        else:
            gp.qprint_timen("The machine state does not match the required" +
                            " starting state for a '" + boot_candidate +
                            "' boot test:")
            gp.print_varx("boot_table[" + boot_candidate + "][start]",
                          boot_table[boot_candidate]['start'], 1)
            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:
        gp.qprint_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)
        gp.qprint_timen("Using default '" + boot_candidate +
                        "' boot type to transition to valid state.")

    gp.dprint_var(boot_candidates)

    # Randomly select a boot from the candidate list.
    boot = random.choice(boot_candidates)

    return boot
Пример #27
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

    signal.signal(signal.SIGUSR1, stop_boot_test)
    gp.qprint_timen("stop_boot_test is armed.")

    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, fmt=gp.hexa())
        set_default_siguser1()
        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 = st.strip_anchor_state(boot_table[boot]['end'])
    else:
        # Assertion:  We trust that the state data was made fresh by the
        # caller.

        gp.qprintn()

        if boot_table[boot]['method_type'] == "keyword":
            rk.my_run_keywords(boot_table[boot].get('lib_file_path', ''),
                               boot_table[boot]['method'],
                               quiet=quiet)

        if boot_table[boot]['bmc_reboot']:
            st.wait_for_comm_cycle(int(state['epoch_seconds']))
            plug_in_setup()
            rc, shell_rc, failed_plug_in_name = \
                grpi.rprocess_plug_in_packages(call_point="post_reboot")
            if rc != 0:
                error_message = "Plug-in failed with non-zero return code.\n"
                error_message += gp.sprint_var(rc, fmt=gp.hexa())
                set_default_siguser1()
                BuiltIn().fail(gp.sprint_error(error_message))
        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="10 seconds",
                          invert=1)

        gp.qprintn()
        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="10 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, fmt=gp.hexa())
        set_default_siguser1()
        BuiltIn().fail(gp.sprint_error(error_message))

    # Restore original sigusr1 handler.
    set_default_siguser1()
Пример #28
0
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.
    """

    global transitional_boot_selected
    global boot_stack

    gp.qprint_timen("Selecting a boot test.")

    if transitional_boot_selected and not boot_success:
        prior_boot = next_boot
        boot_candidate = boot_stack.pop()
        gp.qprint_timen("The prior '" + next_boot + "' was chosen to" +
                        " transition to a valid state for '" + boot_candidate +
                        "' which was at the top of the boot_stack.  Since" +
                        " the '" + next_boot + "' failed, the '" +
                        boot_candidate + "' has been removed from the stack" +
                        " to avoid and endless failure loop.")
        if len(boot_stack) == 0:
            return ""

    my_get_state()
    valid_state()

    transitional_boot_selected = False
    stack_popped = 0
    if len(boot_stack) > 0:
        stack_popped = 1
        gp.qprint_dashes()
        gp.qprint_var(boot_stack)
        gp.qprint_dashes()
        skip_boot_printed = 0
        while len(boot_stack) > 0:
            boot_candidate = boot_stack.pop()
            if stack_mode == 'normal':
                break
            else:
                if st.compare_states(state, boot_table[boot_candidate]['end']):
                    if not skip_boot_printed:
                        gp.qprint_var(stack_mode)
                        gp.qprintn()
                        gp.qprint_timen("Skipping the following boot tests" +
                                        " which are unnecessary since their" +
                                        " required end states match the" +
                                        " current machine state:")
                        skip_boot_printed = 1
                    gp.qprint_var(boot_candidate)
                    boot_candidate = ""
        if boot_candidate == "":
            gp.qprint_dashes()
            gp.qprint_var(boot_stack)
            gp.qprint_dashes()
            return boot_candidate
        if st.compare_states(state, boot_table[boot_candidate]['start']):
            gp.qprint_timen("The machine state is valid for a '" +
                            boot_candidate + "' boot test.")
            gp.qprint_dashes()
            gp.qprint_var(boot_stack)
            gp.qprint_dashes()
            return boot_candidate
        else:
            gp.qprint_timen("The machine state does not match the required" +
                            " starting state for a '" + boot_candidate +
                            "' boot test:")
            gp.qprint_varx("boot_table_start_entry",
                           boot_table[boot_candidate]['start'])
            boot_stack.append(boot_candidate)
            transitional_boot_selected = True
            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:
        gp.qprint_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)
        gp.qprint_timen("Using default '" + boot_candidate +
                        "' boot type to transition to valid state.")

    gp.dprint_var(boot_candidates)

    # Randomly select a boot from the candidate list.
    boot = random.choice(boot_candidates)

    return boot
def obmc_boot_test_py(loc_boot_stack=None,
                      loc_stack_mode=None,
                      loc_quiet=None):
    r"""
    Do main program processing.
    """

    global save_stack

    ga.set_term_options(term_requests={'pgm_names': ['process_plug_in_packages.py']})

    gp.dprintn()
    # Process function parms.
    for parm_name in main_func_parm_list:
        # Get parm's value.
        parm_value = eval("loc_" + parm_name)
        gp.dpvars(parm_name, parm_value)

        if parm_value is not None:
            # Save the global value on a stack.
            cmd_buf = "save_stack.push(BuiltIn().get_variable_value(\"${" +\
                parm_name + "}\"), \"" + parm_name + "\")"
            gp.dpissuing(cmd_buf)
            exec(cmd_buf)

            # Set the global value to the passed value.
            cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
                "}\", loc_" + parm_name + ")"
            gp.dpissuing(cmd_buf)
            exec(cmd_buf)

    gp.dprintn(save_stack.sprint_obj())

    setup()

    init_boot_pass, init_boot_fail = boot_results.return_total_pass_fail()

    if ffdc_only:
        gp.qprint_timen("Caller requested ffdc_only.")
        if do_pre_boot_plug_in_setup:
            pre_boot_plug_in_setup()
        grk.run_key_u("my_ffdc")
        return

    if delete_errlogs:
        # print error logs before delete
        status, error_logs = grk.run_key_u("Get Error Logs")
        pels = pel.peltool("-l", ignore_err=1)
        log.print_error_logs(error_logs, "AdditionalData Message Severity")
        gp.qprint_var(pels)

        # Delete errlogs prior to doing any boot tests.
        grk.run_key(delete_errlogs_cmd, ignore=1)
        grk.run_key(delete_bmcdump_cmd, ignore=1)

    # Process caller's boot_stack.
    while (len(boot_stack) > 0):
        test_loop_body()

    gp.qprint_timen("Finished processing stack.")

    post_stack()

    # Process caller's boot_list.
    if len(boot_list) > 0:
        for ix in range(1, max_num_tests + 1):
            test_loop_body()

    gp.qprint_timen("Completed all requested boot tests.")

    boot_pass, boot_fail = boot_results.return_total_pass_fail()
    new_fail = boot_fail - init_boot_fail
    if new_fail > boot_fail_threshold:
        error_message = "Boot failures exceed the boot failure" +\
                        " threshold:\n" +\
                        gp.sprint_var(new_fail) +\
                        gp.sprint_var(boot_fail_threshold)
        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

    gp.qprintn()

    next_boot = select_boot()
    if next_boot == "":
        return True

    boot_count += 1
    gp.qprint_timen("Starting boot " + str(boot_count) + ".")

    pre_boot_plug_in_setup()

    cmd_buf = ["run_boot", next_boot]
    boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
    if boot_status == "FAIL":
        gp.qprint(msg)

    gp.qprintn()
    if boot_status == "PASS":
        boot_success = 1
        gp.qprint_timen("BOOT_SUCCESS: \"" + next_boot + "\" succeeded.")
    else:
        boot_success = 0
        gp.qprint_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=0)

    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:
        status, ret_values = grk.run_key_u("my_ffdc", ignore=1)
        if status != 'PASS':
            gp.print_error("Call to my_ffdc failed.\n")

    # We need to purge error logs between boots or they build up.
    grk.run_key("Delete Error logs", ignore=1)

    boot_results.print_report()
    gp.qprint_timen("Finished boot " + str(boot_count) + ".")

    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)

    # This should help prevent ConnectionErrors.
    grk.run_key_u("Close All Connections")

    return True
def obmc_boot_test_py(loc_boot_stack=None,
                      loc_stack_mode=None,
                      loc_quiet=None):
    r"""
    Do main program processing.
    """

    global save_stack

    # Process function parms.
    for parm_name in main_func_parm_list:
        # Get parm's value.
        cmd_buf = "parm_value = loc_" + parm_name
        exec(cmd_buf)
        gp.dpvar(parm_name)
        gp.dpvar(parm_value)

        if parm_value is None:
            # Parm was not specified by the calling function so set it to its
            # corresponding global value.
            cmd_buf = "loc_" + parm_name + " = BuiltIn().get_variable_value" +\
                "(\"${" + parm_name + "}\")"
            gp.dpissuing(cmd_buf)
            exec(cmd_buf)
        else:
            # Save the global value on a stack.
            cmd_buf = "save_stack.push(BuiltIn().get_variable_value(\"${" +\
                parm_name + "}\"), \"" + parm_name + "\")"
            gp.dpissuing(cmd_buf)
            exec(cmd_buf)

            # Set the global value to the passed value.
            cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
                "}\", loc_" + parm_name + ")"
            gp.dpissuing(cmd_buf)
            exec(cmd_buf)

    gp.dprintn(save_stack.sprint_obj())

    setup()

    init_boot_pass, init_boot_fail = boot_results.return_total_pass_fail()

    if ffdc_only:
        gp.qprint_timen("Caller requested ffdc_only.")
        pre_boot_plug_in_setup()
        grk.run_key_u("my_ffdc")
        return

    # Process caller's boot_stack.
    while (len(boot_stack) > 0):
        test_loop_body()

    gp.qprint_timen("Finished processing stack.")

    # Process caller's boot_list.
    if len(boot_list) > 0:
        for ix in range(1, max_num_tests + 1):
            test_loop_body()

    gp.qprint_timen("Completed all requested boot tests.")

    boot_pass, boot_fail = boot_results.return_total_pass_fail()
    new_fail = boot_fail - init_boot_fail
    if new_fail > boot_fail_threshold:
        error_message = "Boot failures exceed the boot failure" +\
                        " threshold:\n" +\
                        gp.sprint_var(new_fail) +\
                        gp.sprint_var(boot_fail_threshold)
        BuiltIn().fail(gp.sprint_error(error_message))
Пример #32
0
def process_robot_output_files(robot_cmd_buf=None,
                               robot_rc=None,
                               gzip=1):
    r"""
    Process robot output files which can involve several operations:
    - If the files are in a temporary location, using SAVE_STATUS_POLICY to
      decide whether to move them to a permanent location or to delete them.
    - Gzipping them.

    Description of argument(s):
    robot_cmd_buf                   The complete command string used to invoke
                                    robot.
    robot_rc                        The return code from running the robot
                                    command string.
    gzip                            Indicates whether robot-generated output
                                    should be gzipped.
    """

    robot_cmd_buf = gm.dft(robot_cmd_buf, gcr_last_robot_cmd_buf)
    robot_rc = gm.dft(robot_rc, gcr_last_robot_rc)

    if robot_cmd_buf == "":
        # This can legitimately occur if this function is called from an
        # exit_function without the program having ever run robot_cmd_fnc.
        return

    SAVE_STATUS_POLICY = os.environ.get("SAVE_STATUS_POLICY", "ALWAYS")
    gp.qprint_vars(SAVE_STATUS_POLICY)

    # When SAVE_STATUS_POLICY is "NEVER" robot output files don't even get
    # generated.
    if SAVE_STATUS_POLICY == "NEVER":
        return

    # Compose file_list based on robot command buffer passed in.
    robot_cmd_buf_dict = gc.parse_command_string(robot_cmd_buf)
    outputdir = robot_cmd_buf_dict['outputdir']
    outputdir = gm.add_trailing_slash(outputdir)
    file_list = outputdir + robot_cmd_buf_dict['output'] + " " + outputdir\
        + robot_cmd_buf_dict['log'] + " " + outputdir\
        + robot_cmd_buf_dict['report']

    # Double checking that files are present.
    shell_rc, out_buf = gc.shell_cmd("ls -1 " + file_list + " 2>/dev/null",
                                     show_err=0)
    file_list = re.sub("\n", " ", out_buf.rstrip("\n"))

    if file_list == "":
        gp.qprint_timen("No robot output files were found in " + outputdir
                        + ".")
        return
    gp.qprint_var(robot_rc, 1)
    if SAVE_STATUS_POLICY == "FAIL" and robot_rc == 0:
        gp.qprint_timen("The call to robot produced no failures."
                        + "  Deleting robot output files.")
        gc.shell_cmd("rm -rf " + file_list)
        return

    if gzip:
        gc.shell_cmd("gzip " + file_list)
        # Update the values in file_list.
        file_list = re.sub(" ", ".gz ", file_list) + ".gz"

    # It TMP_ROBOT_DIR_PATH is set, it means the caller wanted the robot
    # output initially directed to TMP_ROBOT_DIR_PATH but later moved to
    # FFDC_DIR_PATH.  Otherwise, we're done.

    if os.environ.get("TMP_ROBOT_DIR_PATH", "") is "":
        return

    # We're directing these to the FFDC dir path so that they'll be subjected
    # to FFDC cleanup.
    target_dir_path = os.environ.get("FFDC_DIR_PATH",
                                     os.environ.get("HOME", ".")
                                     + "/autoipl/ffdc")
    target_dir_path = gm.add_trailing_slash(target_dir_path)

    targ_file_list = [re.sub(".*/", target_dir_path, x)
                      for x in file_list.split(" ")]

    gc.shell_cmd("mv " + file_list + " " + target_dir_path + " >/dev/null",
                 time_out=600)

    gp.qprint_timen("New robot log file locations:")
    gp.qprintn('\n'.join(targ_file_list))
def obmc_boot_test_py(loc_boot_stack=None,
                      loc_stack_mode=None,
                      loc_quiet=None):
    r"""
    Do main program processing.
    """

    global save_stack

    # Process function parms.
    for parm_name in main_func_parm_list:
        # Get parm's value.
        cmd_buf = "parm_value = loc_" + parm_name
        exec(cmd_buf)
        gp.dpvar(parm_name)
        gp.dpvar(parm_value)

        if parm_value is None:
            # Parm was not specified by the calling function so set it to its
            # corresponding global value.
            cmd_buf = "loc_" + parm_name + " = BuiltIn().get_variable_value" +\
                "(\"${" + parm_name + "}\")"
            gp.dpissuing(cmd_buf)
            exec(cmd_buf)
        else:
            # Save the global value on a stack.
            cmd_buf = "save_stack.push(BuiltIn().get_variable_value(\"${" +\
                parm_name + "}\"), \"" + parm_name + "\")"
            gp.dpissuing(cmd_buf)
            exec(cmd_buf)

            # Set the global value to the passed value.
            cmd_buf = "BuiltIn().set_global_variable(\"${" + parm_name +\
                "}\", loc_" + parm_name + ")"
            gp.dpissuing(cmd_buf)
            exec(cmd_buf)

    gp.dprintn(save_stack.sprint_obj())

    setup()

    if ffdc_only:
        gp.qprint_timen("Caller requested ffdc_only.")
        pre_boot_plug_in_setup()
        grk.run_key_u("my_ffdc")
        return

    # Process caller's boot_stack.
    while (len(boot_stack) > 0):
        test_loop_body()

    gp.qprint_timen("Finished processing stack.")

    # Process caller's boot_list.
    if len(boot_list) > 0:
        for ix in range(1, max_num_tests + 1):
            test_loop_body()

    gp.qprint_timen("Completed all requested boot tests.")

    boot_pass, boot_fail = boot_results.return_total_pass_fail()
    if boot_fail > boot_fail_threshold:
        error_message = "Boot failures exceed the boot failure" +\
                        " threshold:\n" +\
                        gp.sprint_var(boot_fail) +\
                        gp.sprint_var(boot_fail_threshold)
        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
    global boot_end_time

    gp.qprintn()

    next_boot = select_boot()
    if next_boot == "":
        return True

    boot_count += 1
    gp.qprint_timen("Starting boot " + str(boot_count) + ".")

    pre_boot_plug_in_setup()

    cmd_buf = ["run_boot", next_boot]
    boot_status, msg = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
    if boot_status == "FAIL":
        gp.qprint(msg)

    gp.qprintn()
    if boot_status == "PASS":
        boot_success = 1
        completion_msg = gp.sprint_timen("BOOT_SUCCESS: \"" + next_boot
                                         + "\" succeeded.")
    else:
        boot_success = 0
        completion_msg = gp.sprint_timen("BOOT_FAILED: \"" + next_boot
                                         + "\" failed.")

    # Set boot_end_time for use by plug-ins.
    boot_end_time = completion_msg[1:33]
    gp.qprint_var(boot_end_time)

    gp.qprint(completion_msg)

    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=0)

    plug_in_setup()
    rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
        call_point='ffdc_check', shell_rc=dump_ffdc_rc(),
        stop_on_plug_in_failure=1, stop_on_non_zero_rc=1)
    if ffdc_check == "All" or\
       shell_rc == dump_ffdc_rc():
        status, ret_values = grk.run_key_u("my_ffdc", ignore=1)
        if status != 'PASS':
            gp.qprint_error("Call to my_ffdc failed.\n")
            # Leave a record for caller that "soft" errors occurred.
            soft_errors = 1
            gpu.save_plug_in_value(soft_errors, pgm_name)

    if delete_errlogs:
        # print error logs before delete
        status, error_logs = grk.run_key_u("Get Error Logs")
        pels = pel.peltool("-l", ignore_err=1)
        log.print_error_logs(error_logs, "AdditionalData Message Severity")
        gp.qprint_var(pels)

        # We need to purge error logs between boots or they build up.
        grk.run_key(delete_errlogs_cmd, ignore=1)
        grk.run_key(delete_bmcdump_cmd, ignore=1)

    boot_results.print_report()
    gp.qprint_timen("Finished boot " + str(boot_count) + ".")

    plug_in_setup()
    rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
        call_point='stop_check', shell_rc=stop_test_rc(),
        stop_on_non_zero_rc=1)
    if shell_rc == stop_test_rc():
        message = "Stopping as requested by user.\n"
        gp.qprint_time(message)
        BuiltIn().fail(message)

    # This should help prevent ConnectionErrors.
    # Purge all redfish and REST connection sessions.
    if redfish_delete_sessions:
        grk.run_key_u("Close All Connections", ignore=1)
        grk.run_key_u("Delete All Redfish Sessions", ignore=1)

    return True