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
11
12from robot.libraries.BuiltIn import BuiltIn
13
14
15###############################################################################
16def ffdc(ffdc_dir_path=None,
17         ffdc_prefix=None):
18
19    r"""
20    Gather First Failure Data Capture (FFDC).
21
22    This includes:
23    - Set global FFDC_TIME.
24    - Create FFDC work space directory.
25    - Write test info details.
26    - Call BMC methods to write/collect FFDC data.
27
28    Description of arguments:
29    ffdc_dir_path  The dir path where FFDC data should be put.
30    ffdc_prefix    The prefix to be given to each FFDC file name generated.
31    """
32
33    # Check if Ping and SSH connection is alive
34    OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
35    cmd_buf = ["Ping Host", OPENBMC_HOST]
36    grp.rpissuing_keyword(cmd_buf)
37    status_ping = BuiltIn().run_keyword_and_return_status(*cmd_buf)
38    grp.rprint_var(status_ping)
39    if status_ping == True:
40        status_ssh = \
41          BuiltIn().run_keyword_and_return_status("Open Connection And Log In")
42        grp.rprint_var(status_ssh)
43        if status_ssh != True:
44            grp.rprint_error("BMC is not communicating. \
45                              Aborting FFDC collection.\n")
46            BuiltIn().run_keyword_and_return_status("Close All Connections")
47            return
48
49    grp.rprint_timen("Collecting FFDC.")
50
51    # Note: Several subordinate functions like 'Get Test Dir and Name' and
52    # 'Header Message' expect global variable FFDC_TIME to be set.
53    cmd_buf = ["Get Current Time Stamp"]
54    grp.rdpissuing_keyword(cmd_buf)
55    FFDC_TIME = BuiltIn().run_keyword(*cmd_buf)
56    BuiltIn().set_global_variable("${FFDC_TIME}", FFDC_TIME)
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    cmd_buf = ["Header Message"]
81    grp.rpissuing_keyword(cmd_buf)
82    BuiltIn().run_keyword(*cmd_buf)
83
84    cmd_buf = ["Call FFDC Methods"]
85    grp.rpissuing_keyword(cmd_buf)
86    BuiltIn().run_keyword(*cmd_buf)
87
88    grp.rprint_timen("Finished collecting FFDC.")
89
90###############################################################################
91
92
93###############################################################################
94def set_ffdc_defaults(ffdc_dir_path=None,
95                      ffdc_prefix=None):
96
97    r"""
98    Set a default value for ffdc_dir_path and ffdc_prefix if they don't
99    already have values.  Return both values.
100
101    Description of arguments:
102    ffdc_dir_path  The dir path where FFDC data should be put.
103    ffdc_prefix    The prefix to be given to each FFDC file name generated.
104
105    NOTE: If global variable ffdc_dir_path_style is set to ${1}, this function
106    will create default values in a newer way.  Otherwise, its behavior
107    will remain unchanged.
108    """
109
110    ffdc_dir_path_style = BuiltIn().get_variable_value(
111        "${ffdc_dir_path_style}")
112
113    if ffdc_dir_path is None:
114        if ffdc_dir_path_style:
115            try:
116                ffdc_dir_path = os.environ['FFDC_DIR_PATH']
117            except KeyError:
118                ffdc_dir_path = os.path.dirname(
119                    BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
120        else:
121            FFDC_LOG_PATH = BuiltIn().get_variable_value("${FFDC_LOG_PATH}")
122            if FFDC_LOG_PATH is None:
123                FFDC_LOG_PATH = ""
124            if FFDC_LOG_PATH == "":
125                FFDC_LOG_PATH = os.path.dirname(
126                    BuiltIn().get_variable_value("${LOG_FILE}")) + "/"
127            error_message = gv.svalid_value(FFDC_LOG_PATH,
128                                            var_name="FFDC_LOG_PATH")
129            if error_message != "":
130                error_message = grp.sprint_error_report(error_message)
131                BuiltIn().fail(error_message)
132            FFDC_LOG_PATH = os.path.normpath(FFDC_LOG_PATH) + os.sep
133
134            cmd_buf = ["Get Test Dir and Name"]
135            grp.rpissuing_keyword(cmd_buf)
136            suitename, testname = BuiltIn().run_keyword(*cmd_buf)
137
138            ffdc_dir_path = FFDC_LOG_PATH + suitename + "/" + testname + "/"
139
140    # Add trailing slash.
141    ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep
142
143    if ffdc_prefix is None:
144        FFDC_TIME = BuiltIn().get_variable_value("${FFDC_TIME}")
145        if ffdc_prefix is None:
146            if ffdc_dir_path_style:
147                OPENBMC_HOST = BuiltIn().get_variable_value("${OPENBMC_HOST}")
148                OPENBMC_NICKNAME = BuiltIn().get_variable_value(
149                    "${OPENBMC_NICKNAME}", default=OPENBMC_HOST)
150                ffdc_prefix = OPENBMC_NICKNAME + "." + FFDC_TIME[2:8] + "." +\
151                    FFDC_TIME[8:14] + "."
152            else:
153                ffdc_prefix = FFDC_TIME + "_"
154
155    return ffdc_dir_path, ffdc_prefix
156
157###############################################################################
158