| OLD | NEW |
| (Empty) | |
| 1 #!/usr/bin/env python |
| 2 # |
| 3 # XXX Python script template |
| 4 # |
| 5 # XXX Describe what the script does here. |
| 6 # |
| 7 |
| 8 import os |
| 9 import optparse |
| 10 import subprocess |
| 11 import sys |
| 12 |
| 13 class CommandRunner: |
| 14 """ |
| 15 Executor class for commands, including "commands" implemented by |
| 16 Python functions. |
| 17 """ |
| 18 verbose = True |
| 19 active = True |
| 20 |
| 21 def __init__(self, dictionary={}): |
| 22 self.subst_dictionary(dictionary) |
| 23 |
| 24 def subst_dictionary(self, dictionary): |
| 25 self._subst_dictionary = dictionary |
| 26 |
| 27 def subst(self, string, dictionary=None): |
| 28 """ |
| 29 Substitutes (via the format operator) the values in the specified |
| 30 dictionary into the specified command. |
| 31 |
| 32 The command can be an (action, string) tuple. In all cases, we |
| 33 perform substitution on strings and don't worry if something isn't |
| 34 a string. (It's probably a Python function to be executed.) |
| 35 """ |
| 36 if dictionary is None: |
| 37 dictionary = self._subst_dictionary |
| 38 if dictionary: |
| 39 try: |
| 40 string = string % dictionary |
| 41 except TypeError: |
| 42 pass |
| 43 return string |
| 44 |
| 45 def display(self, command, stdout=None, stderr=None): |
| 46 if not self.verbose: |
| 47 return |
| 48 if type(command) == type(()): |
| 49 func = command[0] |
| 50 args = command[1:] |
| 51 s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args))) |
| 52 if type(command) == type([]): |
| 53 # TODO: quote arguments containing spaces |
| 54 # TODO: handle meta characters? |
| 55 s = ' '.join(command) |
| 56 else: |
| 57 s = self.subst(command) |
| 58 if not s.endswith('\n'): |
| 59 s += '\n' |
| 60 sys.stdout.write(s) |
| 61 sys.stdout.flush() |
| 62 |
| 63 def execute(self, command, stdout=None, stderr=None): |
| 64 """ |
| 65 Executes a single command. |
| 66 """ |
| 67 if not self.active: |
| 68 return 0 |
| 69 if type(command) == type(''): |
| 70 command = self.subst(command) |
| 71 cmdargs = shlex.split(command) |
| 72 if cmdargs[0] == 'cd': |
| 73 command = (os.chdir,) + tuple(cmdargs[1:]) |
| 74 if type(command) == type(()): |
| 75 func = command[0] |
| 76 args = command[1:] |
| 77 return func(*args) |
| 78 else: |
| 79 if stdout is None: |
| 80 stdout = subprocess.PIPE |
| 81 if stderr is None: |
| 82 stderr = subprocess.STDOUT |
| 83 p = subprocess.Popen(command, |
| 84 shell=(sys.platform == 'win32'), |
| 85 stdout=stdout, |
| 86 stderr=stderr) |
| 87 p.wait() |
| 88 if p.stdout: |
| 89 self.stdout = p.stdout.read() |
| 90 return p.returncode |
| 91 |
| 92 def run(self, command, display=None, stdout=None, stderr=None): |
| 93 """ |
| 94 Runs a single command, displaying it first. |
| 95 """ |
| 96 if display is None: |
| 97 display = command |
| 98 self.display(display) |
| 99 return self.execute(command, stdout, stderr) |
| 100 |
| 101 |
| 102 class Unbuffered: |
| 103 def __init__(self, fp): |
| 104 self.fp = fp |
| 105 def write(self, arg): |
| 106 self.fp.write(arg) |
| 107 self.fp.flush() |
| 108 def __getattr__(self, attr): |
| 109 return getattr(self.fp, attr) |
| 110 |
| 111 sys.stdout = Unbuffered(sys.stdout) |
| 112 sys.stderr = Unbuffered(sys.stderr) |
| 113 |
| 114 |
| 115 def find_all_gyptest_files(directory): |
| 116 result = [] |
| 117 for root, dirs, files in os.walk('test'): |
| 118 if '.svn' in dirs: |
| 119 dirs.remove('.svn') |
| 120 result.extend([ root + '/' + f for f in files |
| 121 if f.startswith('gyptest') ]) |
| 122 result.sort() |
| 123 return result |
| 124 |
| 125 |
| 126 def main(argv=None): |
| 127 if argv is None: |
| 128 argv = sys.argv |
| 129 |
| 130 usage = "gyptest.py [-ahlnq] [-f formats] [test ...]" |
| 131 parser = optparse.OptionParser(usage=usage) |
| 132 parser.add_option("-a", "--all", action="store_true", |
| 133 help="run all tests") |
| 134 parser.add_option("-f", "--format", action="store", default='', |
| 135 help="run tests with the specified formats") |
| 136 parser.add_option("-l", "--list", action="store_true", |
| 137 help="list available tests and exit") |
| 138 parser.add_option("-n", "--no-exec", action="store_true", |
| 139 help="no execute, just print the command line") |
| 140 parser.add_option("--passed", action="store_true", |
| 141 help="report passed tests") |
| 142 parser.add_option("-q", "--quiet", action="store_true", |
| 143 help="quiet, don't print test command lines") |
| 144 opts, args = parser.parse_args(argv[1:]) |
| 145 |
| 146 if not args: |
| 147 if not opts.all: |
| 148 sys.stderr.write('Specify -a to get all tests.\n') |
| 149 return 1 |
| 150 |
| 151 args = find_all_gyptest_files('test') |
| 152 |
| 153 if opts.list: |
| 154 for test in args: |
| 155 print test |
| 156 sys.exit(0) |
| 157 |
| 158 CommandRunner.verbose = not opts.quiet |
| 159 CommandRunner.active = not opts.no_exec |
| 160 cr = CommandRunner() |
| 161 |
| 162 os.environ['PYTHONPATH'] = os.path.abspath('test/lib') |
| 163 if not opts.quiet: |
| 164 sys.stdout.write('PYTHONPATH=%s\n' % os.environ['PYTHONPATH']) |
| 165 |
| 166 passed = [] |
| 167 failed = [] |
| 168 |
| 169 if opts.format: |
| 170 format_list = opts.format.split(',') |
| 171 else: |
| 172 # TODO: not duplicate this mapping from pylib/gyp/__init__.py |
| 173 format_list = [ { |
| 174 'freebsd7': 'make', |
| 175 'freebsd8': 'make', |
| 176 'cygwin': 'msvs', |
| 177 'win32': 'msvs', |
| 178 'linux2': 'scons', |
| 179 'darwin': 'xcode', |
| 180 }[sys.platform] ] |
| 181 |
| 182 for format in format_list: |
| 183 os.environ['TESTGYP_FORMAT'] = format |
| 184 if not opts.quiet: |
| 185 sys.stdout.write('TESTGYP_FORMAT=%s\n' % format) |
| 186 |
| 187 for test in args: |
| 188 status = cr.run([sys.executable, test], |
| 189 stdout=sys.stdout, |
| 190 stderr=sys.stderr) |
| 191 if status: |
| 192 failed.append(test) |
| 193 else: |
| 194 passed.append(test) |
| 195 |
| 196 if not opts.quiet: |
| 197 def report(description, tests): |
| 198 if tests: |
| 199 if len(tests) == 1: |
| 200 sys.stdout.write("\n%s the following test:\n" % description) |
| 201 else: |
| 202 fmt = "\n%s the following %d tests:\n" |
| 203 sys.stdout.write(fmt % (description, len(tests))) |
| 204 sys.stdout.write("\t" + "\n\t".join(tests) + "\n") |
| 205 |
| 206 if opts.passed: |
| 207 report("Passed", passed) |
| 208 report("Failed", failed) |
| 209 |
| 210 if failed: |
| 211 return 1 |
| 212 else: |
| 213 return 0 |
| 214 |
| 215 |
| 216 if __name__ == "__main__": |
| 217 sys.exit(main()) |
| OLD | NEW |