1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#!/usr/bin/env python
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Copyright 2006, Google Inc.
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# All rights reserved.
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Redistribution and use in source and binary forms, with or without
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# modification, are permitted provided that the following conditions are
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# met:
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#     * Redistributions of source code must retain the above copyright
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# notice, this list of conditions and the following disclaimer.
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#     * Redistributions in binary form must reproduce the above
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# copyright notice, this list of conditions and the following disclaimer
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# in the documentation and/or other materials provided with the
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# distribution.
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#     * Neither the name of Google Inc. nor the names of its
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# contributors may be used to endorse or promote products derived from
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# this software without specific prior written permission.
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville"""Unit test utilities for Google C++ Testing Framework."""
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville__author__ = 'wan@google.com (Zhanyong Wan)'
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport atexit
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport os
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport shutil
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport sys
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport tempfile
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleimport unittest
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville_test_module = unittest
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Suppresses the 'Import not at the top of the file' lint complaint.
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# pylint: disable-msg=C6204
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletry:
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  import subprocess
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  _SUBPROCESS_MODULE_AVAILABLE = True
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleexcept:
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  import popen2
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  _SUBPROCESS_MODULE_AVAILABLE = False
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# pylint: enable-msg=C6204
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleIS_WINDOWS = os.name == 'nt'
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleIS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0]
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Here we expose a class from a particular module, depending on the
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# environment. The comment suppresses the 'Invalid variable name' lint
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# complaint.
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTestCase = _test_module.TestCase  # pylint: disable-msg=C6409
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# Initially maps a flag to its default value. After
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville# _ParseAndStripGTestFlags() is called, maps a flag to its actual value.
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville_flag_map = {'gtest_source_dir': os.path.dirname(sys.argv[0]),
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville             'gtest_build_dir': os.path.dirname(sys.argv[0])}
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville_gtest_flags_are_parsed = False
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _ParseAndStripGTestFlags(argv):
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """Parses and strips Google Test flags from argv.  This is idempotent."""
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # Suppresses the lint complaint about a global variable since we need it
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # here to maintain module-wide state.
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  global _gtest_flags_are_parsed  # pylint: disable-msg=W0603
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if _gtest_flags_are_parsed:
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  _gtest_flags_are_parsed = True
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for flag in _flag_map:
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # The environment variable overrides the default value.
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if flag.upper() in os.environ:
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      _flag_map[flag] = os.environ[flag.upper()]
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # The command line flag overrides the environment variable.
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    i = 1  # Skips the program name.
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    while i < len(argv):
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      prefix = '--' + flag + '='
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if argv[i].startswith(prefix):
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        _flag_map[flag] = argv[i][len(prefix):]
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        del argv[i]
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        break
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      else:
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        # We don't increment i in case we just found a --gtest_* flag
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        # and removed it from argv.
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        i += 1
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef GetFlag(flag):
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """Returns the value of the given flag."""
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # In case GetFlag() is called before Main(), we always call
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # _ParseAndStripGTestFlags() here to make sure the --gtest_* flags
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # are parsed.
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  _ParseAndStripGTestFlags(sys.argv)
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return _flag_map[flag]
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef GetSourceDir():
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """Returns the absolute path of the directory where the .py files are."""
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return os.path.abspath(GetFlag('gtest_source_dir'))
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef GetBuildDir():
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """Returns the absolute path of the directory where the test binaries are."""
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return os.path.abspath(GetFlag('gtest_build_dir'))
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville_temp_dir = None
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef _RemoveTempDir():
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if _temp_dir:
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    shutil.rmtree(_temp_dir, ignore_errors=True)
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleatexit.register(_RemoveTempDir)
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef GetTempDir():
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """Returns a directory for temporary files."""
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  global _temp_dir
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if not _temp_dir:
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    _temp_dir = tempfile.mkdtemp()
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return _temp_dir
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef GetTestExecutablePath(executable_name):
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """Returns the absolute path of the test binary given its name.
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  The function will print a message and abort the program if the resulting file
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  doesn't exist.
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Args:
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    executable_name: name of the test binary that the test script runs.
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Returns:
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    The absolute path of the test binary.
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  path = os.path.abspath(os.path.join(GetBuildDir(), executable_name))
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (IS_WINDOWS or IS_CYGWIN) and not path.endswith('.exe'):
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    path += '.exe'
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if not os.path.exists(path):
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    message = (
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        'Unable to find the test binary. Please make sure to provide path\n'
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        'to the binary via the --gtest_build_dir flag or the GTEST_BUILD_DIR\n'
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        'environment variable. For convenient use, invoke this script via\n'
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        'mk_test.py.\n'
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        # TODO(vladl@google.com): change mk_test.py to test.py after renaming
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        # the file.
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        'Please run mk_test.py -h for help.')
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    print >> sys.stderr, message
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sys.exit(1)
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return path
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef GetExitStatus(exit_code):
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """Returns the argument to exit(), or -1 if exit() wasn't called.
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Args:
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    exit_code: the result value of os.system(command).
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if os.name == 'nt':
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # On Windows, os.WEXITSTATUS() doesn't work and os.system() returns
181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # the argument to exit() directly.
182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return exit_code
183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  else:
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # On Unix, os.WEXITSTATUS() must be used to extract the exit status
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # from the result of os.system().
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if os.WIFEXITED(exit_code):
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return os.WEXITSTATUS(exit_code)
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    else:
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return -1
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass Subprocess:
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  def __init__(self, command, working_dir=None, capture_stderr=True):
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    """Changes into a specified directory, if provided, and executes a command.
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Restores the old directory afterwards. Execution results are returned
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    via the following attributes:
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      terminated_by_sygnal   True iff the child process has been terminated
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                             by a signal.
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      signal                 Sygnal that terminated the child process.
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      exited                 True iff the child process exited normally.
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      exit_code              The code with which the child proces exited.
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      output                 Child process's stdout and stderr output
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                             combined in a string.
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    Args:
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      command:        The command to run, in the form of sys.argv.
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      working_dir:    The directory to change into.
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      capture_stderr: Determines whether to capture stderr in the output member
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                      or to discard it.
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    """
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # The subprocess module is the preferrable way of running programs
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # since it is available and behaves consistently on all platforms,
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # including Windows. But it is only available starting in python 2.4.
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # In earlier python versions, we revert to the popen2 module, which is
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # available in python 2.0 and later but doesn't provide required
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # functionality (Popen4) under Windows. This allows us to support Mac
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    # OS X 10.4 Tiger, which has python 2.3 installed.
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if _SUBPROCESS_MODULE_AVAILABLE:
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if capture_stderr:
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        stderr = subprocess.STDOUT
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      else:
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        stderr = subprocess.PIPE
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      p = subprocess.Popen(command,
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                           stdout=subprocess.PIPE, stderr=stderr,
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                           cwd=working_dir, universal_newlines=True)
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      # communicate returns a tuple with the file obect for the child's
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      # output.
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      self.output = p.communicate()[0]
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      self._return_code = p.returncode
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    else:
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      old_dir = os.getcwd()
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      try:
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if working_dir is not None:
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          os.chdir(working_dir)
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if capture_stderr:
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          p = popen2.Popen4(command)
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        else:
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          p = popen2.Popen3(command)
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        p.tochild.close()
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        self.output = p.fromchild.read()
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        ret_code = p.wait()
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      finally:
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        os.chdir(old_dir)
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      # Converts ret_code to match the semantics of
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      # subprocess.Popen.returncode.
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if os.WIFSIGNALED(ret_code):
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        self._return_code = -os.WTERMSIG(ret_code)
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      else:  # os.WIFEXITED(ret_code) should return True here.
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        self._return_code = os.WEXITSTATUS(ret_code)
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if self._return_code < 0:
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      self.terminated_by_signal = True
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      self.exited = False
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      self.signal = -self._return_code
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    else:
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      self.terminated_by_signal = False
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      self.exited = True
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      self.exit_code = self._return_code
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilledef Main():
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  """Runs the unit test."""
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # We must call _ParseAndStripGTestFlags() before calling
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # unittest.main().  Otherwise the latter will be confused by the
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  # --gtest_* flags.
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  _ParseAndStripGTestFlags(sys.argv)
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  _test_module.main()
271