refine tmpdir handling and docs

- clear tmpdir specified with --basetemp
- remove config.mktmp and config.getbasetemp methods
This commit is contained in:
holger krekel 2010-11-21 17:43:18 +01:00
parent 158e160823
commit f456e376b9
9 changed files with 116 additions and 86 deletions

View File

@ -1,4 +1,4 @@
""" command line configuration, ini-file and conftest.py processing. """ """ command line options, ini-file and conftest.py processing. """
import py import py
import sys, os import sys, os
@ -245,8 +245,6 @@ class CmdOptions(object):
class Config(object): class Config(object):
""" access to configuration values, pluginmanager and plugin hooks. """ """ access to configuration values, pluginmanager and plugin hooks. """
basetemp = None
def __init__(self, pluginmanager=None): def __init__(self, pluginmanager=None):
#: command line option values, usually added via parser.addoption(...) #: command line option values, usually added via parser.addoption(...)
#: or parser.getgroup(...).addoption(...) calls #: or parser.getgroup(...).addoption(...) calls
@ -330,29 +328,6 @@ class Config(object):
args.append(py.std.os.getcwd()) args.append(py.std.os.getcwd())
self.args = args self.args = args
def ensuretemp(self, string, dir=True):
return self.getbasetemp().ensure(string, dir=dir)
def getbasetemp(self):
if self.basetemp is None:
basetemp = self.option.basetemp
if basetemp:
basetemp = py.path.local(basetemp)
if not basetemp.check(dir=1):
basetemp.mkdir()
else:
basetemp = py.path.local.make_numbered_dir(prefix='pytest-')
self.basetemp = basetemp
return self.basetemp
def mktemp(self, basename, numbered=False):
basetemp = self.getbasetemp()
if not numbered:
return basetemp.mkdir(basename)
else:
return py.path.local.make_numbered_dir(prefix=basename,
keep=0, rootdir=basetemp, lock_timeout=None)
def getini(self, name): def getini(self, name):
""" return configuration value from an ini file. If the """ return configuration value from an ini file. If the
specified name hasn't been registered through a prior ``parse.addini`` specified name hasn't been registered through a prior ``parse.addini``

View File

@ -173,7 +173,7 @@ class TmpTestdir:
self.Config = request.config.__class__ self.Config = request.config.__class__
self._pytest = request.getfuncargvalue("_pytest") self._pytest = request.getfuncargvalue("_pytest")
# XXX remove duplication with tmpdir plugin # XXX remove duplication with tmpdir plugin
basetmp = request.config.ensuretemp("testdir") basetmp = request.config._tmpdirhandler.ensuretemp("testdir")
name = request.function.__name__ name = request.function.__name__
for i in range(100): for i in range(100):
try: try:
@ -350,7 +350,12 @@ class TmpTestdir:
if not args: if not args:
args = (self.tmpdir,) args = (self.tmpdir,)
config = self.config_preparse() config = self.config_preparse()
args = list(args) + ["--basetemp=%s" % self.tmpdir.dirpath('basetemp')] args = list(args)
for x in args:
if str(x).startswith('--basetemp'):
break
else:
args.append("--basetemp=%s" % self.tmpdir.dirpath('basetemp'))
config.parse(args) config.parse(args)
return config return config
@ -361,7 +366,8 @@ class TmpTestdir:
oldconfig = getattr(py.test, 'config', None) oldconfig = getattr(py.test, 'config', None)
try: try:
c = py.test.config = self.Config() c = py.test.config = self.Config()
c.basetemp = oldconfig.mktemp("reparse", numbered=True) c.basetemp = py.path.local.make_numbered_dir(prefix="reparse",
keep=0, rootdir=self.tmpdir, lock_timeout=None)
c.parse(args) c.parse(args)
return c return c
finally: finally:

View File

