Replace the bundled GYP build system with a newer upstream version that adds z/OS platform support, improves MSVC SDK version detection with compatible SDK fallback, fixes host LDFLAGS handling in ninja generator, and includes various bug fixes and maintainer updates across multiple generator backends.
244 lines
6.8 KiB
Python
Executable File
244 lines
6.8 KiB
Python
Executable File
#!/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 opts.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())
|