blob: 84e6f06ee6c3ce7cfe593c1327d634b21b1c7b21 [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 Walsh8dc99a32020-04-02 13:45:13 -0500147 gv.valid_dir_path(OPENBMCTOOL_DIR_PATH)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500148
149 ROBOT_TEST_BASE_DIR_PATH = gm.add_trailing_slash(ROBOT_TEST_BASE_DIR_PATH)
150 gm.set_mod_global(ROBOT_TEST_BASE_DIR_PATH)
151 os.environ['ROBOT_TEST_BASE_DIR_PATH'] = ROBOT_TEST_BASE_DIR_PATH
152
153 gm.set_mod_global(ROBOT_TEST_RUNNING_FROM_SB)
154 os.environ['ROBOT_TEST_RUNNING_FROM_SB'] = str(ROBOT_TEST_RUNNING_FROM_SB)
155
Michael Walsh8dc99a32020-04-02 13:45:13 -0500156 gm.set_mod_global(OBMC_TOOLS_BASE_DIR_PATH)
157 os.environ['OBMC_TOOLS_BASE_DIR_PATH'] = str(OBMC_TOOLS_BASE_DIR_PATH)
158
159 gm.set_mod_global(OPENBMCTOOL_DIR_PATH)
160 os.environ['OPENBMCTOOL_DIR_PATH'] = str(OPENBMCTOOL_DIR_PATH)
161
162 gm.set_mod_global(MSBARTH_TOOLS_DIR_PATH)
163 os.environ['MSBARTH_TOOLS_DIR_PATH'] = str(MSBARTH_TOOLS_DIR_PATH)
164
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500165
166raw_robot_file_search_path = "${ROBOT_TEST_BASE_DIR_PATH}:" +\
167 "${ROBOT_TEST_BASE_DIR_PATH}tests:${ROBOT_TEST_BASE_DIR_PATH}extended:" +\
168 "${ROBOT_TEST_BASE_DIR_PATH}scratch:${PATH}"
169
170
171def init_robot_file_path(robot_file_path):
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500172 r"""
Michael Walsh410b1782019-10-22 15:56:18 -0500173 Determine full path name for the file path passed in robot_file_path and return it.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500174
Michael Walsh410b1782019-10-22 15:56:18 -0500175 If robot_file_path contains a fully qualified path name, this function will verify that the file exists.
176 If robot_file_path contains a relative path, this function will search for the file and set
177 robot_file_path so that it contains the absolute path to the robot file. This function will search for
178 the robot file using the raw_robot_file_search_path (defined above). Note that if
179 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 -0500180
181 Description of arguments:
Michael Walsh410b1782019-10-22 15:56:18 -0500182 robot_file_path The absolute or relative path to a robot file.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500183 """
184
Michael Walsh2ea965c2019-08-01 16:14:25 -0500185 gv.valid_value(robot_file_path)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500186
187 try:
188 if ROBOT_TEST_BASE_DIR_PATH is NONE:
189 init_robot_test_base_dir_path()
190 except NameError:
191 init_robot_test_base_dir_path()
192
193 if not re.match(r".*\.(robot|py)$", robot_file_path):
194 # No suffix so we'll assign one of "\.robot".
195 robot_file_path = robot_file_path + ".robot"
196
197 abs_path = 0
198 if robot_file_path[0:1] == "/":
199 abs_path = 1
200
201 gp.dprint_vars(abs_path, robot_file_path)
202
203 if not abs_path:
204 cmd_buf = "echo -n \"" + raw_robot_file_search_path + "\""
Michael Walshbffaa1d2018-06-08 15:09:27 -0500205 shell_rc, out_buf = gc.shell_cmd(cmd_buf, quiet=(not debug),
206 print_output=0)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500207 robot_file_search_paths = out_buf
Michael Walsha0ce75a2018-07-31 13:54:29 -0500208 gp.dprint_var(robot_file_search_paths)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500209 robot_file_search_paths_list = robot_file_search_paths.split(':')
210 for search_path in robot_file_search_paths_list:
211 search_path = gm.add_trailing_slash(search_path)
212 candidate_file_path = search_path + robot_file_path
213 gp.dprint_var(candidate_file_path)
214 if os.path.isfile(candidate_file_path):
215 gp.dprint_timen("Found full path to " + robot_file_path + ".")
216 robot_file_path = candidate_file_path
217 break
218
219 gp.dprint_var(robot_file_path)
Michael Walsh2ea965c2019-08-01 16:14:25 -0500220 gv.valid_file_path(robot_file_path)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500221
222 return robot_file_path
223
224
225def get_robot_parm_names():
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500226 r"""
Michael Walsh410b1782019-10-22 15:56:18 -0500227 Return a list containing all of the long parm names (e.g. --outputdir) supported by the robot program.
228 Double dashes are not included in the names returned.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500229 """
230
231 cmd_buf = "robot -h | egrep " +\
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500232 "'^([ ]\\-[a-zA-Z0-9])?[ ]+--[a-zA-Z0-9]+[ ]+' | sed -re" +\
233 " s'/.*\\-\\-//g' -e s'/ .*//g' | sort -u"
Michael Walshbffaa1d2018-06-08 15:09:27 -0500234 shell_rc, out_buf = gc.shell_cmd(cmd_buf, quiet=1, print_output=0)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500235
236 return out_buf.split("\n")
237
238
239def create_robot_cmd_string(robot_file_path, *parms):
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500240 r"""
Michael Walsh410b1782019-10-22 15:56:18 -0500241 Create a robot command string and return it. On failure, return an empty string.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500242
243 Description of arguments:
244 robot_file_path The path to the robot file to be run.
Michael Walsh410b1782019-10-22 15:56:18 -0500245 parms The list of parms to be included in the command string. The name of each
246 variable in this list must be the same as the name of the corresponding
247 parm. This function figures out that name. This function is also able
248 to distinguish robot parms (e.g. --outputdir) from robot program parms
249 (all other parms which will be passed as "-v PARM_NAME:parm_value")..
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500250
251 Example:
252
253 The following call to this function...
Michael Walsh410b1782019-10-22 15:56:18 -0500254 cmd_buf = create_robot_cmd_string("tools/start_sol_console.robot", OPENBMC_HOST, quiet, test_mode, debug,
255 outputdir, output, log, report)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500256
257 Would return a string something like this.
258 robot -v OPENBMC_HOST:beye6 -v quiet:0 -v test_mode:1 -v debug:1
Michael Walsh410b1782019-10-22 15:56:18 -0500259 --outputdir=/gsa/ausgsa/projects/a/status --output=beye6.OS_Console.output.xml
260 --log=beye6.OS_Console.log.html --report=beye6.OS_Console.report.html tools/start_sol_console.robot
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500261 """
262
263 robot_file_path = init_robot_file_path(robot_file_path)
264
265 robot_parm_names = get_robot_parm_names()
266
267 robot_parm_list = []
268
269 stack_frame = 2
270 ix = 2
271 for arg in parms:
272 parm = arg
273 parm = gm.quote_bash_parm(gm.escape_bash_quotes(str(parm)))
274 var_name = gp.get_arg_name(None, ix, stack_frame)
275 if var_name in robot_parm_names:
276 p_string = "--" + var_name + "=" + str(parm)
277 robot_parm_list.append(p_string)
278 else:
279 p_string = "-v " + var_name + ":" + str(parm)
280 robot_parm_list.append(p_string)
281 ix += 1
282
283 robot_cmd_buf = "robot " + ' '.join(robot_parm_list) + " " +\
284 robot_file_path
285
286 return robot_cmd_buf
287
288
Michael Walsha0ce75a2018-07-31 13:54:29 -0500289# Global variables to aid in cleanup after running robot_cmd_fnc.
290gcr_last_robot_cmd_buf = ""
291gcr_last_robot_rc = 0
292
293
294def process_robot_output_files(robot_cmd_buf=None,
295 robot_rc=None,
Michael Walshf33140f2018-11-01 14:05:56 -0500296 gzip=None):
Michael Walsha0ce75a2018-07-31 13:54:29 -0500297 r"""
298 Process robot output files which can involve several operations:
Michael Walsh410b1782019-10-22 15:56:18 -0500299 - If the files are in a temporary location, using SAVE_STATUS_POLICY to decide whether to move them to a
300 permanent location or to delete them.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500301 - Gzipping them.
302
303 Description of argument(s):
Michael Walsh410b1782019-10-22 15:56:18 -0500304 robot_cmd_buf The complete command string used to invoke robot.
305 robot_rc The return code from running the robot command string.
306 gzip Indicates whether robot-generated output should be gzipped.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500307 """
308
309 robot_cmd_buf = gm.dft(robot_cmd_buf, gcr_last_robot_cmd_buf)
310 robot_rc = gm.dft(robot_rc, gcr_last_robot_rc)
Michael Walshf33140f2018-11-01 14:05:56 -0500311 gzip = gm.dft(gzip, int(os.environ.get("GZIP_ROBOT", "1")))
Michael Walsha0ce75a2018-07-31 13:54:29 -0500312
313 if robot_cmd_buf == "":
Michael Walsh410b1782019-10-22 15:56:18 -0500314 # This can legitimately occur if this function is called from an exit_function without the program
315 # having ever run robot_cmd_fnc.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500316 return
317
318 SAVE_STATUS_POLICY = os.environ.get("SAVE_STATUS_POLICY", "ALWAYS")
319 gp.qprint_vars(SAVE_STATUS_POLICY)
320
Michael Walsh410b1782019-10-22 15:56:18 -0500321 # When SAVE_STATUS_POLICY is "NEVER" robot output files don't even get generated.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500322 if SAVE_STATUS_POLICY == "NEVER":
323 return
324
325 # Compose file_list based on robot command buffer passed in.
326 robot_cmd_buf_dict = gc.parse_command_string(robot_cmd_buf)
327 outputdir = robot_cmd_buf_dict['outputdir']
328 outputdir = gm.add_trailing_slash(outputdir)
329 file_list = outputdir + robot_cmd_buf_dict['output'] + " " + outputdir\
330 + robot_cmd_buf_dict['log'] + " " + outputdir\
331 + robot_cmd_buf_dict['report']
332
333 # Double checking that files are present.
334 shell_rc, out_buf = gc.shell_cmd("ls -1 " + file_list + " 2>/dev/null",
335 show_err=0)
336 file_list = re.sub("\n", " ", out_buf.rstrip("\n"))
337
338 if file_list == "":
339 gp.qprint_timen("No robot output files were found in " + outputdir
340 + ".")
341 return
Michael Walsh0d5f96a2019-05-20 10:09:57 -0500342 gp.qprint_var(robot_rc, gp.hexa())
Michael Walsha0ce75a2018-07-31 13:54:29 -0500343 if SAVE_STATUS_POLICY == "FAIL" and robot_rc == 0:
344 gp.qprint_timen("The call to robot produced no failures."
345 + " Deleting robot output files.")
346 gc.shell_cmd("rm -rf " + file_list)
347 return
348
349 if gzip:
Michael Walshe53dfec2018-08-07 15:02:56 -0500350 gc.shell_cmd("gzip -f " + file_list)
Michael Walsha0ce75a2018-07-31 13:54:29 -0500351 # Update the values in file_list.
352 file_list = re.sub(" ", ".gz ", file_list) + ".gz"
353
Michael Walsh410b1782019-10-22 15:56:18 -0500354 # It TMP_ROBOT_DIR_PATH is set, it means the caller wanted the robot output initially directed to
355 # TMP_ROBOT_DIR_PATH but later moved to FFDC_DIR_PATH. Otherwise, we're done.
Michael Walsha0ce75a2018-07-31 13:54:29 -0500356
357 if os.environ.get("TMP_ROBOT_DIR_PATH", "") is "":
358 return
359
Michael Walsh410b1782019-10-22 15:56:18 -0500360 # 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 -0500361 target_dir_path = os.environ.get("FFDC_DIR_PATH",
362 os.environ.get("HOME", ".")
Michael Walsh0a3bdb42019-01-31 16:21:44 +0000363 + "/ffdc")
Michael Walsha0ce75a2018-07-31 13:54:29 -0500364 target_dir_path = gm.add_trailing_slash(target_dir_path)
365
366 targ_file_list = [re.sub(".*/", target_dir_path, x)
367 for x in file_list.split(" ")]
368
369 gc.shell_cmd("mv " + file_list + " " + target_dir_path + " >/dev/null",
370 time_out=600)
371
372 gp.qprint_timen("New robot log file locations:")
373 gp.qprintn('\n'.join(targ_file_list))
374
375
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500376def robot_cmd_fnc(robot_cmd_buf,
Michael Walsh8dc99a32020-04-02 13:45:13 -0500377 robot_jail=os.environ.get('ROBOT_JAIL', ''), test_mode=0):
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500378 r"""
379 Run the robot command string.
380
Michael Walsh410b1782019-10-22 15:56:18 -0500381 This function will set the various PATH variables correctly so that you are running the proper version of
382 all imported files, etc.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500383
384 Description of argument(s):
385 robot_cmd_buf The complete robot command string.
Michael Walsh410b1782019-10-22 15:56:18 -0500386 robot_jail Indicates that this is to run in "robot jail" meaning without visibility
387 to any apolloxxx import files, programs, etc.
Michael Walsh8dc99a32020-04-02 13:45:13 -0500388 test_mode If test_mode is set, this function will not actually run the command.
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500389 """
390
Michael Walsh2ea965c2019-08-01 16:14:25 -0500391 gv.valid_value(robot_cmd_buf)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500392
Michael Walsha0ce75a2018-07-31 13:54:29 -0500393 # Set global variables to aid in cleanup with process_robot_output_files.
394 global gcr_last_robot_cmd_buf
395 global gcr_last_robot_rc
396 gcr_last_robot_cmd_buf = robot_cmd_buf
397
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500398 # Get globals set by init_robot_test_base_dir_path().
399 module = sys.modules["__main__"]
400 try:
401 ROBOT_TEST_BASE_DIR_PATH = getattr(module, "ROBOT_TEST_BASE_DIR_PATH")
402 except NameError:
403 init_robot_test_base_dir_path()
404 ROBOT_TEST_BASE_DIR_PATH = getattr(module, "ROBOT_TEST_BASE_DIR_PATH")
405
Michael Walsh8dc99a32020-04-02 13:45:13 -0500406 ROBOT_TEST_RUNNING_FROM_SB = gm.get_mod_global("ROBOT_TEST_RUNNING_FROM_SB")
407 OPENBMCTOOL_DIR_PATH = gm.get_mod_global("OPENBMCTOOL_DIR_PATH")
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500408
409 if robot_jail == "":
410 if ROBOT_TEST_RUNNING_FROM_SB:
411 robot_jail = 0
412 else:
413 robot_jail = 1
414
415 robot_jail = int(robot_jail)
416 ROBOT_JAIL = os.environ.get('ROBOT_JAIL', '')
417 gp.dprint_vars(ROBOT_TEST_BASE_DIR_PATH, ROBOT_TEST_RUNNING_FROM_SB,
418 ROBOT_JAIL, robot_jail)
419
420 # Save PATH and PYTHONPATH to be restored later.
421 os.environ["SAVED_PYTHONPATH"] = os.environ.get("PYTHONPATH", "")
422 os.environ["SAVED_PATH"] = os.environ.get("PATH", "")
423
424 if robot_jail:
Michael Walsh410b1782019-10-22 15:56:18 -0500425 # Make sure required programs like python and robot can be found in the new restricted PATH.
Michael Walsha5d29bc2019-06-05 15:29:18 -0500426 required_programs = "python robot"
Michael Walsh410b1782019-10-22 15:56:18 -0500427 # It is expected that there will be a "python" program in the tool base bin path which is really a
428 # link to select_version. Ditto for "robot". Call each with the --print_only option to get the
429 # paths to the "real" programs.
Michael Walsha5d29bc2019-06-05 15:29:18 -0500430 cmd_buf = "for program in " + required_programs \
431 + " ; do dirname $(${program} --print_only) ; done 2>/dev/null"
432 rc, out_buf = gc.shell_cmd(cmd_buf, quiet=1, print_output=0)
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500433 PYTHONPATH = ROBOT_TEST_BASE_DIR_PATH + "lib"
434 NEW_PATH_LIST = [ROBOT_TEST_BASE_DIR_PATH + "bin"]
Michael Walsha5d29bc2019-06-05 15:29:18 -0500435 NEW_PATH_LIST.extend(list(set(out_buf.rstrip("\n").split("\n"))))
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500436 NEW_PATH_LIST.extend(["/usr/local/sbin", "/usr/local/bin", "/usr/sbin",
Michael Walsha5d29bc2019-06-05 15:29:18 -0500437 "/usr/bin", "/sbin", "/bin",
Michael Walsh8dc99a32020-04-02 13:45:13 -0500438 OPENBMCTOOL_DIR_PATH.rstrip('/')])
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500439 PATH = ":".join(NEW_PATH_LIST)
440 else:
441 PYTHONPATH = os.environ.get('PYTHONPATH', '') + ":" +\
Michael Walsha5d29bc2019-06-05 15:29:18 -0500442 ROBOT_TEST_BASE_DIR_PATH + "lib"
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500443 PATH = os.environ.get('PATH', '') + ":" + ROBOT_TEST_BASE_DIR_PATH +\
Michael Walsh8dc99a32020-04-02 13:45:13 -0500444 "bin" + ":" + OPENBMCTOOL_DIR_PATH.rstrip('/')
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500445
446 os.environ['PYTHONPATH'] = PYTHONPATH
447 os.environ['PATH'] = PATH
448 gp.dprint_vars(PATH, PYTHONPATH)
449
450 os.environ['FFDC_DIR_PATH_STYLE'] = os.environ.get('FFDC_DIR_PATH_STYLE',
451 '1')
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500452 gp.qpissuing(robot_cmd_buf, test_mode)
453 if test_mode:
454 os.environ["PATH"] = os.environ.get("SAVED_PATH", "")
455 os.environ["PYTHONPATH"] = os.environ.get("SAVED_PYTHONPATH", "")
456 return True
457
458 if quiet:
459 DEVNULL = open(os.devnull, 'wb')
460 stdout = DEVNULL
461 else:
462 stdout = None
463 sub_proc = subprocess.Popen(robot_cmd_buf, stdout=stdout, shell=True)
464 sub_proc.communicate()
465 shell_rc = sub_proc.returncode
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500466 os.environ["PATH"] = os.environ.get("SAVED_PATH", "")
467 os.environ["PYTHONPATH"] = os.environ.get("SAVED_PYTHONPATH", "")
Michael Walsha0ce75a2018-07-31 13:54:29 -0500468 gcr_last_robot_rc = shell_rc
469 process_robot_output_files()
470 if shell_rc != 0:
Michael Walsh0d5f96a2019-05-20 10:09:57 -0500471 gp.print_var(shell_rc, gp.hexa())
Michael Walsha0ce75a2018-07-31 13:54:29 -0500472 return False
Michael Walsh3ba8ecd2018-04-24 11:33:25 -0500473
474 return True