diff options
Diffstat (limited to 'run_project_tests.py')
-rwxr-xr-x | run_project_tests.py | 249 |
1 files changed, 133 insertions, 116 deletions
diff --git a/run_project_tests.py b/run_project_tests.py index 14f135a..b6879ee 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -461,6 +461,8 @@ def create_deterministic_builddir(test: TestDef, use_tmpdir: bool) -> str: src_dir += test.name rel_dirname = 'b ' + hashlib.sha256(src_dir.encode(errors='ignore')).hexdigest()[0:10] abs_pathname = os.path.join(tempfile.gettempdir() if use_tmpdir else os.getcwd(), rel_dirname) + if os.path.exists(abs_pathname): + mesonlib.windows_proof_rmtree(abs_pathname) os.mkdir(abs_pathname) return abs_pathname @@ -474,7 +476,7 @@ def format_parameter_file(file_basename: str, test: TestDef, test_build_dir: str return destination -def detect_parameter_files(test: TestDef, test_build_dir: str) -> (Path, Path): +def detect_parameter_files(test: TestDef, test_build_dir: str) -> T.Tuple[Path, Path]: nativefile = test.path / 'nativefile.ini' crossfile = test.path / 'crossfile.ini' @@ -486,7 +488,9 @@ def detect_parameter_files(test: TestDef, test_build_dir: str) -> (Path, Path): return nativefile, crossfile -def run_test(test: TestDef, extra_args, compiler, backend, flags, commands, should_fail, use_tmp: bool): +def run_test(test: TestDef, extra_args: T.List[str], compiler: str, backend: Backend, + flags: T.List[str], commands: T.Tuple[T.List[str], T.List[str], T.List[str], T.List[str]], + should_fail: bool, use_tmp: bool) -> T.Optional[TestResult]: if test.skip: return None build_dir = create_deterministic_builddir(test, use_tmp) @@ -501,7 +505,10 @@ def run_test(test: TestDef, extra_args, compiler, backend, flags, commands, shou finally: mesonlib.windows_proof_rmtree(build_dir) -def _run_test(test: TestDef, test_build_dir: str, install_dir: str, extra_args, compiler, backend, flags, commands, should_fail): +def _run_test(test: TestDef, test_build_dir: str, install_dir: str, + extra_args: T.List[str], compiler: str, backend: Backend, + flags: T.List[str], commands: T.Tuple[T.List[str], T.List[str], T.List[str], T.List[str]], + should_fail: bool) -> TestResult: compile_commands, clean_commands, install_commands, uninstall_commands = commands gen_start = time.time() # Configure in-process @@ -620,130 +627,140 @@ def _run_test(test: TestDef, test_build_dir: str, install_dir: str, extra_args, return testresult -def gather_tests(testdir: Path, stdout_mandatory: bool) -> T.List[TestDef]: - tests = [t.name for t in testdir.iterdir() if t.is_dir()] - tests = [t for t in tests if not t.startswith('.')] # Filter non-tests files (dot files, etc) - test_defs = [TestDef(testdir / t, None, []) for t in tests] - all_tests = [] # type: T.List[TestDef] - for t in test_defs: - test_def = {} - test_def_file = t.path / 'test.json' - if test_def_file.is_file(): - test_def = json.loads(test_def_file.read_text()) - - # Handle additional environment variables - env = {} # type: T.Dict[str, str] - if 'env' in test_def: - assert isinstance(test_def['env'], dict) - env = test_def['env'] - for key, val in env.items(): - val = val.replace('@ROOT@', t.path.resolve().as_posix()) - val = val.replace('@PATH@', t.env.get('PATH', '')) - env[key] = val - - # Handle installed files - installed = [] # type: T.List[InstalledFile] - if 'installed' in test_def: - installed = [InstalledFile(x) for x in test_def['installed']] - - # Handle expected output - stdout = test_def.get('stdout', []) - if stdout_mandatory and not stdout: - raise RuntimeError("{} must contain a non-empty stdout key".format(test_def_file)) - - # Handle the do_not_set_opts list - do_not_set_opts = test_def.get('do_not_set_opts', []) # type: T.List[str] - - # Skip tests if the tool requirements are not met - if 'tools' in test_def: - assert isinstance(test_def['tools'], dict) - for tool, vers_req in test_def['tools'].items(): - if tool not in tool_vers_map: - t.skip = True - elif not mesonlib.version_compare(tool_vers_map[tool], vers_req): - t.skip = True - - # Skip the matrix code and just update the existing test - if 'matrix' not in test_def: - t.env.update(env) - t.installed_files = installed - t.do_not_set_opts = do_not_set_opts - t.stdout = stdout - all_tests += [t] - continue - # 'matrix; entry is present, so build multiple tests from matrix definition - opt_list = [] # type: T.List[T.List[T.Tuple[str, bool]]] - matrix = test_def['matrix'] - assert "options" in matrix - for key, val in matrix["options"].items(): - assert isinstance(val, list) - tmp_opts = [] # type: T.List[T.Tuple[str, bool]] - for i in val: - assert isinstance(i, dict) - assert "val" in i - skip = False - - # Skip the matrix entry if environment variable is present - if 'skip_on_env' in i: - for skip_env_var in i['skip_on_env']: - if skip_env_var in os.environ: - skip = True - - # Only run the test if all compiler ID's match - if 'compilers' in i: - for lang, id_list in i['compilers'].items(): - if lang not in compiler_id_map or compiler_id_map[lang] not in id_list: - skip = True - break - - # Add an empty matrix entry - if i['val'] is None: - tmp_opts += [(None, skip)] - continue +def load_test_json(t: TestDef, stdout_mandatory: bool) -> T.List[TestDef]: + all_tests: T.List[TestDef] = [] + test_def = {} + test_def_file = t.path / 'test.json' + if test_def_file.is_file(): + test_def = json.loads(test_def_file.read_text()) + + # Handle additional environment variables + env = {} # type: T.Dict[str, str] + if 'env' in test_def: + assert isinstance(test_def['env'], dict) + env = test_def['env'] + for key, val in env.items(): + val = val.replace('@ROOT@', t.path.resolve().as_posix()) + val = val.replace('@PATH@', t.env.get('PATH', '')) + env[key] = val + + # Handle installed files + installed = [] # type: T.List[InstalledFile] + if 'installed' in test_def: + installed = [InstalledFile(x) for x in test_def['installed']] + + # Handle expected output + stdout = test_def.get('stdout', []) + if stdout_mandatory and not stdout: + raise RuntimeError("{} must contain a non-empty stdout key".format(test_def_file)) + + # Handle the do_not_set_opts list + do_not_set_opts = test_def.get('do_not_set_opts', []) # type: T.List[str] + + # Skip tests if the tool requirements are not met + if 'tools' in test_def: + assert isinstance(test_def['tools'], dict) + for tool, vers_req in test_def['tools'].items(): + if tool not in tool_vers_map: + t.skip = True + elif not mesonlib.version_compare(tool_vers_map[tool], vers_req): + t.skip = True + + # Skip the matrix code and just update the existing test + if 'matrix' not in test_def: + t.env.update(env) + t.installed_files = installed + t.do_not_set_opts = do_not_set_opts + t.stdout = stdout + return [t] + + new_opt_list: T.List[T.List[T.Tuple[str, bool]]] + + # 'matrix; entry is present, so build multiple tests from matrix definition + opt_list = [] # type: T.List[T.List[T.Tuple[str, bool]]] + matrix = test_def['matrix'] + assert "options" in matrix + for key, val in matrix["options"].items(): + assert isinstance(val, list) + tmp_opts = [] # type: T.List[T.Tuple[str, bool]] + for i in val: + assert isinstance(i, dict) + assert "val" in i + skip = False + + # Skip the matrix entry if environment variable is present + if 'skip_on_env' in i: + for skip_env_var in i['skip_on_env']: + if skip_env_var in os.environ: + skip = True + + # Only run the test if all compiler ID's match + if 'compilers' in i: + for lang, id_list in i['compilers'].items(): + if lang not in compiler_id_map or compiler_id_map[lang] not in id_list: + skip = True + break - tmp_opts += [('{}={}'.format(key, i['val']), skip)] + # Add an empty matrix entry + if i['val'] is None: + tmp_opts += [(None, skip)] + continue - if opt_list: - new_opt_list = [] # type: T.List[T.List[T.Tuple[str, bool]]] - for i in opt_list: - for j in tmp_opts: - new_opt_list += [[*i, j]] - opt_list = new_opt_list - else: - opt_list = [[x] for x in tmp_opts] + tmp_opts += [('{}={}'.format(key, i['val']), skip)] - # Exclude specific configurations - if 'exclude' in matrix: - assert isinstance(matrix['exclude'], list) - new_opt_list = [] # type: T.List[T.List[T.Tuple[str, bool]]] + if opt_list: + new_opt_list = [] for i in opt_list: - exclude = False - opt_names = [x[0] for x in i] - for j in matrix['exclude']: - ex_list = ['{}={}'.format(k, v) for k, v in j.items()] - if all([x in opt_names for x in ex_list]): - exclude = True - break - - if not exclude: - new_opt_list += [i] - + for j in tmp_opts: + new_opt_list += [[*i, j]] opt_list = new_opt_list + else: + opt_list = [[x] for x in tmp_opts] + # Exclude specific configurations + if 'exclude' in matrix: + assert isinstance(matrix['exclude'], list) + new_opt_list = [] for i in opt_list: - name = ' '.join([x[0] for x in i if x[0] is not None]) - opts = ['-D' + x[0] for x in i if x[0] is not None] - skip = any([x[1] for x in i]) - test = TestDef(t.path, name, opts, skip or t.skip) - test.env.update(env) - test.installed_files = installed - test.do_not_set_opts = do_not_set_opts - test.stdout = stdout - all_tests += [test] + exclude = False + opt_names = [x[0] for x in i] + for j in matrix['exclude']: + ex_list = ['{}={}'.format(k, v) for k, v in j.items()] + if all([x in opt_names for x in ex_list]): + exclude = True + break + + if not exclude: + new_opt_list += [i] + + opt_list = new_opt_list + + for i in opt_list: + name = ' '.join([x[0] for x in i if x[0] is not None]) + opts = ['-D' + x[0] for x in i if x[0] is not None] + skip = any([x[1] for x in i]) + test = TestDef(t.path, name, opts, skip or t.skip) + test.env.update(env) + test.installed_files = installed + test.do_not_set_opts = do_not_set_opts + test.stdout = stdout + all_tests.append(test) + + return all_tests + + +def gather_tests(testdir: Path, stdout_mandatory: bool) -> T.List[TestDef]: + tests = [t.name for t in testdir.iterdir() if t.is_dir()] + tests = [t for t in tests if not t.startswith('.')] # Filter non-tests files (dot files, etc) + test_defs = [TestDef(testdir / t, None, []) for t in tests] + all_tests: T.List[TestDef] = [] + for t in test_defs: + all_tests.extend(load_test_json(t, stdout_mandatory)) return sorted(all_tests) + def have_d_compiler(): if shutil.which("ldc2"): return True |