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