コード例 #1
0
def openbmctool_execute_command_json(command_string,
                                     *args,
                                     **kwargs):
    r"""
    Run the command string as an argument to the openbmctool.py program, parse
    the JSON output into a dictionary and return the dictionary.

    This function is a wrapper for openbmctool_execute_command (defined
    above).  The caller may provide any command string where the output will
    be JSON data.  This function will convert the JSON data to a python
    object, verify that the 'status' field = "ok" and return the 'data'
    sub-field to the caller.

    See openbmctool_execute_command (above) for all field descriptions.
    """

    rc, output = openbmctool_execute_command(command_string,
                                             *args,
                                             **kwargs)
    try:
        json_object = utils.to_json_ordered(output)
    except json.JSONDecodeError:
        BuiltIn().fail(gp.sprint_error(output))

    if json_object['status'] != "ok":
        err_msg = "Error found in JSON data returned by the openbmctool.py "
        err_msg += "command. Expected a 'status' field value of \"ok\":\n"
        err_msg += gp.sprint_var(json_object, 1)
        BuiltIn().fail(gp.sprint_error(err_msg))

    return json_object['data']
コード例 #2
0
def valid_dump(dump_id, dump_dict=None, quiet=None):
    r"""
    Verify that dump_id is a valid.  If it is not valid, issue robot failure
    message.

    A dump is valid if the indicated dump_id refers to an existing dump with a
    valid associated dump file.

    Description of argument(s):
    dump_id                         A dump ID (e.g. "1", "2", etc.)
    dump_dict                       A dump dictionary such as the one returned
                                    by get_dump_dict.  If this value is None,
                                    this function will call get_dump_dict on
                                    the caller's behalf.
    quiet                           If quiet is set to 1, this function will
                                    NOT write status messages to stdout.
    """

    if dump_dict is None:
        dump_dict = get_dump_dict(quiet=quiet)

    if dump_id not in dump_dict:
        message = "The specified dump ID was not found among the existing" \
            + " dumps:\n"
        message += gp.sprint_var(dump_id)
        message += gp.sprint_var(dump_dict)
        BuiltIn().fail(gp.sprint_error(message))

    if not dump_dict[dump_id].endswith("tar.xz"):
        message = "There is no \"tar.xz\" file associated with the given" \
            + " dump_id:\n"
        message += gp.sprint_var(dump_id)
        dump_file_path = dump_dict[dump_id]
        message += gp.sprint_var(dump_file_path)
        BuiltIn().fail(gp.sprint_error(message))
コード例 #3
0
def validate_parms():
    r"""
    Validate all program parameters.
    """

    process_pgm_parms()

    gp.qprintn()

    global openbmc_model
    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")

    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")
    if openbmc_model == "":
        status, ret_values =\
            grk.run_key_u("Get BMC System Model")
        openbmc_model = ret_values
        BuiltIn().set_global_variable("${openbmc_model}", openbmc_model)
    grv.rvalid_value("openbmc_model")
    grv.rvalid_integer("max_num_tests")
    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)

    grv.rvalid_value("stack_mode", valid_values=['normal', 'skip'])
    if len(boot_list) == 0 and len(boot_stack) == 0 and not ffdc_only:
        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)

    selected_PDU_boots = list(
        set(boot_list + boot_stack)
        & set(boot_lists['PDU_reboot']))

    if len(selected_PDU_boots) > 0 and pdu_host == "":
        error_message = "You have selected the following boots which" +\
                        " require a PDU host but no value for pdu_host:\n"
        error_message += gp.sprint_var(selected_PDU_boots)
        error_message += gp.sprint_var(pdu_host, 2)
        BuiltIn().fail(gp.sprint_error(error_message))

    return
コード例 #4
0
def validate_parms():

    r"""
    Validate all program parameters.
    """

    process_pgm_parms()

    gp.qprintn()

    global openbmc_model
    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")

    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")
    if openbmc_model == "":
        status, ret_values =\
            grk.run_key_u("Get BMC System Model")
        openbmc_model = ret_values
        BuiltIn().set_global_variable("${openbmc_model}", openbmc_model)
    grv.rvalid_value("openbmc_model")
    grv.rvalid_integer("max_num_tests")
    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)

    grv.rvalid_value("stack_mode", valid_values=['normal', 'skip'])
    if len(boot_list) == 0 and len(boot_stack) == 0 and not ffdc_only:
        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)

    selected_PDU_boots = list(set(boot_list + boot_stack) &
                              set(boot_lists['PDU_reboot']))

    if len(selected_PDU_boots) > 0 and pdu_host == "":
        error_message = "You have selected the following boots which" +\
                        " require a PDU host but no value for pdu_host:\n"
        error_message += gp.sprint_var(selected_PDU_boots)
        error_message += gp.sprint_var(pdu_host, 2)
        BuiltIn().fail(gp.sprint_error(error_message))

    return
コード例 #5
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")
コード例 #6
0
def stop_boot_test(signal_number=0,
                   frame=None):
    r"""
    Handle SIGUSR1 by aborting the boot test that is running.

    Description of argument(s):
    signal_number  The signal number (should always be 10 for SIGUSR1).
    frame          The frame data.
    """

    gp.qprintn()
    gp.qprint_executing()
    gp.lprint_executing()

    # Restore original sigusr1 handler.
    set_default_siguser1()

    message = "The caller has asked that the boot test be stopped and marked"
    message += " as a failure."

    function_stack = gm.get_function_stack()
    if "wait_state" in function_stack:
        st.set_exit_wait_early_message(message)
    else:
        BuiltIn().fail(gp.sprint_error(message))
コード例 #7
0
def rvalidate_plug_ins(plug_in_dir_paths,
                       quiet=1):

    r"""
    Call the external validate_plug_ins.py program which validates the plug-in
    dir paths given to it.  Return a list containing a normalized path for
    each plug-in selected.

    Description of arguments:
    plug_in_dir_paths               A colon-separated list of plug-in
                                    directory paths.
    quiet                           If quiet is set to 1, this function will
                                    NOT write status messages to stdout.
    """

    cmd_buf = "validate_plug_ins.py \"" + plug_in_dir_paths + "\""
    if int(quiet) != 1:
        grp.rpissuing(cmd_buf)
    rc, out_buf = commands.getstatusoutput(cmd_buf)
    if rc != 0:
        message = gp.sprint_varx("rc", rc, 1) + out_buf
        grp.rprintn(out_buf, 'STDERR')
        BuiltIn().fail(gp.sprint_error("Validate plug ins call failed.  See" +
                                       " stderr text for details.\n"))

    plug_in_packages_list = out_buf.split("\n")
    if len(plug_in_packages_list) == 1 and plug_in_packages_list[0] == "":
        return []

    return plug_in_packages_list
コード例 #8
0
def get_health_check(verify=False):
    r"""
    Get the health_check information and return as a dictionary.

    Example robot code:

    ${health_check}=  Get Health Check
    Rprint Vars  health_check  fmt=1

    Example result:

    health_check:
      [hardware_status]:         OK
      [performance]:             OK

    Description of argument(s):
    verify                          If set, verify that all all expected
                                    field_names are generated by the
                                    health_check command.
    """

    rc, output = openbmctool_execute_command("health_check",
                                             print_output=False,
                                             ignore_err=False)
    health_check = vf.key_value_outbuf_to_dict(output, delim=":")
    if int(verify):
        err_msg = gv.valid_dict(health_check, health_check_fields())
        if err_msg != "":
            BuiltIn().fail(gp.sprint_error(err_msg))

    return health_check
コード例 #9
0
def get_remote_logging_view(verify=False):
    r"""
    Get the remote_logging view information and return as a dictionary.

    Example robot code:

    ${remote_logging_view}=  Get Remote Logging View
    Rprint Vars  remote_logging_view  fmt=1

    Example result:

    remote_logging_view:
      [Address]:                 <blank>
      [AddressFamily]:           xyz.openbmc_project.Network.Client.IPProtocol.IPv4
      [Port]:                    0

    Description of argument(s):
    verify                          If set, verify that all all expected field
                                    names are generated by the 'logging
                                    remote_logging view' command.
    """

    remote_logging_view =\
        openbmctool_execute_command_json("logging remote_logging view",
                                         print_output=False,
                                         ignore_err=False)

    if int(verify):
        err_msg = gv.valid_dict(remote_logging_view,
                                remote_logging_view_fields())
        if err_msg != "":
            BuiltIn().fail(gp.sprint_error(err_msg))

    return remote_logging_view
