1#!/usr/bin/env python
2
3r"""
4This module is the python counterpart to obmc_boot_test.
5"""
6
7from tally_sheet import *
8import gen_robot_print as grp
9import gen_robot_plug_in as grpi
10import state as st
11
12import os
13import time
14import subprocess
15
16from robot.utils import DotDict
17from robot.libraries.BuiltIn import BuiltIn
18from robot.libraries.OperatingSystem import OperatingSystem
19
20# Create boot_results_fields for use in creating boot_results.
21boot_results_fields = DotDict([('total', 0), ('pass', 0), ('fail', 0)])
22# Create boot_results which is global to this module.
23boot_results = tally_sheet('boot type',
24                           boot_results_fields,
25                           'boot_test_results')
26
27boot_results.set_sum_fields(['total', 'pass', 'fail'])
28boot_results.set_calc_fields(['total=pass+fail'])
29
30
31###############################################################################
32def plug_in_setup():
33
34    r"""
35    Initialize all plug-in environment variables for use by the plug-in
36    programs.
37    """
38
39    boot_pass = int(BuiltIn().get_variable_value("${boot_pass}"))
40    if boot_pass > 1:
41        test_really_running = 1
42    else:
43        test_really_running = 0
44
45    BuiltIn().set_global_variable("${test_really_running}",
46                                  test_really_running)
47
48    next_boot = BuiltIn().get_variable_value("${next_boot}")
49    BuiltIn().set_global_variable("${boot_type_desc}", next_boot)
50
51    # Setting master_pid correctly influences the behavior of plug-ins like
52    # DB_Logging
53    program_pid = BuiltIn().get_variable_value("${program_pid}")
54    try:
55        master_pid = OperatingSystem().get_environment_variable(
56            "AUTOBOOT_MASTER_PID")
57    except RuntimeError:
58        master_pid = program_pid
59    if master_pid == "":
60        master_pid = program_pid
61
62    BuiltIn().set_global_variable("${master_pid}", master_pid)
63
64    seconds = time.time()
65    loc_time = time.localtime(seconds)
66    time_string = time.strftime("%y%m%d.%H%M%S.", loc_time)
67
68    openbmc_nickname = BuiltIn().get_variable_value("${openbmc_nickname}")
69    openbmc_host = BuiltIn().get_variable_value("${openbmc_host}")
70    if openbmc_nickname == "":
71        openbmc_nickname = openbmc_host
72    ffdc_prefix = openbmc_nickname
73
74    ffdc_prefix += "." + time_string
75
76    try:
77        ffdc_dir_path = os.environ['FFDC_DIR_PATH']
78        # Add trailing slash.
79        ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep
80    except KeyError:
81        ffdc_dir_path = ""
82    BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path)
83
84    status_dir_path = os.environ.get('STATUS_DIR_PATH', "")
85    if status_dir_path != "":
86        # Add trailing slash.
87        status_dir_path = os.path.normpath(status_dir_path) + os.sep
88    BuiltIn().set_global_variable("${STATUS_DIR_PATH}", status_dir_path)
89
90    base_tool_dir_path = os.environ.get('AUTOBOOT_BASE_TOOL_DIR_PATH', "/tmp")
91    base_tool_dir_path = os.path.normpath(base_tool_dir_path) + os.sep
92    BuiltIn().set_global_variable("${BASE_TOOL_DIR_PATH}", base_tool_dir_path)
93
94    ffdc_list_file_path = base_tool_dir_path + openbmc_nickname +\
95        "/FFDC_FILE_LIST"
96
97    BuiltIn().set_global_variable("${FFDC_LIST_FILE_PATH}",
98                                  ffdc_list_file_path)
99
100    # For each program parameter, set the corresponding AUTOBOOT_ environment
101    # variable value.  Also, set an AUTOBOOT_ environment variable for every
102    # element in additional_values.
103    additional_values = ["boot_type_desc", "boot_success", "boot_pass",
104                         "boot_fail", "test_really_running", "program_pid",
105                         "master_pid", "ffdc_prefix", "ffdc_dir_path",
106                         "status_dir_path", "base_tool_dir_path",
107                         "ffdc_list_file_path"]
108    BuiltIn().set_global_variable("${ffdc_prefix}", ffdc_prefix)
109
110    parm_list = BuiltIn().get_variable_value("@{parm_list}")
111
112    plug_in_vars = parm_list + additional_values
113
114    for var_name in plug_in_vars:
115        var_value = BuiltIn().get_variable_value("${" + var_name + "}")
116        var_name = var_name.upper()
117        if var_value is None:
118            var_value = ""
119        OperatingSystem().set_environment_variable(
120            "AUTOBOOT_" + var_name, var_value)
121
122    debug = int(BuiltIn().get_variable_value("${debug}"))
123    if debug:
124        cmd_buf = "printenv | egrep AUTOBOOT_ | sort -u"
125        grp.rpissuing(cmd_buf)
126        sub_proc = subprocess.Popen(cmd_buf, shell=True,
127                                    stdout=subprocess.PIPE,
128                                    stderr=subprocess.STDOUT)
129        out_buf, err_buf = sub_proc.communicate()
130        shell_rc = sub_proc.returncode
131        grp.rprint(out_buf)
132
133###############################################################################
134
135
136###############################################################################
137def create_boot_results_table():
138
139    r"""
140    Create our boot_results_table.
141    """
142
143    # At some point we'll want to change to reading in our boot types from
144    # some external source (e.g. file).
145
146    boot_results.add_row('BMC Power On')
147    boot_results.add_row('BMC Power Off')
148
149###############################################################################
150
151
152###############################################################################
153def update_boot_results_table(boot_type,
154                              boot_status):
155
156    r"""
157    Update our boot_results_table.  This includes:
158    - Updating the record for the given boot_type by incrementing the pass or
159      fail field.
160    - Calling the calc method to have the totals, etc. calculated.
161    - Updating global variables boot_pass/boot_fail.
162
163    Description of arguments:
164    boot_type    The type of boot just done (e.g. "BMC Power On").
165    boot_status  The status of the boot just done.  This should be equal to
166                 either "pass" or "fail" (case-insensitive).
167    """
168
169    boot_results.inc_row_field(boot_type, boot_status.lower())
170    totals_line = boot_results.calc()
171
172    # The caller of obmc_boot_test can pass boot_pass/boot_fail values because
173    # the caller may have already done some testing (e.g. "BMC OOB").  For the
174    # sake of DB logging done by plug-ins, we want to include these in our
175    # overall totals.
176    initial_boot_pass = int(BuiltIn().get_variable_value(
177        "${initial_boot_pass}"))
178    initial_boot_fail = int(BuiltIn().get_variable_value(
179        "${initial_boot_fail}"))
180
181    BuiltIn().set_global_variable("${boot_pass}",
182                                  totals_line['pass'] + initial_boot_pass)
183    BuiltIn().set_global_variable("${boot_fail}",
184                                  totals_line['fail'] + initial_boot_fail)
185
186###############################################################################
187
188
189###############################################################################
190def print_boot_results_table(header_footer="\n"):
191
192    r"""
193    Print the formatted boot_resuls_table to the console.
194    """
195
196    grp.rprint(header_footer)
197    grp.rprint(boot_results.sprint_report())
198    grp.rprint(header_footer)
199
200###############################################################################
201
202
203###############################################################################
204def my_ffdc():
205
206    r"""
207    Collect FFDC data.
208    """
209
210    plug_in_setup()
211    rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
212        call_point='ffdc', stop_on_plug_in_failure=1)
213
214    AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX']
215
216    # FFDC_LOG_PATH is used by "FFDC" keyword.
217    FFDC_DIR_PATH = BuiltIn().get_variable_value("${FFDC_DIR_PATH}")
218    BuiltIn().set_global_variable("${FFDC_LOG_PATH}",
219                                  FFDC_DIR_PATH)
220
221    cmd_buf = ["FFDC", "ffdc_prefix=" + AUTOBOOT_FFDC_PREFIX]
222    grp.rpissuing_keyword(cmd_buf)
223    BuiltIn().run_keyword(*cmd_buf)
224
225    state = st.get_state()
226    BuiltIn().set_global_variable("${state}",
227                                  state)
228
229    cmd_buf = ["Print Defect Report"]
230    grp.rpissuing_keyword(cmd_buf)
231    BuiltIn().run_keyword(*cmd_buf)
232
233###############################################################################
234