Print full mesonlog on failed tests when run under CI.

pull/611/head
Jussi Pakkanen 9 years ago
parent ba4f26f8bf
commit 436eab9b85
  1. 17
      mesonbuild/compilers.py
  2. 2
      mesonbuild/mlog.py
  3. 35
      run_tests.py

@ -520,7 +520,7 @@ int main () {{ {1}; }}'''
commands.append(srcname)
commands += extra_args
mlog.debug('Running compile:')
mlog.debug('Command line: ', ' '.join(commands))
mlog.debug('Command line: ', ' '.join(commands), '\n')
mlog.debug('Code:\n', code)
p = subprocess.Popen(commands, cwd=os.path.split(srcname)[0], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stde, stdo) = p.communicate()
@ -593,7 +593,6 @@ int main () {{ {1}; }}'''
def run(self, code, env, extra_args=None):
if extra_args is None:
extra_args = []
mlog.debug('Running code:\n\n', code)
if self.is_cross and self.exe_wrapper is None:
raise CrossNoRunException('Can not run test applications in this cross environment.')
(fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix)
@ -612,12 +611,16 @@ int main () {{ {1}; }}'''
commands = self.get_exelist() + args
commands.append(srcname)
commands += self.get_output_args(exename)
mlog.debug('Running code:\n\n', code)
mlog.debug('Command line:', ' '.join(commands))
p = subprocess.Popen(commands, cwd=os.path.split(srcname)[0], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdo, stde) = p.communicate()
stde = stde.decode()
stdo = stdo.decode()
mlog.debug('Compiler stdout:\n', stdo)
mlog.debug('Compiler stderr:\n', stde)
mlog.debug('Compiler stdout:\n')
mlog.debug(stdo)
mlog.debug('Compiler stderr:\n')
mlog.debug(stde)
os.remove(srcname)
if p.returncode != 0:
return RunResult(False)
@ -634,8 +637,10 @@ int main () {{ {1}; }}'''
(so, se) = pe.communicate()
so = so.decode()
se = se.decode()
mlog.debug('Program stdout:\n', so)
mlog.debug('Program stderr:\n', se)
mlog.debug('Program stdout:\n')
mlog.debug(so)
mlog.debug('Program stderr:\n')
mlog.debug(se)
try:
os.remove(exename)
except PermissionError:

@ -71,11 +71,13 @@ def debug(*args, **kwargs):
arr = process_markup(args, False)
if log_file is not None:
print(*arr, file=log_file, **kwargs) # Log file never gets ANSI codes.
log_file.flush()
def log(*args, **kwargs):
arr = process_markup(args, False)
if log_file is not None:
print(*arr, file=log_file, **kwargs) # Log file never gets ANSI codes.
log_file.flush()
if colorize_console:
arr = process_markup(args, True)
print(*arr, **kwargs)

