4 # Copyright (C) 2006, 2007 Google Inc.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 """Script for unittesting the locking module"""
30 from ganeti import locking
31 from ganeti import errors
32 from threading import Thread
35 class TestSharedLock(unittest.TestCase):
36 """SharedLock tests"""
39 self.sl = locking.SharedLock()
40 # helper threads use the 'done' queue to tell the master they finished.
41 self.done = Queue.Queue(0)
43 def testSequenceAndOwnership(self):
44 self.assert_(not self.sl._is_owned())
45 self.sl.acquire(shared=1)
46 self.assert_(self.sl._is_owned())
47 self.assert_(self.sl._is_owned(shared=1))
48 self.assert_(not self.sl._is_owned(shared=0))
50 self.assert_(not self.sl._is_owned())
52 self.assert_(self.sl._is_owned())
53 self.assert_(not self.sl._is_owned(shared=1))
54 self.assert_(self.sl._is_owned(shared=0))
56 self.assert_(not self.sl._is_owned())
57 self.sl.acquire(shared=1)
58 self.assert_(self.sl._is_owned())
59 self.assert_(self.sl._is_owned(shared=1))
60 self.assert_(not self.sl._is_owned(shared=0))
62 self.assert_(not self.sl._is_owned())
64 def testBooleanValue(self):
65 # semaphores are supposed to return a true value on a successful acquire
66 self.assert_(self.sl.acquire(shared=1))
68 self.assert_(self.sl.acquire())
71 def testDoubleLockingStoE(self):
72 self.sl.acquire(shared=1)
73 self.assertRaises(AssertionError, self.sl.acquire)
75 def testDoubleLockingEtoS(self):
77 self.assertRaises(AssertionError, self.sl.acquire, shared=1)
79 def testDoubleLockingStoS(self):
80 self.sl.acquire(shared=1)
81 self.assertRaises(AssertionError, self.sl.acquire, shared=1)
83 def testDoubleLockingEtoE(self):
85 self.assertRaises(AssertionError, self.sl.acquire)
87 # helper functions: called in a separate thread they acquire the lock, send
88 # their identifier on the done queue, then release it.
89 def _doItSharer(self):
91 self.sl.acquire(shared=1)
94 except errors.LockError:
97 def _doItExclusive(self):
102 except errors.LockError:
105 def _doItDelete(self):
109 except errors.LockError:
112 def testSharersCanCoexist(self):
113 self.sl.acquire(shared=1)
114 Thread(target=self._doItSharer).start()
115 self.assert_(self.done.get(True, 1))
118 def testExclusiveBlocksExclusive(self):
120 Thread(target=self._doItExclusive).start()
121 # give it a bit of time to check that it's not actually doing anything
122 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
124 self.assert_(self.done.get(True, 1))
126 def testExclusiveBlocksDelete(self):
128 Thread(target=self._doItDelete).start()
129 # give it a bit of time to check that it's not actually doing anything
130 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
132 self.assert_(self.done.get(True, 1))
134 def testExclusiveBlocksSharer(self):
136 Thread(target=self._doItSharer).start()
138 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
140 self.assert_(self.done.get(True, 1))
142 def testSharerBlocksExclusive(self):
143 self.sl.acquire(shared=1)
144 Thread(target=self._doItExclusive).start()
146 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
148 self.assert_(self.done.get(True, 1))
150 def testSharerBlocksDelete(self):
151 self.sl.acquire(shared=1)
152 Thread(target=self._doItDelete).start()
154 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
156 self.assert_(self.done.get(True, 1))
158 def testWaitingExclusiveBlocksSharer(self):
159 self.sl.acquire(shared=1)
160 # the lock is acquired in shared mode...
161 Thread(target=self._doItExclusive).start()
162 # ...but now an exclusive is waiting...
164 Thread(target=self._doItSharer).start()
165 # ...so the sharer should be blocked as well
166 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
168 # The exclusive passed before
169 self.assertEqual(self.done.get(True, 1), 'EXC')
170 self.assertEqual(self.done.get(True, 1), 'SHR')
172 def testWaitingSharerBlocksExclusive(self):
174 # the lock is acquired in exclusive mode...
175 Thread(target=self._doItSharer).start()
176 # ...but now a sharer is waiting...
178 Thread(target=self._doItExclusive).start()
179 # ...the exclusive is waiting too...
180 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
182 # The sharer passed before
183 self.assertEqual(self.done.get(True, 1), 'SHR')
184 self.assertEqual(self.done.get(True, 1), 'EXC')
186 def testNoNonBlocking(self):
187 self.assertRaises(NotImplementedError, self.sl.acquire, blocking=0)
188 self.assertRaises(NotImplementedError, self.sl.delete, blocking=0)
190 self.sl.delete(blocking=0) # Fine, because the lock is already acquired
192 def testDelete(self):
194 self.assertRaises(errors.LockError, self.sl.acquire)
195 self.assertRaises(errors.LockError, self.sl.acquire, shared=1)
196 self.assertRaises(errors.LockError, self.sl.delete)
198 def testNoDeleteIfSharer(self):
199 self.sl.acquire(shared=1)
200 self.assertRaises(AssertionError, self.sl.delete)
202 def testDeletePendingSharersExclusiveDelete(self):
204 Thread(target=self._doItSharer).start()
205 Thread(target=self._doItSharer).start()
207 Thread(target=self._doItExclusive).start()
208 Thread(target=self._doItDelete).start()
211 # The two threads who were pending return both ERR
212 self.assertEqual(self.done.get(True, 1), 'ERR')
213 self.assertEqual(self.done.get(True, 1), 'ERR')
214 self.assertEqual(self.done.get(True, 1), 'ERR')
215 self.assertEqual(self.done.get(True, 1), 'ERR')
217 def testDeletePendingDeleteExclusiveSharers(self):
219 Thread(target=self._doItDelete).start()
220 Thread(target=self._doItExclusive).start()
222 Thread(target=self._doItSharer).start()
223 Thread(target=self._doItSharer).start()
226 # The two threads who were pending return both ERR
227 self.assertEqual(self.done.get(True, 1), 'ERR')
228 self.assertEqual(self.done.get(True, 1), 'ERR')
229 self.assertEqual(self.done.get(True, 1), 'ERR')
230 self.assertEqual(self.done.get(True, 1), 'ERR')
233 if __name__ == '__main__':
235 #suite = unittest.TestLoader().loadTestsFromTestCase(TestSharedLock)
236 #unittest.TextTestRunner(verbosity=2).run(suite)