diff options
Diffstat (limited to 'test/gtest_test_utils.py')
-rwxr-xr-x | test/gtest_test_utils.py | 50 |
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): |