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):
110 except errors.LockError:
113 def testSharersCanCoexist(self):
114 self.sl.acquire(shared=1)
115 Thread(target=self._doItSharer).start()
116 self.assert_(self.done.get(True, 1))
119 def testExclusiveBlocksExclusive(self):
121 Thread(target=self._doItExclusive).start()
122 # give it a bit of time to check that it's not actually doing anything
123 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
125 self.assert_(self.done.get(True, 1))
127 def testExclusiveBlocksDelete(self):
129 Thread(target=self._doItDelete).start()
130 # give it a bit of time to check that it's not actually doing anything
131 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
133 self.assert_(self.done.get(True, 1))
135 def testExclusiveBlocksSharer(self):
137 Thread(target=self._doItSharer).start()
139 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
141 self.assert_(self.done.get(True, 1))
143 def testSharerBlocksExclusive(self):
144 self.sl.acquire(shared=1)
145 Thread(target=self._doItExclusive).start()
147 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
149 self.assert_(self.done.get(True, 1))
151 def testSharerBlocksDelete(self):
152 self.sl.acquire(shared=1)
153 Thread(target=self._doItDelete).start()
155 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
157 self.assert_(self.done.get(True, 1))
159 def testWaitingExclusiveBlocksSharer(self):
160 self.sl.acquire(shared=1)
161 # the lock is acquired in shared mode...
162 Thread(target=self._doItExclusive).start()
163 # ...but now an exclusive is waiting...
165 Thread(target=self._doItSharer).start()
166 # ...so the sharer should be blocked as well
167 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
169 # The exclusive passed before
170 self.assertEqual(self.done.get(True, 1), 'EXC')
171 self.assertEqual(self.done.get(True, 1), 'SHR')
173 def testWaitingSharerBlocksExclusive(self):
175 # the lock is acquired in exclusive mode...
176 Thread(target=self._doItSharer).start()
177 # ...but now a sharer is waiting...
179 Thread(target=self._doItExclusive).start()
180 # ...the exclusive is waiting too...
181 self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
183 # The sharer passed before
184 self.assertEqual(self.done.get(True, 1), 'SHR')
185 self.assertEqual(self.done.get(True, 1), 'EXC')
187 def testNoNonBlocking(self):
188 self.assertRaises(NotImplementedError, self.sl.acquire, blocking=0)
189 self.assertRaises(NotImplementedError, self.sl.delete, blocking=0)
191 self.sl.delete(blocking=0) # Fine, because the lock is already acquired
193 def testDelete(self):
195 self.assertRaises(errors.LockError, self.sl.acquire)
196 self.assertRaises(errors.LockError, self.sl.delete)
198 def testDeletePendingSharersExclusiveDelete(self):
200 Thread(target=self._doItSharer).start()
201 Thread(target=self._doItSharer).start()
203 Thread(target=self._doItExclusive).start()
204 Thread(target=self._doItDelete).start()
207 # The two threads who were pending return both ERR
208 self.assertEqual(self.done.get(True, 1), 'ERR')
209 self.assertEqual(self.done.get(True, 1), 'ERR')
210 self.assertEqual(self.done.get(True, 1), 'ERR')
211 self.assertEqual(self.done.get(True, 1), 'ERR')
213 def testDeletePendingDeleteExclusiveSharers(self):
215 Thread(target=self._doItDelete).start()
216 Thread(target=self._doItExclusive).start()
218 Thread(target=self._doItSharer).start()
219 Thread(target=self._doItSharer).start()
222 # The two threads who were pending return both ERR
223 self.assertEqual(self.done.get(True, 1), 'ERR')
224 self.assertEqual(self.done.get(True, 1), 'ERR')
225 self.assertEqual(self.done.get(True, 1), 'ERR')
226 self.assertEqual(self.done.get(True, 1), 'ERR')
229 if __name__ == '__main__':
231 #suite = unittest.TestLoader().loadTestsFromTestCase(TestSharedLock)
232 #unittest.TextTestRunner(verbosity=2).run(suite)