From 7ddd364a83b7a8f3ab6720f805df6b62aee6ea88 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Tue, 18 Jul 2023 01:33:39 +0200 Subject: process: preserve the exit code more If the process is killed by a signal, preserve the exit code as it would be reported by $?. --- src/process.c | 2 ++ test/py/conftest.py | 6 +++--- test/py/lib/test_repo.py | 25 +++++++++++++------------ test/py/test_repo.py | 2 +- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/process.c b/src/process.c index ee387bb..3fc866f 100644 --- a/src/process.c +++ b/src/process.c @@ -42,6 +42,8 @@ static int wait_for_child(pid_t pid, int *ec) if (WIFEXITED(status)) *ec = WEXITSTATUS(status); + else if (WIFSIGNALED(status)) + *ec = status; /* Same as $?. */ else *ec = -1; diff --git a/test/py/conftest.py b/test/py/conftest.py index 9bacab4..ab2cbfb 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -99,9 +99,9 @@ def base_cmd_line(pytestconfig): cmd_line = CmdLine.unbuffered() valgrind = pytestconfig.getoption(PARAM_VALGRIND.codename) if valgrind is not None: - # Signal to Valgrind that ci.sh should obviously be exempt from memory - # leak checking: - cmd_line = CmdLine.wrap(CmdLine(valgrind, '--trace-children-skip=*/ci.sh', '--'), cmd_line) + # Signal to Valgrind that ci scripts should obviously be exempt from + # memory leak checking: + cmd_line = CmdLine.wrap(CmdLine(valgrind, '--trace-children-skip=*/ci', '--'), cmd_line) return cmd_line diff --git a/test/py/lib/test_repo.py b/test/py/lib/test_repo.py index aca6dfa..e3e875b 100644 --- a/test/py/lib/test_repo.py +++ b/test/py/lib/test_repo.py @@ -40,7 +40,7 @@ class TestRepo(Repo): # Prevent Pytest from discovering test cases in this class: __test__ = False - def __init__(self, path, ci_script='ci.sh'): + def __init__(self, path, ci_script='ci'): super().__init__(path) self.runs_dir = os.path.join(self.path, 'runs') @@ -78,9 +78,12 @@ class TestRepo(Repo): runs_dir = shlex.quote(self.runs_dir) return CI_SCRIPT.format(runs_dir=runs_dir) - def count_run_files(self): + def _count_run_files(self): return len([name for name in os.listdir(self.runs_dir) if os.path.isfile(os.path.join(self.runs_dir, name))]) + def run_files_are_present(self, expected): + assert expected == self._count_run_files() + class TestRepoOutput(TestRepo, abc.ABC): __test__ = False @@ -223,24 +226,22 @@ class TestRepoSegfault(TestRepo): def __init__(self, repo_path, prog_path): self.prog_path = prog_path - self.prog_name = os.path.basename(prog_path) super().__init__(repo_path) - shutil.copy(prog_path, self.path) - self.run('git', 'add', '--', self.prog_name) - self.run('git', 'commit', '-q', '-m', 'add test program') - @staticmethod def codename(): return 'segfault' - def format_ci_script(self): - script = super().format_ci_script() - added = r'exec {prog}'.format(prog=shlex.quote(f'./{self.prog_name}')) - return f'{script}\n{added}\n' + def write_ci_script(self): + shutil.copy(self.prog_path, self.ci_script_path) def run_exit_code_matches(self, ec): - return ec < 0 + # If WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV, then the $? + # would be 139. + return ec == 139 def run_output_matches(self, output): return "Started the test program.\n" == output.decode() + + def run_files_are_present(self, *args): + return True diff --git a/test/py/test_repo.py b/test/py/test_repo.py index 4fd6b09..49d5a32 100644 --- a/test/py/test_repo.py +++ b/test/py/test_repo.py @@ -61,7 +61,7 @@ def _test_repo_internal(env, repo, numof_processes, runs_per_process): for proc in processes: proc.join() - assert numof_runs == repo.count_run_files() + repo.run_files_are_present(numof_runs) runs = env.db.get_all_runs() assert numof_runs == len(runs) -- cgit v1.2.3