@ -1,17 +1,61 @@
""" support for providing temporary directories to test functions. """ """ support for providing temporary directories to test functions. """
import pytest, py import pytest, py
from _pytest.monkeypatch import monkeypatch
def pytest_configure(config): class TempdirHandler:
def ensuretemp(string, dir=1): def __init__(self, config):
self.config = config
self.trace = config.trace.get("tmpdir")
def ensuretemp(self, string, dir=1):
""" (deprecated) return temporary directory path with """ (deprecated) return temporary directory path with
the given string as the trailing part. It is usually the given string as the trailing part. It is usually
better to use the 'tmpdir' function argument which will better to use the 'tmpdir' function argument which
take care to provide empty unique directories for each provides an empty unique-per-test-invocation directory
test call even if the test is called multiple times. and is guaranteed to be empty.
""" """
#py.log._apiwarn(">1.1", "use tmpdir function argument") #py.log._apiwarn(">1.1", "use tmpdir function argument")
return config.ensuretemp(string, dir=dir) return self.getbasetemp().ensure(string, dir=dir)
pytest.ensuretemp = ensuretemp
def mktemp(self, basename, numbered=True):
basetemp = self.getbasetemp()
if not numbered:
p = basetemp.mkdir(basename)
else:
p = py.path.local.make_numbered_dir(prefix=basename,
keep=0, rootdir=basetemp, lock_timeout=None)
self.trace("mktemp", p)
return p
def getbasetemp(self):
""" return base temporary directory. """
try:
return self._basetemp
except AttributeError:
basetemp = self.config.option.basetemp
if basetemp:
basetemp = py.path.local(basetemp)
if basetemp.check():
basetemp.remove()
basetemp.mkdir()
else:
basetemp = py.path.local.make_numbered_dir(prefix='pytest-')
self._basetemp = t = basetemp
self.trace("new basetemp", t)
return t
def finish(self):
self.trace("finish")
def pytest_configure(config):
config._mp = mp = monkeypatch()
t = TempdirHandler(config)
mp.setattr(config, '_tmpdirhandler', t, raising=False)
mp.setattr(pytest, 'ensuretemp', t.ensuretemp, raising=False)
def pytest_unconfigure(config):
config._tmpdirhandler.finish()
config._mp.undo()
def pytest_funcarg__tmpdir(request): def pytest_funcarg__tmpdir(request):
"""return a temporary directory path object """return a temporary directory path object
@ -22,5 +66,6 @@ def pytest_funcarg__tmpdir(request):
""" """
name = request._pyfuncitem.name name = request._pyfuncitem.name
name = py.std.re.sub("[\W]", "_", name) name = py.std.re.sub("[\W]", "_", name)
x = request.config.mktemp(name, numbered=True) x = request.config._tmpdirhandler.mktemp(name, numbered=True)
return x.realpath() return x.realpath()

View File

@ -5,8 +5,8 @@ py.test: no-boilerplate testing with Python
.. note:: .. note::
version 2.0 introduces ``pytest`` as the main Python import name version 2.0 introduces ``pytest`` as the main Python import name
but for compatibility reasons you can continue to use ``import py`` in examples but you can continue to use ``import py`` and
and ``py.test.XYZ`` to access :ref:`pytest helpers` in your test code. ``py.test.XYZ`` to access :ref:`pytest helpers` in your test code.
Welcome to ``py.test`` documentation: Welcome to ``py.test`` documentation:

View File

@ -54,18 +54,12 @@ Running this would result in a passed test except for the last
the default base temporary directory the default base temporary directory
----------------------------------------------- -----------------------------------------------
..
You can create directories by calling one of two methods
on the config object:
- ``config.mktemp(basename)``: create and return a new tempdir
- ``config.ensuretemp(basename)``: create or return a new tempdir
Temporary directories are by default created as sub directories of Temporary directories are by default created as sub directories of
the system temporary directory. The name will be ``pytest-NUM`` where the system temporary directory. The base name will be ``pytest-NUM`` where
``NUM`` will be incremenated with each test run. Moreover, entries older ``NUM`` will be incremenated with each test run. Moreover, entries older
than 3 temporary directories will be removed. than 3 temporary directories will be removed.
You can override the default temporary directory logic and set it like this:: You can override the default temporary directory setting like this::
py.test --basetemp=mydir py.test --basetemp=mydir

View File

