aboutsummaryrefslogtreecommitdiffstats
path: root/test/gtest_test_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/gtest_test_utils.py')
-rwxr-xr-xtest/gtest_test_utils.py50
1 files changed, 39 insertions, 11 deletions
diff --git a/test/gtest_test_utils.py b/test/gtest_test_utils.py
index 19b5b228..e0f5973e 100755
--- a/test/gtest_test_utils.py
+++ b/test/gtest_test_utils.py
@@ -194,23 +194,28 @@ def GetExitStatus(exit_code):
class Subprocess:
- def __init__(self, command, working_dir=None, capture_stderr=True):
+ def __init__(self, command, working_dir=None, capture_stderr=True, env=None):
"""Changes into a specified directory, if provided, and executes a command.
- Restores the old directory afterwards. Execution results are returned
- via the following attributes:
- terminated_by_sygnal True iff the child process has been terminated
- by a signal.
- signal Sygnal that terminated the child process.
- exited True iff the child process exited normally.
- exit_code The code with which the child proces exited.
- output Child process's stdout and stderr output
- combined in a string.
+
+ Restores the old directory afterwards.
Args:
command: The command to run, in the form of sys.argv.
working_dir: The directory to change into.
capture_stderr: Determines whether to capture stderr in the output member
or to discard it.
+ env: Dictionary with environment to pass to the subprocess.
+
+ Returns:
+ An object that represents outcome of the executed process. It has the
+ following attributes:
+ terminated_by_signal True iff the child process has been terminated
+ by a signal.
+ signal Sygnal that terminated the child process.
+ exited True iff the child process exited normally.
+ exit_code The code with which the child process exited.
+ output Child process's stdout and stderr output
+ combined in a string.
"""
# The subprocess module is the preferrable way of running programs
@@ -228,13 +233,30 @@ class Subprocess:
p = subprocess.Popen(command,
stdout=subprocess.PIPE, stderr=stderr,
- cwd=working_dir, universal_newlines=True)
+ cwd=working_dir, universal_newlines=True, env=env)
# communicate returns a tuple with the file obect for the child's
# output.
self.output = p.communicate()[0]
self._return_code = p.returncode
else:
old_dir = os.getcwd()
+
+ def _ReplaceEnvDict(dest, src):
+ # Changes made by os.environ.clear are not inheritable by child
+ # processes until Python 2.6. To produce inheritable changes we have
+ # to delete environment items with the del statement.
+ for key in dest:
+ del dest[key]
+ dest.update(src)
+
+ # When 'env' is not None, backup the environment variables and replace
+ # them with the passed 'env'. When 'env' is None, we simply use the
+ # current 'os.environ' for compatibility with the subprocess.Popen
+ # semantics used above.
+ if env is not None:
+ old_environ = os.environ.copy()
+ _ReplaceEnvDict(os.environ, env)
+
try:
if working_dir is not None:
os.chdir(working_dir)
@@ -247,6 +269,12 @@ class Subprocess:
ret_code = p.wait()
finally:
os.chdir(old_dir)
+
+ # Restore the old environment variables
+ # if they were replaced.
+ if env is not None:
+ _ReplaceEnvDict(os.environ, old_environ)
+
# Converts ret_code to match the semantics of
# subprocess.Popen.returncode.
if os.WIFSIGNALED(ret_code):