@ -34,21 +34,22 @@ import concurrent.futures as conc
from mesonbuild.coredata import backendlist
class TestResult:
def __init__(self, msg, stdo, stde, conftime=0, buildtime=0, testtime=0):
def __init__(self, msg, stdo, stde, mlog, conftime=0, buildtime=0, testtime=0):
self.msg = msg
self.stdo = stdo
self.stde = stde
self.mlog = mlog
self.conftime = conftime
self.buildtime = buildtime
self.testtime = testtime
class AutoDeletedDir():
def __init__(self, dir):
self.dir = dir
def __init__(self, d):
self.dir = d
def __enter__(self):
os.makedirs(self.dir, exist_ok=True)
return self.dir
def __exit__(self, type, value, traceback):
def __exit__(self, _type, value, traceback):
# On Windows, shutil.rmtree fails sometimes, because 'the directory is not empty'.
# Retrying fixes this.
# That's why we don't use tempfile.TemporaryDirectory, but wrap the deletion in the AutoDeletedDir class.
@ -65,6 +66,7 @@ class AutoDeletedDir():
passing_tests = 0
failing_tests = 0
skipped_tests = 0
failing_logs = []
print_debug = 'MESON_PRINT_TEST_OUTPUT' in os.environ
meson_command = os.path.join(os.getcwd(), 'meson')
@ -236,13 +238,18 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, flags, compile_c
gen_command = [meson_command, '--prefix', '/usr', '--libdir', 'lib', testdir, test_build_dir]\
+ flags + test_args + extra_args
(returncode, stdo, stde) = run_configure_inprocess(gen_command)
try:
logfile = os.path.join(test_build_dir, 'meson-logs/meson-log.txt')
mesonlog = open(logfile, errors='ignore').read()
except Exception:
mesonlog = 'No meson-log.txt found.'
gen_time = time.time() - gen_start
if not should_succeed:
if returncode != 0:
return TestResult('', stdo, stde, gen_time)
return TestResult('Test that should have failed succeeded', stdo, stde, gen_time)
return TestResult('', stdo, stde, mesonlog, gen_time)
return TestResult('Test that should have failed succeeded', stdo, stde, mesonlog, gen_time)
if returncode != 0:
return TestResult('Generating the build system failed.', stdo, stde, gen_time)
return TestResult('Generating the build system failed.', stdo, stde, mesonlog, gen_time)
if 'msbuild' in compile_commands[0]:
sln_name = glob(os.path.join(test_build_dir, '*.sln'))[0]
comp = compile_commands + [os.path.split(sln_name)[-1]]
@ -256,7 +263,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, flags, compile_c
stdo += o.decode(sys.stdout.encoding)
stde += e.decode(sys.stdout.encoding)
if pc.returncode != 0:
return TestResult('Compiling source code failed.', stdo, stde, gen_time, build_time)
return TestResult('Compiling source code failed.', stdo, stde, gen_time, mesonlog, build_time)
test_start = time.time()
# Note that we don't test that running e.g. 'ninja test' actually
# works. One hopes that this is a common enough happening that
@ -266,7 +273,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, flags, compile_c
stdo += tstdo
stde += tstde
if returncode != 0:
return TestResult('Running unit tests failed.', stdo, stde, gen_time, build_time, test_time)
return TestResult('Running unit tests failed.', stdo, stde, mesonlog, gen_time, build_time, test_time)
if len(install_commands) == 0:
return TestResult('', '', '', gen_time, build_time, test_time)
else:
@ -278,8 +285,8 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, flags, compile_c
stdo += o.decode(sys.stdout.encoding)
stde += e.decode(sys.stdout.encoding)
if pi.returncode != 0:
return TestResult('Running install failed.', stdo, stde, gen_time, build_time, test_time)
return TestResult(validate_install(testdir, install_dir), stdo, stde, gen_time, build_time, test_time)
return TestResult('Running install failed.', stdo, stde, mesonlog, gen_time, build_time, test_time)
return TestResult(validate_install(testdir, install_dir), stdo, stde, mesonlog, gen_time, build_time, test_time)
def gather_tests(testdir):
tests = [t.replace('\\', '/').split('/', 2)[2] for t in glob(os.path.join(testdir, '*'))]
@ -348,6 +355,7 @@ def run_tests(extra_args):
print('Failed test%s: %s' % (without_install, t))
print('Reason:', result.msg)
failing_tests += 1
failing_logs.append(result.mlog)
else:
print('Succeeded test%s: %s' % (without_install, t))
passing_tests += 1
@ -432,7 +440,8 @@ if __name__ == '__main__':
print('Total failed tests:', failing_tests)
print('Total skipped tests:', skipped_tests)
if failing_tests > 0 and ('TRAVIS' in os.environ or 'APPVEYOR' in os.environ):
# Cat because it can have stuff of unknown encodings mixed.
subprocess.call(['cat', 'meson-test-run.txt'])
print('\nMesonlogs of failing tests\n')
for l in failing_logs:
print(l, '\n')
sys.exit(failing_tests)

Loading…
Cancel
Save