blob: 244c697666f766fe7cefdd229db3c63bf2cfc294 [file] [log] [blame]
Michael Walsh3ba8ecd2018-04-24 11:33:25 -05001#!/usr/bin/env python
2
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
8import sys
9import os
10import subprocess
11import re
12import time
13import imp
14
15import gen_print as gp
16import gen_valid as gv
17import gen_misc as gm
18import gen_cmd as gc
19
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050020base_path = \
21 os.path.dirname(os.path.dirname(imp.find_module("gen_robot_print")[1])) +\
22 os.sep
23
24
25def init_robot_out_parms(extra_prefix=""):
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050026 r"""
27 Initialize robot output parms such as outputdir, output, etc.
28
29 This function will set global values for the following robot output parms.
30
31 outputdir, output, log, report, loglevel
32
Michael Walsh410b1782019-10-22 15:56:18 -050033 This function would typically be called prior to calling create_robot_cmd_string.
Michael Walshf33140f2018-11-01 14:05:56 -050034
35 Description of argument(s):
Michael Walsh410b1782019-10-22 15:56:18 -050036 extra_prefix An extra prefix to be appended to the default prefix for output file
37 names.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050038 """
39
Michael Walsha0ce75a2018-07-31 13:54:29 -050040 gp.dprint_executing()
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050041 AUTOBOOT_OPENBMC_NICKNAME = gm.get_mod_global("AUTOBOOT_OPENBMC_NICKNAME")
42
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050043 # Set values for call to create_robot_cmd_string.
Michael Walsh410b1782019-10-22 15:56:18 -050044 # Environment variable TMP_ROBOT_DIR_PATH can be set by the user to indicate that robot-generated output
45 # should initially be written to the specified temporary directory and then moved to the normal output
Michael Walsha0ce75a2018-07-31 13:54:29 -050046 # location after completion.
47 outputdir =\
48 os.environ.get("TMP_ROBOT_DIR_PATH",
49 os.environ.get("STATUS_DIR_PATH",
50 os.environ.get("HOME", ".")
Michael Walsh0a3bdb42019-01-31 16:21:44 +000051 + "/status"))
Michael Walsha0ce75a2018-07-31 13:54:29 -050052 outputdir = gm.add_trailing_slash(outputdir)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050053 seconds = time.time()
54 loc_time = time.localtime(seconds)
55 time_string = time.strftime("%y%m%d.%H%M%S", loc_time)
56 file_prefix = AUTOBOOT_OPENBMC_NICKNAME + "." + extra_prefix +\
57 time_string + "."
Michael Walsh410b1782019-10-22 15:56:18 -050058 # Environment variable SAVE_STATUS_POLICY governs when robot-generated output files (e.g. the log.html)
59 # 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 -050060 SAVE_STATUS_POLICY = os.environ.get("SAVE_STATUS_POLICY", "ALWAYS")
61 if SAVE_STATUS_POLICY == "NEVER":
62 output = "NONE"
63 log = "NONE"
64 report = "NONE"
65 else:
66 output = file_prefix + "output.xml"
67 log = file_prefix + "log.html"
68 report = file_prefix + "report.html"
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050069 loglevel = "TRACE"
70
71 # Make create_robot_cmd_string values global.
72 gm.set_mod_global(outputdir)
73 gm.set_mod_global(output)
74 gm.set_mod_global(log)
75 gm.set_mod_global(report)
76 gm.set_mod_global(loglevel)
77
78
79def init_robot_test_base_dir_path():
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050080 r"""
Michael Walsh410b1782019-10-22 15:56:18 -050081 Initialize and validate the environment variable, ROBOT_TEST_BASE_DIR_PATH and set corresponding global
82 variable ROBOT_TEST_RUNNING_FROM_SB.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050083
Michael Walsh410b1782019-10-22 15:56:18 -050084 If ROBOT_TEST_BASE_DIR_PATH is already set, this function will merely validate it. This function will
85 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 -050086 """
87
88 # ROBOT_TEST_BASE_DIR_PATH will be set as follows:
Michael Walsh410b1782019-10-22 15:56:18 -050089 # This function will determine whether we are running in a user sandbox or from a standard apolloxxx
90 # environment.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050091 # - User sandbox:
Michael Walsh410b1782019-10-22 15:56:18 -050092 # If there is a <developer's home dir>/git/openbmc-test-automation/, ROBOT_TEST_BASE_DIR_PATH will be
93 # set to that path. Otherwise, we set it to <program dir path>/git/openbmc-test-automation/
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050094 # - Not in user sandbox:
Michael Walsh410b1782019-10-22 15:56:18 -050095 # ROBOT_TEST_BASE_DIR_PATH will be set to <program dir path>/git/openbmc-test-automation/
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050096
97 ROBOT_TEST_BASE_DIR_PATH = os.environ.get('ROBOT_TEST_BASE_DIR_PATH', "")
Michael Walsh3ba8ecd2018-04-24 11:33:25 -050098 ROBOT_TEST_RUNNING_FROM_SB = \
99 int(os.environ.get('ROBOT_TEST_RUNNING_FROM_SB', "0"))
100 if ROBOT_TEST_BASE_DIR_PATH == "":
101 # ROBOT_TEST_BASE_DIR_PATH was not set by user/caller.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500102 AUTOIPL_VERSION = os.environ.get('AUTOIPL_VERSION', '')
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500103 if AUTOIPL_VERSION == "":
104 ROBOT_TEST_BASE_DIR_PATH = base_path
105 else:
106 suffix = "git/openbmc-test-automation/"
107
Michael Walsh410b1782019-10-22 15:56:18 -0500108 # Determine whether we're running out of a developer sandbox or simply out of an apolloxxx/bin
109 # path.
Michael Walshbffaa1d2018-06-08 15:09:27 -0500110 shell_rc, out_buf = gc.shell_cmd('dirname $(which gen_print.py)',
111 quiet=(not debug), print_output=0)
112 executable_base_dir_path = os.path.realpath(out_buf.rstrip()) + "/"
113 apollo_dir_path = os.environ['AUTO_BASE_PATH'] + AUTOIPL_VERSION +\
114 "/bin/"
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500115 developer_home_dir_path = re.sub('/sandbox.*', '',
116 executable_base_dir_path)
117 developer_home_dir_path = \
118 gm.add_trailing_slash(developer_home_dir_path)
119 gp.dprint_vars(executable_base_dir_path, developer_home_dir_path,
120 apollo_dir_path)
121
122 ROBOT_TEST_RUNNING_FROM_SB = 0
123 if executable_base_dir_path != apollo_dir_path:
124 ROBOT_TEST_RUNNING_FROM_SB = 1
125 gp.dprint_vars(ROBOT_TEST_RUNNING_FROM_SB)
126 ROBOT_TEST_BASE_DIR_PATH = developer_home_dir_path + suffix
127 if not os.path.isdir(ROBOT_TEST_BASE_DIR_PATH):
Michael Walsha0ce75a2018-07-31 13:54:29 -0500128 gp.dprint_timen("NOTE: Sandbox directory "
129 + ROBOT_TEST_BASE_DIR_PATH + " does not"
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500130 + " exist.")
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500131 # Fall back to the apollo dir path.
132 ROBOT_TEST_BASE_DIR_PATH = apollo_dir_path + suffix
133 else:
134 # Use to the apollo dir path.
135 ROBOT_TEST_BASE_DIR_PATH = apollo_dir_path + suffix
136
Michael Walsh8dc99a32020-04-02 13:45:13 -0500137 OBMC_TOOLS_BASE_DIR_PATH = \
138 os.path.dirname(ROBOT_TEST_BASE_DIR_PATH.rstrip("/")) \
139 + "/openbmc-tools/"
140 OPENBMCTOOL_DIR_PATH = OBMC_TOOLS_BASE_DIR_PATH + "thalerj/"
141 MSBARTH_TOOLS_DIR_PATH = OBMC_TOOLS_BASE_DIR_PATH + "msbarth/"
142
Michael Walsh2ea965c2019-08-01 16:14:25 -0500143 gv.valid_value(ROBOT_TEST_BASE_DIR_PATH)
Michael Walsh8dc99a32020-04-02 13:45:13 -0500144 gp.dprint_vars(ROBOT_TEST_RUNNING_FROM_SB, ROBOT_TEST_BASE_DIR_PATH, OBMC_TOOLS_BASE_DIR_PATH,
145 OPENBMCTOOL_DIR_PATH, MSBARTH_TOOLS_DIR_PATH)
Michael Walsh2ea965c2019-08-01 16:14:25 -0500146 gv.valid_dir_path(ROBOT_TEST_BASE_DIR_PATH)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500147
148 ROBOT_TEST_BASE_DIR_PATH = gm.add_trailing_slash(ROBOT_TEST_BASE_DIR_PATH)
149 gm.set_mod_global(ROBOT_TEST_BASE_DIR_PATH)
150 os.environ['ROBOT_TEST_BASE_DIR_PATH'] = ROBOT_TEST_BASE_DIR_PATH
151
152 gm.set_mod_global(ROBOT_TEST_RUNNING_FROM_SB)
153 os.environ['ROBOT_TEST_RUNNING_FROM_SB'] = str(ROBOT_TEST_RUNNING_FROM_SB)
154
Michael Walsh8dc99a32020-04-02 13:45:13 -0500155 gm.set_mod_global(OBMC_TOOLS_BASE_DIR_PATH)
156 os.environ['OBMC_TOOLS_BASE_DIR_PATH'] = str(OBMC_TOOLS_BASE_DIR_PATH)
157
158 gm.set_mod_global(OPENBMCTOOL_DIR_PATH)
159 os.environ['OPENBMCTOOL_DIR_PATH'] = str(OPENBMCTOOL_DIR_PATH)
160
161 gm.set_mod_global(MSBARTH_TOOLS_DIR_PATH)
162 os.environ['MSBARTH_TOOLS_DIR_PATH'] = str(MSBARTH_TOOLS_DIR_PATH)
163
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500164
165raw_robot_file_search_path = "${ROBOT_TEST_BASE_DIR_PATH}:" +\
166 "${ROBOT_TEST_BASE_DIR_PATH}tests:${ROBOT_TEST_BASE_DIR_PATH}extended:" +\
167 "${ROBOT_TEST_BASE_DIR_PATH}scratch:${PATH}"
168
169
170def init_robot_file_path(robot_file_path):
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500171 r"""
Michael Walsh410b1782019-10-22 15:56:18 -0500172 Determine full path name for the file path passed in robot_file_path and return it.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500173
Michael Walsh410b1782019-10-22 15:56:18 -0500174 If robot_file_path contains a fully qualified path name, this function will verify that the file exists.
175 If robot_file_path contains a relative path, this function will search for the file and set
176 robot_file_path so that it contains the absolute path to the robot file. This function will search for
177 the robot file using the raw_robot_file_search_path (defined above). Note that if
178 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 -0500179
180 Description of arguments:
Michael Walsh410b1782019-10-22 15:56:18 -0500181 robot_file_path The absolute or relative path to a robot file.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500182 """
183
Michael Walsh2ea965c2019-08-01 16:14:25 -0500184 gv.valid_value(robot_file_path)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500185
186 try:
187 if ROBOT_TEST_BASE_DIR_PATH is NONE:
188 init_robot_test_base_dir_path()
189 except NameError:
190 init_robot_test_base_dir_path()
191
192 if not re.match(r".*\.(robot|py)$", robot_file_path):
193 # No suffix so we'll assign one of "\.robot".
194 robot_file_path = robot_file_path + ".robot"
195
196 abs_path = 0
197 if robot_file_path[0:1] == "/":
198 abs_path = 1
199
200 gp.dprint_vars(abs_path, robot_file_path)
201
202 if not abs_path:
203 cmd_buf = "echo -n \"" + raw_robot_file_search_path + "\""
Michael Walshbffaa1d2018-06-08 15:09:27 -0500204 shell_rc, out_buf = gc.shell_cmd(cmd_buf, quiet=(not debug),
205 print_output=0)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500206 robot_file_search_paths = out_buf
Michael Walsha0ce75a2018-07-31 13:54:29 -0500207 gp.dprint_var(robot_file_search_paths)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500208 robot_file_search_paths_list = robot_file_search_paths.split(':')
209 for search_path in robot_file_search_paths_list:
210 search_path = gm.add_trailing_slash(search_path)
211 candidate_file_path = search_path + robot_file_path
212 gp.dprint_var(candidate_file_path)
213 if os.path.isfile(candidate_file_path):
214 gp.dprint_timen("Found full path to " + robot_file_path + ".")
215 robot_file_path = candidate_file_path
216 break
217
218 gp.dprint_var(robot_file_path)
Michael Walsh2ea965c2019-08-01 16:14:25 -0500219 gv.valid_file_path(robot_file_path)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500220
221 return robot_file_path
222
223
224def get_robot_parm_names():
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500225 r"""
Michael Walsh410b1782019-10-22 15:56:18 -0500226 Return a list containing all of the long parm names (e.g. --outputdir) supported by the robot program.
227 Double dashes are not included in the names returned.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500228 """
229
230 cmd_buf = "robot -h | egrep " +\
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500231 "'^([ ]\\-[a-zA-Z0-9])?[ ]+--[a-zA-Z0-9]+[ ]+' | sed -re" +\
232 " s'/.*\\-\\-//g' -e s'/ .*//g' | sort -u"
Michael Walshbffaa1d2018-06-08 15:09:27 -0500233 shell_rc, out_buf = gc.shell_cmd(cmd_buf, quiet=1, print_output=0)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500234
235 return out_buf.split("\n")
236
237
238def create_robot_cmd_string(robot_file_path, *parms):
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500239 r"""
Michael Walsh410b1782019-10-22 15:56:18 -0500240 Create a robot command string and return it. On failure, return an empty string.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500241
242 Description of arguments:
243 robot_file_path The path to the robot file to be run.
Michael Walsh410b1782019-10-22 15:56:18 -0500244 parms The list of parms to be included in the command string. The name of each
245 variable in this list must be the same as the name of the corresponding
246 parm. This function figures out that name. This function is also able
247 to distinguish robot parms (e.g. --outputdir) from robot program parms
248 (all other parms which will be passed as "-v PARM_NAME:parm_value")..
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500249
250 Example:
251
252 The following call to this function...
Michael Walsh410b1782019-10-22 15:56:18 -0500253 cmd_buf = create_robot_cmd_string("tools/start_sol_console.robot", OPENBMC_HOST, quiet, test_mode, debug,
254 outputdir, output, log, report)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500255
256 Would return a string something like this.
257 robot -v OPENBMC_HOST:beye6 -v quiet:0 -v test_mode:1 -v debug:1
Michael Walsh410b1782019-10-22 15:56:18 -0500258 --outputdir=/gsa/ausgsa/projects/a/status --output=beye6.OS_Console.output.xml
259 --log=beye6.OS_Console.log.html --report=beye6.OS_Console.report.html tools/start_sol_console.robot
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500260 """
261
262 robot_file_path = init_robot_file_path(robot_file_path)
263
264 robot_parm_names = get_robot_parm_names()
265
266 robot_parm_list = []
267
268 stack_frame = 2
269 ix = 2
270 for arg in parms:
271 parm = arg
272 parm = gm.quote_bash_parm(gm.escape_bash_quotes(str(parm)))
273 var_name = gp.get_arg_name(None, ix, stack_frame)
274 if var_name in robot_parm_names:
275 p_string = "--" + var_name + "=" + str(parm)
276 robot_parm_list.append(p_string)
277 else:
278 p_string = "-v " + var_name + ":" + str(parm)
279 robot_parm_list.append(p_string)
280 ix += 1
281
282 robot_cmd_buf = "robot " + ' '.join(robot_parm_list) + " " +\
283 robot_file_path
284
285 return robot_cmd_buf
286
287
Michael Walsha0ce75a2018-07-31 13:54:29 -0500288# Global variables to aid in cleanup after running robot_cmd_fnc.
289gcr_last_robot_cmd_buf = ""
290gcr_last_robot_rc = 0
291
292
293def process_robot_output_files(robot_cmd_buf=None,
294 robot_rc=None,
Michael Walshf33140f2018-11-01 14:05:56 -0500295 gzip=None):
Michael Walsha0ce75a2018-07-31 13:54:29 -0500296 r"""
297 Process robot output files which can involve several operations:
Michael Walsh410b1782019-10-22 15:56:18 -0500298 - If the files are in a temporary location, using SAVE_STATUS_POLICY to decide whether to move them to a
299 permanent location or to delete them.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500300 - Gzipping them.
301
302 Description of argument(s):
Michael Walsh410b1782019-10-22 15:56:18 -0500303 robot_cmd_buf The complete command string used to invoke robot.
304 robot_rc The return code from running the robot command string.
305 gzip Indicates whether robot-generated output should be gzipped.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500306 """
307
308 robot_cmd_buf = gm.dft(robot_cmd_buf, gcr_last_robot_cmd_buf)
309 robot_rc = gm.dft(robot_rc, gcr_last_robot_rc)
Michael Walshf33140f2018-11-01 14:05:56 -0500310 gzip = gm.dft(gzip, int(os.environ.get("GZIP_ROBOT", "1")))
Michael Walsha0ce75a2018-07-31 13:54:29 -0500311
312 if robot_cmd_buf == "":
Michael Walsh410b1782019-10-22 15:56:18 -0500313 # This can legitimately occur if this function is called from an exit_function without the program
314 # having ever run robot_cmd_fnc.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500315 return
316
317 SAVE_STATUS_POLICY = os.environ.get("SAVE_STATUS_POLICY", "ALWAYS")
318 gp.qprint_vars(SAVE_STATUS_POLICY)
319
Michael Walsh410b1782019-10-22 15:56:18 -0500320 # When SAVE_STATUS_POLICY is "NEVER" robot output files don't even get generated.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500321 if SAVE_STATUS_POLICY == "NEVER":
322 return
323
324 # Compose file_list based on robot command buffer passed in.
325 robot_cmd_buf_dict = gc.parse_command_string(robot_cmd_buf)
326 outputdir = robot_cmd_buf_dict['outputdir']
327 outputdir = gm.add_trailing_slash(outputdir)
328 file_list = outputdir + robot_cmd_buf_dict['output'] + " " + outputdir\
329 + robot_cmd_buf_dict['log'] + " " + outputdir\
330 + robot_cmd_buf_dict['report']
331
332 # Double checking that files are present.
333 shell_rc, out_buf = gc.shell_cmd("ls -1 " + file_list + " 2>/dev/null",
334 show_err=0)
335 file_list = re.sub("\n", " ", out_buf.rstrip("\n"))
336
337 if file_list == "":
338 gp.qprint_timen("No robot output files were found in " + outputdir
339 + ".")
340 return
Michael Walsh0d5f96a2019-05-20 10:09:57 -0500341 gp.qprint_var(robot_rc, gp.hexa())
Michael Walsha0ce75a2018-07-31 13:54:29 -0500342 if SAVE_STATUS_POLICY == "FAIL" and robot_rc == 0:
343 gp.qprint_timen("The call to robot produced no failures."
344 + " Deleting robot output files.")
345 gc.shell_cmd("rm -rf " + file_list)
346 return
347
348 if gzip:
Michael Walshe53dfec2018-08-07 15:02:56 -0500349 gc.shell_cmd("gzip -f " + file_list)
Michael Walsha0ce75a2018-07-31 13:54:29 -0500350 # Update the values in file_list.
351 file_list = re.sub(" ", ".gz ", file_list) + ".gz"
352
Michael Walsh410b1782019-10-22 15:56:18 -0500353 # It TMP_ROBOT_DIR_PATH is set, it means the caller wanted the robot output initially directed to
354 # TMP_ROBOT_DIR_PATH but later moved to FFDC_DIR_PATH. Otherwise, we're done.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500355
356 if os.environ.get("TMP_ROBOT_DIR_PATH", "") is "":
357 return
358
Michael Walsh410b1782019-10-22 15:56:18 -0500359 # We're directing these to the FFDC dir path so that they'll be subjected to FFDC cleanup.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500360 target_dir_path = os.environ.get("FFDC_DIR_PATH",
361 os.environ.get("HOME", ".")
Michael Walsh0a3bdb42019-01-31 16:21:44 +0000362 + "/ffdc")
Michael Walsha0ce75a2018-07-31 13:54:29 -0500363 target_dir_path = gm.add_trailing_slash(target_dir_path)
364
365 targ_file_list = [re.sub(".*/", target_dir_path, x)
366 for x in file_list.split(" ")]
367
368 gc.shell_cmd("mv " + file_list + " " + target_dir_path + " >/dev/null",
369 time_out=600)
370
371 gp.qprint_timen("New robot log file locations:")
372 gp.qprintn('\n'.join(targ_file_list))
373
374
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500375def robot_cmd_fnc(robot_cmd_buf,
Michael Walsh8dc99a32020-04-02 13:45:13 -0500376 robot_jail=os.environ.get('ROBOT_JAIL', ''), test_mode=0):
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500377 r"""
378 Run the robot command string.
379
Michael Walsh410b1782019-10-22 15:56:18 -0500380 This function will set the various PATH variables correctly so that you are running the proper version of
381 all imported files, etc.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500382
383 Description of argument(s):
384 robot_cmd_buf The complete robot command string.
Michael Walsh410b1782019-10-22 15:56:18 -0500385 robot_jail Indicates that this is to run in "robot jail" meaning without visibility
386 to any apolloxxx import files, programs, etc.
Michael Walsh8dc99a32020-04-02 13:45:13 -0500387 test_mode If test_mode is set, this function will not actually run the command.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500388 """
389
Michael Walsh2ea965c2019-08-01 16:14:25 -0500390 gv.valid_value(robot_cmd_buf)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500391
Michael Walsha0ce75a2018-07-31 13:54:29 -0500392 # Set global variables to aid in cleanup with process_robot_output_files.
393 global gcr_last_robot_cmd_buf
394 global gcr_last_robot_rc
395 gcr_last_robot_cmd_buf = robot_cmd_buf
396
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500397 # Get globals set by init_robot_test_base_dir_path().
398 module = sys.modules["__main__"]
399 try:
400 ROBOT_TEST_BASE_DIR_PATH = getattr(module, "ROBOT_TEST_BASE_DIR_PATH")
401 except NameError:
402 init_robot_test_base_dir_path()
403 ROBOT_TEST_BASE_DIR_PATH = getattr(module, "ROBOT_TEST_BASE_DIR_PATH")
404
Michael Walsh8dc99a32020-04-02 13:45:13 -0500405 ROBOT_TEST_RUNNING_FROM_SB = gm.get_mod_global("ROBOT_TEST_RUNNING_FROM_SB")
406 OPENBMCTOOL_DIR_PATH = gm.get_mod_global("OPENBMCTOOL_DIR_PATH")
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500407
408 if robot_jail == "":
409 if ROBOT_TEST_RUNNING_FROM_SB:
410 robot_jail = 0
411 else:
412 robot_jail = 1
413
414 robot_jail = int(robot_jail)
415 ROBOT_JAIL = os.environ.get('ROBOT_JAIL', '')
416 gp.dprint_vars(ROBOT_TEST_BASE_DIR_PATH, ROBOT_TEST_RUNNING_FROM_SB,
417 ROBOT_JAIL, robot_jail)
418
419 # Save PATH and PYTHONPATH to be restored later.
420 os.environ["SAVED_PYTHONPATH"] = os.environ.get("PYTHONPATH", "")
421 os.environ["SAVED_PATH"] = os.environ.get("PATH", "")
422
423 if robot_jail:
Michael Walsh410b1782019-10-22 15:56:18 -0500424 # Make sure required programs like python and robot can be found in the new restricted PATH.
Michael Walsha5d29bc2019-06-05 15:29:18 -0500425 required_programs = "python robot"
Michael Walsh410b1782019-10-22 15:56:18 -0500426 # It is expected that there will be a "python" program in the tool base bin path which is really a
427 # link to select_version. Ditto for "robot". Call each with the --print_only option to get the
428 # paths to the "real" programs.
Michael Walsha5d29bc2019-06-05 15:29:18 -0500429 cmd_buf = "for program in " + required_programs \
430 + " ; do dirname $(${program} --print_only) ; done 2>/dev/null"
431 rc, out_buf = gc.shell_cmd(cmd_buf, quiet=1, print_output=0)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500432 PYTHONPATH = ROBOT_TEST_BASE_DIR_PATH + "lib"
433 NEW_PATH_LIST = [ROBOT_TEST_BASE_DIR_PATH + "bin"]
Michael Walsha5d29bc2019-06-05 15:29:18 -0500434 NEW_PATH_LIST.extend(list(set(out_buf.rstrip("\n").split("\n"))))
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500435 NEW_PATH_LIST.extend(["/usr/local/sbin", "/usr/local/bin", "/usr/sbin",
Michael Walsha5d29bc2019-06-05 15:29:18 -0500436 "/usr/bin", "/sbin", "/bin",
Michael Walsh8dc99a32020-04-02 13:45:13 -0500437 OPENBMCTOOL_DIR_PATH.rstrip('/')])
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500438 PATH = ":".join(NEW_PATH_LIST)
439 else:
440 PYTHONPATH = os.environ.get('PYTHONPATH', '') + ":" +\
Michael Walsha5d29bc2019-06-05 15:29:18 -0500441 ROBOT_TEST_BASE_DIR_PATH + "lib"
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500442 PATH = os.environ.get('PATH', '') + ":" + ROBOT_TEST_BASE_DIR_PATH +\
Michael Walsh8dc99a32020-04-02 13:45:13 -0500443 "bin" + ":" + OPENBMCTOOL_DIR_PATH.rstrip('/')
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500444
445 os.environ['PYTHONPATH'] = PYTHONPATH
446 os.environ['PATH'] = PATH
447 gp.dprint_vars(PATH, PYTHONPATH)
448
449 os.environ['FFDC_DIR_PATH_STYLE'] = os.environ.get('FFDC_DIR_PATH_STYLE',
450 '1')
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500451 gp.qpissuing(robot_cmd_buf, test_mode)
452 if test_mode:
453 os.environ["PATH"] = os.environ.get("SAVED_PATH", "")
454 os.environ["PYTHONPATH"] = os.environ.get("SAVED_PYTHONPATH", "")
455 return True
456
457 if quiet:
458 DEVNULL = open(os.devnull, 'wb')
459 stdout = DEVNULL
460 else:
461 stdout = None
462 sub_proc = subprocess.Popen(robot_cmd_buf, stdout=stdout, shell=True)
463 sub_proc.communicate()
464 shell_rc = sub_proc.returncode
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500465 os.environ["PATH"] = os.environ.get("SAVED_PATH", "")
466 os.environ["PYTHONPATH"] = os.environ.get("SAVED_PYTHONPATH", "")
Michael Walsha0ce75a2018-07-31 13:54:29 -0500467 gcr_last_robot_rc = shell_rc
468 process_robot_output_files()
469 if shell_rc != 0:
Michael Walsh0d5f96a2019-05-20 10:09:57 -0500470 gp.print_var(shell_rc, gp.hexa())
Michael Walsha0ce75a2018-07-31 13:54:29 -0500471 return False
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500472
473 return True