コード例 #10
0
def rvalidate_plug_ins(plug_in_dir_paths, quiet=1):
    r"""
    Call the external validate_plug_ins.py program which validates the plug-in
    dir paths given to it.  Return a list containing a normalized path for
    each plug-in selected.

    Description of arguments:
    plug_in_dir_paths               A colon-separated list of plug-in
                                    directory paths.
    quiet                           If quiet is set to 1, this function will
                                    NOT write status messages to stdout.
    """

    cmd_buf = "validate_plug_ins.py \"" + plug_in_dir_paths + "\""
    rc, out_buf = gc.shell_cmd(cmd_buf, print_output=0)
    if rc != 0:
        BuiltIn().fail(
            gp.sprint_error("Validate plug ins call failed.  See" +
                            " stderr text for details.\n"))

    # plug_in_packages_list = out_buf.split("\n")
    plug_in_packages_list = list(filter(None, out_buf.split("\n")))
    if len(plug_in_packages_list) == 1 and plug_in_packages_list[0] == "":
        return []

    return plug_in_packages_list
コード例 #11
0
def rvalidate_plug_ins(plug_in_dir_paths, quiet=1):
    r"""
    Call the external validate_plug_ins.py program which validates the plug-in
    dir paths given to it.  Return a list containing a normalized path for
    each plug-in selected.

    Description of arguments:
    plug_in_dir_paths               A colon-separated list of plug-in
                                    directory paths.
    quiet                           If quiet is set to 1, this function will
                                    NOT write status messages to stdout.
    """

    cmd_buf = "validate_plug_ins.py \"" + plug_in_dir_paths + "\""
    if int(quiet) != 1:
        grp.rpissuing(cmd_buf)
    rc, out_buf = commands.getstatusoutput(cmd_buf)
    if rc != 0:
        message = gp.sprint_varx("rc", rc, 1) + out_buf
        grp.rprintn(out_buf, 'STDERR')
        BuiltIn().fail(
            gp.sprint_error("Validate plug ins call failed.  See" +
                            " stderr text for details.\n"))

    plug_in_packages_list = out_buf.split("\n")
    if len(plug_in_packages_list) == 1 and plug_in_packages_list[0] == "":
        return []

    return plug_in_packages_list
コード例 #12
0
def which(file_path):
    r"""
    Find the full path of an executable file and return it.

    The PATH environment variable dictates the results of this function.

    Description of arguments:
    file_path                       The relative file path (e.g. "my_file" or
                                    "lib/my_file").
    """

    shell_rc, out_buf = gc.cmd_fnc_u("which " + file_path, quiet=1,
                                     print_output=0, show_err=0)
    if shell_rc != 0:
        error_message = "Failed to find complete path for file \"" +\
                        file_path + "\".\n"
        error_message += gp.sprint_var(shell_rc, 1)
        error_message += out_buf
        if robot_env:
            BuiltIn().fail(gp.sprint_error(error_message))
        else:
            gp.print_error_report(error_message)
            return False

    file_path = out_buf.rstrip("\n")

    return file_path
コード例 #13
0
def which(file_path):
    r"""
    Find the full path of an executable file and return it.

    The PATH environment variable dictates the results of this function.

    Description of arguments:
    file_path                       The relative file path (e.g. "my_file" or
                                    "lib/my_file").
    """

    shell_rc, out_buf = gc.cmd_fnc_u("which " + file_path,
                                     quiet=1,
                                     print_output=0,
                                     show_err=0)
    if shell_rc != 0:
        error_message = "Failed to find complete path for file \"" +\
                        file_path + "\".\n"
        error_message += gp.sprint_var(shell_rc, 1)
        error_message += out_buf
        if robot_env:
            BuiltIn().fail(gp.sprint_error(error_message))
        else:
            gp.print_error_report(error_message)
            return False

    file_path = out_buf.rstrip("\n")

    return file_path
コード例 #14
0
def valid_state():
    r"""
    Verify that our state dictionary contains no blank values.  If we don't get
    valid state data, we cannot continue to work.
    """

    if st.compare_states(state, st.invalid_state_match, 'or'):
        error_message = "The state dictionary contains blank fields which" +\
            " is illegal.\n" + gp.sprint_var(state)
        BuiltIn().fail(gp.sprint_error(error_message))
コード例 #15
0
def valid_state():
    r"""
    Verify that our state dictionary contains no blank values.  If we don't get
    valid state data, we cannot continue to work.
    """

    if st.compare_states(state, st.invalid_state_match, 'or'):
        error_message = "The state dictionary contains blank fields which" +\
            " is illegal.\n" + gp.sprint_var(state)
        BuiltIn().fail(gp.sprint_error(error_message))
コード例 #16
0
def compare_states(state, match_state, match_type='and'):
    r"""
    Compare 2 state dictionaries.  Return True if they match and False if they
    don't.  Note that the match_state dictionary does not need to have an entry
    corresponding to each entry in the state dictionary.  But for each entry
    that it does have, the corresponding state entry will be checked for a
    match.

    Description of arguments:
    state           A state dictionary such as the one returned by the
                    get_state function.
    match_state     A dictionary whose key/value pairs are "state field"/
                    "state value".  The state value is interpreted as a
                    regular expression.  Every value in this dictionary is
                    considered.  When match_type is 'and', if each and every
                    comparison matches, the two dictionaries are considered to
                    be matching.  If match_type is 'or', if any two of the
                    elements compared match, the two dictionaries are
                    considered to be matching.
                    This value may also be any string accepted by
                    return_state_constant (e.g. "standby_match_state").
                    In such a case this function will call
                    return_state_constant to convert it to a proper
                    dictionary as described above.
    match_type      This may be 'and' or 'or'.
    """

    error_message = gv.svalid_value(match_type,
                                    var_name="match_type",
                                    valid_values=['and', 'or'])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    try:
        match_state = return_state_constant(match_state)
    except TypeError:
        pass

    default_match = (match_type == 'and')
    for key, match_state_value in match_state.items():
        # Blank match_state_value means "don't care".
        if match_state_value == "":
            continue
        try:
            match = (re.match(match_state_value, str(state[key])) is not None)
        except KeyError:
            match = False

        if match != default_match:
            return match

    return default_match
コード例 #17
0
def collect_service_data(verify=False):
    r"""
    Run the collect_service_data command and return a list of files generated
    by the command.

    Description of argument(s):
    verify                          If set, verify that all files which can be
                                    created by collect_service_data did, in
                                    fact, get created.
    """

    # Route the output of collect_service_data to a file for easier parsing.
    temp = tempfile.NamedTemporaryFile()
    temp_file_path = temp.name
    openbmctool_execute_command("collect_service_data > " + temp_file_path,
                                ignore_err=False)
    # Isolate the file paths in the collect_service_data output.  We're
    # looking for output lines like this from which to extract the file paths:
    # Inventory collected and stored in /tmp/dummy--2018-09-26_17.59.18/inventory.txt
    rc, file_paths = gc.shell_cmd(
        "egrep 'collected and' " + temp_file_path
        # + " | sed -re 's#.*/tmp#/tmp#g'",
        + " | sed -re 's#[^/]*/#/#'",
        quiet=1,
        print_output=0)
    # Example file_paths value:
    # /tmp/dummy--2018-09-26_17.59.18/inventory.txt
    # /tmp/dummy--2018-09-26_17.59.18/sensorReadings.txt
    # etc.
    # Convert from output to list.
    collect_service_data_file_paths =\
        list(filter(None, file_paths.split("\n")))
    if int(verify):
        # Create a list of files by stripping the dir names from the elements
        # of collect_service_data_file_paths.
        files_obtained = [
            re.sub(r".*/", "", file_path)
            for file_path in collect_service_data_file_paths
        ]
        files_expected = service_data_files()
        files_missing = list(set(files_expected) - set(files_obtained))
        if len(files_missing) > 0:
            gp.printn("collect_service_data output:\n" +
                      gm.file_to_str(temp_file_path))
            err_msg = "The following files are missing from the list of files"
            err_msg += " returned by collect_service_data:\n"
            err_msg += gp.sprint_var(files_missing)
            err_msg += gp.sprint_var(collect_service_data_file_paths)
            BuiltIn().fail(gp.sprint_error(err_msg))

    return collect_service_data_file_paths
