From 75c3b33550624fecb551b16f95ea65bf3323934f Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Thu, 25 Jan 2024 17:15:33 +0100 Subject: linuxnamespaces.run_in_fork: use os._exit instead of sys.exit When using sys.exit, we actually raise a SystemExit exception and as a consequence exit all context managers. If a particular context manager pertains only the process at hand, we don't really care, because our process is supposed to vanish. If a context manager changes external state such as tempfile.NamedTemporaryFile, this is very bad and unexpected. We need to ensure that such cleanup is not performed. This also simplifies the test suite that had to emulate this behaviour already as pytest uses a context manager. --- tests/test_simple.py | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) (limited to 'tests') diff --git a/tests/test_simple.py b/tests/test_simple.py index 8469bb4..cb654aa 100644 --- a/tests/test_simple.py +++ b/tests/test_simple.py @@ -12,22 +12,6 @@ import pytest import linuxnamespaces -def allow_fork_exit(function): - @functools.wraps(function) - def wrapped(*args, **kwargs): - mainpid = os.getpid() - try: - return function(*args, **kwargs) - except SystemExit as sysexit: - if sysexit.code or os.getpid() == mainpid: - raise - - # We're supposed to successfully exit from a child process. If we - # were to return or raise here, pytest would record success or - # failure. Instead we hide this process from pytest. - os._exit(0) - return pytest.mark.forked(wrapped) - class IDAllocationTest(unittest.TestCase): def test_idalloc(self) -> None: alloc = linuxnamespaces.IDAllocation() @@ -58,7 +42,7 @@ class UnshareTest(unittest.TestCase): # UID 1 is not mapped. self.assertRaises(OSError, os.setuid, 1) - @allow_fork_exit + @pytest.mark.forked def test_mount_proc(self) -> None: idmap = linuxnamespaces.IDMapping(0, os.getuid(), 1) linuxnamespaces.unshare( @@ -108,7 +92,7 @@ class UnshareIdmapTest(unittest.TestCase): except ValueError: self.skipTest("insufficient /etc/sub?id allocation") - @allow_fork_exit + @pytest.mark.forked def test_unshare_user_idmap(self) -> None: overflowuid = int(pathlib.Path("/proc/sys/fs/overflowuid").read_text()) uidmap = linuxnamespaces.IDMapping( @@ -131,7 +115,7 @@ class UnshareIdmapTest(unittest.TestCase): os.setuid(1) self.assertEqual(os.getuid(), 1) - @allow_fork_exit + @pytest.mark.forked def test_populate_dev(self) -> None: uidmap = linuxnamespaces.IDMapping( 0, self.uidalloc.allocate(65536), 65536 -- cgit v1.2.3