Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"BrokenIter",
"in_systemd_nspawn_sync_suppressed",
"run_no_yield_async_fn", "run_yielding_async_fn", "async_yield",
"reset_code", "on_github_actions"
"reset_code", "on_github_actions", "requires_root", "requires_non_root",
]


Expand Down Expand Up @@ -3317,3 +3317,8 @@ def control_characters_c0() -> list[str]:
C0 control characters defined as the byte range 0x00-0x1F, and 0x7F.
"""
return [chr(c) for c in range(0x00, 0x20)] + ["\x7F"]


_ROOT_IN_POSIX = hasattr(os, 'geteuid') and os.geteuid() == 0
requires_root = unittest.skipUnless(_ROOT_IN_POSIX, "test needs root privilege")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename these decorators to requires_root_user and requires_non_root_user? At the first look, I wasn't sure what "root" was about. Root window? Root what? :-) Or maybe requires_root_privilege?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you are right - I guess there are several roots :)

requires_non_root = unittest.skipIf(_ROOT_IN_POSIX, "test needs non-root account")
7 changes: 3 additions & 4 deletions Lib/test/test_mailbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from test.support import import_helper, warnings_helper
from test.support import os_helper
from test.support import refleak_helper
from test.support import requires_root
from test.support import socket_helper
import unittest
import textwrap
Expand Down Expand Up @@ -1086,6 +1087,7 @@ def test_permissions_after_flush(self):

self.assertEqual(os.stat(self._path).st_mode, mode)

@requires_root
@unittest.skipUnless(hasattr(os, 'chown'), 'requires os.chown')
def test_ownership_after_flush(self):
# See issue gh-117467
Expand All @@ -1108,10 +1110,7 @@ def test_ownership_after_flush(self):
else:
self.skipTest("test needs more than one group")

try:
os.chown(self._path, other_uid, other_gid)
except OSError:
self.skipTest('test needs root privilege')
os.chown(self._path, other_uid, other_gid)
# Change permissions as in test_permissions_after_flush.
mode = st.st_mode | 0o666
os.chmod(self._path, mode)
Expand Down
14 changes: 6 additions & 8 deletions Lib/test/test_os/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
from test.support import os_helper
from test.support import socket_helper
from test.support import infinite_recursion
from test.support import requires_root
from test.support import requires_non_root
from test.support import warnings_helper
from platform import win32_is_iot
from .utils import create_file
Expand Down Expand Up @@ -67,10 +69,6 @@
from test.support.os_helper import FakePath


root_in_posix = False
if hasattr(os, 'geteuid'):
root_in_posix = (os.geteuid() == 0)

# Detect whether we're on a Linux system that uses the (now outdated
# and unmaintained) linuxthreads threading library. There's an issue
# when combining linuxthreads with a failed execv call: see
Expand Down Expand Up @@ -2257,8 +2255,8 @@ def test_chown_gid(self):
gid = os.stat(os_helper.TESTFN).st_gid
self.assertEqual(gid, gid_2)

@unittest.skipUnless(root_in_posix and len(all_users) > 1,
"test needs root privilege and more than one user")
@requires_root
@unittest.skipUnless(len(all_users) > 1, "test needs more than one user")
def test_chown_with_root(self):
uid_1, uid_2 = all_users[:2]
gid = os.stat(os_helper.TESTFN).st_gid
Expand All @@ -2269,8 +2267,8 @@ def test_chown_with_root(self):
uid = os.stat(os_helper.TESTFN).st_uid
self.assertEqual(uid, uid_2)

@unittest.skipUnless(not root_in_posix and len(all_users) > 1,
"test needs non-root account and more than one user")
@requires_non_root
@unittest.skipUnless(len(all_users) > 1, "test needs and more than one user")
def test_chown_without_permission(self):
uid_1, uid_2 = all_users[:2]
gid = os.stat(os_helper.TESTFN).st_gid
Expand Down
12 changes: 4 additions & 8 deletions Lib/test/test_pathlib/test_pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from test.support import is_emscripten, is_wasi, is_wasm32
from test.support import infinite_recursion
from test.support import os_helper
from test.support import requires_root
from test.support.os_helper import TESTFN, FS_NONASCII, FakePath
try:
import fcntl
Expand All @@ -35,11 +36,6 @@
posix = None


root_in_posix = False
if hasattr(os, 'geteuid'):
root_in_posix = (os.geteuid() == 0)


def patch_replace(old_test):
def new_replace(self, target):
raise OSError(errno.EXDEV, "Cross-device link", self, target)
Expand Down Expand Up @@ -1554,7 +1550,7 @@ def raiser(*args, **kwargs):
self.assertRaises(FileNotFoundError, source.copy, target)

@unittest.skipIf(sys.platform == "win32" or sys.platform == "wasi", "directories are always readable on Windows and WASI")
@unittest.skipIf(root_in_posix, "test fails with root privilege")
@requires_root
def test_copy_dir_no_read_permission(self):
base = self.cls(self.base)
source = base / 'dirE'
Expand Down Expand Up @@ -2027,7 +2023,7 @@ def test_owner(self):
self.assertEqual(expected_name, p.owner())

@unittest.skipUnless(pwd, "the pwd module is needed for this test")
@unittest.skipUnless(root_in_posix, "test needs root privilege")
@requires_root
def test_owner_no_follow_symlinks(self):
all_users = [u.pw_uid for u in pwd.getpwall()]
if len(all_users) < 2:
Expand Down Expand Up @@ -2062,7 +2058,7 @@ def test_group(self):
self.assertEqual(expected_name, p.group())

@unittest.skipUnless(grp, "the grp module is needed for this test")
@unittest.skipUnless(root_in_posix, "test needs root privilege")
@requires_root
def test_group_no_follow_symlinks(self):
all_groups = [g.gr_gid for g in grp.getgrall()]
if len(all_groups) < 2:
Expand Down
Loading