##// END OF EJS Templates
py3: use b'%d' to convert int to bytes instead of str()...
py3: use b'%d' to convert int to bytes instead of str() Differential Revision: https://phab.mercurial-scm.org/D3280

File last commit:

r34727:daf12f69 default
r37599:5b836a4c default
Show More
test-lock.py
296 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 os
import silenttestrunner
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
from mercurial import (
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 )
testlockname = 'testlock'
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):
Siddharth Agarwal
test-lock.py: move temp dir generation to testcase...
r26382 state = teststate(self, tempfile.mkdtemp(dir=os.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):
Siddharth Agarwal
test-lock.py: move temp dir generation to testcase...
r26382 state = teststate(self, tempfile.mkdtemp(dir=os.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):
Siddharth Agarwal
test-lock.py: move temp dir generation to testcase...
r26382 state = teststate(self, tempfile.mkdtemp(dir=os.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
Siddharth Agarwal
test-lock.py: fix testing for forks...
r26386 forklock = copy.deepcopy(lock)
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):
d = tempfile.mkdtemp(dir=os.getcwd())
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):
d = tempfile.mkdtemp(dir=os.getcwd())
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):
d = tempfile.mkdtemp(dir=os.getcwd())
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
forkchildlock = copy.deepcopy(childlock)
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):
d = tempfile.mkdtemp(dir=os.getcwd())
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.
"""
d = tempfile.mkdtemp(dir=os.getcwd())
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__)