##// END OF EJS Templates
test-lock.py: allow PID to be changed in test state...
test-lock.py: allow PID to be changed in test state This will be used in upcoming patches to create locks that appear as if they're being created by child processes.

File last commit:

r26385:fb1a424e default
r26385:fb1a424e default
Show More
test-lock.py
147 lines | 4.4 KiB | text/x-python | PythonLexer
Siddharth Agarwal
tests: add unit tests for locking code...
r26289 from __future__ import absolute_import
import os
import silenttestrunner
import tempfile
import unittest
from mercurial import (
lock,
scmutil,
)
testlockname = 'testlock'
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
tests: add unit tests for locking code...
r26289 lock.lock()
# fake a fork
lock.pid += 1
lock.release()
state.assertreleasecalled(False)
state.assertpostreleasecalled(False)
state.assertlockexists(True)
# release the actual lock
lock.pid -= 1
lock.release()
state.assertreleasecalled(True)
state.assertpostreleasecalled(True)
state.assertlockexists(False)
if __name__ == '__main__':
silenttestrunner.main(__name__)