コード例 #18
0
def valid_dump(dump_id,
               dump_dict=None,
               quiet=None):
    r"""
    Verify that dump_id is a valid.  If it is not valid, issue robot failure
    message.

    A dump is valid if the indicated dump_id refers to an existing dump with a
    valid associated dump file.

    Description of argument(s):
    dump_id                         A dump ID (e.g. "1", "2", etc.)
    dump_dict                       A dump dictionary such as the one returned
                                    by get_dump_dict.  If this value is None,
                                    this function will call get_dump_dict on
                                    the caller's behalf.
    quiet                           If quiet is set to 1, this function will
                                    NOT write status messages to stdout.
    """

    if dump_dict is None:
        dump_dict = get_dump_dict(quiet=quiet)

    if dump_id not in dump_dict:
        message = "The specified dump ID was not found among the existing" \
            + " dumps:\n"
        message += gp.sprint_var(dump_id)
        message += gp.sprint_var(dump_dict)
        BuiltIn().fail(gp.sprint_error(message))

    if not dump_dict[dump_id].endswith("tar.xz"):
        message = "There is no \"tar.xz\" file associated with the given" \
            + " dump_id:\n"
        message += gp.sprint_var(dump_id)
        dump_file_path = dump_dict[dump_id]
        message += gp.sprint_var(dump_file_path)
        BuiltIn().fail(gp.sprint_error(message))
コード例 #19
0
def valid_boot_list(boot_list, valid_boot_types):
    r"""
    Verify that each entry in boot_list is a supported boot test.

    Description of argument(s):
    boot_list                       An array (i.e. list) of boot test types (e.g. "REST Power On").
    valid_boot_types                A list of valid boot types such as that returned by
                                    create_valid_boot_list.
    """

    for boot_name in boot_list:
        boot_name = boot_name.strip(" ")
        error_message = gv.valid_value(boot_name,
                                       valid_values=valid_boot_types,
                                       var_name="boot_name")
        if error_message != "":
            BuiltIn().fail(gp.sprint_error(error_message))
コード例 #20
0
def return_state_constant(state_name='default'):
    r"""
    Return default state dictionary.

    default_state is an initial value which may be of use to callers.
    """

    error_message = gv.svalid_value(state_name,
                                    var_name='state_name',
                                    valid_values=valid_state_constants)
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if state_name == 'default':
        return default_state
    elif state_name == 'standby_match_state':
        return standby_match_state
コード例 #21
0
def valid_boot_list(boot_list,
                    valid_boot_types):
    r"""
    Verify that each entry in boot_list is a supported boot test.

    Description of arguments:
    boot_list         An array (i.e. list) of boot test types
                      (e.g. "BMC Power On").
    valid_boot_types  A list of valid boot types such as that returned by
                      create_valid_boot_list.
    """

    for boot_name in boot_list:
        boot_name = boot_name.strip(" ")
        error_message = gv.svalid_value(boot_name,
                                        valid_values=valid_boot_types,
                                        var_name="boot_name")
        if error_message != "":
            BuiltIn().fail(gp.sprint_error(error_message))
コード例 #22
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")
コード例 #23
0
def get_health_check(verify=False):
    r"""
    Get the health_check information and return as a dictionary.

    Example robot code:

    ${health_check}=  Get Health Check
    Rpvars  1  health_check

    Example result:

    health_check:
      [hardware_status]:         OK
      [performance]:             OK

    Description of argument(s):
    verify                          If set, verify that all all expected
                                    field_names are generated by the
                                    health_check command.
    """

    rc, output = openbmctool_execute_command("health_check",
                                             print_output=False,
                                             ignore_err=False)
    health_check = vf.key_value_outbuf_to_dict(output, delim=":")
    if int(verify):
        # Create a list of files by stripping the dir names from the elements
        # of collect_service_data_file_paths.
        fields_obtained = health_check.keys()
        fields_expected = health_check_fields()
        fields_missing = list(set(fields_expected) - set(fields_obtained))
        if len(fields_missing) > 0:
            err_msg = "The following fields are missing from the output of"
            err_msg += " health_check:\n"
            err_msg += gp.sprint_var(fields_missing)
            err_msg += gp.sprint_var(health_check)
            BuiltIn().fail(gp.sprint_error(err_msg))

    return health_check
コード例 #24
0
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))
コード例 #26
0
def execute_ssh_command(cmd_buf,
                        open_connection_args={},
                        login_args={},
                        print_out=0,
                        print_err=0,
                        ignore_err=1,
                        fork=0,
                        quiet=None,
                        test_mode=None,
                        time_out=None):
    r"""
    Run the given command in an SSH session and return the stdout, stderr and
    the return code.

    If there is no open SSH connection, this function will connect and login.
    Likewise, if the caller has not yet logged in to the connection, this
    function will do the login.

    NOTE: There is special handling when open_connection_args['alias'] equals
    "device_connection".
    - A write, rather than an execute_command, is done.
    - Only stdout is returned (no stderr or rc).
    - print_err, ignore_err and fork are not supported.

    Description of arguments:
    cmd_buf                         The command string to be run in an SSH
                                    session.
    open_connection_args            A dictionary of arg names and values which
                                    are legal to pass to the SSHLibrary
                                    open_connection function as parms/args.
                                    At a minimum, this should contain a 'host'
                                    entry.
    login_args                      A dictionary containing the key/value
                                    pairs which are acceptable to the
                                    SSHLibrary login function as parms/args.
                                    At a minimum, this should contain a
                                    'username' and a 'password' entry.
    print_out                       If this is set, this function will print
                                    the stdout/stderr generated by the shell
                                    command.
    print_err                       If show_err is set, this function will
                                    print a standardized error report if the
                                    shell command returns non-zero.
    ignore_err                      Indicates that errors encountered on the
                                    sshlib.execute_command are to be ignored.
    fork                            Indicates that sshlib.start is to be used
                                    rather than sshlib.execute_command.
    quiet                           Indicates whether this function should run
                                    the pissuing() function which prints an
                                    "Issuing: <cmd string>" to stdout.  This
                                    defaults to the global quiet value.
    test_mode                       If test_mode is set, this function will
                                    not actually run the command.  This
                                    defaults to the global test_mode value.
    time_out                        The amount of time to allow for the
                                    execution of cmd_buf.  A value of None
                                    means that there is no limit to how long
                                    the command may take.
    """

    gp.lprint_executing()

    # Obtain default values.
    quiet = int(gp.get_var_value(quiet, 0))
    test_mode = int(gp.get_var_value(test_mode, 0))

    if not quiet:
        gp.pissuing(cmd_buf, test_mode)
    gp.lpissuing(cmd_buf, test_mode)

    if test_mode:
        return "", "", 0

    global sshlib

    max_exec_cmd_attempts = 2
    # Look for existing SSH connection.
    # Prepare a search connection dictionary.
    search_connection_args = open_connection_args.copy()
    # Remove keys that don't work well for searches.
    search_connection_args.pop("timeout", None)
    connection = find_connection(search_connection_args)
    if connection:
        gp.lprint_timen("Found the following existing connection:")
        gp.lprintn(sprint_connection(connection))
        if connection.alias == "":
            index_or_alias = connection.index
        else:
            index_or_alias = connection.alias
        gp.lprint_timen("Switching to existing connection: \"" +
                        str(index_or_alias) + "\".")
        sshlib.switch_connection(index_or_alias)
    else:
        gp.lprint_timen("Connecting to " + open_connection_args['host'] + ".")
        cix = sshlib.open_connection(**open_connection_args)
        try:
            login_ssh(login_args)
        except Exception:
            except_type, except_value, except_traceback = sys.exc_info()
            rc = 1
            stderr = str(except_value)
            stdout = ""
            max_exec_cmd_attempts = 0

    for exec_cmd_attempt_num in range(1, max_exec_cmd_attempts + 1):
        gp.lprint_var(exec_cmd_attempt_num)
        try:
            if fork:
                sshlib.start_command(cmd_buf)
            else:
                if open_connection_args['alias'] == "device_connection":
                    stdout = sshlib.write(cmd_buf)
                    stderr = ""
                    rc = 0
                else:
                    stdout, stderr, rc = \
                        func_timer.run(sshlib.execute_command,
                                       cmd_buf,
                                       return_stdout=True,
                                       return_stderr=True,
                                       return_rc=True,
                                       time_out=time_out)
        except Exception:
            except_type, except_value, except_traceback = sys.exc_info()
            gp.lprint_var(except_type)
            gp.lprint_varx("except_value", str(except_value))
            # This may be our last time through the retry loop, so setting
            # return variables.
            rc = 1
            stderr = str(except_value)
            stdout = ""

            if except_type is exceptions.AssertionError and\
               re.match(r"Connection not open", str(except_value)):
                try:
                    login_ssh(login_args)
                    # Now we must continue to next loop iteration to retry the
                    # execute_command.
                    continue
                except Exception:
                    except_type, except_value, except_traceback =\
                        sys.exc_info()
                    rc = 1
                    stderr = str(except_value)
                    stdout = ""
                    break

            if (except_type is paramiko.ssh_exception.SSHException
                and re.match(r"SSH session not active", str(except_value))) or\
               (except_type is socket.error
                and re.match(r"\[Errno 104\] Connection reset by peer",
                             str(except_value))) or\
               (except_type is paramiko.ssh_exception.SSHException
                and re.match(r"Timeout opening channel\.",
                             str(except_value))):
                # Close and re-open a connection.
                # Note: close_connection() doesn't appear to get rid of the
                # connection.  It merely closes it.  Since there is a concern
                # about over-consumption of resources, we use
                # close_all_connections() which also gets rid of all
                # connections.
                gp.lprint_timen("Closing all connections.")
                sshlib.close_all_connections()
                gp.lprint_timen("Connecting to " +
                                open_connection_args['host'] + ".")
                cix = sshlib.open_connection(**open_connection_args)
                login_ssh(login_args)
                continue

            # We do not handle any other RuntimeErrors so we will raise the
            # exception again.
            sshlib.close_all_connections()
            gp.lprintn(traceback.format_exc())
            raise (except_value)

        # If we get to this point, the command was executed.
        break

    if fork:
        return

    if rc != 0 and print_err:
        gp.print_var(rc, gp.hexa())
        if not print_out:
            gp.print_var(stderr)
            gp.print_var(stdout)

    if print_out:
        gp.printn(stderr + stdout)

    if not ignore_err:
        message = gp.sprint_error("The prior SSH" +
                                  " command returned a non-zero return" +
                                  " code:\n" + gp.sprint_var(rc, gp.hexa()) +
                                  stderr + "\n")
        BuiltIn().should_be_equal(rc, 0, message)

    if open_connection_args['alias'] == "device_connection":
        return stdout
    return stdout, stderr, rc
