annotate tests/test-lock.py @ 26359:c545d51c901e

lock.release: do not unlink inherited locks This is part of a series that will allow locks to be inherited by subprocesses in limited circumstances. A subprocess unlinking a lock will lead to potential corruption from other concurrent processes.
author Siddharth Agarwal <sid0@fb.com>
date Thu, 24 Sep 2015 16:03:26 -0700
parents db4c192cb9b3
children 94dc10834b79
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
1 from __future__ import absolute_import
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
2
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
3 import os
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
4 import silenttestrunner
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
5 import tempfile
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
6 import unittest
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
7
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
8 from mercurial import (
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
9 lock,
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
10 scmutil,
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
11 )
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
12
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
13 testlockname = 'testlock'
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
14
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
15 class teststate(object):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
16 def __init__(self, testcase):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
17 self._testcase = testcase
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
18 self._acquirecalled = False
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
19 self._releasecalled = False
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
20 self._postreleasecalled = False
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
21 d = tempfile.mkdtemp(dir=os.getcwd())
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
22 self.vfs = scmutil.vfs(d, audit=False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
23
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
24 def makelock(self, *args, **kwargs):
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
25 l = lock.lock(self.vfs, testlockname, releasefn=self.releasefn,
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
26 acquirefn=self.acquirefn, *args, **kwargs)
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
27 l.postrelease.append(self.postreleasefn)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
28 return l
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
29
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
30 def acquirefn(self):
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
31 self._acquirecalled = True
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
32
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
33 def releasefn(self):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
34 self._releasecalled = True
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
35
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
36 def postreleasefn(self):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
37 self._postreleasecalled = True
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
38
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
39 def assertacquirecalled(self, called):
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
40 self._testcase.assertEqual(
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
41 self._acquirecalled, called,
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
42 'expected acquire to be %s but was actually %s' % (
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
43 self._tocalled(called),
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
44 self._tocalled(self._acquirecalled),
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
45 ))
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
46
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
47 def resetacquirefn(self):
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
48 self._acquirecalled = False
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
49
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
50 def assertreleasecalled(self, called):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
51 self._testcase.assertEqual(
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
52 self._releasecalled, called,
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
53 'expected release to be %s but was actually %s' % (
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
54 self._tocalled(called),
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
55 self._tocalled(self._releasecalled),
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
56 ))
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
57
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
58 def assertpostreleasecalled(self, called):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
59 self._testcase.assertEqual(
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
60 self._postreleasecalled, called,
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
61 'expected postrelease to be %s but was actually %s' % (
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
62 self._tocalled(called),
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
63 self._tocalled(self._postreleasecalled),
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
64 ))
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
65
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
66 def assertlockexists(self, exists):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
67 actual = self.vfs.lexists(testlockname)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
68 self._testcase.assertEqual(
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
69 actual, exists,
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
70 'expected lock to %s but actually did %s' % (
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
71 self._toexists(exists),
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
72 self._toexists(actual),
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
73 ))
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
74
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
75 def _tocalled(self, called):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
76 if called:
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
77 return 'called'
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
78 else:
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
79 return 'not called'
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
80
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
81 def _toexists(self, exists):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
82 if exists:
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
83 return 'exists'
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
84 else:
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
85 return 'not exists'
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
86
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
87 class testlock(unittest.TestCase):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
88 def testlock(self):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
89 state = teststate(self)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
90 lock = state.makelock()
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
91 state.assertacquirecalled(True)
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
92 lock.release()
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
93 state.assertreleasecalled(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
94 state.assertpostreleasecalled(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
95 state.assertlockexists(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
96
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
97 def testrecursivelock(self):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
98 state = teststate(self)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
99 lock = state.makelock()
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
100 state.assertacquirecalled(True)
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
101
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
102 state.resetacquirefn()
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
103 lock.lock()
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
104 # recursive lock should not call acquirefn again
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
105 state.assertacquirecalled(False)
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
106
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
107 lock.release() # brings lock refcount down from 2 to 1
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
108 state.assertreleasecalled(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
109 state.assertpostreleasecalled(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
110 state.assertlockexists(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
111
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
112 lock.release() # releases the lock
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
113 state.assertreleasecalled(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
114 state.assertpostreleasecalled(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
115 state.assertlockexists(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
116
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
117 def testlockfork(self):
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
118 state = teststate(self)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
119 lock = state.makelock()
26321
db4c192cb9b3 lock: move acquirefn call to inside the lock
Siddharth Agarwal <sid0@fb.com>
parents: 26289
diff changeset
120 state.assertacquirecalled(True)
26289
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
121 lock.lock()
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
122 # fake a fork
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
123 lock.pid += 1
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
124 lock.release()
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
125 state.assertreleasecalled(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
126 state.assertpostreleasecalled(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
127 state.assertlockexists(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
128
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
129 # release the actual lock
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
130 lock.pid -= 1
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
131 lock.release()
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
132 state.assertreleasecalled(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
133 state.assertpostreleasecalled(True)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
134 state.assertlockexists(False)
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
135
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
136 if __name__ == '__main__':
c4b667a7a51d tests: add unit tests for locking code
Siddharth Agarwal <sid0@fb.com>
parents:
diff changeset
137 silenttestrunner.main(__name__)