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())