Change options from cli to config

This commit is contained in:
Yusuke Kadowaki 2022-10-30 00:53:27 +09:00
parent 321eeae6d1
commit 0eb8723199
4 changed files with 85 additions and 26 deletions

View File

@ -1723,6 +1723,40 @@ passed multiple times. The expected format is ``name=value``. For example::
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
List of fixtures that will be applied to all test functions; this is semantically the same to apply

View File

@ -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:
# GH 7119

View File

@ -7,9 +7,16 @@ import tempfile
from pathlib import Path
from shutil import rmtree
from typing import Optional
from typing import TYPE_CHECKING
from typing import Union
if TYPE_CHECKING:
from typing_extensions import Literal
import attr
from _pytest.config.argparsing import Parser
from .pathlib import LOCK_TIMEOUT
from .pathlib import make_numbered_dir
@ -23,6 +30,8 @@ from _pytest.fixtures import fixture
from _pytest.fixtures import FixtureRequest
from _pytest.monkeypatch import MonkeyPatch
RetentionPolicy = Literal["all", "failed", "none"]
@final
@attr.s(init=False)
@ -36,13 +45,13 @@ class TempPathFactory:
_trace = attr.ib()
_basetemp = attr.ib(type=Optional[Path])
_retention_count = attr.ib(type=int)
_retention_policy = attr.ib(type=str)
_retention_policy = attr.ib(type=RetentionPolicy)
def __init__(
self,
given_basetemp: Optional[Path],
retention_count: int,
retention_policy: str,
retention_policy: RetentionPolicy,
trace,
basetemp: Optional[Path] = None,
*,
@ -73,11 +82,23 @@ class TempPathFactory:
:meta private:
"""
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(
given_basetemp=config.option.basetemp,
trace=config.trace.get("tmpdir"),
retention_count=config.option.tmp_path_retention_count,
retention_policy=config.option.tmp_path_retention_policy,
retention_count=count,
retention_policy=policy,
_ispytest=True,
)
@ -199,6 +220,21 @@ def pytest_configure(config: Config) -> None:
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")
def tmp_path_factory(request: FixtureRequest) -> TempPathFactory:
"""Return a :class:`pytest.TempPathFactory` instance for the test session."""

View File

@ -34,8 +34,6 @@ def test_tmp_path_fixture(pytester: Pytester) -> None:
@attr.s
class FakeConfig:
basetemp = attr.ib()
tmp_path_retention_count = attr.ib(default=3)
tmp_path_retention_policy = attr.ib(default="failed")
@property
def trace(self):
@ -44,6 +42,14 @@ class FakeConfig:
def get(self, key):
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
def option(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."""
# Use the test's tmp_path as the system temproot (/tmp).
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()
# 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).
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()
# Before - simulate bad perms.
os.chmod(basetemp.parent, 0o777)
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()
# After - fixed.