From 29f4da93d4137862129101e8bd1f649a33b8d290 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Tue, 22 Sep 2015 16:28:19 +0200 Subject: [PATCH 1/4] handle access errors when writing cache files silently as pytest warning, fixes #1039 --- _pytest/cacheprovider.py | 20 ++++++++++++++++---- testing/test_cache.py | 15 +++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/_pytest/cacheprovider.py b/_pytest/cacheprovider.py index 977647fee..6fa92e59d 100755 --- a/_pytest/cacheprovider.py +++ b/_pytest/cacheprovider.py @@ -69,10 +69,22 @@ class Cache(object): like e. g. lists of dictionaries. """ path = self._getvaluepath(key) - path.dirpath().ensure_dir() - with path.open("w") as f: - self.trace("cache-write %s: %r" % (key, value,)) - json.dump(value, f, indent=2, sort_keys=True) + try: + path.dirpath().ensure_dir() + except (py.error.EEXIST, py.error.EACCES): + self.config.warn( + code='I9', message='cache could not create cache path %s' % (path,) + ) + return + try: + f = path.open('w') + except py.error.ENOTDIR: + self.config.warn( + code='I9', message='cache could not write path %s' % (path,)) + else: + with f: + self.trace("cache-write %s: %r" % (key, value,)) + json.dump(value, f, indent=2, sort_keys=True) class LFPlugin: diff --git a/testing/test_cache.py b/testing/test_cache.py index 8eac4e8e0..5205014e3 100755 --- a/testing/test_cache.py +++ b/testing/test_cache.py @@ -25,6 +25,21 @@ class TestNewAPI: val = config.cache.get("key/name", -2) assert val == -2 + def test_cache_writefail_cachfile_silent(self, testdir): + testdir.makeini("[pytest]") + testdir.tmpdir.join('.cache').write('gone wrong') + config = testdir.parseconfigure() + cache = config.cache + cache.set('test/broken', []) + + def test_cache_writefail_permissions(selfself, testdir): + testdir.makeini("[pytest]") + testdir.tmpdir.ensure_dir('.cache').chmod(0) + config = testdir.parseconfigure() + cache = config.cache + cache.set('test/broken', []) + + def test_config_cache(self, testdir): testdir.makeconftest(""" def pytest_configure(config): From 6e519183532a1f857fdd3c434e9595a46b13503d Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Tue, 22 Sep 2015 16:33:27 +0200 Subject: [PATCH 2/4] update changelog --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index e2ecbef59..820c61c42 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,7 @@ - fix issue 877: propperly handle assertion explanations with non-ascii repr Thanks Mathieu Agopian for the report and Ronny Pfannschmidt for the PR. +- fix issue 1029: transform errors when writing cache values into pytest-warnings 2.8.0 ----------------------------- From ea9a491fb3aae3580e17a1c1ef073afe7860df0d Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Tue, 22 Sep 2015 20:24:37 +0200 Subject: [PATCH 3/4] add an acceptance test for cache write errors --- _pytest/cacheprovider.py | 2 +- testing/test_cache.py | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/_pytest/cacheprovider.py b/_pytest/cacheprovider.py index 6fa92e59d..e4ae64ab3 100755 --- a/_pytest/cacheprovider.py +++ b/_pytest/cacheprovider.py @@ -73,7 +73,7 @@ class Cache(object): path.dirpath().ensure_dir() except (py.error.EEXIST, py.error.EACCES): self.config.warn( - code='I9', message='cache could not create cache path %s' % (path,) + code='I9', message='could not create cache path %s' % (path,) ) return try: diff --git a/testing/test_cache.py b/testing/test_cache.py index 5205014e3..bd33c1c7d 100755 --- a/testing/test_cache.py +++ b/testing/test_cache.py @@ -32,13 +32,26 @@ class TestNewAPI: cache = config.cache cache.set('test/broken', []) - def test_cache_writefail_permissions(selfself, testdir): + def test_cache_writefail_permissions(self, testdir): testdir.makeini("[pytest]") testdir.tmpdir.ensure_dir('.cache').chmod(0) config = testdir.parseconfigure() cache = config.cache cache.set('test/broken', []) + def test_cache_failure_warns(self, testdir): + testdir.tmpdir.ensure_dir('.cache').chmod(0) + testdir.makepyfile(""" + def test_pass(): + pass + + """) + result = testdir.runpytest('-rw') + assert result.ret == 0 + result.stdout.fnmatch_lines([ + "*could not create cache path*", + "*1 pytest-warnings*", + ]) def test_config_cache(self, testdir): testdir.makeconftest(""" From 7f776fe19ad05d5180d7ae3efc3674e94ccba365 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Tue, 22 Sep 2015 20:49:11 +0200 Subject: [PATCH 4/4] skip chmod using cache access warning tests on windows --- testing/test_cache.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testing/test_cache.py b/testing/test_cache.py index bd33c1c7d..0538be9d7 100755 --- a/testing/test_cache.py +++ b/testing/test_cache.py @@ -1,3 +1,4 @@ +import sys import pytest import os import shutil @@ -32,6 +33,7 @@ class TestNewAPI: cache = config.cache cache.set('test/broken', []) + @pytest.mark.skipif(sys.platform.startswith('win'), reason='no chmod on windows') def test_cache_writefail_permissions(self, testdir): testdir.makeini("[pytest]") testdir.tmpdir.ensure_dir('.cache').chmod(0) @@ -39,6 +41,7 @@ class TestNewAPI: cache = config.cache cache.set('test/broken', []) + @pytest.mark.skipif(sys.platform.startswith('win'), reason='no chmod on windows') def test_cache_failure_warns(self, testdir): testdir.tmpdir.ensure_dir('.cache').chmod(0) testdir.makepyfile("""