##// END OF EJS Templates
localrepo: add a note about parentenvvar...
localrepo: add a note about parentenvvar Review feedback from Pierre-Yves David.

File last commit:

r26387:e16f80f8 default
r26472:406a654b default
Show More
test-lock.py
256 lines | 8.0 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
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 (
lock,
scmutil,
)
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):
return type(x)(x.im_func, copy.deepcopy(x.im_self, memo), x.im_class)
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):
return os.getpid() + self._pidoffset
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
Siddharth Agarwal
test-lock.py: move temp dir generation to testcase...
r26382 self.vfs = scmutil.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
lockname = parentlock.prepinherit()
parentstate.assertreleasecalled(True)
parentstate.assertpostreleasecalled(False)
parentstate.assertlockexists(True)
childstate = teststate(self, d, pidoffset=1)
childlock = childstate.makelock(parentlock=lockname)
childstate.assertacquirecalled(True)
# release the child lock -- the lock file should still exist on disk
childlock.release()
childstate.assertreleasecalled(True)
childstate.assertpostreleasecalled(True)
childstate.assertlockexists(True)
parentstate.resetacquirefn()
parentlock.reacquire()
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)
lock0name = lock0.prepinherit()
state0.assertreleasecalled(True)
state0.assertpostreleasecalled(False)
state0.assertlockexists(True)
state1 = teststate(self, d, pidoffset=1)
lock1 = state1.makelock(parentlock=lock0name)
state1.assertacquirecalled(True)
# from within lock1, acquire another lock
lock1name = lock1.prepinherit()
# since the file on disk is lock0's this should have the same name
self.assertEqual(lock0name, lock1name)
state2 = teststate(self, d, pidoffset=2)
lock2 = state2.makelock(parentlock=lock1name)
state2.assertacquirecalled(True)
lock2.release()
state2.assertreleasecalled(True)
state2.assertpostreleasecalled(True)
state2.assertlockexists(True)
state1.resetacquirefn()
lock1.reacquire()
state1.assertacquirecalled(True)
lock1.release()
state1.assertreleasecalled(True)
state1.assertpostreleasecalled(True)
state1.assertlockexists(True)
lock0.reacquire()
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
lockname = parentlock.prepinherit()
childstate = teststate(self, d, pidoffset=1)
childlock = childstate.makelock(parentlock=lockname)
childstate.assertacquirecalled(True)
# fork the child lock
forkchildlock = copy.deepcopy(childlock)
forkchildlock._pidoffset += 1
forkchildlock.release()
childstate.assertreleasecalled(False)
childstate.assertpostreleasecalled(False)
childstate.assertlockexists(True)
# release the child lock
childlock.release()
childstate.assertreleasecalled(True)
childstate.assertpostreleasecalled(True)
childstate.assertlockexists(True)
parentlock.reacquire()
parentlock.release()
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 if __name__ == '__main__':
silenttestrunner.main(__name__)