Add option to fail fast in tests

pull/3424/head
Niklas Claesson 7 years ago
parent 4ef4edee2f
commit 4911a51aa2
  1. 8
      run_cross_test.py
  2. 23
      run_project_tests.py
  3. 15
      run_tests.py

@ -30,10 +30,11 @@ import argparse
from run_project_tests import gather_tests, run_tests, StopException, setup_commands from run_project_tests import gather_tests, run_tests, StopException, setup_commands
from run_project_tests import failing_logs from run_project_tests import failing_logs
def runtests(cross_file): def runtests(cross_file, failfast):
commontests = [('common', gather_tests(Path('test cases', 'common')), False)] commontests = [('common', gather_tests(Path('test cases', 'common')), False)]
try: try:
(passing_tests, failing_tests, skipped_tests) = run_tests(commontests, 'meson-cross-test-run', ['--cross', cross_file]) (passing_tests, failing_tests, skipped_tests) = \
run_tests(commontests, 'meson-cross-test-run', failfast, ['--cross', cross_file])
except StopException: except StopException:
pass pass
print('\nTotal passed cross tests:', passing_tests) print('\nTotal passed cross tests:', passing_tests)
@ -47,10 +48,11 @@ def runtests(cross_file):
def main(): def main():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--failfast', action='store_true')
parser.add_argument('cross_file') parser.add_argument('cross_file')
options = parser.parse_args() options = parser.parse_args()
setup_commands('ninja') setup_commands('ninja')
return runtests(options.cross_file) return runtests(options.cross_file, options.failfast)
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())

