##// END OF EJS Templates
test-lock.py: add a lock wrapper that allows faking the PID...
Siddharth Agarwal -
r26384:ad6e56d0 default
parent child Browse files
Show More
@@ -1,136 +1,145 b''
1 1 from __future__ import absolute_import
2 2
3 3 import os
4 4 import silenttestrunner
5 5 import tempfile
6 6 import unittest
7 7
8 8 from mercurial import (
9 9 lock,
10 10 scmutil,
11 11 )
12 12
13 13 testlockname = 'testlock'
14 14
15 class lockwrapper(lock.lock):
16 def __init__(self, pidoffset, *args, **kwargs):
17 # lock.lock.__init__() calls lock(), so the pidoffset assignment needs
18 # to be earlier
19 self._pidoffset = pidoffset
20 super(lockwrapper, self).__init__(*args, **kwargs)
21 def _getpid(self):
22 return os.getpid() + self._pidoffset
23
15 24 class teststate(object):
16 25 def __init__(self, testcase, dir):
17 26 self._testcase = testcase
18 27 self._acquirecalled = False
19 28 self._releasecalled = False
20 29 self._postreleasecalled = False
21 30 self.vfs = scmutil.vfs(dir, audit=False)
22 31
23 32 def makelock(self, *args, **kwargs):
24 33 l = lock.lock(self.vfs, testlockname, releasefn=self.releasefn,
25 34 acquirefn=self.acquirefn, *args, **kwargs)
26 35 l.postrelease.append(self.postreleasefn)
27 36 return l
28 37
29 38 def acquirefn(self):
30 39 self._acquirecalled = True
31 40
32 41 def releasefn(self):
33 42 self._releasecalled = True
34 43
35 44 def postreleasefn(self):
36 45 self._postreleasecalled = True
37 46
38 47 def assertacquirecalled(self, called):
39 48 self._testcase.assertEqual(
40 49 self._acquirecalled, called,
41 50 'expected acquire to be %s but was actually %s' % (
42 51 self._tocalled(called),
43 52 self._tocalled(self._acquirecalled),
44 53 ))
45 54
46 55 def resetacquirefn(self):
47 56 self._acquirecalled = False
48 57
49 58 def assertreleasecalled(self, called):
50 59 self._testcase.assertEqual(
51 60 self._releasecalled, called,
52 61 'expected release to be %s but was actually %s' % (
53 62 self._tocalled(called),
54 63 self._tocalled(self._releasecalled),
55 64 ))
56 65
57 66 def assertpostreleasecalled(self, called):
58 67 self._testcase.assertEqual(
59 68 self._postreleasecalled, called,
60 69 'expected postrelease to be %s but was actually %s' % (
61 70 self._tocalled(called),
62 71 self._tocalled(self._postreleasecalled),
63 72 ))
64 73
65 74 def assertlockexists(self, exists):
66 75 actual = self.vfs.lexists(testlockname)
67 76 self._testcase.assertEqual(
68 77 actual, exists,
69 78 'expected lock to %s but actually did %s' % (
70 79 self._toexists(exists),
71 80 self._toexists(actual),
72 81 ))
73 82
74 83 def _tocalled(self, called):
75 84 if called:
76 85 return 'called'
77 86 else:
78 87 return 'not called'
79 88
80 89 def _toexists(self, exists):
81 90 if exists:
82 91 return 'exist'
83 92 else:
84 93 return 'not exist'
85 94
86 95 class testlock(unittest.TestCase):
87 96 def testlock(self):
88 97 state = teststate(self, tempfile.mkdtemp(dir=os.getcwd()))
89 98 lock = state.makelock()
90 99 state.assertacquirecalled(True)
91 100 lock.release()
92 101 state.assertreleasecalled(True)
93 102 state.assertpostreleasecalled(True)
94 103 state.assertlockexists(False)
95 104
96 105 def testrecursivelock(self):
97 106 state = teststate(self, tempfile.mkdtemp(dir=os.getcwd()))
98 107 lock = state.makelock()
99 108 state.assertacquirecalled(True)
100 109
101 110 state.resetacquirefn()
102 111 lock.lock()
103 112 # recursive lock should not call acquirefn again
104 113 state.assertacquirecalled(False)
105 114
106 115 lock.release() # brings lock refcount down from 2 to 1
107 116 state.assertreleasecalled(False)
108 117 state.assertpostreleasecalled(False)
109 118 state.assertlockexists(True)
110 119
111 120 lock.release() # releases the lock
112 121 state.assertreleasecalled(True)
113 122 state.assertpostreleasecalled(True)
114 123 state.assertlockexists(False)
115 124
116 125 def testlockfork(self):
117 126 state = teststate(self, tempfile.mkdtemp(dir=os.getcwd()))
118 127 lock = state.makelock()
119 128 state.assertacquirecalled(True)
120 129 lock.lock()
121 130 # fake a fork
122 131 lock.pid += 1
123 132 lock.release()
124 133 state.assertreleasecalled(False)
125 134 state.assertpostreleasecalled(False)
126 135 state.assertlockexists(True)
127 136
128 137 # release the actual lock
129 138 lock.pid -= 1
130 139 lock.release()
131 140 state.assertreleasecalled(True)
132 141 state.assertpostreleasecalled(True)
133 142 state.assertlockexists(False)
134 143
135 144 if __name__ == '__main__':
136 145 silenttestrunner.main(__name__)
General Comments 0
You need to be logged in to leave comments. Login now