1#!/usr/bin/env python
2
3r"""
4This module is the python counterpart to openbmc_ffdc.robot..
5"""
6
7import os
8
9import gen_robot_print as grp
10import gen_valid as gv
11import gen_robot_keyword as grk
12
13from robot.libraries.BuiltIn import BuiltIn
14
15
16###############################################################################
17def ffdc(ffdc_dir_path=None,
18         ffdc_prefix=None,
19         ffdc_function_list=""):
20
21    r"""
22    Gather First Failure Data Capture (FFDC).
23
24    This includes:
25    - Set global FFDC_TIME.
26    - Create FFDC work space directory.
27    - Write test info details.
28    - Call BMC methods to write/collect FFDC data.
29
30    Description of arguments:
31    ffdc_dir_path       The dir path where FFDC data should be put.
32    ffdc_prefix         The prefix to be given to each FFDC file name
33                        generated.
34    ffdc_function_list  A colon-delimited list of all the types of FFDC data
35                        you wish to have collected.  A blank value means that
36                        all possible kinds of FFDC are to be collected.  See
37                        FFDC_METHOD_CALL object in lib/openbmc_ffdc_list.py
38                        for possible choices.
39    """
40
41    # Check if Ping and SSH connection is alive
42    OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
43    status, status_ping = grk.run_key("Ping Host  " + OPENBMC_HOST)
44    grp.rprint_var(status_ping)
45    if status_ping:
46        status_ssh = \
47            BuiltIn().run_keyword_and_return_status("Open Connection And" +
48                                                    " Log In")
49        grp.rprint_var(status_ssh)
50        if not status_ssh:
51            grp.rprint_error("BMC is not communicating. \
52                              Aborting FFDC collection.\n")
53            BuiltIn().run_keyword_and_return_status("Close All Connections")
54            return
55
56    grp.rprint_timen("Collecting FFDC.")
57
58    # Get default values for arguments.
59    ffdc_dir_path, ffdc_prefix = set_ffdc_defaults(ffdc_dir_path, ffdc_prefix)
60    grp.rprint_var(ffdc_dir_path)
61    grp.rprint_var(ffdc_prefix)
62
63    # LOG_PREFIX is used by subordinate functions.
64    LOG_PREFIX = ffdc_dir_path + ffdc_prefix
65    BuiltIn().set_global_variable("${LOG_PREFIX}", LOG_PREFIX)
66
67    cmd_buf = ["Create Directory", ffdc_dir_path]
68    grp.rpissuing_keyword(cmd_buf)
69    status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
70    if status != "PASS":
71        error_message = grp.sprint_error_report("Create Directory failed" +
72                                                " with the following" +
73                                                " error:\n" + output)
74        BuiltIn().fail(error_message)
75
76    # FFDC_FILE_PATH is used by Header Message.
77    FFDC_FILE_PATH = ffdc_dir_path + ffdc_prefix + "BMC_general.txt"
78    BuiltIn().set_global_variable("${FFDC_FILE_PATH}", FFDC_FILE_PATH)
79
80    grk.run_key("Header Message")
81
82    grk.run_key_u("Call FFDC Methods  ffdc_function_list=" +
83                  ffdc_function_list)
84
85    grp.rprint_timen("Finished collecting FFDC.")
86
87###############################################################################
88
89
90###############################################################################
91def set_ffdc_defaults(ffdc_dir_path=None,
92                      ffdc_prefix=None):
93
94    r"""
95    Set a default value for ffdc_dir_path and ffdc_prefix if they don't
96    already have values.  Return both values.
97
98    Description of arguments:
99    ffdc_dir_path  The dir path where FFDC data should be put.
100    ffdc_prefix    The prefix to be given to each FFDC file name generated.
101
102    NOTE: If global variable ffdc_dir_path_style is set to ${1}, this function
103    will create default values in a newer way.  Otherwise, its behavior
104    will remain unchanged.
105    """
106
107    # Note: Several subordinate functions like 'Get Test Dir and Name' and
108    # 'Header Message' expect global variable FFDC_TIME to be set.
109    cmd_buf = ["Get Current Time Stamp"]
110    grp.rdpissuing_keyword(cmd_buf)
111    FFDC_TIME = BuiltIn().run_keyword(*cmd_buf)
112    BuiltIn().set_global_variable("${FFDC_TIME}", FFDC_TIME)
113
114    ffdc_dir_path_style = BuiltIn().get_variable_value(
115        "${ffdc_dir_path_style}")
116
117    if ffdc_dir_path is None:
118        if ffdc_dir_path_style:
119            try:
120                ffdc_dir_path = os.environ['FFDC_DIR_PATH']
121            except KeyError:
122                ffdc_dir_path = os.path.dirname(
123                    BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
124        else:
125            FFDC_LOG_PATH = os.getcwd() + "/logs/"
126            if FFDC_LOG_PATH is None:
127                FFDC_LOG_PATH = ""
128            if FFDC_LOG_PATH == "":
129                FFDC_LOG_PATH = os.path.dirname(
130                    BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
131            error_message = gv.svalid_value(FFDC_LOG_PATH,
132                                            var_name="FFDC_LOG_PATH")
133            if error_message != "":
134                error_message = grp.sprint_error_report(error_message)
135                BuiltIn().fail(error_message)
136            FFDC_LOG_PATH = os.path.normpath(FFDC_LOG_PATH) + os.sep
137
138            cmd_buf = ["Get Test Dir and Name"]
139            grp.rpissuing_keyword(cmd_buf)
140            suitename, testname = BuiltIn().run_keyword(*cmd_buf)
141
142            ffdc_dir_path = FFDC_LOG_PATH + suitename + "/" + testname + "/"
143
144    # Add trailing slash.
145    ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep
146
147    if ffdc_prefix is None:
148        FFDC_TIME = BuiltIn().get_variable_value("${FFDC_TIME}")
149        if ffdc_prefix is None:
150            if ffdc_dir_path_style:
151                OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
152                OPENBMC_NICKNAME = BuiltIn().get_variable_value(
153                    "${OPENBMC_NICKNAME}", default=OPENBMC_HOST)
154                ffdc_prefix = OPENBMC_NICKNAME + "." + FFDC_TIME[2:8] + "." +\
155                    FFDC_TIME[8:14] + "."
156            else:
157                ffdc_prefix = FFDC_TIME + "_"
158
159    BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path)
160    BuiltIn().set_global_variable("${FFDC_PREFIX}", ffdc_prefix)
161
162    return ffdc_dir_path, ffdc_prefix
163
164###############################################################################
165