|
|
|
@ -14,14 +14,22 @@ |
|
|
|
|
# See the License for the specific language governing permissions and |
|
|
|
|
# limitations under the License. |
|
|
|
|
|
|
|
|
|
from glob import glob |
|
|
|
|
import itertools |
|
|
|
|
import os, subprocess, shutil, sys, signal |
|
|
|
|
import os |
|
|
|
|
import subprocess |
|
|
|
|
import shutil |
|
|
|
|
import sys |
|
|
|
|
import signal |
|
|
|
|
from io import StringIO |
|
|
|
|
from ast import literal_eval |
|
|
|
|
from enum import Enum |
|
|
|
|
import tempfile |
|
|
|
|
from mesonbuild import build, environment, mesonlib, mlog, mtest |
|
|
|
|
from pathlib import Path, PurePath |
|
|
|
|
from mesonbuild import build |
|
|
|
|
from mesonbuild import environment |
|
|
|
|
from mesonbuild import mesonlib |
|
|
|
|
from mesonbuild import mlog |
|
|
|
|
from mesonbuild import mtest |
|
|
|
|
from mesonbuild.mesonlib import stringlistify, Popen_safe |
|
|
|
|
from mesonbuild.coredata import backendlist |
|
|
|
|
import argparse |
|
|
|
@ -198,7 +206,7 @@ def validate_install(srcdir, installdir, compiler, env): |
|
|
|
|
|
|
|
|
|
def log_text_file(logfile, testdir, stdo, stde): |
|
|
|
|
global stop, executor, futures |
|
|
|
|
logfile.write('%s\nstdout\n\n---\n' % testdir) |
|
|
|
|
logfile.write('%s\nstdout\n\n---\n' % testdir.as_posix()) |
|
|
|
|
logfile.write(stdo) |
|
|
|
|
logfile.write('\n\n---\n\nstderr\n\n---\n') |
|
|
|
|
logfile.write(stde) |
|
|
|
@ -245,11 +253,11 @@ def run_test_inprocess(testdir): |
|
|
|
|
sys.stderr = mystderr = StringIO() |
|
|
|
|
old_cwd = os.getcwd() |
|
|
|
|
os.chdir(testdir) |
|
|
|
|
test_log_fname = 'meson-logs/testlog.txt' |
|
|
|
|
test_log_fname = Path('meson-logs', 'testlog.txt') |
|
|
|
|
try: |
|
|
|
|
returncode_test = mtest.run(['--no-rebuild']) |
|
|
|
|
if os.path.exists(test_log_fname): |
|
|
|
|
test_log = open(test_log_fname, errors='ignore').read() |
|
|
|
|
if test_log_fname.exists(): |
|
|
|
|
test_log = test_log_fname.open(errors='ignore').read() |
|
|
|
|
else: |
|
|
|
|
test_log = '' |
|
|
|
|
returncode_benchmark = mtest.run(['--no-rebuild', '--benchmark', '--logbase', 'benchmarklog']) |
|
|
|
@ -318,9 +326,8 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen |
|
|
|
|
gen_args += [testdir, test_build_dir] + flags + test_args + extra_args |
|
|
|
|
(returncode, stdo, stde) = run_configure(meson_command, gen_args) |
|
|
|
|
try: |
|
|
|
|
logfile = os.path.join(test_build_dir, 'meson-logs/meson-log.txt') |
|
|
|
|
with open(logfile, encoding='utf-8', errors='ignore') as f: |
|
|
|
|
mesonlog = f.read() |
|
|
|
|
logfile = Path(test_build_dir, 'meson-logs', 'meson-log.txt') |
|
|
|
|
mesonlog = logfile.open(errors='ignore', encoding='utf-8').read() |
|
|
|
|
except Exception: |
|
|
|
|
mesonlog = no_meson_log_msg |
|
|
|
|
gen_time = time.time() - gen_start |
|
|
|
@ -390,11 +397,11 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen |
|
|
|
|
return TestResult(validate_install(testdir, install_dir, compiler, builddata.environment), |
|
|
|
|
BuildStep.validate, stdo, stde, mesonlog, gen_time, build_time, test_time) |
|
|
|
|
|
|
|
|
|
def gather_tests(testdir): |
|
|
|
|
tests = [t.replace('\\', '/').split('/', 2)[2] for t in glob(testdir + '/*')] |
|
|
|
|
def gather_tests(testdir: Path): |
|
|
|
|
tests = [t.name for t in testdir.glob('*')] |
|
|
|
|
testlist = [(int(t.split()[0]), t) for t in tests] |
|
|
|
|
testlist.sort() |
|
|
|
|
tests = [os.path.join(testdir, t[1]) for t in testlist] |
|
|
|
|
tests = [testdir / t[1] for t in testlist] |
|
|
|
|
return tests |
|
|
|
|
|
|
|
|
|
def have_d_compiler(): |
|
|
|
@ -517,7 +524,7 @@ def detect_tests_to_run(): |
|
|
|
|
('fpga', 'fpga', shutil.which('yosys') is None), |
|
|
|
|
('frameworks', 'frameworks', False), |
|
|
|
|
] |
|
|
|
|
gathered_tests = [(name, gather_tests('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 |
|
|
|
|
|
|
|
|
|
def run_tests(all_tests, log_name_base, extra_args): |
|
|
|
@ -566,18 +573,18 @@ def _run_tests(all_tests, log_name_base, extra_args): |
|
|
|
|
for t in test_cases: |
|
|
|
|
# Jenkins screws us over by automatically sorting test cases by name |
|
|
|
|
# and getting it wrong by not doing logical number sorting. |
|
|
|
|
(testnum, testbase) = os.path.split(t)[-1].split(' ', 1) |
|
|
|
|
(testnum, testbase) = t.name.split(' ', 1) |
|
|
|
|
testname = '%.3d %s' % (int(testnum), testbase) |
|
|
|
|
should_fail = False |
|
|
|
|
if name.startswith('failing'): |
|
|
|
|
should_fail = name.split('failing-')[1] |
|
|
|
|
result = executor.submit(run_test, skipped, t, extra_args, system_compiler, backend, backend_flags, commands, should_fail) |
|
|
|
|
result = executor.submit(run_test, skipped, t.as_posix(), extra_args, system_compiler, backend, backend_flags, commands, should_fail) |
|
|
|
|
futures.append((testname, t, result)) |
|
|
|
|
for (testname, t, result) in futures: |
|
|
|
|
sys.stdout.flush() |
|
|
|
|
result = result.result() |
|
|
|
|
if (result is None) or (('MESON_SKIP_TEST' in result.stdo) and (skippable(name, t))): |
|
|
|
|
print(yellow('Skipping:'), t) |
|
|
|
|
if (result is None) or (('MESON_SKIP_TEST' in result.stdo) and (skippable(name, t.as_posix()))): |
|
|
|
|
print(yellow('Skipping:'), t.as_posix()) |
|
|
|
|
current_test = ET.SubElement(current_suite, 'testcase', {'name': testname, |
|
|
|
|
'classname': name}) |
|
|
|
|
ET.SubElement(current_test, 'skipped', {}) |
|
|
|
@ -585,7 +592,7 @@ def _run_tests(all_tests, log_name_base, extra_args): |
|
|
|
|
else: |
|
|
|
|
without_install = "" if len(install_commands) > 0 else " (without install)" |
|
|
|
|
if result.msg != '': |
|
|
|
|
print(red('Failed test{} during {}: {!r}'.format(without_install, result.step.name, t))) |
|
|
|
|
print(red('Failed test{} during {}: {!r}'.format(without_install, result.step.name, t.as_posix()))) |
|
|
|
|
print('Reason:', result.msg) |
|
|
|
|
failing_tests += 1 |
|
|
|
|
if result.step == BuildStep.configure and result.mlog != no_meson_log_msg: |
|
|
|
@ -597,7 +604,7 @@ def _run_tests(all_tests, log_name_base, extra_args): |
|
|
|
|
failing_logs.append(result.stdo) |
|
|
|
|
failing_logs.append(result.stde) |
|
|
|
|
else: |
|
|
|
|
print('Succeeded test%s: %s' % (without_install, t)) |
|
|
|
|
print('Succeeded test%s: %s' % (without_install, t.as_posix())) |
|
|
|
|
passing_tests += 1 |
|
|
|
|
conf_time += result.conftime |
|
|
|
|
build_time += result.buildtime |
|
|
|
@ -641,7 +648,7 @@ def check_format(): |
|
|
|
|
|
|
|
|
|
def check_meson_commands_work(): |
|
|
|
|
global backend, meson_command, compile_commands, test_commands, install_commands |
|
|
|
|
testdir = 'test cases/common/1 trivial' |
|
|
|
|
testdir = PurePath('test cases', 'common', '1 trivial').as_posix() |
|
|
|
|
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir: |
|
|
|
|
print('Checking that configuring works...') |
|
|
|
|
gen_cmd = mesonlib.meson_command + [testdir, build_dir] + backend_flags |
|
|
|
@ -706,7 +713,7 @@ if __name__ == '__main__': |
|
|
|
|
except UnicodeError: |
|
|
|
|
print(l.encode('ascii', errors='replace').decode(), '\n') |
|
|
|
|
for name, dirs, skip in all_tests: |
|
|
|
|
dirs = (os.path.basename(x) for x in dirs) |
|
|
|
|
dirs = (x.name for x in dirs) |
|
|
|
|
for k, g in itertools.groupby(dirs, key=lambda x: x.split()[0]): |
|
|
|
|
tests = list(g) |
|
|
|
|
if len(tests) != 1: |
|
|
|
|