##// END OF EJS Templates
py3: byteify test-lock.py...
Matt Harbison -
r39984:5ee3146c default
parent child Browse files
Show More
@@ -1,296 +1,296 b''
1 1 from __future__ import absolute_import
2 2
3 3 import copy
4 4 import errno
5 import os
6 5 import silenttestrunner
7 6 import tempfile
8 7 import types
9 8 import unittest
10 9
11 10 from mercurial import (
11 encoding,
12 12 error,
13 13 lock,
14 14 vfs as vfsmod,
15 15 )
16 16
17 testlockname = 'testlock'
17 testlockname = b'testlock'
18 18
19 19 # work around http://bugs.python.org/issue1515
20 20 if types.MethodType not in copy._deepcopy_dispatch:
21 21 def _deepcopy_method(x, memo):
22 22 return type(x)(x.__func__, copy.deepcopy(x.__self__, memo), x.im_class)
23 23 copy._deepcopy_dispatch[types.MethodType] = _deepcopy_method
24 24
25 25 class lockwrapper(lock.lock):
26 26 def __init__(self, pidoffset, *args, **kwargs):
27 27 # lock.lock.__init__() calls lock(), so the pidoffset assignment needs
28 28 # to be earlier
29 29 self._pidoffset = pidoffset
30 30 super(lockwrapper, self).__init__(*args, **kwargs)
31 31 def _getpid(self):
32 32 return super(lockwrapper, self)._getpid() + self._pidoffset
33 33
34 34 class teststate(object):
35 35 def __init__(self, testcase, dir, pidoffset=0):
36 36 self._testcase = testcase
37 37 self._acquirecalled = False
38 38 self._releasecalled = False
39 39 self._postreleasecalled = False
40 40 self.vfs = vfsmod.vfs(dir, audit=False)
41 41 self._pidoffset = pidoffset
42 42
43 43 def makelock(self, *args, **kwargs):
44 44 l = lockwrapper(self._pidoffset, self.vfs, testlockname,
45 45 releasefn=self.releasefn, acquirefn=self.acquirefn,
46 46 *args, **kwargs)
47 47 l.postrelease.append(self.postreleasefn)
48 48 return l
49 49
50 50 def acquirefn(self):
51 51 self._acquirecalled = True
52 52
53 53 def releasefn(self):
54 54 self._releasecalled = True
55 55
56 56 def postreleasefn(self):
57 57 self._postreleasecalled = True
58 58
59 59 def assertacquirecalled(self, called):
60 60 self._testcase.assertEqual(
61 61 self._acquirecalled, called,
62 62 'expected acquire to be %s but was actually %s' % (
63 63 self._tocalled(called),
64 64 self._tocalled(self._acquirecalled),
65 65 ))
66 66
67 67 def resetacquirefn(self):
68 68 self._acquirecalled = False
69 69
70 70 def assertreleasecalled(self, called):
71 71 self._testcase.assertEqual(
72 72 self._releasecalled, called,
73 73 'expected release to be %s but was actually %s' % (
74 74 self._tocalled(called),
75 75 self._tocalled(self._releasecalled),
76 76 ))
77 77
78 78 def assertpostreleasecalled(self, called):
79 79 self._testcase.assertEqual(
80 80 self._postreleasecalled, called,
81 81 'expected postrelease to be %s but was actually %s' % (
82 82 self._tocalled(called),
83 83 self._tocalled(self._postreleasecalled),
84 84 ))
85 85
86 86 def assertlockexists(self, exists):
87 87 actual = self.vfs.lexists(testlockname)
88 88 self._testcase.assertEqual(
89 89 actual, exists,
90 90 'expected lock to %s but actually did %s' % (
91 91 self._toexists(exists),
92 92 self._toexists(actual),
93 93 ))
94 94
95 95 def _tocalled(self, called):
96 96 if called:
97 97 return 'called'
98 98 else:
99 99 return 'not called'
100 100
101 101 def _toexists(self, exists):
102 102 if exists:
103 103 return 'exist'
104 104 else:
105 105 return 'not exist'
106 106
107 107 class testlock(unittest.TestCase):
108 108 def testlock(self):
109 state = teststate(self, tempfile.mkdtemp(dir=os.getcwd()))
109 state = teststate(self, tempfile.mkdtemp(dir=encoding.getcwd()))
110 110 lock = state.makelock()
111 111 state.assertacquirecalled(True)
112 112 lock.release()
113 113 state.assertreleasecalled(True)
114 114 state.assertpostreleasecalled(True)
115 115 state.assertlockexists(False)
116 116
117 117 def testrecursivelock(self):
118 state = teststate(self, tempfile.mkdtemp(dir=os.getcwd()))
118 state = teststate(self, tempfile.mkdtemp(dir=encoding.getcwd()))
119 119 lock = state.makelock()
120 120 state.assertacquirecalled(True)
121 121
122 122 state.resetacquirefn()
123 123 lock.lock()
124 124 # recursive lock should not call acquirefn again
125 125 state.assertacquirecalled(False)
126 126
127 127 lock.release() # brings lock refcount down from 2 to 1
128 128 state.assertreleasecalled(False)
129 129 state.assertpostreleasecalled(False)
130 130 state.assertlockexists(True)
131 131
132 132 lock.release() # releases the lock
133 133 state.assertreleasecalled(True)
134 134 state.assertpostreleasecalled(True)
135 135 state.assertlockexists(False)
136 136
137 137 def testlockfork(self):
138 state = teststate(self, tempfile.mkdtemp(dir=os.getcwd()))
138 state = teststate(self, tempfile.mkdtemp(dir=encoding.getcwd()))
139 139 lock = state.makelock()
140 140 state.assertacquirecalled(True)
141 141
142 142 # fake a fork
143 143 forklock = copy.deepcopy(lock)
144 144 forklock._pidoffset = 1
145 145 forklock.release()
146 146 state.assertreleasecalled(False)
147 147 state.assertpostreleasecalled(False)
148 148 state.assertlockexists(True)
149 149
150 150 # release the actual lock
151 151 lock.release()
152 152 state.assertreleasecalled(True)
153 153 state.assertpostreleasecalled(True)
154 154 state.assertlockexists(False)
155 155
156 156 def testinheritlock(self):
157 d = tempfile.mkdtemp(dir=os.getcwd())
157 d = tempfile.mkdtemp(dir=encoding.getcwd())
158 158 parentstate = teststate(self, d)
159 159 parentlock = parentstate.makelock()
160 160 parentstate.assertacquirecalled(True)
161 161
162 162 # set up lock inheritance
163 163 with parentlock.inherit() as lockname:
164 164 parentstate.assertreleasecalled(True)
165 165 parentstate.assertpostreleasecalled(False)
166 166 parentstate.assertlockexists(True)
167 167
168 168 childstate = teststate(self, d, pidoffset=1)
169 169 childlock = childstate.makelock(parentlock=lockname)
170 170 childstate.assertacquirecalled(True)
171 171
172 172 childlock.release()
173 173 childstate.assertreleasecalled(True)
174 174 childstate.assertpostreleasecalled(False)
175 175 childstate.assertlockexists(True)
176 176
177 177 parentstate.resetacquirefn()
178 178
179 179 parentstate.assertacquirecalled(True)
180 180
181 181 parentlock.release()
182 182 parentstate.assertreleasecalled(True)
183 183 parentstate.assertpostreleasecalled(True)
184 184 parentstate.assertlockexists(False)
185 185
186 186 def testmultilock(self):
187 d = tempfile.mkdtemp(dir=os.getcwd())
187 d = tempfile.mkdtemp(dir=encoding.getcwd())
188 188 state0 = teststate(self, d)
189 189 lock0 = state0.makelock()
190 190 state0.assertacquirecalled(True)
191 191
192 192 with lock0.inherit() as lock0name:
193 193 state0.assertreleasecalled(True)
194 194 state0.assertpostreleasecalled(False)
195 195 state0.assertlockexists(True)
196 196
197 197 state1 = teststate(self, d, pidoffset=1)
198 198 lock1 = state1.makelock(parentlock=lock0name)
199 199 state1.assertacquirecalled(True)
200 200
201 201 # from within lock1, acquire another lock
202 202 with lock1.inherit() as lock1name:
203 203 # since the file on disk is lock0's this should have the same
204 204 # name
205 205 self.assertEqual(lock0name, lock1name)
206 206
207 207 state2 = teststate(self, d, pidoffset=2)
208 208 lock2 = state2.makelock(parentlock=lock1name)
209 209 state2.assertacquirecalled(True)
210 210
211 211 lock2.release()
212 212 state2.assertreleasecalled(True)
213 213 state2.assertpostreleasecalled(False)
214 214 state2.assertlockexists(True)
215 215
216 216 state1.resetacquirefn()
217 217
218 218 state1.assertacquirecalled(True)
219 219
220 220 lock1.release()
221 221 state1.assertreleasecalled(True)
222 222 state1.assertpostreleasecalled(False)
223 223 state1.assertlockexists(True)
224 224
225 225 lock0.release()
226 226
227 227 def testinheritlockfork(self):
228 d = tempfile.mkdtemp(dir=os.getcwd())
228 d = tempfile.mkdtemp(dir=encoding.getcwd())
229 229 parentstate = teststate(self, d)
230 230 parentlock = parentstate.makelock()
231 231 parentstate.assertacquirecalled(True)
232 232
233 233 # set up lock inheritance
234 234 with parentlock.inherit() as lockname:
235 235 childstate = teststate(self, d, pidoffset=1)
236 236 childlock = childstate.makelock(parentlock=lockname)
237 237 childstate.assertacquirecalled(True)
238 238
239 239 # fork the child lock
240 240 forkchildlock = copy.deepcopy(childlock)
241 241 forkchildlock._pidoffset += 1
242 242 forkchildlock.release()
243 243 childstate.assertreleasecalled(False)
244 244 childstate.assertpostreleasecalled(False)
245 245 childstate.assertlockexists(True)
246 246
247 247 # release the child lock
248 248 childlock.release()
249 249 childstate.assertreleasecalled(True)
250 250 childstate.assertpostreleasecalled(False)
251 251 childstate.assertlockexists(True)
252 252
253 253 parentlock.release()
254 254
255 255 def testinheritcheck(self):
256 d = tempfile.mkdtemp(dir=os.getcwd())
256 d = tempfile.mkdtemp(dir=encoding.getcwd())
257 257 state = teststate(self, d)
258 258 def check():
259 259 raise error.LockInheritanceContractViolation('check failed')
260 260 lock = state.makelock(inheritchecker=check)
261 261 state.assertacquirecalled(True)
262 262
263 263 with self.assertRaises(error.LockInheritanceContractViolation):
264 264 with lock.inherit():
265 265 pass
266 266
267 267 lock.release()
268 268
269 269 def testfrequentlockunlock(self):
270 270 """This tests whether lock acquisition fails as expected, even if
271 271 (1) lock can't be acquired (makelock fails by EEXIST), and
272 272 (2) locker info can't be read in (readlock fails by ENOENT) while
273 273 retrying 5 times.
274 274 """
275 275
276 d = tempfile.mkdtemp(dir=os.getcwd())
276 d = tempfile.mkdtemp(dir=encoding.getcwd())
277 277 state = teststate(self, d)
278 278
279 279 def emulatefrequentlock(*args):
280 280 raise OSError(errno.EEXIST, "File exists")
281 281 def emulatefrequentunlock(*args):
282 282 raise OSError(errno.ENOENT, "No such file or directory")
283 283
284 284 state.vfs.makelock = emulatefrequentlock
285 285 state.vfs.readlock = emulatefrequentunlock
286 286
287 287 try:
288 288 state.makelock(timeout=0)
289 289 self.fail("unexpected lock acquisition")
290 290 except error.LockHeld as why:
291 291 self.assertTrue(why.errno == errno.ETIMEDOUT)
292 292 self.assertTrue(why.locker == "")
293 293 state.assertlockexists(False)
294 294
295 295 if __name__ == '__main__':
296 296 silenttestrunner.main(__name__)
General Comments 0
You need to be logged in to leave comments. Login now