Add PYTEST_TMPDIR_FILE_MASK environment variable
This commit is contained in:
parent
97a2761d72
commit
65fb513b9e
1
AUTHORS
1
AUTHORS
|
@ -172,6 +172,7 @@ Javier Romero
|
|||
Jeff Rackauckas
|
||||
Jeff Widman
|
||||
Jenni Rinker
|
||||
Jim Brannlund
|
||||
John Eddie Ayson
|
||||
John Litborn
|
||||
John Towler
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Added ``PYTEST_TMPDIR_FILE_MASK`` environment variable which controls the file permissions of any files or directories created by the ``tmp_path`` fixtures.
|
|
@ -155,4 +155,16 @@ When distributing tests on the local machine using ``pytest-xdist``, care is tak
|
|||
automatically configure a basetemp directory for the sub processes such that all temporary
|
||||
data lands below a single per-test run basetemp directory.
|
||||
|
||||
|
||||
.. _`file permissions`:
|
||||
|
||||
File permissions
|
||||
----------------
|
||||
|
||||
Any file or directory created by the above fixtures are by default created with private permissions (file mask 700).
|
||||
|
||||
You can override the file mask by setting the :envvar:`PYTEST_TMPDIR_FILE_MODE` environment variable as an octal string, the default being `0o700`.
|
||||
|
||||
This is for example useful in cases where created files or directories have to be shared by docker containers etc.
|
||||
|
||||
.. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html
|
||||
|
|
|
@ -1090,6 +1090,10 @@ Sets a `pygment style <https://pygments.org/docs/styles/>`_ to use for the code
|
|||
|
||||
Sets the :envvar:`PYTEST_THEME` to be either *dark* or *light*.
|
||||
|
||||
.. envar:: PYTEST_TMPDIR_FILE_MODE
|
||||
|
||||
Sets the file mode of any temporary files or directories. Defaults to `0o700`. See :fixture:`tmp_path` :fixture:`tmp_path_factory`.
|
||||
|
||||
.. envvar:: PY_COLORS
|
||||
|
||||
When set to ``1``, pytest will use color in terminal output.
|
||||
|
|
|
@ -51,6 +51,8 @@ _IGNORED_WINERRORS = (
|
|||
1921, # ERROR_CANT_RESOLVE_FILENAME - fix for broken symlink pointing to itself
|
||||
)
|
||||
|
||||
TMPDIR_FILE_MODE = int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "0o700"), 8)
|
||||
|
||||
|
||||
def _ignore_error(exception):
|
||||
return (
|
||||
|
@ -206,7 +208,7 @@ def _force_symlink(
|
|||
pass
|
||||
|
||||
|
||||
def make_numbered_dir(root: Path, prefix: str, mode: int = 0o700) -> Path:
|
||||
def make_numbered_dir(root: Path, prefix: str, mode: int = TMPDIR_FILE_MODE) -> Path:
|
||||
"""Create a directory with an increased number as suffix for the given prefix."""
|
||||
for i in range(10):
|
||||
# try up to 10 times to create the folder
|
||||
|
|
|
@ -82,6 +82,8 @@ IGNORE_PAM = [ # filenames added when obtaining details about the current user
|
|||
"/var/lib/sss/mc/passwd"
|
||||
]
|
||||
|
||||
TMPDIR_FILE_MODE = int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "0o700"), 8)
|
||||
|
||||
|
||||
def pytest_addoption(parser: Parser) -> None:
|
||||
parser.addoption(
|
||||
|
@ -1502,7 +1504,9 @@ class Pytester:
|
|||
The result.
|
||||
"""
|
||||
__tracebackhide__ = True
|
||||
p = make_numbered_dir(root=self.path, prefix="runpytest-", mode=0o700)
|
||||
p = make_numbered_dir(
|
||||
root=self.path, prefix="runpytest-", mode=TMPDIR_FILE_MODE
|
||||
)
|
||||
args = ("--basetemp=%s" % p,) + args
|
||||
plugins = [x for x in self.plugins if isinstance(x, str)]
|
||||
if plugins:
|
||||
|
@ -1521,7 +1525,7 @@ class Pytester:
|
|||
The pexpect child is returned.
|
||||
"""
|
||||
basetemp = self.path / "temp-pexpect"
|
||||
basetemp.mkdir(mode=0o700)
|
||||
basetemp.mkdir(mode=TMPDIR_FILE_MODE)
|
||||
invoke = " ".join(map(str, self._getpytestargs()))
|
||||
cmd = f"{invoke} --basetemp={basetemp} {string}"
|
||||
return self.spawn(cmd, expect_timeout=expect_timeout)
|
||||
|
|
|
@ -41,6 +41,8 @@ from _pytest.monkeypatch import MonkeyPatch
|
|||
|
||||
tmppath_result_key = StashKey[Dict[str, bool]]()
|
||||
|
||||
TMPDIR_FILE_MODE = int(os.getenv("PYTEST_TMPDIR_FILE_MODE", "0o700"), 8)
|
||||
|
||||
|
||||
@final
|
||||
@dataclasses.dataclass
|
||||
|
@ -136,9 +138,11 @@ class TempPathFactory:
|
|||
basename = self._ensure_relative_to_basetemp(basename)
|
||||
if not numbered:
|
||||
p = self.getbasetemp().joinpath(basename)
|
||||
p.mkdir(mode=0o700)
|
||||
p.mkdir(mode=TMPDIR_FILE_MODE)
|
||||
else:
|
||||
p = make_numbered_dir(root=self.getbasetemp(), prefix=basename, mode=0o700)
|
||||
p = make_numbered_dir(
|
||||
root=self.getbasetemp(), prefix=basename, mode=TMPDIR_FILE_MODE
|
||||
)
|
||||
self._trace("mktemp", p)
|
||||
return p
|
||||
|
||||
|
@ -155,7 +159,7 @@ class TempPathFactory:
|
|||
basetemp = self._given_basetemp
|
||||
if basetemp.exists():
|
||||
rm_rf(basetemp)
|
||||
basetemp.mkdir(mode=0o700)
|
||||
basetemp.mkdir(mode=TMPDIR_FILE_MODE)
|
||||
basetemp = basetemp.resolve()
|
||||
else:
|
||||
from_env = os.environ.get("PYTEST_DEBUG_TEMPROOT")
|
||||
|
@ -165,11 +169,11 @@ class TempPathFactory:
|
|||
# make_numbered_dir() call
|
||||
rootdir = temproot.joinpath(f"pytest-of-{user}")
|
||||
try:
|
||||
rootdir.mkdir(mode=0o700, exist_ok=True)
|
||||
rootdir.mkdir(mode=TMPDIR_FILE_MODE, exist_ok=True)
|
||||
except OSError:
|
||||
# getuser() likely returned illegal characters for the platform, use unknown back off mechanism
|
||||
rootdir = temproot.joinpath("pytest-of-unknown")
|
||||
rootdir.mkdir(mode=0o700, exist_ok=True)
|
||||
rootdir.mkdir(mode=TMPDIR_FILE_MODE, exist_ok=True)
|
||||
# Because we use exist_ok=True with a predictable name, make sure
|
||||
# we are the owners, to prevent any funny business (on unix, where
|
||||
# temproot is usually shared).
|
||||
|
@ -197,7 +201,7 @@ class TempPathFactory:
|
|||
root=rootdir,
|
||||
keep=keep,
|
||||
lock_timeout=LOCK_TIMEOUT,
|
||||
mode=0o700,
|
||||
mode=TMPDIR_FILE_MODE,
|
||||
)
|
||||
assert basetemp is not None, basetemp
|
||||
self._basetemp = basetemp
|
||||
|
|
|
@ -623,3 +623,19 @@ def test_tmp_path_factory_fixes_up_world_readable_permissions(
|
|||
|
||||
# After - fixed.
|
||||
assert (basetemp.parent.stat().st_mode & 0o077) == 0
|
||||
|
||||
|
||||
def test_tmp_path_factory_user_specified_permissions(
|
||||
tmp_path: Path, monkeypatch: MonkeyPatch
|
||||
) -> None:
|
||||
"""Verify that pytest creates directories under /tmp with user specified permissions."""
|
||||
# Use the test's tmp_path as the system temproot (/tmp).
|
||||
monkeypatch.setenv("PYTEST_DEBUG_TEMPROOT", str(tmp_path))
|
||||
monkeypatch.setenv("PYTEST_TMPDIR_FILE_MODE", "0o777")
|
||||
tmp_factory = TempPathFactory(None, 3, "all", lambda *args: None, _ispytest=True)
|
||||
basetemp = tmp_factory.getbasetemp()
|
||||
|
||||
# User specified permissions.
|
||||
assert (basetemp.stat().st_mode & 0o000) == 0
|
||||
# Parent too (pytest-of-foo).
|
||||
assert (basetemp.parent.stat().st_mode & 0o000) == 0
|
||||
|
|
Loading…
Reference in New Issue