コード例 #27
0
def check_state(match_state,
                invert=0,
                print_string="",
                openbmc_host="",
                openbmc_username="",
                openbmc_password="",
                os_host="",
                os_username="",
                os_password="",
                quiet=None):
    r"""
    Check that the Open BMC machine's composite state matches the specified
    state.  On success, this keyword returns the machine's composite state as a
    dictionary.

    Description of arguments:
    match_state       A dictionary whose key/value pairs are "state field"/
                      "state value".  The state value is interpreted as a
                      regular expression.  Example call from robot:
                      ${match_state}=  Create Dictionary  chassis=^On$
                      ...  bmc=^Ready$
                      ...  boot_progress=^OSStart$
                      ${state}=  Check State  &{match_state}
    invert            If this flag is set, this function will succeed if the
                      states do NOT match.
    print_string      This function will print this string to the console prior
                      to getting the state.
    openbmc_host      The DNS name or IP address of the BMC.
                      This defaults to global ${OPENBMC_HOST}.
    openbmc_username  The username to be used to login to the BMC.
                      This defaults to global ${OPENBMC_USERNAME}.
    openbmc_password  The password to be used to login to the BMC.
                      This defaults to global ${OPENBMC_PASSWORD}.
    os_host           The DNS name or IP address of the operating system.
                      This defaults to global ${OS_HOST}.
    os_username       The username to be used to login to the OS.
                      This defaults to global ${OS_USERNAME}.
    os_password       The password to be used to login to the OS.
                      This defaults to global ${OS_PASSWORD}.
    quiet             Indicates whether status details should be written to the
                      console.  Defaults to either global value of ${QUIET} or
                      to 1.
    """

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

    grp.rprint(print_string)

    req_states = match_state.keys()
    # Initialize state.
    state = get_state(openbmc_host=openbmc_host,
                      openbmc_username=openbmc_username,
                      openbmc_password=openbmc_password,
                      os_host=os_host,
                      os_username=os_username,
                      os_password=os_password,
                      req_states=req_states,
                      quiet=quiet)
    if not quiet:
        gp.print_var(state)

    match = compare_states(state, match_state)

    if invert and match:
        fail_msg = "The current state of the machine matches the match" +\
                   " state:\n" + gp.sprint_varx("state", state)
        BuiltIn().fail("\n" + gp.sprint_error(fail_msg))
    elif not invert and not match:
        fail_msg = "The current state of the machine does NOT match the" +\
                   " match state:\n" +\
                   gp.sprint_varx("state", state)
        BuiltIn().fail("\n" + gp.sprint_error(fail_msg))

    return state
コード例 #28
0
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))
コード例 #29
0
def execute_ssh_command(cmd_buf,
                        open_connection_args={},
                        login_args={},
                        print_out=0,
                        print_err=0,
                        ignore_err=1,
                        fork=0,
                        quiet=None,
                        test_mode=None):
    r"""
    Run the given command in an SSH session and return the stdout, stderr and
    the return code.

    If there is no open SSH connection, this function will connect and login.
    Likewise, if the caller has not yet logged in to the connection, this
    function will do the login.

    NOTE: There is special handling when open_connection_args['alias'] equals
    "device_connection".
    - A write, rather than an execute_command, is done.
    - Only stdout is returned (no stderr or rc).
    - print_err, ignore_err and fork are not supported.

    Description of arguments:
    cmd_buf                         The command string to be run in an SSH
                                    session.
    open_connection_args            A dictionary of arg names and values which
                                    are legal to pass to the SSHLibrary
                                    open_connection function as parms/args.
                                    At a minimum, this should contain a 'host'
                                    entry.
    login_args                      A dictionary containing the key/value
                                    pairs which are acceptable to the
                                    SSHLibrary login function as parms/args.
                                    At a minimum, this should contain a
                                    'username' and a 'password' entry.
    print_out                       If this is set, this function will print
                                    the stdout/stderr generated by the shell
                                    command.
    print_err                       If show_err is set, this function will
                                    print a standardized error report if the
                                    shell command returns non-zero.
    ignore_err                      Indicates that errors encountered on the
                                    sshlib.execute_command are to be ignored.
    fork                            Indicates that sshlib.start is to be used
                                    rather than sshlib.execute_command.
    quiet                           Indicates whether this function should run
                                    the pissuing() function which prints an
                                    "Issuing: <cmd string>" to stdout.  This
                                    defaults to the global quiet value.
    test_mode                       If test_mode is set, this function will
                                    not actually run the command.  This
                                    defaults to the global test_mode value.
    """

    gp.lprint_executing()

    # Obtain default values.
    quiet = int(gp.get_var_value(quiet, 0))
    test_mode = int(gp.get_var_value(test_mode, 0))

    if not quiet:
        gp.pissuing(cmd_buf, test_mode)
    gp.lpissuing(cmd_buf, test_mode)

    if test_mode:
        return "", "", 0

    global sshlib

    max_exec_cmd_attempts = 2
    # Look for existing SSH connection.
    # Prepare a search connection dictionary.
    search_connection_args = open_connection_args.copy()
    # Remove keys that don't work well for searches.
    search_connection_args.pop("timeout", None)
    connection = find_connection(search_connection_args)
    if connection:
        gp.lprint_timen("Found the following existing connection:")
        gp.lprintn(sprint_connection(connection))
        if connection.alias == "":
            index_or_alias = connection.index
        else:
            index_or_alias = connection.alias
        gp.lprint_timen("Switching to existing connection: \""
                        + str(index_or_alias) + "\".")
        sshlib.switch_connection(index_or_alias)
    else:
        gp.lprint_timen("Connecting to " + open_connection_args['host'] + ".")
        cix = sshlib.open_connection(**open_connection_args)
        try:
            login_ssh(login_args)
        except Exception as login_exception:
            except_type, except_value, except_traceback = sys.exc_info()
            rc = 1
            stderr = str(except_value)
            stdout = ""
            max_exec_cmd_attempts = 0

    for exec_cmd_attempt_num in range(1, max_exec_cmd_attempts + 1):
        gp.lprint_var(exec_cmd_attempt_num)
        try:
            if fork:
                sshlib.start_command(cmd_buf)
            else:
                if open_connection_args['alias'] == "device_connection":
                    stdout = sshlib.write(cmd_buf)
                    stderr = ""
                    rc = 0
                else:
                    stdout, stderr, rc = \
                        sshlib.execute_command(cmd_buf,
                                               return_stdout=True,
                                               return_stderr=True,
                                               return_rc=True)
        except Exception as execute_exception:
            except_type, except_value, except_traceback = sys.exc_info()
            gp.lprint_var(except_type)
            gp.lprint_varx("except_value", str(except_value))

            if except_type is exceptions.AssertionError and\
               re.match(r"Connection not open", str(except_value)):
                login_ssh(login_args)
                # Now we must continue to next loop iteration to retry the
                # execute_command.
                continue
            if (except_type is paramiko.ssh_exception.SSHException
                and re.match(r"SSH session not active", str(except_value))) or\
               (except_type is socket.error
                and re.match(r"\[Errno 104\] Connection reset by peer",
                             str(except_value))):
                # Close and re-open a connection.
                # Note: close_connection() doesn't appear to get rid of the
                # connection.  It merely closes it.  Since there is a concern
                # about over-consumption of resources, we use
                # close_all_connections() which also gets rid of all
                # connections.
                gp.lprint_timen("Closing all connections.")
                sshlib.close_all_connections()
                gp.lprint_timen("Connecting to "
                                + open_connection_args['host'] + ".")
                cix = sshlib.open_connection(**open_connection_args)
                login_ssh(login_args)
                continue

            # We do not handle any other RuntimeErrors so we will raise the
            # exception again.
            sshlib.close_all_connections()
            raise(execute_exception)

        # If we get to this point, the command was executed.
        break

    if fork:
        return

    if rc != 0 and print_err:
        gp.print_var(rc, 1)
        if not print_out:
            gp.print_var(stderr)
            gp.print_var(stdout)

    if print_out:
        gp.printn(stderr + stdout)

    if not ignore_err:
        message = gp.sprint_error("The prior SSH"
                                  + " command returned a non-zero return"
                                  + " code:\n" + gp.sprint_var(rc, 1) + stderr
                                  + "\n")
        BuiltIn().should_be_equal(rc, 0, message)

    if open_connection_args['alias'] == "device_connection":
        return stdout
    return stdout, stderr, rc
