##// END OF EJS Templates
smartset: use native set operations as fast paths...
smartset: use native set operations as fast paths For set operations like "&" and "-", where we know both basesets have their sets ready, and the first set is sorted, use the native Python set operations as a fast path. Note: "+" is not optimized as that will break the ordering. This leads to noticeable improvements on performance: revset | before | after | delta ---------------------------------------------------------------- draft() & draft() & draft() & draft() | 776 | 477 | -39% draft() + draft() + draft() + draft() | 2849 | 2864 | draft() - draft() + draft() - draft() | 943 | 240 | -75% draft() - draft() - draft() - draft() | 557 | 197 | -64% (time measured in microseconds)

File last commit:

r28027:14033c5d default
r31020:2d1bf840 default
Show More
test-lock.py
271 lines | 8.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
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,
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):
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
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
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)
def tryinherit():
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
self.assertRaises(error.LockInheritanceContractViolation, tryinherit)
lock.release()
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 if __name__ == '__main__':
silenttestrunner.main(__name__)