blob: 653dde1c0ddcb9420ac56beb672cd9f1e3208569 [file] [log] [blame]
Michael Walsh0bbd8602016-11-22 11:31:49 -06001#!/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
Michael Walsh55302292017-01-10 11:43:02 -06009import gen_robot_plug_in as grpi
10import state as st
Michael Walsh0bbd8602016-11-22 11:31:49 -060011
12import os
13import time
14import subprocess
Michael Walsh341c21e2017-01-17 16:25:20 -060015import glob
Michael Walsh0bbd8602016-11-22 11:31:49 -060016
17from robot.utils import DotDict
18from robot.libraries.BuiltIn import BuiltIn
19from robot.libraries.OperatingSystem import OperatingSystem
20
21# Create boot_results_fields for use in creating boot_results.
22boot_results_fields = DotDict([('total', 0), ('pass', 0), ('fail', 0)])
23# Create boot_results which is global to this module.
24boot_results = tally_sheet('boot type',
25 boot_results_fields,
26 'boot_test_results')
27
28boot_results.set_sum_fields(['total', 'pass', 'fail'])
29boot_results.set_calc_fields(['total=pass+fail'])
30
31
32###############################################################################
Michael Walsh0bbd8602016-11-22 11:31:49 -060033def plug_in_setup():
34
35 r"""
36 Initialize all plug-in environment variables for use by the plug-in
37 programs.
38 """
39
40 boot_pass = int(BuiltIn().get_variable_value("${boot_pass}"))
41 if boot_pass > 1:
42 test_really_running = 1
43 else:
44 test_really_running = 0
45
46 BuiltIn().set_global_variable("${test_really_running}",
47 test_really_running)
48
49 next_boot = BuiltIn().get_variable_value("${next_boot}")
50 BuiltIn().set_global_variable("${boot_type_desc}", next_boot)
51
52 # Setting master_pid correctly influences the behavior of plug-ins like
53 # DB_Logging
54 program_pid = BuiltIn().get_variable_value("${program_pid}")
55 try:
56 master_pid = OperatingSystem().get_environment_variable(
57 "AUTOBOOT_MASTER_PID")
58 except RuntimeError:
59 master_pid = program_pid
60 if master_pid == "":
61 master_pid = program_pid
62
63 BuiltIn().set_global_variable("${master_pid}", master_pid)
64
65 seconds = time.time()
66 loc_time = time.localtime(seconds)
67 time_string = time.strftime("%y%m%d.%H%M%S.", loc_time)
68
69 openbmc_nickname = BuiltIn().get_variable_value("${openbmc_nickname}")
Michael Walsh769c2a12016-12-13 15:45:17 -060070 openbmc_host = BuiltIn().get_variable_value("${openbmc_host}")
Michael Walsh0bbd8602016-11-22 11:31:49 -060071 if openbmc_nickname == "":
Michael Walsh55302292017-01-10 11:43:02 -060072 openbmc_nickname = openbmc_host
73 ffdc_prefix = openbmc_nickname
Michael Walsh0bbd8602016-11-22 11:31:49 -060074
75 ffdc_prefix += "." + time_string
76
Michael Walsh86de0d22016-12-05 10:13:15 -060077 try:
78 ffdc_dir_path = os.environ['FFDC_DIR_PATH']
79 # Add trailing slash.
80 ffdc_dir_path = os.path.normpath(ffdc_dir_path) + os.sep
81 except KeyError:
82 ffdc_dir_path = ""
Michael Walsh0bbd8602016-11-22 11:31:49 -060083 BuiltIn().set_global_variable("${FFDC_DIR_PATH}", ffdc_dir_path)
84
Michael Walsh55302292017-01-10 11:43:02 -060085 status_dir_path = os.environ.get('STATUS_DIR_PATH', "")
86 if status_dir_path != "":
87 # Add trailing slash.
88 status_dir_path = os.path.normpath(status_dir_path) + os.sep
89 BuiltIn().set_global_variable("${STATUS_DIR_PATH}", status_dir_path)
90
91 base_tool_dir_path = os.environ.get('AUTOBOOT_BASE_TOOL_DIR_PATH', "/tmp")
Michael Walsh4c9a6452016-12-13 16:03:11 -060092 base_tool_dir_path = os.path.normpath(base_tool_dir_path) + os.sep
93 BuiltIn().set_global_variable("${BASE_TOOL_DIR_PATH}", base_tool_dir_path)
94
Michael Walsh55302292017-01-10 11:43:02 -060095 ffdc_list_file_path = base_tool_dir_path + openbmc_nickname +\
96 "/FFDC_FILE_LIST"
Michael Walsh4c9a6452016-12-13 16:03:11 -060097
98 BuiltIn().set_global_variable("${FFDC_LIST_FILE_PATH}",
99 ffdc_list_file_path)
100
Michael Walsh0bbd8602016-11-22 11:31:49 -0600101 # For each program parameter, set the corresponding AUTOBOOT_ environment
102 # variable value. Also, set an AUTOBOOT_ environment variable for every
103 # element in additional_values.
104 additional_values = ["boot_type_desc", "boot_success", "boot_pass",
105 "boot_fail", "test_really_running", "program_pid",
Michael Walsh4c9a6452016-12-13 16:03:11 -0600106 "master_pid", "ffdc_prefix", "ffdc_dir_path",
Michael Walsh55302292017-01-10 11:43:02 -0600107 "status_dir_path", "base_tool_dir_path",
108 "ffdc_list_file_path"]
Michael Walsh0bbd8602016-11-22 11:31:49 -0600109 BuiltIn().set_global_variable("${ffdc_prefix}", ffdc_prefix)
110
111 parm_list = BuiltIn().get_variable_value("@{parm_list}")
112
113 plug_in_vars = parm_list + additional_values
114
115 for var_name in plug_in_vars:
116 var_value = BuiltIn().get_variable_value("${" + var_name + "}")
117 var_name = var_name.upper()
118 if var_value is None:
119 var_value = ""
120 OperatingSystem().set_environment_variable(
121 "AUTOBOOT_" + var_name, var_value)
122
123 debug = int(BuiltIn().get_variable_value("${debug}"))
124 if debug:
125 cmd_buf = "printenv | egrep AUTOBOOT_ | sort -u"
126 grp.rpissuing(cmd_buf)
127 sub_proc = subprocess.Popen(cmd_buf, shell=True,
128 stdout=subprocess.PIPE,
129 stderr=subprocess.STDOUT)
130 out_buf, err_buf = sub_proc.communicate()
131 shell_rc = sub_proc.returncode
132 grp.rprint(out_buf)
133
134###############################################################################
135
136
137###############################################################################
138def create_boot_results_table():
139
140 r"""
141 Create our boot_results_table.
142 """
143
144 # At some point we'll want to change to reading in our boot types from
145 # some external source (e.g. file).
146
147 boot_results.add_row('BMC Power On')
148 boot_results.add_row('BMC Power Off')
149
150###############################################################################
151
152
153###############################################################################
154def update_boot_results_table(boot_type,
155 boot_status):
156
157 r"""
158 Update our boot_results_table. This includes:
159 - Updating the record for the given boot_type by incrementing the pass or
160 fail field.
161 - Calling the calc method to have the totals, etc. calculated.
162 - Updating global variables boot_pass/boot_fail.
163
164 Description of arguments:
165 boot_type The type of boot just done (e.g. "BMC Power On").
166 boot_status The status of the boot just done. This should be equal to
167 either "pass" or "fail" (case-insensitive).
168 """
169
170 boot_results.inc_row_field(boot_type, boot_status.lower())
171 totals_line = boot_results.calc()
172
173 # The caller of obmc_boot_test can pass boot_pass/boot_fail values because
174 # the caller may have already done some testing (e.g. "BMC OOB"). For the
175 # sake of DB logging done by plug-ins, we want to include these in our
176 # overall totals.
177 initial_boot_pass = int(BuiltIn().get_variable_value(
178 "${initial_boot_pass}"))
179 initial_boot_fail = int(BuiltIn().get_variable_value(
180 "${initial_boot_fail}"))
181
182 BuiltIn().set_global_variable("${boot_pass}",
183 totals_line['pass'] + initial_boot_pass)
184 BuiltIn().set_global_variable("${boot_fail}",
185 totals_line['fail'] + initial_boot_fail)
186
187###############################################################################
188
189
190###############################################################################
191def print_boot_results_table(header_footer="\n"):
192
193 r"""
194 Print the formatted boot_resuls_table to the console.
195 """
196
Michael Walsh341c21e2017-01-17 16:25:20 -0600197 grp.rqprint(header_footer)
198 grp.rqprint(boot_results.sprint_report())
199 grp.rqprint(header_footer)
200
201###############################################################################
202
203
204###############################################################################
205def select_boot(state):
206
207 r"""
208 Select a boot test to be run based on our current state and return the
209 chosen boot type.
210
211 Description of arguments:
212 state The state of the machine, which will include the power state..
213 """
214
215 if 'chassis' in state:
216 # New style state.
217 if state['chassis'] == 'Off':
218 boot = 'BMC Power On'
219 else:
220 boot = 'BMC Power Off'
221 else:
222 # Old style state.
223 if state['power'] == 0:
224 boot = 'BMC Power On'
225 else:
226 boot = 'BMC Power Off'
227
228 return boot
Michael Walsh0bbd8602016-11-22 11:31:49 -0600229
230###############################################################################
Michael Walsh55302292017-01-10 11:43:02 -0600231
232
233###############################################################################
234def my_ffdc():
235
236 r"""
237 Collect FFDC data.
238 """
239
240 plug_in_setup()
241 rc, shell_rc, failed_plug_in_name = grpi.rprocess_plug_in_packages(
242 call_point='ffdc', stop_on_plug_in_failure=1)
243
244 AUTOBOOT_FFDC_PREFIX = os.environ['AUTOBOOT_FFDC_PREFIX']
245
246 # FFDC_LOG_PATH is used by "FFDC" keyword.
247 FFDC_DIR_PATH = BuiltIn().get_variable_value("${FFDC_DIR_PATH}")
248 BuiltIn().set_global_variable("${FFDC_LOG_PATH}",
249 FFDC_DIR_PATH)
250
251 cmd_buf = ["FFDC", "ffdc_prefix=" + AUTOBOOT_FFDC_PREFIX]
252 grp.rpissuing_keyword(cmd_buf)
253 BuiltIn().run_keyword(*cmd_buf)
254
255 state = st.get_state()
256 BuiltIn().set_global_variable("${state}",
257 state)
258
259 cmd_buf = ["Print Defect Report"]
260 grp.rpissuing_keyword(cmd_buf)
261 BuiltIn().run_keyword(*cmd_buf)
262
263###############################################################################
Michael Walsh341c21e2017-01-17 16:25:20 -0600264
265
266###############################################################################
267def print_last_boots():
268
269 r"""
270 Print the last ten boots done with their time stamps.
271 """
272
273 # indent 0, 90 chars wide, linefeed, char is "="
274 grp.rqprint_dashes(0, 90)
275 grp.rqprintn("Last 10 boots:\n")
276 last_ten = BuiltIn().get_variable_value("${LAST_TEN}")
277
278 for boot_entry in last_ten:
279 grp.rqprint(boot_entry)
280 grp.rqprint_dashes(0, 90)
281
282###############################################################################
283
284
285###############################################################################
286def print_test_start_message(boot_keyword):
287
288 r"""
289 Print a message indicating what boot test is about to run.
290
291 Description of arguments:
292 boot_keyword The name of the boot which is to be run
293 (e.g. "BMC Power On").
294 """
295
296 doing_msg = gp.sprint_timen("Doing \"" + boot_keyword + "\".")
297 grp.rqprint(doing_msg)
298
299 last_ten = BuiltIn().get_variable_value("${LAST_TEN}")
300 last_ten.append(doing_msg)
301
302 if len(last_ten) > 10:
303 del last_ten[0]
304
305###############################################################################
306
307
308###############################################################################
309def print_defect_report():
310
311 r"""
312 Print a defect report.
313 """
314
315 grp.rqprintn()
316 # indent=0, width=90, linefeed=1, char="="
317 grp.rqprint_dashes(0, 90, 1, "=")
318 grp.rqprintn("Copy this data to the defect:\n")
319
320 parm_list = BuiltIn().get_variable_value("${parm_list}")
321
322 grp.rqpvars(*parm_list)
323
324 grp.rqprintn()
325
326 print_last_boots()
327 grp.rqprintn()
328 state = BuiltIn().get_variable_value("${state}")
329 grp.rqpvar(state)
330
331 # At some point I'd like to have the 'Call FFDC Methods' return a list
332 # of files it has collected. In that case, the following "ls" command
333 # would no longer be needed. For now, however, glob shows the files
334 # named in FFDC_LIST_FILE_PATH so I will refrain from printing those
335 # out (so we don't see duplicates in the list).
336
337 LOG_PREFIX = BuiltIn().get_variable_value("${LOG_PREFIX}")
338
339 output = '\n'.join(glob.glob(LOG_PREFIX + '*'))
340
341 FFDC_LIST_FILE_PATH = \
342 BuiltIn().get_variable_value("${FFDC_LIST_FILE_PATH}")
343
344 try:
345 ffdc_list = open(FFDC_LIST_FILE_PATH, 'r')
346 except IOError:
347 ffdc_list = ""
348
349 status_file_path = BuiltIn().get_variable_value("${status_file_path}")
350
351 grp.rqprintn()
352 grp.rqprintn("FFDC data files:")
353 if status_file_path != "":
354 grp.rqprintn(status_file_path)
355
356 grp.rqprintn(output)
357 # grp.rqprintn(ffdc_list)
358 grp.rqprintn()
359
360 grp.rqprint_dashes(0, 90, 1, "=")
361
362###############################################################################