Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/tests/TestScripts/testBazelExitGuardFile.py
diff options
context:
space:
mode:
authorLeitwolf2026-10-24 19:03:40 +0300
committerGitHub2026-10-24 19:03:40 +0300
commit4f1c759cffcb14bd6511e1d7c5fbace682e24f2d (patch)
tree415fe5d48a5b48650bba3747beaf245d727c4f61 /tests/TestScripts/testBazelExitGuardFile.py
parent83c6fc3ac13abe83fa39f7b5f8559ccaf4412233 (diff)
parent622188f9c08e4af35941c146979883ed4882410e (diff)
downloadcatch3-4f1c759cffcb14bd6511e1d7c5fbace682e24f2d.tar.gz
Merge pull request #15 from Progmasoft/feature/catch3-runner
Replace Catch2's runner with the Catch3 runner
Diffstat (limited to 'tests/TestScripts/testBazelExitGuardFile.py')
-rwxr-xr-xtests/TestScripts/testBazelExitGuardFile.py167
1 files changed, 63 insertions, 104 deletions
diff --git a/tests/TestScripts/testBazelExitGuardFile.py b/tests/TestScripts/testBazelExitGuardFile.py
index c1186689..376049d2 100755
--- a/tests/TestScripts/testBazelExitGuardFile.py
+++ b/tests/TestScripts/testBazelExitGuardFile.py
@@ -7,119 +7,78 @@
# SPDX-License-Identifier: BSL-1.0
-import os
-import stat
-import sys
-import subprocess
-
-def generate_path_suffix() -> str:
- return os.urandom(16).hex()[:16]
+"""
+Checks the premature-exit guard file: the runner creates it when the run
+starts and removes it when the run ends. A test that ends its process is a
+crash the runner reports, so the guard is removed then too. The guard is
+created only the user can read, and a symbolic link in its place is refused.
+Arguments: the test binary and a directory for the guard files.
+"""
-def run_common(cmd, env = None):
- cmd_env = env if env is not None else os.environ.copy()
- print('Running:', cmd)
-
- try:
- ret = subprocess.run(
- cmd,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- check=True,
- universal_newlines=True,
- env=cmd_env
- )
- except subprocess.SubprocessError as ex:
- print('Could not run "{}"'.format(cmd))
- print("Return code: {}".format(ex.returncode))
- print("stdout: {}".format(ex.stdout))
- print("stderr: {}".format(ex.stderr))
- raise
-
-
-def test_bazel_env_vars(bin_path, guard_path):
- env = os.environ.copy()
- env["TEST_PREMATURE_EXIT_FILE"] = guard_path
- env["BAZEL_TEST"] = '1'
- run_common([bin_path], env)
+import os
+import subprocess
+import sys
-def test_cli_parameter(bin_path, guard_path):
- # Reuse a deliberately permissive stale guard file to verify that the
- # implementation tightens its permissions before truncating it.
- if os.name != 'nt':
- with open(guard_path, 'w'):
- pass
- os.chmod(guard_path, 0o666)
- cmd = [
- bin_path,
- '--premature-exit-guard-file',
- guard_path
- ]
- run_common(cmd)
- if os.name != 'nt':
- target_path = guard_path + '.target'
- symlink_path = guard_path + '.symlink'
- sentinel = 'do not truncate a symlink target\n'
- with open(target_path, 'w') as target:
- target.write(sentinel)
- os.symlink(target_path, symlink_path)
- try:
- result = subprocess.run(
- [bin_path, '--premature-exit-guard-file', symlink_path],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- universal_newlines=True,
- )
- assert result.returncode != 0, (
- 'A symlink was accepted as a premature-exit guard file'
- )
- with open(target_path, 'r') as target:
- assert target.read() == sentinel, (
- 'Opening the guard-file symlink modified its target'
- )
- finally:
- os.remove(symlink_path)
- os.remove(target_path)
+def guard_path(directory: str) -> str:
+ return os.path.join(directory, 'guard_file.' + os.urandom(8).hex())
-def test_no_crash(bin_path, guard_path):
- cmd = [
- bin_path,
- '--premature-exit-guard-file',
- guard_path,
- # Disable the quick-exit test
- '~[quick_exit]'
- ]
- run_common(cmd)
-checks = {
- 'bazel': (test_bazel_env_vars, True),
- 'cli': (test_cli_parameter, True),
- 'no-crash': (test_no_crash, False),
-}
+def run(cmd, env = None, expected = 0):
+ print('Running:', cmd)
+ result = subprocess.run(cmd,
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE,
+ universal_newlines = True,
+ env = env)
+ if result.returncode != expected:
+ print('Return code {} instead of {}'.format(result.returncode, expected))
+ print('stdout:', result.stdout)
+ print('stderr:', result.stderr)
+ exit(1)
+ return result
bin_path = os.path.abspath(sys.argv[1])
output_dir = os.path.abspath(sys.argv[2])
-test_kind = sys.argv[3]
-guard_file_path = os.path.join(output_dir, f"guard_file.{generate_path_suffix()}")
-print(f'Guard file path: "{guard_file_path}"')
-
-check_func, file_should_exist = checks[test_kind]
-check_func(bin_path, guard_file_path)
-assert os.path.exists(guard_file_path) == file_should_exist
-if file_should_exist and os.name != 'nt':
- guard_mode = stat.S_IMODE(os.stat(guard_file_path).st_mode)
- assert guard_mode & 0o077 == 0, (
- f'Guard file permissions are accessible to group/others: {guard_mode:o}'
- )
-# With randomly generated file suffix, we should not run into name conflicts.
-# However, we try to cleanup anyway, to avoid having infinity files in
-# long living build directories.
-if file_should_exist:
+# Bazel names the guard in the environment.
+path = guard_path(output_dir)
+env = os.environ.copy()
+env['BAZEL_TEST'] = '1'
+env['TEST_PREMATURE_EXIT_FILE'] = path
+run([bin_path, 'pass'], env)
+assert not os.path.exists(path), 'the guard was left behind after a normal run'
+
+# A test that exits the process is a crash; the run still ends normally.
+path = guard_path(output_dir)
+run([bin_path, '--retries=off', '--premature-exit-guard-file=' + path], expected = 42)
+assert not os.path.exists(path), 'the guard was left behind after a crash'
+
+if os.name != 'nt':
+ # A stale guard with loose permissions is tightened while the run lasts.
+ path = guard_path(output_dir)
+ with open(path, 'w'):
+ pass
+ os.chmod(path, 0o666)
+ run([bin_path, 'pass', '--premature-exit-guard-file=' + path])
+
+ target_path = path + '.target'
+ symlink_path = path + '.symlink'
+ sentinel = 'do not truncate a symlink target\n'
+ with open(target_path, 'w') as target:
+ target.write(sentinel)
+ os.symlink(target_path, symlink_path)
try:
- os.remove(guard_file_path)
- except Exception as ex:
- print(f'Could not remove file {guard_file_path} because: {ex}')
-
+ result = subprocess.run(
+ [bin_path, 'pass', '--premature-exit-guard-file=' + symlink_path],
+ stdout = subprocess.PIPE,
+ stderr = subprocess.PIPE,
+ universal_newlines = True)
+ assert result.returncode != 0, 'a symlink was accepted as the guard file'
+ with open(target_path, 'r') as target:
+ assert target.read() == sentinel, 'the symlink target was modified'
+ finally:
+ os.remove(symlink_path)
+ os.remove(target_path)