blob: e873c52eb0176f3b79f352fa60ee8edf6a44c95c [file] [log] [blame]
George Keishinge7e91712021-09-03 11:28:44 -05001#!/usr/bin/env python3
Michael Walsh3ba8ecd2018-04-24 11:33:25 -05002
3r"""
Michael Walsh410b1782019-10-22 15:56:18 -05004This module provides functions which are useful to plug-ins call-point programs that wish to make external
5robot program calls.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -05006"""
7
George Keishinge635ddc2022-12-08 07:38:02 -06008import imp
Patrick Williams20f38712022-12-08 06:18:26 -06009import os
10import re
11import subprocess
12import sys
13import time
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050014
Patrick Williams20f38712022-12-08 06:18:26 -060015import gen_cmd as gc
16import gen_misc as gm
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050017import gen_print as gp
18import gen_valid as gv
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050019
Patrick Williams20f38712022-12-08 06:18:26 -060020base_path = (
21 os.path.dirname(os.path.dirname(imp.find_module("gen_robot_print")[1]))
22 + os.sep
23)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050024
25
26def init_robot_out_parms(extra_prefix=""):
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050027 r"""
28 Initialize robot output parms such as outputdir, output, etc.
29
30 This function will set global values for the following robot output parms.
31
Michael Walsh1f961b72020-06-16 15:54:11 -050032 outputdir, output, log, report, loglevel, consolecolors, consolemarkers
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050033
Michael Walsh410b1782019-10-22 15:56:18 -050034 This function would typically be called prior to calling create_robot_cmd_string.
Michael Walshf33140f2018-11-01 14:05:56 -050035
36 Description of argument(s):
Michael Walsh410b1782019-10-22 15:56:18 -050037 extra_prefix An extra prefix to be appended to the default prefix for output file
38 names.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050039 """
40
Michael Walsha0ce75a2018-07-31 13:54:29 -050041 gp.dprint_executing()
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050042 AUTOBOOT_OPENBMC_NICKNAME = gm.get_mod_global("AUTOBOOT_OPENBMC_NICKNAME")
43
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050044 # Set values for call to create_robot_cmd_string.
Michael Walsh410b1782019-10-22 15:56:18 -050045 # Environment variable TMP_ROBOT_DIR_PATH can be set by the user to indicate that robot-generated output
46 # should initially be written to the specified temporary directory and then moved to the normal output
Michael Walsha0ce75a2018-07-31 13:54:29 -050047 # location after completion.
Patrick Williams20f38712022-12-08 06:18:26 -060048 outputdir = os.environ.get(
49 "TMP_ROBOT_DIR_PATH",
50 os.environ.get(
51 "STATUS_DIR_PATH", os.environ.get("HOME", ".") + "/status"
52 ),
53 )
Michael Walsha0ce75a2018-07-31 13:54:29 -050054 outputdir = gm.add_trailing_slash(outputdir)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050055 seconds = time.time()
56 loc_time = time.localtime(seconds)
57 time_string = time.strftime("%y%m%d.%H%M%S", loc_time)
Patrick Williams20f38712022-12-08 06:18:26 -060058 file_prefix = (
59 AUTOBOOT_OPENBMC_NICKNAME + "." + extra_prefix + time_string + "."
60 )
Michael Walsh410b1782019-10-22 15:56:18 -050061 # Environment variable SAVE_STATUS_POLICY governs when robot-generated output files (e.g. the log.html)
62 # will be moved from TMP_ROBOT_DIR_PATH to FFDC_DIR_PATH. Valid values are "ALWAYS", "NEVER" and "FAIL".
Michael Walsha0ce75a2018-07-31 13:54:29 -050063 SAVE_STATUS_POLICY = os.environ.get("SAVE_STATUS_POLICY", "ALWAYS")
64 if SAVE_STATUS_POLICY == "NEVER":
65 output = "NONE"
66 log = "NONE"
67 report = "NONE"
68 else:
69 output = file_prefix + "output.xml"
70 log = file_prefix + "log.html"
71 report = file_prefix + "report.html"
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050072 loglevel = "TRACE"
Patrick Williams20f38712022-12-08 06:18:26 -060073 consolecolors = "off"
74 consolemarkers = "off"
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050075
76 # Make create_robot_cmd_string values global.
77 gm.set_mod_global(outputdir)
78 gm.set_mod_global(output)
79 gm.set_mod_global(log)
80 gm.set_mod_global(report)
81 gm.set_mod_global(loglevel)
Michael Walsh1f961b72020-06-16 15:54:11 -050082 gm.set_mod_global(consolecolors)
83 gm.set_mod_global(consolemarkers)
84
Patrick Williams20f38712022-12-08 06:18:26 -060085 return (
86 outputdir,
87 output,
88 log,
89 report,
90 loglevel,
91 consolecolors,
92 consolemarkers,
93 )
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050094
95
96def init_robot_test_base_dir_path():
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050097 r"""
Michael Walsh410b1782019-10-22 15:56:18 -050098 Initialize and validate the environment variable, ROBOT_TEST_BASE_DIR_PATH and set corresponding global
99 variable ROBOT_TEST_RUNNING_FROM_SB.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500100
Michael Walsh410b1782019-10-22 15:56:18 -0500101 If ROBOT_TEST_BASE_DIR_PATH is already set, this function will merely validate it. This function will
102 also set environment variable ROBOT_TEST_RUNNING_FROM_SB when ROBOT_TEST_BASE_DIR_PATH is not pre-set.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500103 """
104
105 # ROBOT_TEST_BASE_DIR_PATH will be set as follows:
Michael Walsh410b1782019-10-22 15:56:18 -0500106 # This function will determine whether we are running in a user sandbox or from a standard apolloxxx
107 # environment.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500108 # - User sandbox:
Michael Walsh410b1782019-10-22 15:56:18 -0500109 # If there is a <developer's home dir>/git/openbmc-test-automation/, ROBOT_TEST_BASE_DIR_PATH will be
110 # set to that path. Otherwise, we set it to <program dir path>/git/openbmc-test-automation/
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500111 # - Not in user sandbox:
Michael Walsh410b1782019-10-22 15:56:18 -0500112 # ROBOT_TEST_BASE_DIR_PATH will be set to <program dir path>/git/openbmc-test-automation/
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500113
Patrick Williams20f38712022-12-08 06:18:26 -0600114 ROBOT_TEST_BASE_DIR_PATH = os.environ.get("ROBOT_TEST_BASE_DIR_PATH", "")
115 ROBOT_TEST_RUNNING_FROM_SB = int(
116 os.environ.get("ROBOT_TEST_RUNNING_FROM_SB", "0")
117 )
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500118 if ROBOT_TEST_BASE_DIR_PATH == "":
119 # ROBOT_TEST_BASE_DIR_PATH was not set by user/caller.
Patrick Williams20f38712022-12-08 06:18:26 -0600120 AUTOIPL_VERSION = os.environ.get("AUTOIPL_VERSION", "")
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500121 if AUTOIPL_VERSION == "":
122 ROBOT_TEST_BASE_DIR_PATH = base_path
123 else:
124 suffix = "git/openbmc-test-automation/"
125
Michael Walsh410b1782019-10-22 15:56:18 -0500126 # Determine whether we're running out of a developer sandbox or simply out of an apolloxxx/bin
127 # path.
Patrick Williams20f38712022-12-08 06:18:26 -0600128 shell_rc, out_buf = gc.shell_cmd(
129 "dirname $(which gen_print.py)",
130 quiet=(not debug),
131 print_output=0,
132 )
Michael Walshbffaa1d2018-06-08 15:09:27 -0500133 executable_base_dir_path = os.path.realpath(out_buf.rstrip()) + "/"
Patrick Williams20f38712022-12-08 06:18:26 -0600134 apollo_dir_path = (
135 os.environ["AUTO_BASE_PATH"] + AUTOIPL_VERSION + "/bin/"
136 )
137 developer_home_dir_path = re.sub(
138 "/sandbox.*", "", executable_base_dir_path
139 )
140 developer_home_dir_path = gm.add_trailing_slash(
141 developer_home_dir_path
142 )
143 gp.dprint_vars(
144 executable_base_dir_path,
145 developer_home_dir_path,
146 apollo_dir_path,
147 )
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500148
149 ROBOT_TEST_RUNNING_FROM_SB = 0
150 if executable_base_dir_path != apollo_dir_path:
151 ROBOT_TEST_RUNNING_FROM_SB = 1
152 gp.dprint_vars(ROBOT_TEST_RUNNING_FROM_SB)
153 ROBOT_TEST_BASE_DIR_PATH = developer_home_dir_path + suffix
154 if not os.path.isdir(ROBOT_TEST_BASE_DIR_PATH):
Patrick Williams20f38712022-12-08 06:18:26 -0600155 gp.dprint_timen(
156 "NOTE: Sandbox directory "
157 + ROBOT_TEST_BASE_DIR_PATH
158 + " does not"
159 + " exist."
160 )
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500161 # Fall back to the apollo dir path.
162 ROBOT_TEST_BASE_DIR_PATH = apollo_dir_path + suffix
163 else:
164 # Use to the apollo dir path.
165 ROBOT_TEST_BASE_DIR_PATH = apollo_dir_path + suffix
166
Patrick Williams20f38712022-12-08 06:18:26 -0600167 OBMC_TOOLS_BASE_DIR_PATH = (
168 os.path.dirname(ROBOT_TEST_BASE_DIR_PATH.rstrip("/"))
Michael Walsh8dc99a32020-04-02 13:45:13 -0500169 + "/openbmc-tools/"
Patrick Williams20f38712022-12-08 06:18:26 -0600170 )
George Keishinga7b19122020-10-04 23:03:04 -0500171 OPENBMCTOOL_DIR_PATH = OBMC_TOOLS_BASE_DIR_PATH + "openbmctool/"
Patrick Williams20f38712022-12-08 06:18:26 -0600172 JSON_CHECKER_TOOLS_DIR_PATH = (
173 OBMC_TOOLS_BASE_DIR_PATH + "expectedJsonChecker/"
174 )
Michael Walsh8dc99a32020-04-02 13:45:13 -0500175
Michael Walsh2ea965c2019-08-01 16:14:25 -0500176 gv.valid_value(ROBOT_TEST_BASE_DIR_PATH)
Patrick Williams20f38712022-12-08 06:18:26 -0600177 gp.dprint_vars(
178 ROBOT_TEST_RUNNING_FROM_SB,
179 ROBOT_TEST_BASE_DIR_PATH,
180 OBMC_TOOLS_BASE_DIR_PATH,
181 OPENBMCTOOL_DIR_PATH,
182 JSON_CHECKER_TOOLS_DIR_PATH,
183 )
Michael Walsh2ea965c2019-08-01 16:14:25 -0500184 gv.valid_dir_path(ROBOT_TEST_BASE_DIR_PATH)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500185
186 ROBOT_TEST_BASE_DIR_PATH = gm.add_trailing_slash(ROBOT_TEST_BASE_DIR_PATH)
187 gm.set_mod_global(ROBOT_TEST_BASE_DIR_PATH)
Patrick Williams20f38712022-12-08 06:18:26 -0600188 os.environ["ROBOT_TEST_BASE_DIR_PATH"] = ROBOT_TEST_BASE_DIR_PATH
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500189
190 gm.set_mod_global(ROBOT_TEST_RUNNING_FROM_SB)
Patrick Williams20f38712022-12-08 06:18:26 -0600191 os.environ["ROBOT_TEST_RUNNING_FROM_SB"] = str(ROBOT_TEST_RUNNING_FROM_SB)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500192
Michael Walsh8dc99a32020-04-02 13:45:13 -0500193 gm.set_mod_global(OBMC_TOOLS_BASE_DIR_PATH)
Patrick Williams20f38712022-12-08 06:18:26 -0600194 os.environ["OBMC_TOOLS_BASE_DIR_PATH"] = str(OBMC_TOOLS_BASE_DIR_PATH)
Michael Walsh8dc99a32020-04-02 13:45:13 -0500195
196 gm.set_mod_global(OPENBMCTOOL_DIR_PATH)
Patrick Williams20f38712022-12-08 06:18:26 -0600197 os.environ["OPENBMCTOOL_DIR_PATH"] = str(OPENBMCTOOL_DIR_PATH)
Michael Walsh8dc99a32020-04-02 13:45:13 -0500198
George Keishinga7b19122020-10-04 23:03:04 -0500199 gm.set_mod_global(JSON_CHECKER_TOOLS_DIR_PATH)
Patrick Williams20f38712022-12-08 06:18:26 -0600200 os.environ["JSON_CHECKER_TOOLS_DIR_PATH"] = str(
201 JSON_CHECKER_TOOLS_DIR_PATH
202 )
Michael Walsh8dc99a32020-04-02 13:45:13 -0500203
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500204
Patrick Williams20f38712022-12-08 06:18:26 -0600205raw_robot_file_search_path = (
206 "${ROBOT_TEST_BASE_DIR_PATH}:"
207 + "${ROBOT_TEST_BASE_DIR_PATH}tests:${ROBOT_TEST_BASE_DIR_PATH}extended:"
208 + "${ROBOT_TEST_BASE_DIR_PATH}scratch:${PATH}"
209)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500210
211
212def init_robot_file_path(robot_file_path):
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500213 r"""
Michael Walsh410b1782019-10-22 15:56:18 -0500214 Determine full path name for the file path passed in robot_file_path and return it.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500215
Michael Walsh410b1782019-10-22 15:56:18 -0500216 If robot_file_path contains a fully qualified path name, this function will verify that the file exists.
217 If robot_file_path contains a relative path, this function will search for the file and set
218 robot_file_path so that it contains the absolute path to the robot file. This function will search for
219 the robot file using the raw_robot_file_search_path (defined above). Note that if
220 ROBOT_TEST_BASE_DIR_PATH is not set, this function will call init_robot_test_base_dir_path to set it.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500221
222 Description of arguments:
Michael Walsh410b1782019-10-22 15:56:18 -0500223 robot_file_path The absolute or relative path to a robot file.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500224 """
225
Michael Walsh2ea965c2019-08-01 16:14:25 -0500226 gv.valid_value(robot_file_path)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500227
228 try:
229 if ROBOT_TEST_BASE_DIR_PATH is NONE:
230 init_robot_test_base_dir_path()
231 except NameError:
232 init_robot_test_base_dir_path()
233
234 if not re.match(r".*\.(robot|py)$", robot_file_path):
235 # No suffix so we'll assign one of "\.robot".
236 robot_file_path = robot_file_path + ".robot"
237
238 abs_path = 0
239 if robot_file_path[0:1] == "/":
240 abs_path = 1
241
242 gp.dprint_vars(abs_path, robot_file_path)
243
244 if not abs_path:
Patrick Williams20f38712022-12-08 06:18:26 -0600245 cmd_buf = 'echo -n "' + raw_robot_file_search_path + '"'
246 shell_rc, out_buf = gc.shell_cmd(
247 cmd_buf, quiet=(not debug), print_output=0
248 )
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500249 robot_file_search_paths = out_buf
Michael Walsha0ce75a2018-07-31 13:54:29 -0500250 gp.dprint_var(robot_file_search_paths)
Patrick Williams20f38712022-12-08 06:18:26 -0600251 robot_file_search_paths_list = robot_file_search_paths.split(":")
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500252 for search_path in robot_file_search_paths_list:
253 search_path = gm.add_trailing_slash(search_path)
254 candidate_file_path = search_path + robot_file_path
255 gp.dprint_var(candidate_file_path)
256 if os.path.isfile(candidate_file_path):
257 gp.dprint_timen("Found full path to " + robot_file_path + ".")
258 robot_file_path = candidate_file_path
259 break
260
261 gp.dprint_var(robot_file_path)
Michael Walsh2ea965c2019-08-01 16:14:25 -0500262 gv.valid_file_path(robot_file_path)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500263
264 return robot_file_path
265
266
267def get_robot_parm_names():
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500268 r"""
Michael Walsh410b1782019-10-22 15:56:18 -0500269 Return a list containing all of the long parm names (e.g. --outputdir) supported by the robot program.
270 Double dashes are not included in the names returned.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500271 """
272
Patrick Williams20f38712022-12-08 06:18:26 -0600273 cmd_buf = (
274 "robot -h | egrep "
275 + "'^([ ]\\-[a-zA-Z0-9])?[ ]+--[a-zA-Z0-9]+[ ]+' | sed -re"
276 + " s'/.*\\-\\-//g' -e s'/ .*//g' | sort -u"
277 )
Michael Walshbffaa1d2018-06-08 15:09:27 -0500278 shell_rc, out_buf = gc.shell_cmd(cmd_buf, quiet=1, print_output=0)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500279
280 return out_buf.split("\n")
281
282
283def create_robot_cmd_string(robot_file_path, *parms):
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500284 r"""
Michael Walsh410b1782019-10-22 15:56:18 -0500285 Create a robot command string and return it. On failure, return an empty string.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500286
287 Description of arguments:
288 robot_file_path The path to the robot file to be run.
Michael Walsh410b1782019-10-22 15:56:18 -0500289 parms The list of parms to be included in the command string. The name of each
290 variable in this list must be the same as the name of the corresponding
291 parm. This function figures out that name. This function is also able
292 to distinguish robot parms (e.g. --outputdir) from robot program parms
293 (all other parms which will be passed as "-v PARM_NAME:parm_value")..
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500294
295 Example:
296
297 The following call to this function...
Michael Walsh410b1782019-10-22 15:56:18 -0500298 cmd_buf = create_robot_cmd_string("tools/start_sol_console.robot", OPENBMC_HOST, quiet, test_mode, debug,
299 outputdir, output, log, report)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500300
301 Would return a string something like this.
302 robot -v OPENBMC_HOST:beye6 -v quiet:0 -v test_mode:1 -v debug:1
Michael Walsh410b1782019-10-22 15:56:18 -0500303 --outputdir=/gsa/ausgsa/projects/a/status --output=beye6.OS_Console.output.xml
304 --log=beye6.OS_Console.log.html --report=beye6.OS_Console.report.html tools/start_sol_console.robot
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500305 """
306
307 robot_file_path = init_robot_file_path(robot_file_path)
308
309 robot_parm_names = get_robot_parm_names()
310
311 robot_parm_list = []
312
313 stack_frame = 2
314 ix = 2
315 for arg in parms:
316 parm = arg
317 parm = gm.quote_bash_parm(gm.escape_bash_quotes(str(parm)))
318 var_name = gp.get_arg_name(None, ix, stack_frame)
319 if var_name in robot_parm_names:
320 p_string = "--" + var_name + "=" + str(parm)
321 robot_parm_list.append(p_string)
322 else:
323 p_string = "-v " + var_name + ":" + str(parm)
324 robot_parm_list.append(p_string)
325 ix += 1
326
Patrick Williams20f38712022-12-08 06:18:26 -0600327 robot_cmd_buf = (
328 "robot " + " ".join(robot_parm_list) + " " + robot_file_path
329 )
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500330
331 return robot_cmd_buf
332
333
Michael Walsha0ce75a2018-07-31 13:54:29 -0500334# Global variables to aid in cleanup after running robot_cmd_fnc.
335gcr_last_robot_cmd_buf = ""
336gcr_last_robot_rc = 0
337
338
Patrick Williams20f38712022-12-08 06:18:26 -0600339def process_robot_output_files(robot_cmd_buf=None, robot_rc=None, gzip=None):
Michael Walsha0ce75a2018-07-31 13:54:29 -0500340 r"""
341 Process robot output files which can involve several operations:
Michael Walsh410b1782019-10-22 15:56:18 -0500342 - If the files are in a temporary location, using SAVE_STATUS_POLICY to decide whether to move them to a
343 permanent location or to delete them.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500344 - Gzipping them.
345
346 Description of argument(s):
Michael Walsh410b1782019-10-22 15:56:18 -0500347 robot_cmd_buf The complete command string used to invoke robot.
348 robot_rc The return code from running the robot command string.
349 gzip Indicates whether robot-generated output should be gzipped.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500350 """
351
352 robot_cmd_buf = gm.dft(robot_cmd_buf, gcr_last_robot_cmd_buf)
353 robot_rc = gm.dft(robot_rc, gcr_last_robot_rc)
Michael Walshf33140f2018-11-01 14:05:56 -0500354 gzip = gm.dft(gzip, int(os.environ.get("GZIP_ROBOT", "1")))
Michael Walsha0ce75a2018-07-31 13:54:29 -0500355
356 if robot_cmd_buf == "":
Michael Walsh410b1782019-10-22 15:56:18 -0500357 # This can legitimately occur if this function is called from an exit_function without the program
358 # having ever run robot_cmd_fnc.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500359 return
360
361 SAVE_STATUS_POLICY = os.environ.get("SAVE_STATUS_POLICY", "ALWAYS")
362 gp.qprint_vars(SAVE_STATUS_POLICY)
363
Michael Walsh410b1782019-10-22 15:56:18 -0500364 # When SAVE_STATUS_POLICY is "NEVER" robot output files don't even get generated.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500365 if SAVE_STATUS_POLICY == "NEVER":
366 return
367
368 # Compose file_list based on robot command buffer passed in.
369 robot_cmd_buf_dict = gc.parse_command_string(robot_cmd_buf)
Patrick Williams20f38712022-12-08 06:18:26 -0600370 outputdir = robot_cmd_buf_dict["outputdir"]
Michael Walsha0ce75a2018-07-31 13:54:29 -0500371 outputdir = gm.add_trailing_slash(outputdir)
Patrick Williams20f38712022-12-08 06:18:26 -0600372 file_list = (
373 outputdir
374 + robot_cmd_buf_dict["output"]
375 + " "
376 + outputdir
377 + robot_cmd_buf_dict["log"]
378 + " "
379 + outputdir
380 + robot_cmd_buf_dict["report"]
381 )
Michael Walsha0ce75a2018-07-31 13:54:29 -0500382
383 # Double checking that files are present.
Patrick Williams20f38712022-12-08 06:18:26 -0600384 shell_rc, out_buf = gc.shell_cmd(
385 "ls -1 " + file_list + " 2>/dev/null", show_err=0
386 )
Michael Walsha0ce75a2018-07-31 13:54:29 -0500387 file_list = re.sub("\n", " ", out_buf.rstrip("\n"))
388
389 if file_list == "":
Patrick Williams20f38712022-12-08 06:18:26 -0600390 gp.qprint_timen(
391 "No robot output files were found in " + outputdir + "."
392 )
Michael Walsha0ce75a2018-07-31 13:54:29 -0500393 return
Michael Walsh0d5f96a2019-05-20 10:09:57 -0500394 gp.qprint_var(robot_rc, gp.hexa())
Michael Walsha0ce75a2018-07-31 13:54:29 -0500395 if SAVE_STATUS_POLICY == "FAIL" and robot_rc == 0:
Patrick Williams20f38712022-12-08 06:18:26 -0600396 gp.qprint_timen(
397 "The call to robot produced no failures."
398 + " Deleting robot output files."
399 )
Michael Walsha0ce75a2018-07-31 13:54:29 -0500400 gc.shell_cmd("rm -rf " + file_list)
401 return
402
403 if gzip:
Michael Walshe53dfec2018-08-07 15:02:56 -0500404 gc.shell_cmd("gzip -f " + file_list)
Michael Walsha0ce75a2018-07-31 13:54:29 -0500405 # Update the values in file_list.
406 file_list = re.sub(" ", ".gz ", file_list) + ".gz"
407
Michael Walsh410b1782019-10-22 15:56:18 -0500408 # It TMP_ROBOT_DIR_PATH is set, it means the caller wanted the robot output initially directed to
409 # TMP_ROBOT_DIR_PATH but later moved to FFDC_DIR_PATH. Otherwise, we're done.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500410
George Keishinge7e91712021-09-03 11:28:44 -0500411 if os.environ.get("TMP_ROBOT_DIR_PATH", "") == "":
Michael Walsha0ce75a2018-07-31 13:54:29 -0500412 return
413
Michael Walsh410b1782019-10-22 15:56:18 -0500414 # We're directing these to the FFDC dir path so that they'll be subjected to FFDC cleanup.
Patrick Williams20f38712022-12-08 06:18:26 -0600415 target_dir_path = os.environ.get(
416 "FFDC_DIR_PATH", os.environ.get("HOME", ".") + "/ffdc"
417 )
Michael Walsha0ce75a2018-07-31 13:54:29 -0500418 target_dir_path = gm.add_trailing_slash(target_dir_path)
419
Patrick Williams20f38712022-12-08 06:18:26 -0600420 targ_file_list = [
421 re.sub(".*/", target_dir_path, x) for x in file_list.split(" ")
422 ]
Michael Walsha0ce75a2018-07-31 13:54:29 -0500423
Patrick Williams20f38712022-12-08 06:18:26 -0600424 gc.shell_cmd(
425 "mv " + file_list + " " + target_dir_path + " >/dev/null", time_out=600
426 )
Michael Walsha0ce75a2018-07-31 13:54:29 -0500427
428 gp.qprint_timen("New robot log file locations:")
Patrick Williams20f38712022-12-08 06:18:26 -0600429 gp.qprintn("\n".join(targ_file_list))
Michael Walsha0ce75a2018-07-31 13:54:29 -0500430
431
Patrick Williams20f38712022-12-08 06:18:26 -0600432def robot_cmd_fnc(
433 robot_cmd_buf,
434 robot_jail=os.environ.get("ROBOT_JAIL", ""),
435 quiet=None,
436 test_mode=0,
437):
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500438 r"""
439 Run the robot command string.
440
Michael Walsh410b1782019-10-22 15:56:18 -0500441 This function will set the various PATH variables correctly so that you are running the proper version of
442 all imported files, etc.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500443
444 Description of argument(s):
445 robot_cmd_buf The complete robot command string.
Michael Walsh410b1782019-10-22 15:56:18 -0500446 robot_jail Indicates that this is to run in "robot jail" meaning without visibility
447 to any apolloxxx import files, programs, etc.
Michael Walsh8dc99a32020-04-02 13:45:13 -0500448 test_mode If test_mode is set, this function will not actually run the command.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500449 """
450
Patrick Williams20f38712022-12-08 06:18:26 -0600451 quiet = int(gm.dft(quiet, gp.get_stack_var("quiet", 0)))
Michael Walsh2ea965c2019-08-01 16:14:25 -0500452 gv.valid_value(robot_cmd_buf)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500453
Michael Walsha0ce75a2018-07-31 13:54:29 -0500454 # Set global variables to aid in cleanup with process_robot_output_files.
455 global gcr_last_robot_cmd_buf
456 global gcr_last_robot_rc
457 gcr_last_robot_cmd_buf = robot_cmd_buf
458
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500459 # Get globals set by init_robot_test_base_dir_path().
460 module = sys.modules["__main__"]
461 try:
462 ROBOT_TEST_BASE_DIR_PATH = getattr(module, "ROBOT_TEST_BASE_DIR_PATH")
463 except NameError:
464 init_robot_test_base_dir_path()
465 ROBOT_TEST_BASE_DIR_PATH = getattr(module, "ROBOT_TEST_BASE_DIR_PATH")
466
Patrick Williams20f38712022-12-08 06:18:26 -0600467 ROBOT_TEST_RUNNING_FROM_SB = gm.get_mod_global(
468 "ROBOT_TEST_RUNNING_FROM_SB"
469 )
Michael Walsh8dc99a32020-04-02 13:45:13 -0500470 OPENBMCTOOL_DIR_PATH = gm.get_mod_global("OPENBMCTOOL_DIR_PATH")
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500471
472 if robot_jail == "":
473 if ROBOT_TEST_RUNNING_FROM_SB:
474 robot_jail = 0
475 else:
476 robot_jail = 1
477
478 robot_jail = int(robot_jail)
Patrick Williams20f38712022-12-08 06:18:26 -0600479 ROBOT_JAIL = os.environ.get("ROBOT_JAIL", "")
480 gp.dprint_vars(
481 ROBOT_TEST_BASE_DIR_PATH,
482 ROBOT_TEST_RUNNING_FROM_SB,
483 ROBOT_JAIL,
484 robot_jail,
485 )
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500486
487 # Save PATH and PYTHONPATH to be restored later.
488 os.environ["SAVED_PYTHONPATH"] = os.environ.get("PYTHONPATH", "")
489 os.environ["SAVED_PATH"] = os.environ.get("PATH", "")
490
491 if robot_jail:
Michael Walsh410b1782019-10-22 15:56:18 -0500492 # Make sure required programs like python and robot can be found in the new restricted PATH.
Michael Walsha5d29bc2019-06-05 15:29:18 -0500493 required_programs = "python robot"
Michael Walsh410b1782019-10-22 15:56:18 -0500494 # It is expected that there will be a "python" program in the tool base bin path which is really a
495 # link to select_version. Ditto for "robot". Call each with the --print_only option to get the
496 # paths to the "real" programs.
Patrick Williams20f38712022-12-08 06:18:26 -0600497 cmd_buf = (
498 "for program in "
499 + required_programs
Michael Walsha5d29bc2019-06-05 15:29:18 -0500500 + " ; do dirname $(${program} --print_only) ; done 2>/dev/null"
Patrick Williams20f38712022-12-08 06:18:26 -0600501 )
Michael Walsha5d29bc2019-06-05 15:29:18 -0500502 rc, out_buf = gc.shell_cmd(cmd_buf, quiet=1, print_output=0)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500503 PYTHONPATH = ROBOT_TEST_BASE_DIR_PATH + "lib"
504 NEW_PATH_LIST = [ROBOT_TEST_BASE_DIR_PATH + "bin"]
Michael Walsha5d29bc2019-06-05 15:29:18 -0500505 NEW_PATH_LIST.extend(list(set(out_buf.rstrip("\n").split("\n"))))
Patrick Williams20f38712022-12-08 06:18:26 -0600506 NEW_PATH_LIST.extend(
507 [
508 "/usr/local/sbin",
509 "/usr/local/bin",
510 "/usr/sbin",
511 "/usr/bin",
512 "/sbin",
513 "/bin",
514 OPENBMCTOOL_DIR_PATH.rstrip("/"),
515 ]
516 )
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500517 PATH = ":".join(NEW_PATH_LIST)
518 else:
Patrick Williams20f38712022-12-08 06:18:26 -0600519 PYTHONPATH = (
520 os.environ.get("PYTHONPATH", "")
521 + ":"
522 + ROBOT_TEST_BASE_DIR_PATH
523 + "lib"
524 )
525 PATH = (
526 os.environ.get("PATH", "")
527 + ":"
528 + ROBOT_TEST_BASE_DIR_PATH
529 + "bin"
530 + ":"
531 + OPENBMCTOOL_DIR_PATH.rstrip("/")
532 )
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500533
Patrick Williams20f38712022-12-08 06:18:26 -0600534 os.environ["PYTHONPATH"] = PYTHONPATH
535 os.environ["PATH"] = PATH
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500536 gp.dprint_vars(PATH, PYTHONPATH)
537
Patrick Williams20f38712022-12-08 06:18:26 -0600538 os.environ["FFDC_DIR_PATH_STYLE"] = os.environ.get(
539 "FFDC_DIR_PATH_STYLE", "1"
540 )
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500541 gp.qpissuing(robot_cmd_buf, test_mode)
542 if test_mode:
543 os.environ["PATH"] = os.environ.get("SAVED_PATH", "")
544 os.environ["PYTHONPATH"] = os.environ.get("SAVED_PYTHONPATH", "")
545 return True
546
547 if quiet:
Patrick Williams20f38712022-12-08 06:18:26 -0600548 DEVNULL = open(os.devnull, "wb")
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500549 stdout = DEVNULL
550 else:
551 stdout = None
552 sub_proc = subprocess.Popen(robot_cmd_buf, stdout=stdout, shell=True)
553 sub_proc.communicate()
554 shell_rc = sub_proc.returncode
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500555 os.environ["PATH"] = os.environ.get("SAVED_PATH", "")
556 os.environ["PYTHONPATH"] = os.environ.get("SAVED_PYTHONPATH", "")
Michael Walsha0ce75a2018-07-31 13:54:29 -0500557 gcr_last_robot_rc = shell_rc
558 process_robot_output_files()
559 if shell_rc != 0:
Michael Walsh0d5f96a2019-05-20 10:09:57 -0500560 gp.print_var(shell_rc, gp.hexa())
Michael Walsha0ce75a2018-07-31 13:54:29 -0500561 return False
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500562
563 return True