summaryrefslogtreecommitdiff
path: root/lib/spack/external/_pytest/cacheprovider.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/spack/external/_pytest/cacheprovider.py')
-rwxr-xr-x[-rw-r--r--]lib/spack/external/_pytest/cacheprovider.py71
1 files changed, 43 insertions, 28 deletions
diff --git a/lib/spack/external/_pytest/cacheprovider.py b/lib/spack/external/_pytest/cacheprovider.py
index 0657001f2d..c537c14472 100644..100755
--- a/lib/spack/external/_pytest/cacheprovider.py
+++ b/lib/spack/external/_pytest/cacheprovider.py
@@ -1,20 +1,21 @@
"""
merged implementation of the cache provider
-the name cache was not choosen to ensure pluggy automatically
+the name cache was not chosen to ensure pluggy automatically
ignores the external pytest-cache
"""
-
+from __future__ import absolute_import, division, print_function
import py
import pytest
import json
+import os
from os.path import sep as _sep, altsep as _altsep
class Cache(object):
def __init__(self, config):
self.config = config
- self._cachedir = config.rootdir.join(".cache")
+ self._cachedir = Cache.cache_dir_from_config(config)
self.trace = config.trace.root.get("cache")
if config.getvalue("cacheclear"):
self.trace("clearing cachedir")
@@ -22,6 +23,16 @@ class Cache(object):
self._cachedir.remove()
self._cachedir.mkdir()
+ @staticmethod
+ def cache_dir_from_config(config):
+ cache_dir = config.getini("cache_dir")
+ cache_dir = os.path.expanduser(cache_dir)
+ cache_dir = os.path.expandvars(cache_dir)
+ if os.path.isabs(cache_dir):
+ return py.path.local(cache_dir)
+ else:
+ return config.rootdir.join(cache_dir)
+
def makedir(self, name):
""" return a directory path object with the given name. If the
directory does not yet exist, it will be created. You can use it
@@ -89,31 +100,31 @@ class Cache(object):
class LFPlugin:
""" Plugin which implements the --lf (run last-failing) option """
+
def __init__(self, config):
self.config = config
active_keys = 'lf', 'failedfirst'
self.active = any(config.getvalue(key) for key in active_keys)
- if self.active:
- self.lastfailed = config.cache.get("cache/lastfailed", {})
- else:
- self.lastfailed = {}
+ self.lastfailed = config.cache.get("cache/lastfailed", {})
+ self._previously_failed_count = None
- def pytest_report_header(self):
+ def pytest_report_collectionfinish(self):
if self.active:
- if not self.lastfailed:
+ if not self._previously_failed_count:
mode = "run all (no recorded failures)"
else:
- mode = "rerun last %d failures%s" % (
- len(self.lastfailed),
- " first" if self.config.getvalue("failedfirst") else "")
+ noun = 'failure' if self._previously_failed_count == 1 else 'failures'
+ suffix = " first" if self.config.getvalue("failedfirst") else ""
+ mode = "rerun previous {count} {noun}{suffix}".format(
+ count=self._previously_failed_count, suffix=suffix, noun=noun
+ )
return "run-last-failure: %s" % mode
def pytest_runtest_logreport(self, report):
- if report.failed and "xfail" not in report.keywords:
+ if (report.when == 'call' and report.passed) or report.skipped:
+ self.lastfailed.pop(report.nodeid, None)
+ elif report.failed:
self.lastfailed[report.nodeid] = True
- elif not report.failed:
- if report.when == "call":
- self.lastfailed.pop(report.nodeid, None)
def pytest_collectreport(self, report):
passed = report.outcome in ('passed', 'skipped')
@@ -135,22 +146,24 @@ class LFPlugin:
previously_failed.append(item)
else:
previously_passed.append(item)
- if not previously_failed and previously_passed:
+ self._previously_failed_count = len(previously_failed)
+ if not previously_failed:
# running a subset of all tests with recorded failures outside
# of the set of tests currently executing
- pass
- elif self.config.getvalue("failedfirst"):
- items[:] = previously_failed + previously_passed
- else:
+ return
+ if self.config.getvalue("lf"):
items[:] = previously_failed
config.hook.pytest_deselected(items=previously_passed)
+ else:
+ items[:] = previously_failed + previously_passed
def pytest_sessionfinish(self, session):
config = self.config
if config.getvalue("cacheshow") or hasattr(config, "slaveinput"):
return
- prev_failed = config.cache.get("cache/lastfailed", None) is not None
- if (session.testscollected and prev_failed) or self.lastfailed:
+
+ saved_lastfailed = config.cache.get("cache/lastfailed", {})
+ if saved_lastfailed != self.lastfailed:
config.cache.set("cache/lastfailed", self.lastfailed)
@@ -171,6 +184,9 @@ def pytest_addoption(parser):
group.addoption(
'--cache-clear', action='store_true', dest="cacheclear",
help="remove all cache contents at start of test run.")
+ parser.addini(
+ "cache_dir", default='.cache',
+ help="cache directory path.")
def pytest_cmdline_main(config):
@@ -179,7 +195,6 @@ def pytest_cmdline_main(config):
return wrap_session(config, cacheshow)
-
@pytest.hookimpl(tryfirst=True)
def pytest_configure(config):
config.cache = Cache(config)
@@ -219,12 +234,12 @@ def cacheshow(config, session):
basedir = config.cache._cachedir
vdir = basedir.join("v")
tw.sep("-", "cache values")
- for valpath in vdir.visit(lambda x: x.isfile()):
+ for valpath in sorted(vdir.visit(lambda x: x.isfile())):
key = valpath.relto(vdir).replace(valpath.sep, "/")
val = config.cache.get(key, dummy)
if val is dummy:
tw.line("%s contains unreadable content, "
- "will be ignored" % key)
+ "will be ignored" % key)
else:
tw.line("%s contains:" % key)
stream = py.io.TextIO()
@@ -235,8 +250,8 @@ def cacheshow(config, session):
ddir = basedir.join("d")
if ddir.isdir() and ddir.listdir():
tw.sep("-", "cache directories")
- for p in basedir.join("d").visit():
- #if p.check(dir=1):
+ for p in sorted(basedir.join("d").visit()):
+ # if p.check(dir=1):
# print("%s/" % p.relto(basedir))
if p.isfile():
key = p.relto(basedir)