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