test-lock.py
208 lines
| 5.9 KiB
| text/x-python
|
PythonLexer
/ tests / test-lock.py
Siddharth Agarwal
|
r26386 | import copy | ||
FUJIWARA Katsunori
|
r32089 | import errno | ||
Siddharth Agarwal
|
r26289 | import tempfile | ||
Siddharth Agarwal
|
r26386 | import types | ||
Siddharth Agarwal
|
r26289 | import unittest | ||
FUJIWARA Katsunori
|
r40240 | import silenttestrunner | ||
Siddharth Agarwal
|
r26289 | from mercurial import ( | ||
Matt Harbison
|
r39984 | encoding, | ||
Siddharth Agarwal
|
r26498 | error, | ||
Siddharth Agarwal
|
r26289 | lock, | ||
Pierre-Yves David
|
r31249 | vfs as vfsmod, | ||
Siddharth Agarwal
|
r26289 | ) | ||
Matt Harbison
|
r39984 | testlockname = b'testlock' | ||
Siddharth Agarwal
|
r26289 | |||
Siddharth Agarwal
|
r26386 | # work around http://bugs.python.org/issue1515 | ||
if types.MethodType not in copy._deepcopy_dispatch: | ||||
Augie Fackler
|
r43346 | |||
Siddharth Agarwal
|
r26386 | def _deepcopy_method(x, memo): | ||
Augie Fackler
|
r34727 | return type(x)(x.__func__, copy.deepcopy(x.__self__, memo), x.im_class) | ||
Augie Fackler
|
r43346 | |||
Siddharth Agarwal
|
r26386 | copy._deepcopy_dispatch[types.MethodType] = _deepcopy_method | ||
Augie Fackler
|
r43346 | |||
Siddharth Agarwal
|
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) | ||||
Augie Fackler
|
r43346 | |||
Siddharth Agarwal
|
r26384 | def _getpid(self): | ||
timeless
|
r28027 | return super(lockwrapper, self)._getpid() + self._pidoffset | ||
Siddharth Agarwal
|
r26384 | |||
Augie Fackler
|
r43346 | |||
Gregory Szorc
|
r49801 | class teststate: | ||
Siddharth Agarwal
|
r26385 | def __init__(self, testcase, dir, pidoffset=0): | ||
Siddharth Agarwal
|
r26289 | self._testcase = testcase | ||
Siddharth Agarwal
|
r26321 | self._acquirecalled = False | ||
Siddharth Agarwal
|
r26289 | self._releasecalled = False | ||
self._postreleasecalled = False | ||||
Pierre-Yves David
|
r31249 | self.vfs = vfsmod.vfs(dir, audit=False) | ||
Siddharth Agarwal
|
r26385 | self._pidoffset = pidoffset | ||
Siddharth Agarwal
|
r26289 | |||
def makelock(self, *args, **kwargs): | ||||
Augie Fackler
|
r43346 | l = lockwrapper( | ||
self._pidoffset, | ||||
self.vfs, | ||||
testlockname, | ||||
releasefn=self.releasefn, | ||||
acquirefn=self.acquirefn, | ||||
*args, | ||||
**kwargs | ||||
) | ||||
Siddharth Agarwal
|
r26289 | l.postrelease.append(self.postreleasefn) | ||
return l | ||||
Siddharth Agarwal
|
r26321 | def acquirefn(self): | ||
self._acquirecalled = True | ||||
Siddharth Agarwal
|
r26289 | def releasefn(self): | ||
self._releasecalled = True | ||||
Kyle Lippincott
|
r44217 | def postreleasefn(self, success): | ||
Siddharth Agarwal
|
r26289 | self._postreleasecalled = True | ||
Siddharth Agarwal
|
r26321 | def assertacquirecalled(self, called): | ||
self._testcase.assertEqual( | ||||
Augie Fackler
|
r43346 | self._acquirecalled, | ||
called, | ||||
'expected acquire to be %s but was actually %s' | ||||
Augie Fackler
|
r46554 | % ( | ||
self._tocalled(called), | ||||
self._tocalled(self._acquirecalled), | ||||
), | ||||
Augie Fackler
|
r43346 | ) | ||
Siddharth Agarwal
|
r26321 | |||
def resetacquirefn(self): | ||||
self._acquirecalled = False | ||||
Siddharth Agarwal
|
r26289 | def assertreleasecalled(self, called): | ||
self._testcase.assertEqual( | ||||
Augie Fackler
|
r43346 | self._releasecalled, | ||
called, | ||||
'expected release to be %s but was actually %s' | ||||
Augie Fackler
|
r46554 | % ( | ||
self._tocalled(called), | ||||
self._tocalled(self._releasecalled), | ||||
), | ||||
Augie Fackler
|
r43346 | ) | ||
Siddharth Agarwal
|
r26289 | |||
def assertpostreleasecalled(self, called): | ||||
self._testcase.assertEqual( | ||||
Augie Fackler
|
r43346 | self._postreleasecalled, | ||
called, | ||||
'expected postrelease to be %s but was actually %s' | ||||
% ( | ||||
Siddharth Agarwal
|
r26289 | self._tocalled(called), | ||
self._tocalled(self._postreleasecalled), | ||||
Augie Fackler
|
r43346 | ), | ||
) | ||||
Siddharth Agarwal
|
r26289 | |||
def assertlockexists(self, exists): | ||||
actual = self.vfs.lexists(testlockname) | ||||
self._testcase.assertEqual( | ||||
Augie Fackler
|
r43346 | actual, | ||
exists, | ||||
'expected lock to %s but actually did %s' | ||||
Augie Fackler
|
r46554 | % ( | ||
self._toexists(exists), | ||||
self._toexists(actual), | ||||
), | ||||
Augie Fackler
|
r43346 | ) | ||
Siddharth Agarwal
|
r26289 | |||
def _tocalled(self, called): | ||||
if called: | ||||
return 'called' | ||||
else: | ||||
return 'not called' | ||||
def _toexists(self, exists): | ||||
if exists: | ||||
Siddharth Agarwal
|
r26381 | return 'exist' | ||
Siddharth Agarwal
|
r26289 | else: | ||
Siddharth Agarwal
|
r26381 | return 'not exist' | ||
Siddharth Agarwal
|
r26289 | |||
Augie Fackler
|
r43346 | |||
Siddharth Agarwal
|
r26289 | class testlock(unittest.TestCase): | ||
def testlock(self): | ||||
Matt Harbison
|
r39984 | state = teststate(self, tempfile.mkdtemp(dir=encoding.getcwd())) | ||
Siddharth Agarwal
|
r26289 | lock = state.makelock() | ||
Siddharth Agarwal
|
r26321 | state.assertacquirecalled(True) | ||
Siddharth Agarwal
|
r26289 | lock.release() | ||
state.assertreleasecalled(True) | ||||
state.assertpostreleasecalled(True) | ||||
state.assertlockexists(False) | ||||
def testrecursivelock(self): | ||||
Matt Harbison
|
r39984 | state = teststate(self, tempfile.mkdtemp(dir=encoding.getcwd())) | ||
Siddharth Agarwal
|
r26289 | lock = state.makelock() | ||
Siddharth Agarwal
|
r26321 | state.assertacquirecalled(True) | ||
state.resetacquirefn() | ||||
Siddharth Agarwal
|
r26289 | lock.lock() | ||
Siddharth Agarwal
|
r26321 | # recursive lock should not call acquirefn again | ||
state.assertacquirecalled(False) | ||||
Augie Fackler
|
r43346 | lock.release() # brings lock refcount down from 2 to 1 | ||
Siddharth Agarwal
|
r26289 | state.assertreleasecalled(False) | ||
state.assertpostreleasecalled(False) | ||||
state.assertlockexists(True) | ||||
Augie Fackler
|
r43346 | lock.release() # releases the lock | ||
Siddharth Agarwal
|
r26289 | state.assertreleasecalled(True) | ||
state.assertpostreleasecalled(True) | ||||
state.assertlockexists(False) | ||||
def testlockfork(self): | ||||
Matt Harbison
|
r39984 | state = teststate(self, tempfile.mkdtemp(dir=encoding.getcwd())) | ||
Siddharth Agarwal
|
r26289 | lock = state.makelock() | ||
Siddharth Agarwal
|
r26321 | state.assertacquirecalled(True) | ||
Siddharth Agarwal
|
r26386 | |||
Siddharth Agarwal
|
r26289 | # fake a fork | ||
Gregory Szorc
|
r41622 | forklock = copy.copy(lock) | ||
Siddharth Agarwal
|
r26386 | forklock._pidoffset = 1 | ||
forklock.release() | ||||
Siddharth Agarwal
|
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) | ||||
FUJIWARA Katsunori
|
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
|
r39984 | d = tempfile.mkdtemp(dir=encoding.getcwd()) | ||
FUJIWARA Katsunori
|
r32089 | state = teststate(self, d) | ||
def emulatefrequentlock(*args): | ||||
raise OSError(errno.EEXIST, "File exists") | ||||
Augie Fackler
|
r43346 | |||
FUJIWARA Katsunori
|
r32089 | 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) | ||||
Gregory Szorc
|
r41623 | self.assertTrue(why.locker == b"") | ||
FUJIWARA Katsunori
|
r32089 | state.assertlockexists(False) | ||
Augie Fackler
|
r43346 | |||
Siddharth Agarwal
|
r26289 | if __name__ == '__main__': | ||
silenttestrunner.main(__name__) | ||||