media/webrtc/trunk/testing/gtest/test/gtest_test_utils.py

Wed, 31 Dec 2014 07:53:36 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:53:36 +0100
branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
permissions
-rwxr-xr-x

Correct small whitespace inconsistency, lost while renaming variables.

     1 #!/usr/bin/env python
     2 #
     3 # Copyright 2006, Google Inc.
     4 # All rights reserved.
     5 #
     6 # Redistribution and use in source and binary forms, with or without
     7 # modification, are permitted provided that the following conditions are
     8 # met:
     9 #
    10 #     * Redistributions of source code must retain the above copyright
    11 # notice, this list of conditions and the following disclaimer.
    12 #     * Redistributions in binary form must reproduce the above
    13 # copyright notice, this list of conditions and the following disclaimer
    14 # in the documentation and/or other materials provided with the
    15 # distribution.
    16 #     * Neither the name of Google Inc. nor the names of its
    17 # contributors may be used to endorse or promote products derived from
    18 # this software without specific prior written permission.
    19 #
    20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    23 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    24 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    25 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    26 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    27 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    28 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    29 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    30 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    32 """Unit test utilities for Google C++ Testing Framework."""
    34 __author__ = 'wan@google.com (Zhanyong Wan)'
    36 import atexit
    37 import os
    38 import shutil
    39 import sys
    40 import tempfile
    41 import unittest
    42 _test_module = unittest
    44 # Suppresses the 'Import not at the top of the file' lint complaint.
    45 # pylint: disable-msg=C6204
    46 try:
    47   import subprocess
    48   _SUBPROCESS_MODULE_AVAILABLE = True
    49 except:
    50   import popen2
    51   _SUBPROCESS_MODULE_AVAILABLE = False
    52 # pylint: enable-msg=C6204
    54 GTEST_OUTPUT_VAR_NAME = 'GTEST_OUTPUT'
    56 IS_WINDOWS = os.name == 'nt'
    57 IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0]
    59 # Here we expose a class from a particular module, depending on the
    60 # environment. The comment suppresses the 'Invalid variable name' lint
    61 # complaint.
    62 TestCase = _test_module.TestCase  # pylint: disable-msg=C6409
    64 # Initially maps a flag to its default value. After
    65 # _ParseAndStripGTestFlags() is called, maps a flag to its actual value.
    66 _flag_map = {'source_dir': os.path.dirname(sys.argv[0]),
    67              'build_dir': os.path.dirname(sys.argv[0])}
    68 _gtest_flags_are_parsed = False
    71 def _ParseAndStripGTestFlags(argv):
    72   """Parses and strips Google Test flags from argv.  This is idempotent."""
    74   # Suppresses the lint complaint about a global variable since we need it
    75   # here to maintain module-wide state.
    76   global _gtest_flags_are_parsed  # pylint: disable-msg=W0603
    77   if _gtest_flags_are_parsed:
    78     return
    80   _gtest_flags_are_parsed = True
    81   for flag in _flag_map:
    82     # The environment variable overrides the default value.
    83     if flag.upper() in os.environ:
    84       _flag_map[flag] = os.environ[flag.upper()]
    86     # The command line flag overrides the environment variable.
    87     i = 1  # Skips the program name.
    88     while i < len(argv):
    89       prefix = '--' + flag + '='
    90       if argv[i].startswith(prefix):
    91         _flag_map[flag] = argv[i][len(prefix):]
    92         del argv[i]
    93         break
    94       else:
    95         # We don't increment i in case we just found a --gtest_* flag
    96         # and removed it from argv.
    97         i += 1
   100 def GetFlag(flag):
   101   """Returns the value of the given flag."""
   103   # In case GetFlag() is called before Main(), we always call
   104   # _ParseAndStripGTestFlags() here to make sure the --gtest_* flags
   105   # are parsed.
   106   _ParseAndStripGTestFlags(sys.argv)
   108   return _flag_map[flag]
   111 def GetSourceDir():
   112   """Returns the absolute path of the directory where the .py files are."""
   114   return os.path.abspath(GetFlag('source_dir'))
   117 def GetBuildDir():
   118   """Returns the absolute path of the directory where the test binaries are."""
   120   return os.path.abspath(GetFlag('build_dir'))
   123 _temp_dir = None
   125 def _RemoveTempDir():
   126   if _temp_dir:
   127     shutil.rmtree(_temp_dir, ignore_errors=True)
   129 atexit.register(_RemoveTempDir)
   132 def GetTempDir():
   133   """Returns a directory for temporary files."""
   135   global _temp_dir
   136   if not _temp_dir:
   137     _temp_dir = tempfile.mkdtemp()
   138   return _temp_dir
   141 def GetTestExecutablePath(executable_name, build_dir=None):
   142   """Returns the absolute path of the test binary given its name.
   144   The function will print a message and abort the program if the resulting file
   145   doesn't exist.
   147   Args:
   148     executable_name: name of the test binary that the test script runs.
   149     build_dir:       directory where to look for executables, by default
   150                      the result of GetBuildDir().
   152   Returns:
   153     The absolute path of the test binary.
   154   """
   156   path = os.path.abspath(os.path.join(build_dir or GetBuildDir(),
   157                                       executable_name))
   158   if (IS_WINDOWS or IS_CYGWIN) and not path.endswith('.exe'):
   159     path += '.exe'
   161   if not os.path.exists(path):
   162     message = (
   163         'Unable to find the test binary. Please make sure to provide path\n'
   164         'to the binary via the --build_dir flag or the BUILD_DIR\n'
   165         'environment variable.')
   166     print >> sys.stderr, message
   167     sys.exit(1)
   169   return path
   172 def GetExitStatus(exit_code):
   173   """Returns the argument to exit(), or -1 if exit() wasn't called.
   175   Args:
   176     exit_code: the result value of os.system(command).
   177   """
   179   if os.name == 'nt':
   180     # On Windows, os.WEXITSTATUS() doesn't work and os.system() returns
   181     # the argument to exit() directly.
   182     return exit_code
   183   else:
   184     # On Unix, os.WEXITSTATUS() must be used to extract the exit status
   185     # from the result of os.system().
   186     if os.WIFEXITED(exit_code):
   187       return os.WEXITSTATUS(exit_code)
   188     else:
   189       return -1
   192 class Subprocess:
   193   def __init__(self, command, working_dir=None, capture_stderr=True, env=None):
   194     """Changes into a specified directory, if provided, and executes a command.
   196     Restores the old directory afterwards.
   198     Args:
   199       command:        The command to run, in the form of sys.argv.
   200       working_dir:    The directory to change into.
   201       capture_stderr: Determines whether to capture stderr in the output member
   202                       or to discard it.
   203       env:            Dictionary with environment to pass to the subprocess.
   205     Returns:
   206       An object that represents outcome of the executed process. It has the
   207       following attributes:
   208         terminated_by_signal   True iff the child process has been terminated
   209                                by a signal.
   210         signal                 Sygnal that terminated the child process.
   211         exited                 True iff the child process exited normally.
   212         exit_code              The code with which the child process exited.
   213         output                 Child process's stdout and stderr output
   214                                combined in a string.
   215     """
   217     # The subprocess module is the preferrable way of running programs
   218     # since it is available and behaves consistently on all platforms,
   219     # including Windows. But it is only available starting in python 2.4.
   220     # In earlier python versions, we revert to the popen2 module, which is
   221     # available in python 2.0 and later but doesn't provide required
   222     # functionality (Popen4) under Windows. This allows us to support Mac
   223     # OS X 10.4 Tiger, which has python 2.3 installed.
   224     if _SUBPROCESS_MODULE_AVAILABLE:
   225       if capture_stderr:
   226         stderr = subprocess.STDOUT
   227       else:
   228         stderr = subprocess.PIPE
   230       p = subprocess.Popen(command,
   231                            stdout=subprocess.PIPE, stderr=stderr,
   232                            cwd=working_dir, universal_newlines=True, env=env)
   233       # communicate returns a tuple with the file obect for the child's
   234       # output.
   235       self.output = p.communicate()[0]
   236       self._return_code = p.returncode
   237     else:
   238       old_dir = os.getcwd()
   240       def _ReplaceEnvDict(dest, src):
   241         # Changes made by os.environ.clear are not inheritable by child
   242         # processes until Python 2.6. To produce inheritable changes we have
   243         # to delete environment items with the del statement.
   244         for key in dest.keys():
   245           del dest[key]
   246         dest.update(src)
   248       # When 'env' is not None, backup the environment variables and replace
   249       # them with the passed 'env'. When 'env' is None, we simply use the
   250       # current 'os.environ' for compatibility with the subprocess.Popen
   251       # semantics used above.
   252       if env is not None:
   253         old_environ = os.environ.copy()
   254         _ReplaceEnvDict(os.environ, env)
   256       try:
   257         if working_dir is not None:
   258           os.chdir(working_dir)
   259         if capture_stderr:
   260           p = popen2.Popen4(command)
   261         else:
   262           p = popen2.Popen3(command)
   263         p.tochild.close()
   264         self.output = p.fromchild.read()
   265         ret_code = p.wait()
   266       finally:
   267         os.chdir(old_dir)
   269         # Restore the old environment variables
   270         # if they were replaced.
   271         if env is not None:
   272           _ReplaceEnvDict(os.environ, old_environ)
   274       # Converts ret_code to match the semantics of
   275       # subprocess.Popen.returncode.
   276       if os.WIFSIGNALED(ret_code):
   277         self._return_code = -os.WTERMSIG(ret_code)
   278       else:  # os.WIFEXITED(ret_code) should return True here.
   279         self._return_code = os.WEXITSTATUS(ret_code)
   281     if self._return_code < 0:
   282       self.terminated_by_signal = True
   283       self.exited = False
   284       self.signal = -self._return_code
   285     else:
   286       self.terminated_by_signal = False
   287       self.exited = True
   288       self.exit_code = self._return_code
   291 def Main():
   292   """Runs the unit test."""
   294   # We must call _ParseAndStripGTestFlags() before calling
   295   # unittest.main().  Otherwise the latter will be confused by the
   296   # --gtest_* flags.
   297   _ParseAndStripGTestFlags(sys.argv)
   298   # The tested binaries should not be writing XML output files unless the
   299   # script explicitly instructs them to.
   300   # TODO(vladl@google.com): Move this into Subprocess when we implement
   301   # passing environment into it as a parameter.
   302   if GTEST_OUTPUT_VAR_NAME in os.environ:
   303     del os.environ[GTEST_OUTPUT_VAR_NAME]
   305   _test_module.main()

mercurial