summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_posix.py
diff options
context:
space:
mode:
authorNoam Cohen <noam@noam.me>2022-10-20 09:08:54 (GMT)
committerGitHub <noreply@github.com>2022-10-20 09:08:54 (GMT)
commita371a7e03e43e08cae70235a71904989c0f57a5e (patch)
tree40b9d4b13ec579ae370760e2dafd888e32f2b06f /Lib/test/test_posix.py
parentc1e02d4e4e09dfc9d57c4d36eca1bbf312d4162d (diff)
downloadcpython-a371a7e03e43e08cae70235a71904989c0f57a5e.zip
cpython-a371a7e03e43e08cae70235a71904989c0f57a5e.tar.gz
cpython-a371a7e03e43e08cae70235a71904989c0f57a5e.tar.bz2
gh-95023: Added os.setns and os.unshare functions (#95046)
Added os.setns and os.unshare to easily switch between namespaces on Linux. Co-authored-by: Christian Heimes <christian@python.org> Co-authored-by: CAM Gerlach <CAM.Gerlach@Gerlach.CAM> Co-authored-by: Victor Stinner <vstinner@python.org>
Diffstat (limited to 'Lib/test/test_posix.py')
-rw-r--r--Lib/test/test_posix.py47
1 files changed, 47 insertions, 0 deletions
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index be561af..442dec8 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -2191,6 +2191,53 @@ class TestPosixWeaklinking(unittest.TestCase):
os.utime("path", dir_fd=0)
+class NamespacesTests(unittest.TestCase):
+ """Tests for os.unshare() and os.setns()."""
+
+ @unittest.skipUnless(hasattr(os, 'unshare'), 'needs os.unshare()')
+ @unittest.skipUnless(hasattr(os, 'setns'), 'needs os.setns()')
+ @unittest.skipUnless(os.path.exists('/proc/self/ns/uts'), 'need /proc/self/ns/uts')
+ @support.requires_linux_version(3, 0, 0)
+ def test_unshare_setns(self):
+ code = """if 1:
+ import errno
+ import os
+ import sys
+ fd = os.open('/proc/self/ns/uts', os.O_RDONLY)
+ try:
+ original = os.readlink('/proc/self/ns/uts')
+ try:
+ os.unshare(os.CLONE_NEWUTS)
+ except OSError as e:
+ if e.errno == errno.ENOSPC:
+ # skip test if limit is exceeded
+ sys.exit()
+ raise
+ new = os.readlink('/proc/self/ns/uts')
+ if original == new:
+ raise Exception('os.unshare failed')
+ os.setns(fd, os.CLONE_NEWUTS)
+ restored = os.readlink('/proc/self/ns/uts')
+ if original != restored:
+ raise Exception('os.setns failed')
+ except PermissionError:
+ # The calling process did not have the required privileges
+ # for this operation
+ pass
+ except OSError as e:
+ # Skip the test on these errors:
+ # - ENOSYS: syscall not available
+ # - EINVAL: kernel was not configured with the CONFIG_UTS_NS option
+ # - ENOMEM: not enough memory
+ if e.errno not in (errno.ENOSYS, errno.EINVAL, errno.ENOMEM):
+ raise
+ finally:
+ os.close(fd)
+ """
+
+ assert_python_ok("-c", code)
+
+
def tearDownModule():
support.reap_children()