##// END OF EJS Templates
tests: perform a shallow copy instead of a deep copy...
tests: perform a shallow copy instead of a deep copy Python 3 can't perform a deep copy because it looks like symbols in the locals() namespace are not deep-copyable. For the curious, somehow the deepcopy() is attempting to copy objects attached to the unittest.* functions for the running test! We don't use deepcopy() anywhere in the code base and a shallow object copy should be sufficient to test lock copying. Actually, I'm not sure why we even test this, as I couldn't find copy.copy() being used for lock copying either. Who knows. Differential Revision: https://phab.mercurial-scm.org/D5770

File last commit:

r41519:9701bac5 default
r41519:9701bac5 default
Show More
test-lock.py
297 lines | 9.6 KiB | text/x-python | PythonLexer
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 from __future__ import absolute_import
Siddharth Agarwal
test-lock.py: fix testing for forks...
r26386 import copy
FUJIWARA Katsunori
lock: avoid unintentional lock acquisition at failure of readlock...
r32089 import errno
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 import tempfile
Siddharth Agarwal
test-lock.py: fix testing for forks...
r26386 import types
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 import unittest
FUJIWARA Katsunori
tests: fix style issue of importing order in test-lock.py...
r40240 import silenttestrunner
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 from mercurial import (
Matt Harbison
py3: byteify test-lock.py...
r39984 encoding,
Siddharth Agarwal
lock: add a way to prevent locks from being inherited...
r26498 error,
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 lock,
Pierre-Yves David
vfs: use 'vfs' module directly in 'test-lock'...
r31249 vfs as vfsmod,
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 )
Matt Harbison
py3: byteify test-lock.py...
r39984 testlockname = b'testlock'
Siddharth Agarwal
tests: add unit tests for locking code...
r26289
Siddharth Agarwal
test-lock.py: fix testing for forks...
r26386 # work around http://bugs.python.org/issue1515
if types.MethodType not in copy._deepcopy_dispatch:
def _deepcopy_method(x, memo):
Augie Fackler
python3: replace im_{self,func} with __{self,func}__ globally...
r34727 return type(x)(x.__func__, copy.deepcopy(x.__self__, memo), x.im_class)
Siddharth Agarwal
test-lock.py: fix testing for forks...
r26386 copy._deepcopy_dispatch[types.MethodType] = _deepcopy_method
Siddharth Agarwal
test-lock.py: add a lock wrapper that allows faking the PID...
r26384 class lockwrapper(lock.lock):
def __init__(self, pidoffset, *args, **kwargs):
# lock.lock.__init__() calls lock(), so the pidoffset assignment needs
# to be earlier
self._pidoffset = pidoffset
super(lockwrapper, self).__init__(*args, **kwargs)
def _getpid(self):
timeless
util: enable getpid to be replaced...
r28027 return super(lockwrapper, self)._getpid() + self._pidoffset
Siddharth Agarwal
test-lock.py: add a lock wrapper that allows faking the PID...
r26384
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 class teststate(object):
Siddharth Agarwal
test-lock.py: allow PID to be changed in test state...
r26385 def __init__(self, testcase, dir, pidoffset=0):
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 self._testcase = testcase
Siddharth Agarwal
lock: move acquirefn call to inside the lock...
r26321 self._acquirecalled = False
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 self._releasecalled = False
self._postreleasecalled = False
Pierre-Yves David
vfs: use 'vfs' module directly in 'test-lock'...
r31249 self.vfs = vfsmod.vfs(dir, audit=False)
Siddharth Agarwal
test-lock.py: allow PID to be changed in test state...
r26385 self._pidoffset = pidoffset
Siddharth Agarwal
tests: add unit tests for locking code...
r26289
def makelock(self, *args, **kwargs):
Siddharth Agarwal
test-lock.py: allow PID to be changed in test state...
r26385 l = lockwrapper(self._pidoffset, self.vfs, testlockname,
releasefn=self.releasefn, acquirefn=self.acquirefn,
*args, **kwargs)
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 l.postrelease.append(self.postreleasefn)
return l
Siddharth Agarwal
lock: move acquirefn call to inside the lock...
r26321 def acquirefn(self):
self._acquirecalled = True
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 def releasefn(self):
self._releasecalled = True
def postreleasefn(self):
self._postreleasecalled = True
Siddharth Agarwal
lock: move acquirefn call to inside the lock...
r26321 def assertacquirecalled(self, called):
self._testcase.assertEqual(
self._acquirecalled, called,
'expected acquire to be %s but was actually %s' % (
self._tocalled(called),
self._tocalled(self._acquirecalled),
))
def resetacquirefn(self):
self._acquirecalled = False
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 def assertreleasecalled(self, called):
self._testcase.assertEqual(
self._releasecalled, called,
'expected release to be %s but was actually %s' % (
self._tocalled(called),
self._tocalled(self._releasecalled),
))
def assertpostreleasecalled(self, called):
self._testcase.assertEqual(
self._postreleasecalled, called,
'expected postrelease to be %s but was actually %s' % (
self._tocalled(called),
self._tocalled(self._postreleasecalled),
))
def assertlockexists(self, exists):
actual = self.vfs.lexists(testlockname)
self._testcase.assertEqual(
actual, exists,
'expected lock to %s but actually did %s' % (
self._toexists(exists),
self._toexists(actual),
))
def _tocalled(self, called):
if called:
return 'called'
else:
return 'not called'
def _toexists(self, exists):
if exists:
Siddharth Agarwal
test-lock.py: copy-edit assertions about file existing...
r26381 return 'exist'
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 else:
Siddharth Agarwal
test-lock.py: copy-edit assertions about file existing...
r26381 return 'not exist'
Siddharth Agarwal
tests: add unit tests for locking code...
r26289
class testlock(unittest.TestCase):
def testlock(self):
Matt Harbison
py3: byteify test-lock.py...
r39984 state = teststate(self, tempfile.mkdtemp(dir=encoding.getcwd()))
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 lock = state.makelock()
Siddharth Agarwal
lock: move acquirefn call to inside the lock...
r26321 state.assertacquirecalled(True)
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 lock.release()
state.assertreleasecalled(True)
state.assertpostreleasecalled(True)
state.assertlockexists(False)
def testrecursivelock(self):
Matt Harbison
py3: byteify test-lock.py...
r39984 state = teststate(self, tempfile.mkdtemp(dir=encoding.getcwd()))
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 lock = state.makelock()
Siddharth Agarwal
lock: move acquirefn call to inside the lock...
r26321 state.assertacquirecalled(True)
state.resetacquirefn()
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 lock.lock()
Siddharth Agarwal
lock: move acquirefn call to inside the lock...
r26321 # recursive lock should not call acquirefn again
state.assertacquirecalled(False)
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 lock.release() # brings lock refcount down from 2 to 1
state.assertreleasecalled(False)
state.assertpostreleasecalled(False)
state.assertlockexists(True)
lock.release() # releases the lock
state.assertreleasecalled(True)
state.assertpostreleasecalled(True)
state.assertlockexists(False)
def testlockfork(self):
Matt Harbison
py3: byteify test-lock.py...
r39984 state = teststate(self, tempfile.mkdtemp(dir=encoding.getcwd()))
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 lock = state.makelock()
Siddharth Agarwal
lock: move acquirefn call to inside the lock...
r26321 state.assertacquirecalled(True)
Siddharth Agarwal
test-lock.py: fix testing for forks...
r26386
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 # fake a fork
Gregory Szorc
tests: perform a shallow copy instead of a deep copy...
r41519 forklock = copy.copy(lock)
Siddharth Agarwal
test-lock.py: fix testing for forks...
r26386 forklock._pidoffset = 1
forklock.release()
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 state.assertreleasecalled(False)
state.assertpostreleasecalled(False)
state.assertlockexists(True)
# release the actual lock
lock.release()
state.assertreleasecalled(True)
state.assertpostreleasecalled(True)
state.assertlockexists(False)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387 def testinheritlock(self):
Matt Harbison
py3: byteify test-lock.py...
r39984 d = tempfile.mkdtemp(dir=encoding.getcwd())
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387 parentstate = teststate(self, d)
parentlock = parentstate.makelock()
parentstate.assertacquirecalled(True)
# set up lock inheritance
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 with parentlock.inherit() as lockname:
parentstate.assertreleasecalled(True)
parentstate.assertpostreleasecalled(False)
parentstate.assertlockexists(True)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 childstate = teststate(self, d, pidoffset=1)
childlock = childstate.makelock(parentlock=lockname)
childstate.assertacquirecalled(True)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 childlock.release()
childstate.assertreleasecalled(True)
Siddharth Agarwal
lock.release: don't call postrelease functions for inherited locks...
r26474 childstate.assertpostreleasecalled(False)
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 childstate.assertlockexists(True)
parentstate.resetacquirefn()
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387 parentstate.assertacquirecalled(True)
parentlock.release()
parentstate.assertreleasecalled(True)
parentstate.assertpostreleasecalled(True)
parentstate.assertlockexists(False)
def testmultilock(self):
Matt Harbison
py3: byteify test-lock.py...
r39984 d = tempfile.mkdtemp(dir=encoding.getcwd())
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387 state0 = teststate(self, d)
lock0 = state0.makelock()
state0.assertacquirecalled(True)
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 with lock0.inherit() as lock0name:
state0.assertreleasecalled(True)
state0.assertpostreleasecalled(False)
state0.assertlockexists(True)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 state1 = teststate(self, d, pidoffset=1)
lock1 = state1.makelock(parentlock=lock0name)
state1.assertacquirecalled(True)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 # from within lock1, acquire another lock
with lock1.inherit() as lock1name:
# since the file on disk is lock0's this should have the same
# name
self.assertEqual(lock0name, lock1name)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 state2 = teststate(self, d, pidoffset=2)
lock2 = state2.makelock(parentlock=lock1name)
state2.assertacquirecalled(True)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 lock2.release()
state2.assertreleasecalled(True)
Siddharth Agarwal
lock.release: don't call postrelease functions for inherited locks...
r26474 state2.assertpostreleasecalled(False)
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 state2.assertlockexists(True)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 state1.resetacquirefn()
state1.assertacquirecalled(True)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 lock1.release()
state1.assertreleasecalled(True)
Siddharth Agarwal
lock.release: don't call postrelease functions for inherited locks...
r26474 state1.assertpostreleasecalled(False)
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 state1.assertlockexists(True)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387
lock0.release()
def testinheritlockfork(self):
Matt Harbison
py3: byteify test-lock.py...
r39984 d = tempfile.mkdtemp(dir=encoding.getcwd())
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387 parentstate = teststate(self, d)
parentlock = parentstate.makelock()
parentstate.assertacquirecalled(True)
# set up lock inheritance
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 with parentlock.inherit() as lockname:
childstate = teststate(self, d, pidoffset=1)
childlock = childstate.makelock(parentlock=lockname)
childstate.assertacquirecalled(True)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 # fork the child lock
Gregory Szorc
tests: perform a shallow copy instead of a deep copy...
r41519 forkchildlock = copy.copy(childlock)
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 forkchildlock._pidoffset += 1
forkchildlock.release()
childstate.assertreleasecalled(False)
childstate.assertpostreleasecalled(False)
childstate.assertlockexists(True)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 # release the child lock
childlock.release()
childstate.assertreleasecalled(True)
Siddharth Agarwal
lock.release: don't call postrelease functions for inherited locks...
r26474 childstate.assertpostreleasecalled(False)
Siddharth Agarwal
lock: turn prepinherit/reacquire into a single context manager...
r26473 childstate.assertlockexists(True)
Siddharth Agarwal
lock: recognize parent locks while acquiring...
r26387
parentlock.release()
Siddharth Agarwal
lock: add a way to prevent locks from being inherited...
r26498 def testinheritcheck(self):
Matt Harbison
py3: byteify test-lock.py...
r39984 d = tempfile.mkdtemp(dir=encoding.getcwd())
Siddharth Agarwal
lock: add a way to prevent locks from being inherited...
r26498 state = teststate(self, d)
def check():
raise error.LockInheritanceContractViolation('check failed')
lock = state.makelock(inheritchecker=check)
state.assertacquirecalled(True)
Gregory Szorc
tests: use context manager form of assertRaises...
r32279 with self.assertRaises(error.LockInheritanceContractViolation):
Siddharth Agarwal
localrepo: prevent wlock from being inherited when a transaction is running...
r26499 with lock.inherit():
Siddharth Agarwal
lock: add a way to prevent locks from being inherited...
r26498 pass
lock.release()
FUJIWARA Katsunori
lock: avoid unintentional lock acquisition at failure of readlock...
r32089 def testfrequentlockunlock(self):
"""This tests whether lock acquisition fails as expected, even if
(1) lock can't be acquired (makelock fails by EEXIST), and
(2) locker info can't be read in (readlock fails by ENOENT) while
retrying 5 times.
"""
Matt Harbison
py3: byteify test-lock.py...
r39984 d = tempfile.mkdtemp(dir=encoding.getcwd())
FUJIWARA Katsunori
lock: avoid unintentional lock acquisition at failure of readlock...
r32089 state = teststate(self, d)
def emulatefrequentlock(*args):
raise OSError(errno.EEXIST, "File exists")
def emulatefrequentunlock(*args):
raise OSError(errno.ENOENT, "No such file or directory")
state.vfs.makelock = emulatefrequentlock
state.vfs.readlock = emulatefrequentunlock
try:
state.makelock(timeout=0)
self.fail("unexpected lock acquisition")
except error.LockHeld as why:
self.assertTrue(why.errno == errno.ETIMEDOUT)
self.assertTrue(why.locker == "")
state.assertlockexists(False)
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 if __name__ == '__main__':
silenttestrunner.main(__name__)