Change options from cli to config
This commit is contained in:
parent
321eeae6d1
commit
0eb8723199
|
@ -1723,6 +1723,40 @@ passed multiple times. The expected format is ``name=value``. For example::
|
||||||
directories when executing from the root directory.
|
directories when executing from the root directory.
|
||||||
|
|
||||||
|
|
||||||
|
.. confval:: tmp_path_retention_count
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
How many sessions should we keep the `tmp_path` directories,
|
||||||
|
according to `tmp_path_retention_policy`.
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[pytest]
|
||||||
|
tmp_path_retention_count = 3
|
||||||
|
|
||||||
|
Default: 3
|
||||||
|
|
||||||
|
|
||||||
|
.. confval:: tmp_path_retention_policy
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Controls which directories created by the `tmp_path` fixture are kept around,
|
||||||
|
based on test outcome.
|
||||||
|
|
||||||
|
* `all`: retains directories for all tests, regardless of the outcome.
|
||||||
|
* `failed`: retains directories only for tests with outcome `error` or `failed`.
|
||||||
|
* `none`: directories are always removed after each test ends, regardless of the outcome.
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[pytest]
|
||||||
|
tmp_path_retention_policy = "all"
|
||||||
|
|
||||||
|
Default: failed
|
||||||
|
|
||||||
|
|
||||||
.. confval:: usefixtures
|
.. confval:: usefixtures
|
||||||
|
|
||||||
List of fixtures that will be applied to all test functions; this is semantically the same to apply
|
List of fixtures that will be applied to all test functions; this is semantically the same to apply
|
||||||
|
|
|
@ -228,23 +228,6 @@ def pytest_addoption(parser: Parser) -> None:
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
group.addoption(
|
|
||||||
"--tmp-path-retention-count",
|
|
||||||
dest="tmp_path_retention_count",
|
|
||||||
default=3,
|
|
||||||
type=int,
|
|
||||||
metavar="num",
|
|
||||||
help="How many sessions should we keep the `tmp_path` directories, according to `tmp_path_retention_policy`.",
|
|
||||||
)
|
|
||||||
|
|
||||||
group.addoption(
|
|
||||||
"--tmp-path-retention-policy",
|
|
||||||
default="failed",
|
|
||||||
choices=["all", "failed", "none"],
|
|
||||||
dest="tmp_path_retention_policy",
|
|
||||||
help="Controls which directories created by the `tmp_path` fixture are kept around, based on test outcome.",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def validate_basetemp(path: str) -> str:
|
def validate_basetemp(path: str) -> str:
|
||||||
# GH 7119
|
# GH 7119
|
||||||
|
|
|
@ -7,9 +7,16 @@ import tempfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from typing_extensions import Literal
|
||||||
|
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
|
from _pytest.config.argparsing import Parser
|
||||||
|
|
||||||
|
|
||||||
from .pathlib import LOCK_TIMEOUT
|
from .pathlib import LOCK_TIMEOUT
|
||||||
from .pathlib import make_numbered_dir
|
from .pathlib import make_numbered_dir
|
||||||
|
@ -23,6 +30,8 @@ from _pytest.fixtures import fixture
|
||||||
from _pytest.fixtures import FixtureRequest
|
from _pytest.fixtures import FixtureRequest
|
||||||
from _pytest.monkeypatch import MonkeyPatch
|
from _pytest.monkeypatch import MonkeyPatch
|
||||||
|
|
||||||
|
RetentionPolicy = Literal["all", "failed", "none"]
|
||||||
|
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@attr.s(init=False)
|
@attr.s(init=False)
|
||||||
|
@ -36,13 +45,13 @@ class TempPathFactory:
|
||||||
_trace = attr.ib()
|
_trace = attr.ib()
|
||||||
_basetemp = attr.ib(type=Optional[Path])
|
_basetemp = attr.ib(type=Optional[Path])
|
||||||
_retention_count = attr.ib(type=int)
|
_retention_count = attr.ib(type=int)
|
||||||
_retention_policy = attr.ib(type=str)
|
_retention_policy = attr.ib(type=RetentionPolicy)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
given_basetemp: Optional[Path],
|
given_basetemp: Optional[Path],
|
||||||
retention_count: int,
|
retention_count: int,
|
||||||
retention_policy: str,
|
retention_policy: RetentionPolicy,
|
||||||
trace,
|
trace,
|
||||||
basetemp: Optional[Path] = None,
|
basetemp: Optional[Path] = None,
|
||||||
*,
|
*,
|
||||||
|
@ -73,11 +82,23 @@ class TempPathFactory:
|
||||||
:meta private:
|
:meta private:
|
||||||
"""
|
"""
|
||||||
check_ispytest(_ispytest)
|
check_ispytest(_ispytest)
|
||||||
|
count = int(config.getini("tmp_path_retention_count"))
|
||||||
|
if count < 0:
|
||||||
|
raise ValueError(
|
||||||
|
f"tmp_path_retention_count must be >= 0. Current input: {count}."
|
||||||
|
)
|
||||||
|
|
||||||
|
policy = config.getini("tmp_path_retention_policy")
|
||||||
|
if policy not in ("all", "failed", "none"):
|
||||||
|
raise ValueError(
|
||||||
|
f"tmp_path_retention_policy must be either all, failed, none. Current intput: {policy}."
|
||||||
|
)
|
||||||
|
|
||||||
return cls(
|
return cls(
|
||||||
given_basetemp=config.option.basetemp,
|
given_basetemp=config.option.basetemp,
|
||||||
trace=config.trace.get("tmpdir"),
|
trace=config.trace.get("tmpdir"),
|
||||||
retention_count=config.option.tmp_path_retention_count,
|
retention_count=count,
|
||||||
retention_policy=config.option.tmp_path_retention_policy,
|
retention_policy=policy,
|
||||||
_ispytest=True,
|
_ispytest=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -199,6 +220,21 @@ def pytest_configure(config: Config) -> None:
|
||||||
mp.setattr(config, "_tmp_path_factory", _tmp_path_factory, raising=False)
|
mp.setattr(config, "_tmp_path_factory", _tmp_path_factory, raising=False)
|
||||||
|
|
||||||
|
|
||||||
|
def pytest_addoption(parser: Parser) -> None:
|
||||||
|
parser.addini(
|
||||||
|
"tmp_path_retention_count",
|
||||||
|
help="How many sessions should we keep the `tmp_path` directories, according to `tmp_path_retention_policy`.",
|
||||||
|
default=3,
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.addini(
|
||||||
|
"tmp_path_retention_policy",
|
||||||
|
help="Controls which directories created by the `tmp_path` fixture are kept around, based on test outcome. "
|
||||||
|
"(all/failed/none)",
|
||||||
|
default="failed",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@fixture(scope="session")
|
@fixture(scope="session")
|
||||||
def tmp_path_factory(request: FixtureRequest) -> TempPathFactory:
|
def tmp_path_factory(request: FixtureRequest) -> TempPathFactory:
|
||||||
"""Return a :class:`pytest.TempPathFactory` instance for the test session."""
|
"""Return a :class:`pytest.TempPathFactory` instance for the test session."""
|
||||||
|
|
|
@ -34,8 +34,6 @@ def test_tmp_path_fixture(pytester: Pytester) -> None:
|
||||||
@attr.s
|
@attr.s
|
||||||
class FakeConfig:
|
class FakeConfig:
|
||||||
basetemp = attr.ib()
|
basetemp = attr.ib()
|
||||||
tmp_path_retention_count = attr.ib(default=3)
|
|
||||||
tmp_path_retention_policy = attr.ib(default="failed")
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def trace(self):
|
def trace(self):
|
||||||
|
@ -44,6 +42,14 @@ class FakeConfig:
|
||||||
def get(self, key):
|
def get(self, key):
|
||||||
return lambda *k: None
|
return lambda *k: None
|
||||||
|
|
||||||
|
def getini(self, name):
|
||||||
|
if name == "tmp_path_retention_count":
|
||||||
|
return 3
|
||||||
|
elif name == "tmp_path_retention_policy":
|
||||||
|
return "failed"
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def option(self):
|
def option(self):
|
||||||
return self
|
return self
|
||||||
|
@ -453,7 +459,7 @@ def test_tmp_path_factory_create_directory_with_safe_permissions(
|
||||||
"""Verify that pytest creates directories under /tmp with private permissions."""
|
"""Verify that pytest creates directories under /tmp with private permissions."""
|
||||||
# Use the test's tmp_path as the system temproot (/tmp).
|
# Use the test's tmp_path as the system temproot (/tmp).
|
||||||
monkeypatch.setenv("PYTEST_DEBUG_TEMPROOT", str(tmp_path))
|
monkeypatch.setenv("PYTEST_DEBUG_TEMPROOT", str(tmp_path))
|
||||||
tmp_factory = TempPathFactory(None, 3, "fail", lambda *args: None, _ispytest=True)
|
tmp_factory = TempPathFactory(None, 3, "failed", lambda *args: None, _ispytest=True)
|
||||||
basetemp = tmp_factory.getbasetemp()
|
basetemp = tmp_factory.getbasetemp()
|
||||||
|
|
||||||
# No world-readable permissions.
|
# No world-readable permissions.
|
||||||
|
@ -473,14 +479,14 @@ def test_tmp_path_factory_fixes_up_world_readable_permissions(
|
||||||
"""
|
"""
|
||||||
# Use the test's tmp_path as the system temproot (/tmp).
|
# Use the test's tmp_path as the system temproot (/tmp).
|
||||||
monkeypatch.setenv("PYTEST_DEBUG_TEMPROOT", str(tmp_path))
|
monkeypatch.setenv("PYTEST_DEBUG_TEMPROOT", str(tmp_path))
|
||||||
tmp_factory = TempPathFactory(None, 3, "fail", lambda *args: None, _ispytest=True)
|
tmp_factory = TempPathFactory(None, 3, "failed", lambda *args: None, _ispytest=True)
|
||||||
basetemp = tmp_factory.getbasetemp()
|
basetemp = tmp_factory.getbasetemp()
|
||||||
|
|
||||||
# Before - simulate bad perms.
|
# Before - simulate bad perms.
|
||||||
os.chmod(basetemp.parent, 0o777)
|
os.chmod(basetemp.parent, 0o777)
|
||||||
assert (basetemp.parent.stat().st_mode & 0o077) != 0
|
assert (basetemp.parent.stat().st_mode & 0o077) != 0
|
||||||
|
|
||||||
tmp_factory = TempPathFactory(None, 3, "fail", lambda *args: None, _ispytest=True)
|
tmp_factory = TempPathFactory(None, 3, "failed", lambda *args: None, _ispytest=True)
|
||||||
basetemp = tmp_factory.getbasetemp()
|
basetemp = tmp_factory.getbasetemp()
|
||||||
|
|
||||||
# After - fixed.
|
# After - fixed.
|
||||||
|
|
Loading…
Reference in New Issue