コード例 #30
0
def check_state(match_state,
                invert=0,
                print_string="",
                openbmc_host="",
                openbmc_username="",
                openbmc_password="",
                os_host="",
                os_username="",
                os_password="",
                quiet=None):
    r"""
    Check that the Open BMC machine's composite state matches the specified
    state.  On success, this keyword returns the machine's composite state as a
    dictionary.

    Description of argument(s):
    match_state       A dictionary whose key/value pairs are "state field"/
                      "state value".  The state value is interpreted as a
                      regular expression.  Example call from robot:
                      ${match_state}=  Create Dictionary  chassis=^On$
                      ...  bmc=^Ready$
                      ...  boot_progress=^OSStart$
                      ${state}=  Check State  &{match_state}
    invert            If this flag is set, this function will succeed if the
                      states do NOT match.
    print_string      This function will print this string to the console prior
                      to getting the state.
    openbmc_host      The DNS name or IP address of the BMC.
                      This defaults to global ${OPENBMC_HOST}.
    openbmc_username  The username to be used to login to the BMC.
                      This defaults to global ${OPENBMC_USERNAME}.
    openbmc_password  The password to be used to login to the BMC.
                      This defaults to global ${OPENBMC_PASSWORD}.
    os_host           The DNS name or IP address of the operating system.
                      This defaults to global ${OS_HOST}.
    os_username       The username to be used to login to the OS.
                      This defaults to global ${OS_USERNAME}.
    os_password       The password to be used to login to the OS.
                      This defaults to global ${OS_PASSWORD}.
    quiet             Indicates whether status details should be written to the
                      console.  Defaults to either global value of ${QUIET} or
                      to 1.
    """

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

    gp.gp_print(print_string)

    try:
        match_state = return_state_constant(match_state)
    except TypeError:
        pass

    req_states = list(match_state.keys())
    # Remove special-case match key from req_states.
    if expressions_key() in req_states:
        req_states.remove(expressions_key())
    # Initialize state.
    state = get_state(openbmc_host=openbmc_host,
                      openbmc_username=openbmc_username,
                      openbmc_password=openbmc_password,
                      os_host=os_host,
                      os_username=os_username,
                      os_password=os_password,
                      req_states=req_states,
                      quiet=quiet)
    if not quiet:
        gp.print_var(state)

    if exit_wait_early_message != "":
        # The exit_wait_early_message has been set by a signal handler so we
        # will exit "successfully".  It is incumbent upon the calling function
        # (e.g. wait_state) to check/clear this variable and to fail
        # appropriately.
        return state

    match = compare_states(state, match_state)

    if invert and match:
        fail_msg = "The current state of the machine matches the match" +\
                   " state:\n" + gp.sprint_varx("state", state)
        BuiltIn().fail("\n" + gp.sprint_error(fail_msg))
    elif not invert and not match:
        fail_msg = "The current state of the machine does NOT match the" +\
                   " match state:\n" +\
                   gp.sprint_varx("state", state)
        BuiltIn().fail("\n" + gp.sprint_error(fail_msg))

    return state