@ -36,7 +36,7 @@ import argparse
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import time import time
import multiprocessing import multiprocessing
from concurrent.futures import ProcessPoolExecutor from concurrent.futures import ProcessPoolExecutor, CancelledError
import re import re
from run_tests import get_fake_options, run_configure, get_meson_script from run_tests import get_fake_options, run_configure, get_meson_script
from run_tests import get_backend_commands, get_backend_args_for_dir, Backend from run_tests import get_backend_commands, get_backend_args_for_dir, Backend
@ -523,14 +523,14 @@ def detect_tests_to_run():
gathered_tests = [(name, gather_tests(Path('test cases', subdir)), skip) for name, subdir, skip in all_tests] gathered_tests = [(name, gather_tests(Path('test cases', subdir)), skip) for name, subdir, skip in all_tests]
return gathered_tests return gathered_tests
def run_tests(all_tests, log_name_base, extra_args): def run_tests(all_tests, log_name_base, failfast, extra_args):
global logfile global logfile
txtname = log_name_base + '.txt' txtname = log_name_base + '.txt'
with open(txtname, 'w', encoding='utf-8', errors='ignore') as lf: with open(txtname, 'w', encoding='utf-8', errors='ignore') as lf:
logfile = lf logfile = lf
return _run_tests(all_tests, log_name_base, extra_args) return _run_tests(all_tests, log_name_base, failfast, extra_args)
def _run_tests(all_tests, log_name_base, extra_args): def _run_tests(all_tests, log_name_base, failfast, extra_args):
global stop, executor, futures, system_compiler global stop, executor, futures, system_compiler
xmlname = log_name_base + '.xml' xmlname = log_name_base + '.xml'
junit_root = ET.Element('testsuites') junit_root = ET.Element('testsuites')
@ -578,7 +578,10 @@ def _run_tests(all_tests, log_name_base, extra_args):
futures.append((testname, t, result)) futures.append((testname, t, result))
for (testname, t, result) in futures: for (testname, t, result) in futures:
sys.stdout.flush() sys.stdout.flush()
try:
result = result.result() result = result.result()
except CancelledError:
continue
if (result is None) or (('MESON_SKIP_TEST' in result.stdo) and (skippable(name, t.as_posix()))): if (result is None) or (('MESON_SKIP_TEST' in result.stdo) and (skippable(name, t.as_posix()))):
print(yellow('Skipping:'), t.as_posix()) print(yellow('Skipping:'), t.as_posix())
current_test = ET.SubElement(current_suite, 'testcase', {'name': testname, current_test = ET.SubElement(current_suite, 'testcase', {'name': testname,
@ -599,6 +602,10 @@ def _run_tests(all_tests, log_name_base, extra_args):
else: else:
failing_logs.append(result.stdo) failing_logs.append(result.stdo)
failing_logs.append(result.stde) failing_logs.append(result.stde)
if failfast:
print("Cancelling the rest of the tests")
for (_, _, res) in futures:
res.cancel()
else: else:
print('Succeeded test%s: %s' % (without_install, t.as_posix())) print('Succeeded test%s: %s' % (without_install, t.as_posix()))
passing_tests += 1 passing_tests += 1
@ -616,6 +623,10 @@ def _run_tests(all_tests, log_name_base, extra_args):
stdoel.text = result.stdo stdoel.text = result.stdo
stdeel = ET.SubElement(current_test, 'system-err') stdeel = ET.SubElement(current_test, 'system-err')
stdeel.text = result.stde stdeel.text = result.stde
if failfast and failing_tests > 0:
break
print("\nTotal configuration time: %.2fs" % conf_time) print("\nTotal configuration time: %.2fs" % conf_time)
print("Total build time: %.2fs" % build_time) print("Total build time: %.2fs" % build_time)
print("Total test time: %.2fs" % test_time) print("Total test time: %.2fs" % test_time)
@ -709,6 +720,8 @@ if __name__ == '__main__':
help='arguments that are passed directly to Meson (remember to have -- before these).') help='arguments that are passed directly to Meson (remember to have -- before these).')
parser.add_argument('--backend', default=None, dest='backend', parser.add_argument('--backend', default=None, dest='backend',
choices=backendlist) choices=backendlist)
parser.add_argument('--failfast', action='store_true',
help='Stop running if test case fails')
options = parser.parse_args() options = parser.parse_args()
setup_commands(options.backend) setup_commands(options.backend)
@ -720,7 +733,7 @@ if __name__ == '__main__':
check_meson_commands_work() check_meson_commands_work()
try: try:
all_tests = detect_tests_to_run() all_tests = detect_tests_to_run()
(passing_tests, failing_tests, skipped_tests) = run_tests(all_tests, 'meson-test-run', options.extra_args) (passing_tests, failing_tests, skipped_tests) = run_tests(all_tests, 'meson-test-run', options.failfast, options.extra_args)
except StopException: except StopException:
pass pass
print('\nTotal passed tests:', green(str(passing_tests))) print('\nTotal passed tests:', green(str(passing_tests)))

@ -226,6 +226,7 @@ def main():
parser.add_argument('--backend', default=None, dest='backend', parser.add_argument('--backend', default=None, dest='backend',
choices=backendlist) choices=backendlist)
parser.add_argument('--cross', default=False, dest='cross', action='store_true') parser.add_argument('--cross', default=False, dest='cross', action='store_true')
parser.add_argument('--failfast', action='store_true')
(options, _) = parser.parse_known_args() (options, _) = parser.parse_known_args()
# Enable coverage early... # Enable coverage early...
enable_coverage = options.cov enable_coverage = options.cov
@ -286,9 +287,17 @@ def main():
env['PYTHONPATH'] = os.pathsep.join([temp_dir] + env.get('PYTHONPATH', [])) env['PYTHONPATH'] = os.pathsep.join([temp_dir] + env.get('PYTHONPATH', []))
if not cross: if not cross:
cmd = mesonlib.python_command + ['run_meson_command_tests.py', '-v'] cmd = mesonlib.python_command + ['run_meson_command_tests.py', '-v']
if options.failfast:
cmd += ['--failfast']
returncode += subprocess.call(cmd, env=env) returncode += subprocess.call(cmd, env=env)
if options.failfast and returncode != 0:
return returncode
cmd = mesonlib.python_command + ['run_unittests.py', '-v'] cmd = mesonlib.python_command + ['run_unittests.py', '-v']
if options.failfast:
cmd += ['--failfast']
returncode += subprocess.call(cmd, env=env) returncode += subprocess.call(cmd, env=env)
if options.failfast and returncode != 0:
return returncode
cmd = mesonlib.python_command + ['run_project_tests.py'] + sys.argv[1:] cmd = mesonlib.python_command + ['run_project_tests.py'] + sys.argv[1:]
returncode += subprocess.call(cmd, env=env) returncode += subprocess.call(cmd, env=env)
else: else:
@ -296,11 +305,17 @@ def main():
print(mlog.bold('Running armhf cross tests.').get_text(mlog.colorize_console)) print(mlog.bold('Running armhf cross tests.').get_text(mlog.colorize_console))
print() print()
cmd = cross_test_args + ['cross/ubuntu-armhf.txt'] cmd = cross_test_args + ['cross/ubuntu-armhf.txt']
if options.failfast:
cmd += ['--failfast']
returncode += subprocess.call(cmd, env=env) returncode += subprocess.call(cmd, env=env)
if options.failfast and returncode != 0:
return returncode
print(mlog.bold('Running mingw-w64 64-bit cross tests.') print(mlog.bold('Running mingw-w64 64-bit cross tests.')
.get_text(mlog.colorize_console)) .get_text(mlog.colorize_console))
print() print()
cmd = cross_test_args + ['cross/linux-mingw-w64-64bit.txt'] cmd = cross_test_args + ['cross/linux-mingw-w64-64bit.txt']
if options.failfast:
cmd += ['--failfast']
returncode += subprocess.call(cmd, env=env) returncode += subprocess.call(cmd, env=env)
return returncode return returncode

Loading…
Cancel
Save