media/webrtc/trunk/tools/gyp/gyptest.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/webrtc/trunk/tools/gyp/gyptest.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,266 @@
     1.4 +#!/usr/bin/env python
     1.5 +
     1.6 +# Copyright (c) 2012 Google Inc. All rights reserved.
     1.7 +# Use of this source code is governed by a BSD-style license that can be
     1.8 +# found in the LICENSE file.
     1.9 +
    1.10 +__doc__ = """
    1.11 +gyptest.py -- test runner for GYP tests.
    1.12 +"""
    1.13 +
    1.14 +import os
    1.15 +import optparse
    1.16 +import subprocess
    1.17 +import sys
    1.18 +
    1.19 +class CommandRunner:
    1.20 +  """
    1.21 +  Executor class for commands, including "commands" implemented by
    1.22 +  Python functions.
    1.23 +  """
    1.24 +  verbose = True
    1.25 +  active = True
    1.26 +
    1.27 +  def __init__(self, dictionary={}):
    1.28 +    self.subst_dictionary(dictionary)
    1.29 +
    1.30 +  def subst_dictionary(self, dictionary):
    1.31 +    self._subst_dictionary = dictionary
    1.32 +
    1.33 +  def subst(self, string, dictionary=None):
    1.34 +    """
    1.35 +    Substitutes (via the format operator) the values in the specified
    1.36 +    dictionary into the specified command.
    1.37 +
    1.38 +    The command can be an (action, string) tuple.  In all cases, we
    1.39 +    perform substitution on strings and don't worry if something isn't
    1.40 +    a string.  (It's probably a Python function to be executed.)
    1.41 +    """
    1.42 +    if dictionary is None:
    1.43 +      dictionary = self._subst_dictionary
    1.44 +    if dictionary:
    1.45 +      try:
    1.46 +        string = string % dictionary
    1.47 +      except TypeError:
    1.48 +        pass
    1.49 +    return string
    1.50 +
    1.51 +  def display(self, command, stdout=None, stderr=None):
    1.52 +    if not self.verbose:
    1.53 +      return
    1.54 +    if type(command) == type(()):
    1.55 +      func = command[0]
    1.56 +      args = command[1:]
    1.57 +      s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args)))
    1.58 +    if type(command) == type([]):
    1.59 +      # TODO:  quote arguments containing spaces
    1.60 +      # TODO:  handle meta characters?
    1.61 +      s = ' '.join(command)
    1.62 +    else:
    1.63 +      s = self.subst(command)
    1.64 +    if not s.endswith('\n'):
    1.65 +      s += '\n'
    1.66 +    sys.stdout.write(s)
    1.67 +    sys.stdout.flush()
    1.68 +
    1.69 +  def execute(self, command, stdout=None, stderr=None):
    1.70 +    """
    1.71 +    Executes a single command.
    1.72 +    """
    1.73 +    if not self.active:
    1.74 +      return 0
    1.75 +    if type(command) == type(''):
    1.76 +      command = self.subst(command)
    1.77 +      cmdargs = shlex.split(command)
    1.78 +      if cmdargs[0] == 'cd':
    1.79 +         command = (os.chdir,) + tuple(cmdargs[1:])
    1.80 +    if type(command) == type(()):
    1.81 +      func = command[0]
    1.82 +      args = command[1:]
    1.83 +      return func(*args)
    1.84 +    else:
    1.85 +      if stdout is sys.stdout:
    1.86 +        # Same as passing sys.stdout, except python2.4 doesn't fail on it.
    1.87 +        subout = None
    1.88 +      else:
    1.89 +        # Open pipe for anything else so Popen works on python2.4.
    1.90 +        subout = subprocess.PIPE
    1.91 +      if stderr is sys.stderr:
    1.92 +        # Same as passing sys.stderr, except python2.4 doesn't fail on it.
    1.93 +        suberr = None
    1.94 +      elif stderr is None:
    1.95 +        # Merge with stdout if stderr isn't specified.
    1.96 +        suberr = subprocess.STDOUT
    1.97 +      else:
    1.98 +        # Open pipe for anything else so Popen works on python2.4.
    1.99 +        suberr = subprocess.PIPE
   1.100 +      p = subprocess.Popen(command,
   1.101 +                           shell=(sys.platform == 'win32'),
   1.102 +                           stdout=subout,
   1.103 +                           stderr=suberr)
   1.104 +      p.wait()
   1.105 +      if stdout is None:
   1.106 +        self.stdout = p.stdout.read()
   1.107 +      elif stdout is not sys.stdout:
   1.108 +        stdout.write(p.stdout.read())
   1.109 +      if stderr not in (None, sys.stderr):
   1.110 +        stderr.write(p.stderr.read())
   1.111 +      return p.returncode
   1.112 +
   1.113 +  def run(self, command, display=None, stdout=None, stderr=None):
   1.114 +    """
   1.115 +    Runs a single command, displaying it first.
   1.116 +    """
   1.117 +    if display is None:
   1.118 +      display = command
   1.119 +    self.display(display)
   1.120 +    return self.execute(command, stdout, stderr)
   1.121 +
   1.122 +
   1.123 +class Unbuffered:
   1.124 +  def __init__(self, fp):
   1.125 +    self.fp = fp
   1.126 +  def write(self, arg):
   1.127 +    self.fp.write(arg)
   1.128 +    self.fp.flush()
   1.129 +  def __getattr__(self, attr):
   1.130 +    return getattr(self.fp, attr)
   1.131 +
   1.132 +sys.stdout = Unbuffered(sys.stdout)
   1.133 +sys.stderr = Unbuffered(sys.stderr)
   1.134 +
   1.135 +
   1.136 +def find_all_gyptest_files(directory):
   1.137 +    result = []
   1.138 +    for root, dirs, files in os.walk(directory):
   1.139 +      if '.svn' in dirs:
   1.140 +        dirs.remove('.svn')
   1.141 +      result.extend([ os.path.join(root, f) for f in files
   1.142 +                     if f.startswith('gyptest') and f.endswith('.py') ])
   1.143 +    result.sort()
   1.144 +    return result
   1.145 +
   1.146 +
   1.147 +def main(argv=None):
   1.148 +  if argv is None:
   1.149 +    argv = sys.argv
   1.150 +
   1.151 +  usage = "gyptest.py [-ahlnq] [-f formats] [test ...]"
   1.152 +  parser = optparse.OptionParser(usage=usage)
   1.153 +  parser.add_option("-a", "--all", action="store_true",
   1.154 +            help="run all tests")
   1.155 +  parser.add_option("-C", "--chdir", action="store", default=None,
   1.156 +            help="chdir to the specified directory")
   1.157 +  parser.add_option("-f", "--format", action="store", default='',
   1.158 +            help="run tests with the specified formats")
   1.159 +  parser.add_option("-G", '--gyp_option', action="append", default=[],
   1.160 +            help="Add -G options to the gyp command line")
   1.161 +  parser.add_option("-l", "--list", action="store_true",
   1.162 +            help="list available tests and exit")
   1.163 +  parser.add_option("-n", "--no-exec", action="store_true",
   1.164 +            help="no execute, just print the command line")
   1.165 +  parser.add_option("--passed", action="store_true",
   1.166 +            help="report passed tests")
   1.167 +  parser.add_option("--path", action="append", default=[],
   1.168 +            help="additional $PATH directory")
   1.169 +  parser.add_option("-q", "--quiet", action="store_true",
   1.170 +            help="quiet, don't print test command lines")
   1.171 +  opts, args = parser.parse_args(argv[1:])
   1.172 +
   1.173 +  if opts.chdir:
   1.174 +    os.chdir(opts.chdir)
   1.175 +
   1.176 +  if opts.path:
   1.177 +    extra_path = [os.path.abspath(p) for p in opts.path]
   1.178 +    extra_path = os.pathsep.join(extra_path)
   1.179 +    os.environ['PATH'] += os.pathsep + extra_path
   1.180 +
   1.181 +  if not args:
   1.182 +    if not opts.all:
   1.183 +      sys.stderr.write('Specify -a to get all tests.\n')
   1.184 +      return 1
   1.185 +    args = ['test']
   1.186 +
   1.187 +  tests = []
   1.188 +  for arg in args:
   1.189 +    if os.path.isdir(arg):
   1.190 +      tests.extend(find_all_gyptest_files(os.path.normpath(arg)))
   1.191 +    else:
   1.192 +      tests.append(arg)
   1.193 +
   1.194 +  if opts.list:
   1.195 +    for test in tests:
   1.196 +      print test
   1.197 +    sys.exit(0)
   1.198 +
   1.199 +  CommandRunner.verbose = not opts.quiet
   1.200 +  CommandRunner.active = not opts.no_exec
   1.201 +  cr = CommandRunner()
   1.202 +
   1.203 +  os.environ['PYTHONPATH'] = os.path.abspath('test/lib')
   1.204 +  if not opts.quiet:
   1.205 +    sys.stdout.write('PYTHONPATH=%s\n' % os.environ['PYTHONPATH'])
   1.206 +
   1.207 +  passed = []
   1.208 +  failed = []
   1.209 +  no_result = []
   1.210 +
   1.211 +  if opts.format:
   1.212 +    format_list = opts.format.split(',')
   1.213 +  else:
   1.214 +    # TODO:  not duplicate this mapping from pylib/gyp/__init__.py
   1.215 +    format_list = {
   1.216 +      'freebsd7': ['make'],
   1.217 +      'freebsd8': ['make'],
   1.218 +      'cygwin':   ['msvs'],
   1.219 +      'win32':    ['msvs', 'ninja'],
   1.220 +      'linux2':   ['make', 'ninja'],
   1.221 +      'linux3':   ['make', 'ninja'],
   1.222 +      'darwin':   ['make', 'ninja', 'xcode'],
   1.223 +    }[sys.platform]
   1.224 +
   1.225 +  for format in format_list:
   1.226 +    os.environ['TESTGYP_FORMAT'] = format
   1.227 +    if not opts.quiet:
   1.228 +      sys.stdout.write('TESTGYP_FORMAT=%s\n' % format)
   1.229 +
   1.230 +    gyp_options = []
   1.231 +    for option in opts.gyp_option:
   1.232 +      gyp_options += ['-G', option]
   1.233 +    if gyp_options and not opts.quiet:
   1.234 +      sys.stdout.write('Extra Gyp options: %s\n' % gyp_options)
   1.235 +
   1.236 +    for test in tests:
   1.237 +      status = cr.run([sys.executable, test] + gyp_options,
   1.238 +                      stdout=sys.stdout,
   1.239 +                      stderr=sys.stderr)
   1.240 +      if status == 2:
   1.241 +        no_result.append(test)
   1.242 +      elif status:
   1.243 +        failed.append(test)
   1.244 +      else:
   1.245 +        passed.append(test)
   1.246 +
   1.247 +  if not opts.quiet:
   1.248 +    def report(description, tests):
   1.249 +      if tests:
   1.250 +        if len(tests) == 1:
   1.251 +          sys.stdout.write("\n%s the following test:\n" % description)
   1.252 +        else:
   1.253 +          fmt = "\n%s the following %d tests:\n"
   1.254 +          sys.stdout.write(fmt % (description, len(tests)))
   1.255 +        sys.stdout.write("\t" + "\n\t".join(tests) + "\n")
   1.256 +
   1.257 +    if opts.passed:
   1.258 +      report("Passed", passed)
   1.259 +    report("Failed", failed)
   1.260 +    report("No result from", no_result)
   1.261 +
   1.262 +  if failed:
   1.263 +    return 1
   1.264 +  else:
   1.265 +    return 0
   1.266 +
   1.267 +
   1.268 +if __name__ == "__main__":
   1.269 +  sys.exit(main())

mercurial