コード例 #31
0
def get_os_state(os_host="",
                 os_username="",
                 os_password="",
                 req_states=default_os_req_states,
                 os_up=True,
                 quiet=None):
    r"""
    Get component states for the operating system such as ping, login,
    etc, put them into a dictionary and return them to the caller.

    Note that all substate values are strings.

    Description of argument(s):
    os_host      The DNS name or IP address of the operating system.
                 This defaults to global ${OS_HOST}.
    os_username  The username to be used to login to the OS.
                 This defaults to global ${OS_USERNAME}.
    os_password  The password to be used to login to the OS.
                 This defaults to global ${OS_PASSWORD}.
    req_states   This is a list of states whose values are being requested by
                 the caller.
    os_up        If the caller knows that the os can't possibly be up, it can
                 improve performance by passing os_up=False.  This function
                 will then simply return default values for all requested os
                 sub states.
    quiet        Indicates whether status details (e.g. curl commands) should
                 be written to the console.
                 Defaults to either global value of ${QUIET} or to 1.
    """

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

    # Set parm defaults where necessary and validate all parms.
    if os_host == "":
        os_host = BuiltIn().get_variable_value("${OS_HOST}")
    error_message = gv.valid_value(os_host, invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if os_username == "":
        os_username = BuiltIn().get_variable_value("${OS_USERNAME}")
    error_message = gv.valid_value(os_username, invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if os_password == "":
        os_password = BuiltIn().get_variable_value("${OS_PASSWORD}")
    error_message = gv.valid_value(os_password, invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    invalid_req_states = [sub_state for sub_state in req_states
                          if sub_state not in valid_os_req_states]
    if len(invalid_req_states) > 0:
        error_message = "The following req_states are not supported:\n" +\
            gp.sprint_var(invalid_req_states)
        BuiltIn().fail(gp.sprint_error(error_message))

    # Initialize all substate values supported by this function.
    os_ping = 0
    os_login = 0
    os_run_cmd = 0

    if os_up:
        if 'os_ping' in req_states:
            # See if the OS pings.
            rc, out_buf = gc.shell_cmd("ping -c 1 -w 2 " + os_host,
                                       print_output=0, show_err=0,
                                       ignore_err=1)
            if rc == 0:
                os_ping = 1

        # Programming note: All attributes which do not require an ssh login
        # should have been processed by this point.
        master_req_login = ['os_login', 'os_run_cmd']
        req_login = [sub_state for sub_state in req_states if sub_state in
                     master_req_login]
        must_login = (len(req_login) > 0)

        if must_login:
            output, stderr, rc = bsu.os_execute_command("uptime", quiet=quiet,
                                                        ignore_err=1,
                                                        time_out=20)
            if rc == 0:
                os_login = 1
                os_run_cmd = 1
            else:
                gp.dprint_vars(output, stderr)
                gp.dprint_vars(rc, 1)

    os_state = DotDict()
    for sub_state in req_states:
        cmd_buf = "os_state['" + sub_state + "'] = str(" + sub_state + ")"
        exec(cmd_buf)

    return os_state
コード例 #32
0
def get_state(openbmc_host="",
              openbmc_username="",
              openbmc_password="",
              os_host="",
              os_username="",
              os_password="",
              req_states=default_req_states,
              quiet=None):
    r"""
    Get component states such as chassis state, bmc state, etc, put them into a
    dictionary and return them to the caller.

    Note that all substate values are strings.

    Description of arguments:
    openbmc_host      The DNS name or IP address of the BMC.
                      This defaults to global ${OPENBMC_HOST}.
    openbmc_username  The username to be used to login to the BMC.
                      This defaults to global ${OPENBMC_USERNAME}.
    openbmc_password  The password to be used to login to the BMC.
                      This defaults to global ${OPENBMC_PASSWORD}.
    os_host           The DNS name or IP address of the operating system.
                      This defaults to global ${OS_HOST}.
    os_username       The username to be used to login to the OS.
                      This defaults to global ${OS_USERNAME}.
    os_password       The password to be used to login to the OS.
                      This defaults to global ${OS_PASSWORD}.
    req_states        This is a list of states whose values are being requested
                      by the caller.
    quiet             Indicates whether status details (e.g. curl commands)
                      should be written to the console.
                      Defaults to either global value of ${QUIET} or to 1.
    """

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

    # Set parm defaults where necessary and validate all parms.
    if openbmc_host == "":
        openbmc_host = BuiltIn().get_variable_value("${OPENBMC_HOST}")
    error_message = gv.svalid_value(openbmc_host,
                                    var_name="openbmc_host",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if openbmc_username == "":
        openbmc_username = BuiltIn().get_variable_value("${OPENBMC_USERNAME}")
    error_message = gv.svalid_value(openbmc_username,
                                    var_name="openbmc_username",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if openbmc_password == "":
        openbmc_password = BuiltIn().get_variable_value("${OPENBMC_PASSWORD}")
    error_message = gv.svalid_value(openbmc_password,
                                    var_name="openbmc_password",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    # NOTE: OS parms are optional.
    if os_host == "":
        os_host = BuiltIn().get_variable_value("${OS_HOST}")
        if os_host is None:
            os_host = ""

    if os_username is "":
        os_username = BuiltIn().get_variable_value("${OS_USERNAME}")
        if os_username is None:
            os_username = ""

    if os_password is "":
        os_password = BuiltIn().get_variable_value("${OS_PASSWORD}")
        if os_password is None:
            os_password = ""

    invalid_req_states = [
        sub_state for sub_state in req_states
        if sub_state not in valid_req_states
    ]
    if len(invalid_req_states) > 0:
        error_message = "The following req_states are not supported:\n" +\
            gp.sprint_var(invalid_req_states)
        BuiltIn().fail(gp.sprint_error(error_message))

    # Initialize all substate values supported by this function.
    ping = 0
    packet_loss = ''
    uptime = ''
    epoch_seconds = ''
    rest = '1'
    chassis = ''
    bmc = ''
    boot_progress = ''
    host = ''

    # Get the component states.
    if 'ping' in req_states:
        # See if the OS pings.
        cmd_buf = "ping -c 1 -w 2 " + openbmc_host
        if not quiet:
            gp.pissuing(cmd_buf)
        rc, out_buf = commands.getstatusoutput(cmd_buf)
        if rc == 0:
            ping = 1

    if 'packet_loss' in req_states:
        # See if the OS pings.
        cmd_buf = "ping -c 5 -w 5 " + openbmc_host +\
            " | egrep 'packet loss' | sed -re 's/.* ([0-9]+)%.*/\\1/g'"
        if not quiet:
            gp.pissuing(cmd_buf)
        rc, out_buf = commands.getstatusoutput(cmd_buf)
        if rc == 0:
            packet_loss = out_buf.rstrip("\n")

    if 'uptime' in req_states:
        cmd_buf = [
            "BMC Execute Command", "cat /proc/uptime | cut -f 1 -d ' '",
            'quiet=${1}'
        ]
        if not quiet:
            grp.rpissuing_keyword(cmd_buf)
        status, ret_values = \
            BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
        if status == "PASS":
            stdout, stderr, rc = ret_values
            if rc == 0 and stderr == "":
                uptime = stdout

    if 'epoch_seconds' in req_states:
        date_cmd_buf = "date -u +%s"
        if USE_BMC_EPOCH_TIME:
            cmd_buf = ["BMC Execute Command", date_cmd_buf, 'quiet=${1}']
            if not quiet:
                grp.rpissuing_keyword(cmd_buf)
            status, ret_values = \
                BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
            if status == "PASS":
                stdout, stderr, rc = ret_values
                if rc == 0 and stderr == "":
                    epoch_seconds = stdout.rstrip("\n")
        else:
            shell_rc, out_buf = gc.cmd_fnc_u(date_cmd_buf,
                                             quiet=1,
                                             print_output=0)
            if shell_rc == 0:
                epoch_seconds = out_buf.rstrip("\n")

    master_req_rest = ['rest', 'chassis', 'bmc', 'boot_progress', 'host']
    req_rest = [
        sub_state for sub_state in req_states if sub_state in master_req_rest
    ]
    need_rest = (len(req_rest) > 0)

    # Though we could try to determine 'rest' state on any of several calls,
    # for simplicity, we'll use 'chassis' to figure it out (even if the caller
    # hasn't explicitly asked for 'chassis').
    if 'chassis' in req_states or need_rest:
        cmd_buf = ["Get Chassis Power State", "quiet=${" + str(quiet) + "}"]
        grp.rdpissuing_keyword(cmd_buf)
        status, ret_values = \
            BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
        if status == "PASS":
            chassis = ret_values
            chassis = re.sub(r'.*\.', "", chassis)
            rest = '1'
        else:
            rest = ret_values

    if rest == '1':
        if 'bmc' in req_states:
            if OBMC_STATES_VERSION == 0:
                qualifier = "utils"
            else:
                # This will not be supported much longer.
                qualifier = "state_manager"
            cmd_buf = [
                qualifier + ".Get BMC State", "quiet=${" + str(quiet) + "}"
            ]
            grp.rdpissuing_keyword(cmd_buf)
            status, ret_values = \
                BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
            if status == "PASS":
                bmc = ret_values

        if 'boot_progress' in req_states:
            cmd_buf = ["Get Boot Progress", "quiet=${" + str(quiet) + "}"]
            grp.rdpissuing_keyword(cmd_buf)
            status, ret_values = \
                BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
            if status == "PASS":
                boot_progress = ret_values

        if 'host' in req_states:
            if OBMC_STATES_VERSION > 0:
                cmd_buf = ["Get Host State", "quiet=${" + str(quiet) + "}"]
                grp.rdpissuing_keyword(cmd_buf)
                status, ret_values = \
                    BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
                if status == "PASS":
                    host = ret_values
                    # Strip everything up to the final period.
                    host = re.sub(r'.*\.', "", host)

    state = DotDict()
    for sub_state in req_states:
        if sub_state.startswith("os_"):
            # We pass "os_" requests on to get_os_state.
            continue
        cmd_buf = "state['" + sub_state + "'] = str(" + sub_state + ")"
        exec(cmd_buf)

    if os_host == "":
        # The caller has not specified an os_host so as far as we're concerned,
        # it doesn't exist.
        return state

    os_req_states = [
        sub_state for sub_state in req_states if sub_state.startswith('os_')
    ]

    if len(os_req_states) > 0:
        # The caller has specified an os_host and they have requested
        # information on os substates.

        # Based on the information gathered on bmc, we'll try to make a
        # determination of whether the os is even up.  We'll pass the result
        # of that assessment to get_os_state to enhance performance.
        os_up_match = DotDict()
        for sub_state in master_os_up_match:
            if sub_state in req_states:
                os_up_match[sub_state] = master_os_up_match[sub_state]
        os_up = compare_states(state, os_up_match)
        os_state = get_os_state(os_host=os_host,
                                os_username=os_username,
                                os_password=os_password,
                                req_states=os_req_states,
                                os_up=os_up,
                                quiet=quiet)
        # Append os_state dictionary to ours.
        state.update(os_state)

    return state
コード例 #33
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 = 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, 1)
                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, 1)
        BuiltIn().fail(gp.sprint_error(error_message))
コード例 #34
0
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))
コード例 #35
0
def compare_states(state,
                   match_state,
                   match_type='and'):
    r"""
    Compare 2 state dictionaries.  Return True if they match and False if they
    don't.  Note that the match_state dictionary does not need to have an entry
    corresponding to each entry in the state dictionary.  But for each entry
    that it does have, the corresponding state entry will be checked for a
    match.

    Description of argument(s):
    state           A state dictionary such as the one returned by the
                    get_state function.
    match_state     A dictionary whose key/value pairs are "state field"/
                    "state value".  The state value is interpreted as a
                    regular expression.  Every value in this dictionary is
                    considered.  When match_type is 'and', if each and every
                    comparison matches, the two dictionaries are considered to
                    be matching.  If match_type is 'or', if any two of the
                    elements compared match, the two dictionaries are
                    considered to be matching.

                    This value may also be any string accepted by
                    return_state_constant (e.g. "standby_match_state").  In
                    such a case this function will call return_state_constant
                    to convert it to a proper dictionary as described above.

                    Finally, one special value is accepted for the key field:
                    expression_key().  If such an entry exists, its value is
                    taken to be a list of expressions to be evaluated.  These
                    expressions may reference state dictionary entries by
                    simply coding them in standard python syntax (e.g.
                    state['key1']).  What follows is an example expression:

                    "int(float(state['uptime'])) < int(state['elapsed_boot_time'])"

                    In this example, if the state dictionary's 'uptime' entry
                    is less than its 'elapsed_boot_time' entry, it would
                    qualify as a match.
    match_type      This may be 'and' or 'or'.
    """

    error_message = gv.valid_value(match_type, valid_values=['and', 'or'])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    try:
        match_state = return_state_constant(match_state)
    except TypeError:
        pass

    default_match = (match_type == 'and')
    for key, match_state_value in match_state.items():
        # Blank match_state_value means "don't care".
        if match_state_value == "":
            continue
        if key == expressions_key():
            for expr in match_state_value:
                # Use python interpreter to evaluate the expression.
                match = eval(expr)
                if match != default_match:
                    return match
        else:
            try:
                match = (re.match(match_state_value, str(state[key])) is not None)
            except KeyError:
                match = False
            if match != default_match:
                return match

    return default_match
コード例 #36
0
def get_os_state(os_host="",
                 os_username="",
                 os_password="",
                 req_states=default_os_req_states,
                 os_up=True,
                 quiet=None):
    r"""
    Get component states for the operating system such as ping, login,
    etc, put them into a dictionary and return them to the caller.

    Note that all substate values are strings.

    Description of arguments:
    os_host      The DNS name or IP address of the operating system.
                 This defaults to global ${OS_HOST}.
    os_username  The username to be used to login to the OS.
                 This defaults to global ${OS_USERNAME}.
    os_password  The password to be used to login to the OS.
                 This defaults to global ${OS_PASSWORD}.
    req_states   This is a list of states whose values are being requested by
                 the caller.
    os_up        If the caller knows that the os can't possibly be up, it can
                 improve performance by passing os_up=False.  This function
                 will then simply return default values for all requested os
                 sub states.
    quiet        Indicates whether status details (e.g. curl commands) should
                 be written to the console.
                 Defaults to either global value of ${QUIET} or to 1.
    """

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

    # Set parm defaults where necessary and validate all parms.
    if os_host == "":
        os_host = BuiltIn().get_variable_value("${OS_HOST}")
    error_message = gv.svalid_value(os_host,
                                    var_name="os_host",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if os_username == "":
        os_username = BuiltIn().get_variable_value("${OS_USERNAME}")
    error_message = gv.svalid_value(os_username,
                                    var_name="os_username",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if os_password == "":
        os_password = BuiltIn().get_variable_value("${OS_PASSWORD}")
    error_message = gv.svalid_value(os_password,
                                    var_name="os_password",
                                    invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    invalid_req_states = [
        sub_state for sub_state in req_states
        if sub_state not in valid_os_req_states
    ]
    if len(invalid_req_states) > 0:
        error_message = "The following req_states are not supported:\n" +\
            gp.sprint_var(invalid_req_states)
        BuiltIn().fail(gp.sprint_error(error_message))

    # Initialize all substate values supported by this function.
    os_ping = 0
    os_login = 0
    os_run_cmd = 0

    if os_up:
        if 'os_ping' in req_states:
            # See if the OS pings.
            cmd_buf = "ping -c 1 -w 2 " + os_host
            if not quiet:
                gp.pissuing(cmd_buf)
            rc, out_buf = commands.getstatusoutput(cmd_buf)
            if rc == 0:
                os_ping = 1

        # Programming note: All attributes which do not require an ssh login
        # should have been processed by this point.
        master_req_login = ['os_login', 'os_run_cmd']
        req_login = [
            sub_state for sub_state in req_states
            if sub_state in master_req_login
        ]
        must_login = (len(req_login) > 0)

        if must_login:
            # Open SSH connection to OS.  Note that this doesn't fail even when
            # the OS is not up.
            cmd_buf = ["SSHLibrary.Open Connection", os_host]
            if not quiet:
                grp.rpissuing_keyword(cmd_buf)
            ix = BuiltIn().run_keyword(*cmd_buf)

            # Login to OS.
            cmd_buf = ["Login", os_username, os_password]
            if not quiet:
                grp.rpissuing_keyword(cmd_buf)
            status, ret_values = \
                BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
            if status == "PASS":
                os_login = 1
            else:
                gp.dprint_var(status)
                gp.dprint_var(ret_values)

            if os_login:
                if 'os_run_cmd' in req_states:
                    # Try running a simple command (uptime) on the OS.
                    cmd_buf = [
                        "Execute Command", "uptime", "return_stderr=True",
                        "return_rc=True"
                    ]
                    if not quiet:
                        grp.rpissuing_keyword(cmd_buf)
                    # Note that in spite of its name, there are occasions
                    # where run_keyword_and_ignore_error can fail.
                    status, ret_values = \
                        BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
                    if status == "PASS":
                        stdout, stderr, rc = ret_values
                        if rc == 0 and stderr == "":
                            os_run_cmd = 1
                        else:
                            gp.dprint_var(status)
                            gp.dprint_var(stdout)
                            gp.dprint_var(stderr)
                            gp.dprint_var(rc)
                    else:
                        gp.dprint_var(status)
                        gp.dprint_var(ret_values)

    os_state = DotDict()
    for sub_state in req_states:
        cmd_buf = "os_state['" + sub_state + "'] = str(" + sub_state + ")"
        exec(cmd_buf)

    return os_state
コード例 #37
0
def get_state(openbmc_host="",
              openbmc_username="",
              openbmc_password="",
              os_host="",
              os_username="",
              os_password="",
              req_states=default_req_states,
              quiet=None):
    r"""
    Get component states such as chassis state, bmc state, etc, put them into a
    dictionary and return them to the caller.

    Note that all substate values are strings.

    Note: If elapsed_boot_time is included in req_states, it is the caller's
    duty to call set_start_boot_seconds() in order to set global
    start_boot_seconds.  elapsed_boot_time is the current time minus
    start_boot_seconds.

    Description of argument(s):
    openbmc_host      The DNS name or IP address of the BMC.
                      This defaults to global ${OPENBMC_HOST}.
    openbmc_username  The username to be used to login to the BMC.
                      This defaults to global ${OPENBMC_USERNAME}.
    openbmc_password  The password to be used to login to the BMC.
                      This defaults to global ${OPENBMC_PASSWORD}.
    os_host           The DNS name or IP address of the operating system.
                      This defaults to global ${OS_HOST}.
    os_username       The username to be used to login to the OS.
                      This defaults to global ${OS_USERNAME}.
    os_password       The password to be used to login to the OS.
                      This defaults to global ${OS_PASSWORD}.
    req_states        This is a list of states whose values are being requested
                      by the caller.
    quiet             Indicates whether status details (e.g. curl commands)
                      should be written to the console.
                      Defaults to either global value of ${QUIET} or to 1.
    """

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

    # Set parm defaults where necessary and validate all parms.
    if openbmc_host == "":
        openbmc_host = BuiltIn().get_variable_value("${OPENBMC_HOST}")
    error_message = gv.valid_value(openbmc_host, invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if openbmc_username == "":
        openbmc_username = BuiltIn().get_variable_value("${OPENBMC_USERNAME}")
    error_message = gv.valid_value(openbmc_username, invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    if openbmc_password == "":
        openbmc_password = BuiltIn().get_variable_value("${OPENBMC_PASSWORD}")
    error_message = gv.valid_value(openbmc_password, invalid_values=[None, ""])
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    # NOTE: OS parms are optional.
    if os_host == "":
        os_host = BuiltIn().get_variable_value("${OS_HOST}")
        if os_host is None:
            os_host = ""

    if os_username is "":
        os_username = BuiltIn().get_variable_value("${OS_USERNAME}")
        if os_username is None:
            os_username = ""

    if os_password is "":
        os_password = BuiltIn().get_variable_value("${OS_PASSWORD}")
        if os_password is None:
            os_password = ""

    invalid_req_states = [sub_state for sub_state in req_states
                          if sub_state not in valid_req_states]
    if len(invalid_req_states) > 0:
        error_message = "The following req_states are not supported:\n" +\
            gp.sprint_var(invalid_req_states)
        BuiltIn().fail(gp.sprint_error(error_message))

    # Initialize all substate values supported by this function.
    ping = 0
    packet_loss = ''
    uptime = ''
    epoch_seconds = ''
    elapsed_boot_time = ''
    rest = ''
    chassis = ''
    requested_chassis = ''
    bmc = ''
    requested_bmc = ''
    boot_progress = ''
    operating_system = ''
    host = ''
    requested_host = ''
    attempts_left = ''

    # Get the component states.
    if 'ping' in req_states:
        # See if the OS pings.
        rc, out_buf = gc.shell_cmd("ping -c 1 -w 2 " + openbmc_host,
                                   print_output=0, show_err=0,
                                   ignore_err=1)
        if rc == 0:
            ping = 1

    if 'packet_loss' in req_states:
        # See if the OS pings.
        cmd_buf = "ping -c 5 -w 5 " + openbmc_host +\
            " | egrep 'packet loss' | sed -re 's/.* ([0-9]+)%.*/\\1/g'"
        rc, out_buf = gc.shell_cmd(cmd_buf,
                                   print_output=0, show_err=0,
                                   ignore_err=1)
        if rc == 0:
            packet_loss = out_buf.rstrip("\n")

    if 'uptime' in req_states:
        # Sometimes reading uptime results in a blank value. Call with
        # wait_until_keyword_succeeds to ensure a non-blank value is obtained.
        remote_cmd_buf = "read uptime filler 2>/dev/null < /proc/uptime" +\
            " && [ ! -z \"${uptime}\" ] && echo ${uptime}"
        cmd_buf = ["BMC Execute Command",
                   re.sub('\\$', '\\$', remote_cmd_buf), 'quiet=1',
                   'test_mode=0']
        gp.qprint_issuing(cmd_buf, 0)
        gp.qprint_issuing(remote_cmd_buf, 0)
        try:
            stdout, stderr, rc =\
                BuiltIn().wait_until_keyword_succeeds("10 sec", "0 sec",
                                                      *cmd_buf)
            if rc == 0 and stderr == "":
                uptime = stdout
        except AssertionError as my_assertion_error:
            pass

    if 'epoch_seconds' in req_states or 'elapsed_boot_time' in req_states:
        date_cmd_buf = "date -u +%s"
        if USE_BMC_EPOCH_TIME:
            cmd_buf = ["BMC Execute Command", date_cmd_buf, 'quiet=${1}']
            if not quiet:
                gp.print_issuing(cmd_buf)
            status, ret_values = \
                BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
            if status == "PASS":
                stdout, stderr, rc = ret_values
                if rc == 0 and stderr == "":
                    epoch_seconds = stdout.rstrip("\n")
        else:
            shell_rc, out_buf = gc.cmd_fnc_u(date_cmd_buf,
                                             quiet=quiet,
                                             print_output=0)
            if shell_rc == 0:
                epoch_seconds = out_buf.rstrip("\n")

    if 'elapsed_boot_time' in req_states:
        global start_boot_seconds
        elapsed_boot_time = int(epoch_seconds) - start_boot_seconds

    master_req_rest = ['rest', 'host', 'requested_host', 'operating_system',
                       'attempts_left', 'boot_progress', 'chassis',
                       'requested_chassis' 'bmc' 'requested_bmc']

    req_rest = [sub_state for sub_state in req_states if sub_state in
                master_req_rest]
    need_rest = (len(req_rest) > 0)
    state = DotDict()
    if need_rest:
        cmd_buf = ["Read Properties", SYSTEM_STATE_URI + "enumerate",
                   "quiet=${" + str(quiet) + "}"]
        gp.dprint_issuing(cmd_buf)
        status, ret_values = \
            BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
        if status == "PASS":
            state['rest'] = '1'
        else:
            state['rest'] = '0'

        if int(state['rest']):
            for url_path in ret_values:
                for attr_name in ret_values[url_path]:
                    # Create a state key value based on the attr_name.
                    try:
                        ret_values[url_path][attr_name] = \
                            re.sub(r'.*\.', "",
                                   ret_values[url_path][attr_name])
                    except TypeError:
                        pass
                    # Do some key name manipulations.
                    new_attr_name = re.sub(r'^Current|(State|Transition)$',
                                           "", attr_name)
                    new_attr_name = re.sub(r'BMC', r'Bmc', new_attr_name)
                    new_attr_name = re.sub(r'([A-Z][a-z])', r'_\1',
                                           new_attr_name)
                    new_attr_name = new_attr_name.lower().lstrip("_")
                    new_attr_name = re.sub(r'power', r'chassis', new_attr_name)
                    if new_attr_name in req_states:
                        state[new_attr_name] = ret_values[url_path][attr_name]

    for sub_state in req_states:
        if sub_state in state:
            continue
        if sub_state.startswith("os_"):
            # We pass "os_" requests on to get_os_state.
            continue
        cmd_buf = "state['" + sub_state + "'] = str(" + sub_state + ")"
        exec(cmd_buf)

    if os_host == "":
        # The caller has not specified an os_host so as far as we're concerned,
        # it doesn't exist.
        return state

    os_req_states = [sub_state for sub_state in req_states
                     if sub_state.startswith('os_')]

    if len(os_req_states) > 0:
        # The caller has specified an os_host and they have requested
        # information on os substates.

        # Based on the information gathered on bmc, we'll try to make a
        # determination of whether the os is even up.  We'll pass the result
        # of that assessment to get_os_state to enhance performance.
        os_up_match = DotDict()
        for sub_state in master_os_up_match:
            if sub_state in req_states:
                os_up_match[sub_state] = master_os_up_match[sub_state]
        os_up = compare_states(state, os_up_match)
        os_state = get_os_state(os_host=os_host,
                                os_username=os_username,
                                os_password=os_password,
                                req_states=os_req_states,
                                os_up=os_up,
                                quiet=quiet)
        # Append os_state dictionary to ours.
        state.update(os_state)

    return state
コード例 #38
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 = 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, 1)
                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, 1)
        BuiltIn().fail(gp.sprint_error(error_message))
コード例 #39
0
def wait_state(match_state=(),
               wait_time="1 min",
               interval="1 second",
               invert=0,
               openbmc_host="",
               openbmc_username="",
               openbmc_password="",
               os_host="",
               os_username="",
               os_password="",
               quiet=None):
    r"""
    Wait for the Open BMC machine's composite state to match the specified
    state.  On success, this keyword returns the machine's composite state as
    a dictionary.

    Description of argument(s):
    match_state       A dictionary whose key/value pairs are "state field"/
                      "state value".  See check_state (above) for details.
                      This value may also be any string accepted by
                      return_state_constant (e.g. "standby_match_state").
                      In such a case this function will call
                      return_state_constant to convert it to a proper
                      dictionary as described above.
    wait_time         The total amount of time to wait for the desired state.
                      This value may be expressed in Robot Framework's time
                      format (e.g. 1 minute, 2 min 3 s, 4.5).
    interval          The amount of time between state checks.
                      This value may be expressed in Robot Framework's time
                      format (e.g. 1 minute, 2 min 3 s, 4.5).
    invert            If this flag is set, this function will for the state of
                      the machine to cease to match the match state.
    openbmc_host      The DNS name or IP address of the BMC.
                      This defaults to global ${OPENBMC_HOST}.
    openbmc_username  The username to be used to login to the BMC.
                      This defaults to global ${OPENBMC_USERNAME}.
    openbmc_password  The password to be used to login to the BMC.
                      This defaults to global ${OPENBMC_PASSWORD}.
    os_host           The DNS name or IP address of the operating system.
                      This defaults to global ${OS_HOST}.
    os_username       The username to be used to login to the OS.
                      This defaults to global ${OS_USERNAME}.
    os_password       The password to be used to login to the OS.
                      This defaults to global ${OS_PASSWORD}.
    quiet             Indicates whether status details should be written to the
                      console.  Defaults to either global value of ${QUIET} or
                      to 1.
    """

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

    try:
        match_state = return_state_constant(match_state)
    except TypeError:
        pass

    if not quiet:
        if invert:
            alt_text = "cease to "
        else:
            alt_text = ""
        gp.print_timen("Checking every " + str(interval) + " for up to "
                       + str(wait_time) + " for the state of the machine to "
                       + alt_text + "match the state shown below.")
        gp.print_var(match_state)

    if quiet:
        print_string = ""
    else:
        print_string = "#"

    debug = int(BuiltIn().get_variable_value("${debug}", "0"))
    if debug:
        # In debug we print state so no need to print the "#".
        print_string = ""
    check_state_quiet = 1 - debug
    cmd_buf = ["Check State", match_state, "invert=${" + str(invert) + "}",
               "print_string=" + print_string, "openbmc_host=" + openbmc_host,
               "openbmc_username="******"openbmc_password="******"os_host=" + os_host,
               "os_username="******"os_password="******"quiet=${" + str(check_state_quiet) + "}"]
    gp.dprint_issuing(cmd_buf)
    try:
        state = BuiltIn().wait_until_keyword_succeeds(wait_time, interval,
                                                      *cmd_buf)
    except AssertionError as my_assertion_error:
        gp.printn()
        message = my_assertion_error.args[0]
        BuiltIn().fail(message)

    if exit_wait_early_message:
        # The global exit_wait_early_message was set by a signal handler
        # indicating that we should fail.
        message = exit_wait_early_message
        # Clear the exit_wait_early_message variable for future use.
        set_exit_wait_early_message("")
        BuiltIn().fail(gp.sprint_error(message))

    if not quiet:
        gp.printn()
        if invert:
            gp.print_timen("The states no longer match:")
        else:
            gp.print_timen("The states match:")
        gp.print_var(state)

    return state
コード例 #40
0
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))