fix race condition as reported by Ralf Schmitt

This commit is contained in:
holger krekel
2011-04-14 21:35:27 +02:00
parent bd30e96ab0
commit d9c5f18478
3 changed files with 24 additions and 6 deletions

View File

@@ -5,6 +5,9 @@
- fix issue34 - distributed testing with -p plugin now works correctly - fix issue34 - distributed testing with -p plugin now works correctly
- fix race condition in looponfail mode where a concurrent file removal
could cause a crash
1.5 1.5
------------------------- -------------------------

View File

@@ -14,11 +14,11 @@ class TestStatRecorder:
changed = sd.check() changed = sd.check()
assert changed assert changed
tmp.ensure("new.py") p = tmp.ensure("new.py")
changed = sd.check() changed = sd.check()
assert changed assert changed
tmp.join("new.py").remove() p.remove()
changed = sd.check() changed = sd.check()
assert changed assert changed
@@ -36,6 +36,24 @@ class TestStatRecorder:
changed = sd.check() changed = sd.check()
assert changed assert changed
def test_filechange_deletion_race(self, tmpdir, monkeypatch):
tmp = tmpdir
sd = StatRecorder([tmp])
changed = sd.check()
assert not changed
p = tmp.ensure("new.py")
changed = sd.check()
assert changed
p.remove()
# make check()'s visit() call return our just removed
# path as if we were in a race condition
monkeypatch.setattr(tmp, 'visit', lambda *args: [p])
changed = sd.check()
assert changed
def test_pycremoval(self, tmpdir): def test_pycremoval(self, tmpdir):
tmp = tmpdir tmp = tmpdir
hello = tmp.ensure("hello.py") hello = tmp.ensure("hello.py")

View File

@@ -201,14 +201,11 @@ class StatRecorder:
newstat = {} newstat = {}
for rootdir in self.rootdirlist: for rootdir in self.rootdirlist:
for path in rootdir.visit(self.fil, self.rec): for path in rootdir.visit(self.fil, self.rec):
oldstat = statcache.get(path, None) oldstat = statcache.pop(path, None)
if oldstat is not None:
del statcache[path]
try: try:
newstat[path] = curstat = path.stat() newstat[path] = curstat = path.stat()
except py.error.ENOENT: except py.error.ENOENT:
if oldstat: if oldstat:
del statcache[path]
changed = True changed = True
else: else:
if oldstat: if oldstat: