diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2016-06-22 22:42:59 +0300 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2016-06-23 00:03:59 +0300 |
commit | 436eab9b85d78e36c66afa650059d0ebe5b156c5 (patch) | |
tree | fb16024c55339400d40052d87d171a7b089ed244 | |
parent | ba4f26f8bfa33885157585c5e71695ae05093e7e (diff) | |
download | meson-436eab9b85d78e36c66afa650059d0ebe5b156c5.zip meson-436eab9b85d78e36c66afa650059d0ebe5b156c5.tar.gz meson-436eab9b85d78e36c66afa650059d0ebe5b156c5.tar.bz2 |
Print full mesonlog on failed tests when run under CI.
-rw-r--r-- | mesonbuild/compilers.py | 17 | ||||
-rw-r--r-- | mesonbuild/mlog.py | 2 | ||||
-rwxr-xr-x | run_tests.py | 35 |
3 files changed, 35 insertions, 19 deletions
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index 610cfd1..884732f 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.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: diff --git a/mesonbuild/mlog.py b/mesonbuild/mlog.py index 2807c2b..dab51bd 100644 --- a/mesonbuild/mlog.py +++ b/mesonbuild/mlog.py @@ -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) diff --git a/run_tests.py b/run_tests.py index 5fdfce9..69e4d4e 100755 --- a/run_tests.py +++ b/run_tests.py @@ -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) |