diff options
Diffstat (limited to 'third_party/python/gyp/gyptest.py')
-rwxr-xr-x | third_party/python/gyp/gyptest.py | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/third_party/python/gyp/gyptest.py b/third_party/python/gyp/gyptest.py new file mode 100755 index 0000000000..1a9ffca7a1 --- /dev/null +++ b/third_party/python/gyp/gyptest.py @@ -0,0 +1,243 @@ +#!/usr/bin/env python +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""gyptest.py -- test runner for GYP tests.""" + +from __future__ import print_function + +import argparse +import math +import os +import platform +import subprocess +import sys +import time + + +def is_test_name(f): + return f.startswith('gyptest') and f.endswith('.py') + + +def find_all_gyptest_files(directory): + result = [] + for root, dirs, files in os.walk(directory): + result.extend([ os.path.join(root, f) for f in files if is_test_name(f) ]) + result.sort() + return result + + +def main(argv=None): + if argv is None: + argv = sys.argv + + parser = argparse.ArgumentParser() + parser.add_argument("-a", "--all", action="store_true", + help="run all tests") + parser.add_argument("-C", "--chdir", action="store", + help="change to directory") + parser.add_argument("-f", "--format", action="store", default='', + help="run tests with the specified formats") + parser.add_argument("-G", '--gyp_option', action="append", default=[], + help="Add -G options to the gyp command line") + parser.add_argument("-l", "--list", action="store_true", + help="list available tests and exit") + parser.add_argument("-n", "--no-exec", action="store_true", + help="no execute, just print the command line") + parser.add_argument("--path", action="append", default=[], + help="additional $PATH directory") + parser.add_argument("-q", "--quiet", action="store_true", + help="quiet, don't print anything unless there are failures") + parser.add_argument("-v", "--verbose", action="store_true", + help="print configuration info and test results.") + parser.add_argument('tests', nargs='*') + args = parser.parse_args(argv[1:]) + + if args.chdir: + os.chdir(args.chdir) + + if args.path: + extra_path = [os.path.abspath(p) for p in args.path] + extra_path = os.pathsep.join(extra_path) + os.environ['PATH'] = extra_path + os.pathsep + os.environ['PATH'] + + if not args.tests: + if not args.all: + sys.stderr.write('Specify -a to get all tests.\n') + return 1 + args.tests = ['test'] + + tests = [] + for arg in args.tests: + if os.path.isdir(arg): + tests.extend(find_all_gyptest_files(os.path.normpath(arg))) + else: + if not is_test_name(os.path.basename(arg)): + print(arg, 'is not a valid gyp test name.', file=sys.stderr) + sys.exit(1) + tests.append(arg) + + if args.list: + for test in tests: + print(test) + sys.exit(0) + + os.environ['PYTHONPATH'] = os.path.abspath('test/lib') + + if args.verbose: + print_configuration_info() + + if args.gyp_option and not args.quiet: + print('Extra Gyp options: %s\n' % args.gyp_option) + + if args.format: + format_list = args.format.split(',') + else: + format_list = { + 'aix5': ['make'], + 'freebsd7': ['make'], + 'freebsd8': ['make'], + 'openbsd5': ['make'], + 'cygwin': ['msvs'], + 'win32': ['msvs', 'ninja'], + 'linux': ['make', 'ninja'], + 'linux2': ['make', 'ninja'], + 'linux3': ['make', 'ninja'], + + # TODO: Re-enable xcode-ninja. + # https://bugs.chromium.org/p/gyp/issues/detail?id=530 + # 'darwin': ['make', 'ninja', 'xcode', 'xcode-ninja'], + 'darwin': ['make', 'ninja', 'xcode'], + }[sys.platform] + + gyp_options = [] + for option in args.gyp_option: + gyp_options += ['-G', option] + + runner = Runner(format_list, tests, gyp_options, args.verbose) + runner.run() + + if not args.quiet: + runner.print_results() + + if runner.failures: + return 1 + else: + return 0 + + +def print_configuration_info(): + print('Test configuration:') + if sys.platform == 'darwin': + sys.path.append(os.path.abspath('test/lib')) + import TestMac + print(' Mac %s %s' % (platform.mac_ver()[0], platform.mac_ver()[2])) + print(' Xcode %s' % TestMac.Xcode.Version()) + elif sys.platform == 'win32': + sys.path.append(os.path.abspath('pylib')) + import gyp.MSVSVersion + print(' Win %s %s\n' % platform.win32_ver()[0:2]) + print(' MSVS %s' % + gyp.MSVSVersion.SelectVisualStudioVersion().Description()) + elif sys.platform in ('linux', 'linux2'): + print(' Linux %s' % ' '.join(platform.linux_distribution())) + print(' Python %s' % platform.python_version()) + print(' PYTHONPATH=%s' % os.environ['PYTHONPATH']) + print() + + +class Runner(object): + def __init__(self, formats, tests, gyp_options, verbose): + self.formats = formats + self.tests = tests + self.verbose = verbose + self.gyp_options = gyp_options + self.failures = [] + self.num_tests = len(formats) * len(tests) + num_digits = len(str(self.num_tests)) + self.fmt_str = '[%%%dd/%%%dd] (%%s) %%s' % (num_digits, num_digits) + self.isatty = sys.stdout.isatty() and not self.verbose + self.env = os.environ.copy() + self.hpos = 0 + + def run(self): + run_start = time.time() + + i = 1 + for fmt in self.formats: + for test in self.tests: + self.run_test(test, fmt, i) + i += 1 + + if self.isatty: + self.erase_current_line() + + self.took = time.time() - run_start + + def run_test(self, test, fmt, i): + if self.isatty: + self.erase_current_line() + + msg = self.fmt_str % (i, self.num_tests, fmt, test) + self.print_(msg) + + start = time.time() + cmd = [sys.executable, test] + self.gyp_options + self.env['TESTGYP_FORMAT'] = fmt + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, env=self.env) + proc.wait() + took = time.time() - start + + stdout = proc.stdout.read().decode('utf8') + if proc.returncode == 2: + res = 'skipped' + elif proc.returncode: + res = 'failed' + self.failures.append('(%s) %s' % (test, fmt)) + else: + res = 'passed' + res_msg = ' %s %.3fs' % (res, took) + self.print_(res_msg) + + if (stdout and + not stdout.endswith('PASSED\n') and + not (stdout.endswith('NO RESULT\n'))): + print() + for l in stdout.splitlines(): + print(' %s' % l) + elif not self.isatty: + print() + + def print_(self, msg): + print(msg, end='') + index = msg.rfind('\n') + if index == -1: + self.hpos += len(msg) + else: + self.hpos = len(msg) - index + sys.stdout.flush() + + def erase_current_line(self): + print('\b' * self.hpos + ' ' * self.hpos + '\b' * self.hpos, end='') + sys.stdout.flush() + self.hpos = 0 + + def print_results(self): + num_failures = len(self.failures) + if num_failures: + print() + if num_failures == 1: + print("Failed the following test:") + else: + print("Failed the following %d tests:" % num_failures) + print("\t" + "\n\t".join(sorted(self.failures))) + print() + print('Ran %d tests in %.3fs, %d failed.' % (self.num_tests, self.took, + num_failures)) + print() + + +if __name__ == "__main__": + sys.exit(main()) |