@ -33,16 +33,6 @@ class TestGeneralUsage:
'*1 passed*', '*1 passed*',
]) ])
def test_basetemp(self, testdir):
mytemp = testdir.tmpdir.mkdir("mytemp")
p = testdir.makepyfile("""
def test_1(pytestconfig):
pytestconfig.getbasetemp().ensure("hello")
""")
result = testdir.runpytest(p, '--basetemp=%s' % mytemp)
assert result.ret == 0
assert mytemp.join('hello').check()
def test_assertion_magic(self, testdir): def test_assertion_magic(self, testdir):
p = testdir.makepyfile(""" p = testdir.makepyfile("""
def test_this(): def test_this():

View File

@ -81,33 +81,6 @@ class TestConfigCmdlineParsing:
pytest.raises(AssertionError, "config.parse([])") pytest.raises(AssertionError, "config.parse([])")
class TestConfigTmpdir:
def test_getbasetemp(self, testdir):
config = testdir.Config()
config.basetemp = "hello"
config.getbasetemp() == "hello"
def test_mktemp(self, testdir):
config = testdir.Config()
config.basetemp = testdir.mkdir("hello")
tmp = config.mktemp("world")
assert tmp.relto(config.basetemp) == "world"
tmp = config.mktemp("this", numbered=True)
assert tmp.relto(config.basetemp).startswith("this")
tmp2 = config.mktemp("this", numbered=True)
assert tmp2.relto(config.basetemp).startswith("this")
assert tmp2 != tmp
def test_reparse(self, testdir):
config2 = testdir.reparseconfig([])
config3 = testdir.reparseconfig([])
assert config2.getbasetemp() != config3.getbasetemp()
assert not config2.getbasetemp().relto(config3.getbasetemp())
assert not config3.getbasetemp().relto(config2.getbasetemp())
def test_reparse_filename_too_long(self, testdir):
config = testdir.reparseconfig(["--basetemp=%s" % ("123"*300)])
class TestConfigAPI: class TestConfigAPI:
def test_config_trace(self, testdir): def test_config_trace(self, testdir):

View File

@ -1,6 +1,6 @@
import py, pytest import py, pytest
from _pytest.tmpdir import pytest_funcarg__tmpdir from _pytest.tmpdir import pytest_funcarg__tmpdir, TempdirHandler
from _pytest.python import FuncargRequest from _pytest.python import FuncargRequest
def test_funcarg(testdir): def test_funcarg(testdir):
@ -27,3 +27,51 @@ def test_ensuretemp(recwarn):
assert d1 == d2 assert d1 == d2
assert d1.check(dir=1) assert d1.check(dir=1)
class TestTempdirHandler:
def test_mktemp(self, testdir):
config = testdir.Config()
config.option.basetemp = testdir.mkdir("hello")
t = TempdirHandler(config)
tmp = t.mktemp("world")
assert tmp.relto(t.getbasetemp()) == "world0"
tmp = t.mktemp("this")
assert tmp.relto(t.getbasetemp()).startswith("this")
tmp2 = t.mktemp("this")
assert tmp2.relto(t.getbasetemp()).startswith("this")
assert tmp2 != tmp
class TestConfigTmpdir:
def test_getbasetemp_custom_removes_old(self, testdir):
p = testdir.tmpdir.join("xyz")
config = testdir.parseconfigure("--basetemp=xyz")
b = config._tmpdirhandler.getbasetemp()
assert b == p
h = b.ensure("hello")
config._tmpdirhandler.getbasetemp()
assert h.check()
config = testdir.parseconfigure("--basetemp=xyz")
b2 = config._tmpdirhandler.getbasetemp()
assert b2.check()
assert not h.check()
def test_reparse(self, testdir):
config2 = testdir.reparseconfig([])
config3 = testdir.reparseconfig([])
assert config2.basetemp != config3.basetemp
assert not config2.basetemp.relto(config3.basetemp)
assert not config3.basetemp.relto(config2.basetemp)
def test_reparse_filename_too_long(self, testdir):
config = testdir.reparseconfig(["--basetemp=%s" % ("123"*300)])
def test_basetemp(testdir):
mytemp = testdir.tmpdir.mkdir("mytemp")
p = testdir.makepyfile("""
import pytest
def test_1():
pytest.ensuretemp("hello")
""")
result = testdir.runpytest(p, '--basetemp=%s' % mytemp)
assert result.ret == 0
assert mytemp.join('hello').check()

View File

@ -66,4 +66,3 @@ minversion=2.0
plugins=pytester plugins=pytester
addopts= -rxf --pyargs --doctest-modules addopts= -rxf --pyargs --doctest-modules
rsyncdirs=tox.ini pytest.py _pytest testing rsyncdirs=tox.ini pytest.py _pytest testing