Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.locking_unittest.py @ 3d16a983

History | View | Annotate | Download (46.7 kB)

1 162c1c1f Guido Trotter
#!/usr/bin/python
2 162c1c1f Guido Trotter
#
3 162c1c1f Guido Trotter
4 162c1c1f Guido Trotter
# Copyright (C) 2006, 2007 Google Inc.
5 162c1c1f Guido Trotter
#
6 162c1c1f Guido Trotter
# This program is free software; you can redistribute it and/or modify
7 162c1c1f Guido Trotter
# it under the terms of the GNU General Public License as published by
8 162c1c1f Guido Trotter
# the Free Software Foundation; either version 2 of the License, or
9 162c1c1f Guido Trotter
# (at your option) any later version.
10 162c1c1f Guido Trotter
#
11 162c1c1f Guido Trotter
# This program is distributed in the hope that it will be useful, but
12 162c1c1f Guido Trotter
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 162c1c1f Guido Trotter
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 162c1c1f Guido Trotter
# General Public License for more details.
15 162c1c1f Guido Trotter
#
16 162c1c1f Guido Trotter
# You should have received a copy of the GNU General Public License
17 162c1c1f Guido Trotter
# along with this program; if not, write to the Free Software
18 162c1c1f Guido Trotter
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 162c1c1f Guido Trotter
# 0.0510-1301, USA.
20 162c1c1f Guido Trotter
21 162c1c1f Guido Trotter
22 162c1c1f Guido Trotter
"""Script for unittesting the locking module"""
23 162c1c1f Guido Trotter
24 162c1c1f Guido Trotter
25 162c1c1f Guido Trotter
import os
26 162c1c1f Guido Trotter
import unittest
27 162c1c1f Guido Trotter
import time
28 162c1c1f Guido Trotter
import Queue
29 84e344d4 Michael Hanselmann
import threading
30 162c1c1f Guido Trotter
31 162c1c1f Guido Trotter
from ganeti import locking
32 a95fd5d7 Guido Trotter
from ganeti import errors
33 162c1c1f Guido Trotter
34 25231ec5 Michael Hanselmann
import testutils
35 25231ec5 Michael Hanselmann
36 162c1c1f Guido Trotter
37 42a999d1 Guido Trotter
# This is used to test the ssynchronize decorator.
38 42a999d1 Guido Trotter
# Since it's passed as input to a decorator it must be declared as a global.
39 42a999d1 Guido Trotter
_decoratorlock = locking.SharedLock()
40 42a999d1 Guido Trotter
41 4607c978 Iustin Pop
#: List for looping tests
42 4607c978 Iustin Pop
ITERATIONS = range(8)
43 4607c978 Iustin Pop
44 84e344d4 Michael Hanselmann
45 4607c978 Iustin Pop
def _Repeat(fn):
46 4607c978 Iustin Pop
  """Decorator for executing a function many times"""
47 4607c978 Iustin Pop
  def wrapper(*args, **kwargs):
48 4607c978 Iustin Pop
    for i in ITERATIONS:
49 4607c978 Iustin Pop
      fn(*args, **kwargs)
50 4607c978 Iustin Pop
  return wrapper
51 4607c978 Iustin Pop
52 84e344d4 Michael Hanselmann
53 5aab242c Michael Hanselmann
def SafeSleep(duration):
54 5aab242c Michael Hanselmann
  start = time.time()
55 5aab242c Michael Hanselmann
  while True:
56 5aab242c Michael Hanselmann
    delay = start + duration - time.time()
57 5aab242c Michael Hanselmann
    if delay <= 0.0:
58 5aab242c Michael Hanselmann
      break
59 5aab242c Michael Hanselmann
    time.sleep(delay)
60 5aab242c Michael Hanselmann
61 5aab242c Michael Hanselmann
62 4607c978 Iustin Pop
class _ThreadedTestCase(unittest.TestCase):
63 4607c978 Iustin Pop
  """Test class that supports adding/waiting on threads"""
64 4607c978 Iustin Pop
  def setUp(self):
65 4607c978 Iustin Pop
    unittest.TestCase.setUp(self)
66 63f2e724 Guido Trotter
    self.done = Queue.Queue(0)
67 4607c978 Iustin Pop
    self.threads = []
68 4607c978 Iustin Pop
69 4607c978 Iustin Pop
  def _addThread(self, *args, **kwargs):
70 4607c978 Iustin Pop
    """Create and remember a new thread"""
71 84e344d4 Michael Hanselmann
    t = threading.Thread(*args, **kwargs)
72 4607c978 Iustin Pop
    self.threads.append(t)
73 4607c978 Iustin Pop
    t.start()
74 4607c978 Iustin Pop
    return t
75 4607c978 Iustin Pop
76 4607c978 Iustin Pop
  def _waitThreads(self):
77 4607c978 Iustin Pop
    """Wait for all our threads to finish"""
78 4607c978 Iustin Pop
    for t in self.threads:
79 4607c978 Iustin Pop
      t.join(60)
80 4607c978 Iustin Pop
      self.failIf(t.isAlive())
81 4607c978 Iustin Pop
    self.threads = []
82 42a999d1 Guido Trotter
83 4607c978 Iustin Pop
84 c5fe2a67 Guido Trotter
class _ConditionTestCase(_ThreadedTestCase):
85 c5fe2a67 Guido Trotter
  """Common test case for conditions"""
86 48dabc6a Michael Hanselmann
87 c5fe2a67 Guido Trotter
  def setUp(self, cls):
88 48dabc6a Michael Hanselmann
    _ThreadedTestCase.setUp(self)
89 48dabc6a Michael Hanselmann
    self.lock = threading.Lock()
90 c5fe2a67 Guido Trotter
    self.cond = cls(self.lock)
91 48dabc6a Michael Hanselmann
92 c5fe2a67 Guido Trotter
  def _testAcquireRelease(self):
93 158206e0 Manuel Franceschini
    self.assertFalse(self.cond._is_owned())
94 48dabc6a Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.wait)
95 48dabc6a Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.notifyAll)
96 48dabc6a Michael Hanselmann
97 48dabc6a Michael Hanselmann
    self.cond.acquire()
98 48dabc6a Michael Hanselmann
    self.assert_(self.cond._is_owned())
99 48dabc6a Michael Hanselmann
    self.cond.notifyAll()
100 48dabc6a Michael Hanselmann
    self.assert_(self.cond._is_owned())
101 48dabc6a Michael Hanselmann
    self.cond.release()
102 48dabc6a Michael Hanselmann
103 158206e0 Manuel Franceschini
    self.assertFalse(self.cond._is_owned())
104 48dabc6a Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.wait)
105 48dabc6a Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.notifyAll)
106 48dabc6a Michael Hanselmann
107 c5fe2a67 Guido Trotter
  def _testNotification(self):
108 48dabc6a Michael Hanselmann
    def _NotifyAll():
109 b8140229 Guido Trotter
      self.done.put("NE")
110 48dabc6a Michael Hanselmann
      self.cond.acquire()
111 b8140229 Guido Trotter
      self.done.put("NA")
112 48dabc6a Michael Hanselmann
      self.cond.notifyAll()
113 b8140229 Guido Trotter
      self.done.put("NN")
114 48dabc6a Michael Hanselmann
      self.cond.release()
115 48dabc6a Michael Hanselmann
116 48dabc6a Michael Hanselmann
    self.cond.acquire()
117 48dabc6a Michael Hanselmann
    self._addThread(target=_NotifyAll)
118 b8140229 Guido Trotter
    self.assertEqual(self.done.get(True, 1), "NE")
119 b8140229 Guido Trotter
    self.assertRaises(Queue.Empty, self.done.get_nowait)
120 48dabc6a Michael Hanselmann
    self.cond.wait()
121 b8140229 Guido Trotter
    self.assertEqual(self.done.get(True, 1), "NA")
122 b8140229 Guido Trotter
    self.assertEqual(self.done.get(True, 1), "NN")
123 48dabc6a Michael Hanselmann
    self.assert_(self.cond._is_owned())
124 48dabc6a Michael Hanselmann
    self.cond.release()
125 158206e0 Manuel Franceschini
    self.assertFalse(self.cond._is_owned())
126 48dabc6a Michael Hanselmann
127 c5fe2a67 Guido Trotter
128 34cb5617 Guido Trotter
class TestSingleNotifyPipeCondition(_ConditionTestCase):
129 34cb5617 Guido Trotter
  """SingleNotifyPipeCondition tests"""
130 34cb5617 Guido Trotter
131 34cb5617 Guido Trotter
  def setUp(self):
132 34cb5617 Guido Trotter
    _ConditionTestCase.setUp(self, locking.SingleNotifyPipeCondition)
133 34cb5617 Guido Trotter
134 34cb5617 Guido Trotter
  def testAcquireRelease(self):
135 34cb5617 Guido Trotter
    self._testAcquireRelease()
136 34cb5617 Guido Trotter
137 34cb5617 Guido Trotter
  def testNotification(self):
138 34cb5617 Guido Trotter
    self._testNotification()
139 34cb5617 Guido Trotter
140 34cb5617 Guido Trotter
  def testWaitReuse(self):
141 34cb5617 Guido Trotter
    self.cond.acquire()
142 34cb5617 Guido Trotter
    self.cond.wait(0)
143 34cb5617 Guido Trotter
    self.cond.wait(0.1)
144 34cb5617 Guido Trotter
    self.cond.release()
145 34cb5617 Guido Trotter
146 34cb5617 Guido Trotter
  def testNoNotifyReuse(self):
147 34cb5617 Guido Trotter
    self.cond.acquire()
148 34cb5617 Guido Trotter
    self.cond.notifyAll()
149 34cb5617 Guido Trotter
    self.assertRaises(RuntimeError, self.cond.wait)
150 34cb5617 Guido Trotter
    self.assertRaises(RuntimeError, self.cond.notifyAll)
151 34cb5617 Guido Trotter
    self.cond.release()
152 34cb5617 Guido Trotter
153 34cb5617 Guido Trotter
154 c5fe2a67 Guido Trotter
class TestPipeCondition(_ConditionTestCase):
155 34cb5617 Guido Trotter
  """PipeCondition tests"""
156 c5fe2a67 Guido Trotter
157 c5fe2a67 Guido Trotter
  def setUp(self):
158 34cb5617 Guido Trotter
    _ConditionTestCase.setUp(self, locking.PipeCondition)
159 c5fe2a67 Guido Trotter
160 c5fe2a67 Guido Trotter
  def testAcquireRelease(self):
161 c5fe2a67 Guido Trotter
    self._testAcquireRelease()
162 c5fe2a67 Guido Trotter
163 c5fe2a67 Guido Trotter
  def testNotification(self):
164 c5fe2a67 Guido Trotter
    self._testNotification()
165 c5fe2a67 Guido Trotter
166 48dabc6a Michael Hanselmann
  def _TestWait(self, fn):
167 48dabc6a Michael Hanselmann
    self._addThread(target=fn)
168 48dabc6a Michael Hanselmann
    self._addThread(target=fn)
169 48dabc6a Michael Hanselmann
    self._addThread(target=fn)
170 48dabc6a Michael Hanselmann
171 48dabc6a Michael Hanselmann
    # Wait for threads to be waiting
172 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get(True, 1), "A")
173 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get(True, 1), "A")
174 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get(True, 1), "A")
175 48dabc6a Michael Hanselmann
176 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
177 48dabc6a Michael Hanselmann
178 48dabc6a Michael Hanselmann
    self.cond.acquire()
179 48dabc6a Michael Hanselmann
    self.assertEqual(self.cond._nwaiters, 3)
180 48dabc6a Michael Hanselmann
    # This new thread can"t acquire the lock, and thus call wait, before we
181 48dabc6a Michael Hanselmann
    # release it
182 48dabc6a Michael Hanselmann
    self._addThread(target=fn)
183 48dabc6a Michael Hanselmann
    self.cond.notifyAll()
184 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
185 48dabc6a Michael Hanselmann
    self.cond.release()
186 48dabc6a Michael Hanselmann
187 48dabc6a Michael Hanselmann
    # We should now get 3 W and 1 A (for the new thread) in whatever order
188 48dabc6a Michael Hanselmann
    w = 0
189 48dabc6a Michael Hanselmann
    a = 0
190 48dabc6a Michael Hanselmann
    for i in range(4):
191 48dabc6a Michael Hanselmann
      got = self.done.get(True, 1)
192 48dabc6a Michael Hanselmann
      if got == "W":
193 48dabc6a Michael Hanselmann
        w += 1
194 48dabc6a Michael Hanselmann
      elif got == "A":
195 48dabc6a Michael Hanselmann
        a += 1
196 48dabc6a Michael Hanselmann
      else:
197 48dabc6a Michael Hanselmann
        self.fail("Got %s on the done queue" % got)
198 48dabc6a Michael Hanselmann
199 48dabc6a Michael Hanselmann
    self.assertEqual(w, 3)
200 48dabc6a Michael Hanselmann
    self.assertEqual(a, 1)
201 48dabc6a Michael Hanselmann
202 48dabc6a Michael Hanselmann
    self.cond.acquire()
203 48dabc6a Michael Hanselmann
    self.cond.notifyAll()
204 48dabc6a Michael Hanselmann
    self.cond.release()
205 48dabc6a Michael Hanselmann
    self._waitThreads()
206 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "W")
207 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
208 48dabc6a Michael Hanselmann
209 48dabc6a Michael Hanselmann
  def testBlockingWait(self):
210 48dabc6a Michael Hanselmann
    def _BlockingWait():
211 48dabc6a Michael Hanselmann
      self.cond.acquire()
212 48dabc6a Michael Hanselmann
      self.done.put("A")
213 48dabc6a Michael Hanselmann
      self.cond.wait()
214 48dabc6a Michael Hanselmann
      self.cond.release()
215 48dabc6a Michael Hanselmann
      self.done.put("W")
216 48dabc6a Michael Hanselmann
217 48dabc6a Michael Hanselmann
    self._TestWait(_BlockingWait)
218 48dabc6a Michael Hanselmann
219 48dabc6a Michael Hanselmann
  def testLongTimeoutWait(self):
220 48dabc6a Michael Hanselmann
    def _Helper():
221 48dabc6a Michael Hanselmann
      self.cond.acquire()
222 48dabc6a Michael Hanselmann
      self.done.put("A")
223 48dabc6a Michael Hanselmann
      self.cond.wait(15.0)
224 48dabc6a Michael Hanselmann
      self.cond.release()
225 48dabc6a Michael Hanselmann
      self.done.put("W")
226 48dabc6a Michael Hanselmann
227 48dabc6a Michael Hanselmann
    self._TestWait(_Helper)
228 48dabc6a Michael Hanselmann
229 48dabc6a Michael Hanselmann
  def _TimeoutWait(self, timeout, check):
230 48dabc6a Michael Hanselmann
    self.cond.acquire()
231 48dabc6a Michael Hanselmann
    self.cond.wait(timeout)
232 48dabc6a Michael Hanselmann
    self.cond.release()
233 48dabc6a Michael Hanselmann
    self.done.put(check)
234 48dabc6a Michael Hanselmann
235 48dabc6a Michael Hanselmann
  def testShortTimeoutWait(self):
236 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0.1, "T1"))
237 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0.1, "T1"))
238 48dabc6a Michael Hanselmann
    self._waitThreads()
239 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T1")
240 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T1")
241 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
242 48dabc6a Michael Hanselmann
243 48dabc6a Michael Hanselmann
  def testZeroTimeoutWait(self):
244 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0, "T0"))
245 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0, "T0"))
246 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0, "T0"))
247 48dabc6a Michael Hanselmann
    self._waitThreads()
248 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T0")
249 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T0")
250 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T0")
251 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
252 48dabc6a Michael Hanselmann
253 48dabc6a Michael Hanselmann
254 4607c978 Iustin Pop
class TestSharedLock(_ThreadedTestCase):
255 d6646186 Guido Trotter
  """SharedLock tests"""
256 162c1c1f Guido Trotter
257 162c1c1f Guido Trotter
  def setUp(self):
258 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
259 162c1c1f Guido Trotter
    self.sl = locking.SharedLock()
260 162c1c1f Guido Trotter
261 162c1c1f Guido Trotter
  def testSequenceAndOwnership(self):
262 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned())
263 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
264 162c1c1f Guido Trotter
    self.assert_(self.sl._is_owned())
265 162c1c1f Guido Trotter
    self.assert_(self.sl._is_owned(shared=1))
266 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned(shared=0))
267 162c1c1f Guido Trotter
    self.sl.release()
268 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned())
269 162c1c1f Guido Trotter
    self.sl.acquire()
270 162c1c1f Guido Trotter
    self.assert_(self.sl._is_owned())
271 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned(shared=1))
272 162c1c1f Guido Trotter
    self.assert_(self.sl._is_owned(shared=0))
273 162c1c1f Guido Trotter
    self.sl.release()
274 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned())
275 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
276 162c1c1f Guido Trotter
    self.assert_(self.sl._is_owned())
277 162c1c1f Guido Trotter
    self.assert_(self.sl._is_owned(shared=1))
278 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned(shared=0))
279 162c1c1f Guido Trotter
    self.sl.release()
280 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned())
281 162c1c1f Guido Trotter
282 162c1c1f Guido Trotter
  def testBooleanValue(self):
283 162c1c1f Guido Trotter
    # semaphores are supposed to return a true value on a successful acquire
284 162c1c1f Guido Trotter
    self.assert_(self.sl.acquire(shared=1))
285 162c1c1f Guido Trotter
    self.sl.release()
286 162c1c1f Guido Trotter
    self.assert_(self.sl.acquire())
287 162c1c1f Guido Trotter
    self.sl.release()
288 162c1c1f Guido Trotter
289 162c1c1f Guido Trotter
  def testDoubleLockingStoE(self):
290 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
291 162c1c1f Guido Trotter
    self.assertRaises(AssertionError, self.sl.acquire)
292 162c1c1f Guido Trotter
293 162c1c1f Guido Trotter
  def testDoubleLockingEtoS(self):
294 162c1c1f Guido Trotter
    self.sl.acquire()
295 162c1c1f Guido Trotter
    self.assertRaises(AssertionError, self.sl.acquire, shared=1)
296 162c1c1f Guido Trotter
297 162c1c1f Guido Trotter
  def testDoubleLockingStoS(self):
298 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
299 162c1c1f Guido Trotter
    self.assertRaises(AssertionError, self.sl.acquire, shared=1)
300 162c1c1f Guido Trotter
301 162c1c1f Guido Trotter
  def testDoubleLockingEtoE(self):
302 162c1c1f Guido Trotter
    self.sl.acquire()
303 162c1c1f Guido Trotter
    self.assertRaises(AssertionError, self.sl.acquire)
304 162c1c1f Guido Trotter
305 162c1c1f Guido Trotter
  # helper functions: called in a separate thread they acquire the lock, send
306 162c1c1f Guido Trotter
  # their identifier on the done queue, then release it.
307 162c1c1f Guido Trotter
  def _doItSharer(self):
308 a95fd5d7 Guido Trotter
    try:
309 a95fd5d7 Guido Trotter
      self.sl.acquire(shared=1)
310 a95fd5d7 Guido Trotter
      self.done.put('SHR')
311 a95fd5d7 Guido Trotter
      self.sl.release()
312 a95fd5d7 Guido Trotter
    except errors.LockError:
313 a95fd5d7 Guido Trotter
      self.done.put('ERR')
314 162c1c1f Guido Trotter
315 162c1c1f Guido Trotter
  def _doItExclusive(self):
316 a95fd5d7 Guido Trotter
    try:
317 a95fd5d7 Guido Trotter
      self.sl.acquire()
318 a95fd5d7 Guido Trotter
      self.done.put('EXC')
319 a95fd5d7 Guido Trotter
      self.sl.release()
320 a95fd5d7 Guido Trotter
    except errors.LockError:
321 a95fd5d7 Guido Trotter
      self.done.put('ERR')
322 a95fd5d7 Guido Trotter
323 a95fd5d7 Guido Trotter
  def _doItDelete(self):
324 a95fd5d7 Guido Trotter
    try:
325 4354ab03 Guido Trotter
      self.sl.delete()
326 a95fd5d7 Guido Trotter
      self.done.put('DEL')
327 a95fd5d7 Guido Trotter
    except errors.LockError:
328 a95fd5d7 Guido Trotter
      self.done.put('ERR')
329 162c1c1f Guido Trotter
330 162c1c1f Guido Trotter
  def testSharersCanCoexist(self):
331 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
332 84e344d4 Michael Hanselmann
    threading.Thread(target=self._doItSharer).start()
333 162c1c1f Guido Trotter
    self.assert_(self.done.get(True, 1))
334 162c1c1f Guido Trotter
    self.sl.release()
335 162c1c1f Guido Trotter
336 4607c978 Iustin Pop
  @_Repeat
337 162c1c1f Guido Trotter
  def testExclusiveBlocksExclusive(self):
338 162c1c1f Guido Trotter
    self.sl.acquire()
339 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
340 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
341 162c1c1f Guido Trotter
    self.sl.release()
342 4607c978 Iustin Pop
    self._waitThreads()
343 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'EXC')
344 162c1c1f Guido Trotter
345 4607c978 Iustin Pop
  @_Repeat
346 a95fd5d7 Guido Trotter
  def testExclusiveBlocksDelete(self):
347 a95fd5d7 Guido Trotter
    self.sl.acquire()
348 4607c978 Iustin Pop
    self._addThread(target=self._doItDelete)
349 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
350 a95fd5d7 Guido Trotter
    self.sl.release()
351 4607c978 Iustin Pop
    self._waitThreads()
352 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'DEL')
353 4607c978 Iustin Pop
    self.sl = locking.SharedLock()
354 a95fd5d7 Guido Trotter
355 4607c978 Iustin Pop
  @_Repeat
356 162c1c1f Guido Trotter
  def testExclusiveBlocksSharer(self):
357 162c1c1f Guido Trotter
    self.sl.acquire()
358 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
359 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
360 162c1c1f Guido Trotter
    self.sl.release()
361 4607c978 Iustin Pop
    self._waitThreads()
362 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'SHR')
363 162c1c1f Guido Trotter
364 4607c978 Iustin Pop
  @_Repeat
365 162c1c1f Guido Trotter
  def testSharerBlocksExclusive(self):
366 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
367 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
368 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
369 162c1c1f Guido Trotter
    self.sl.release()
370 4607c978 Iustin Pop
    self._waitThreads()
371 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'EXC')
372 162c1c1f Guido Trotter
373 4607c978 Iustin Pop
  @_Repeat
374 a95fd5d7 Guido Trotter
  def testSharerBlocksDelete(self):
375 a95fd5d7 Guido Trotter
    self.sl.acquire(shared=1)
376 4607c978 Iustin Pop
    self._addThread(target=self._doItDelete)
377 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
378 a95fd5d7 Guido Trotter
    self.sl.release()
379 4607c978 Iustin Pop
    self._waitThreads()
380 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'DEL')
381 4607c978 Iustin Pop
    self.sl = locking.SharedLock()
382 a95fd5d7 Guido Trotter
383 4607c978 Iustin Pop
  @_Repeat
384 162c1c1f Guido Trotter
  def testWaitingExclusiveBlocksSharer(self):
385 e6416152 Iustin Pop
    """SKIPPED testWaitingExclusiveBlockSharer"""
386 e6416152 Iustin Pop
    return
387 e6416152 Iustin Pop
388 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
389 162c1c1f Guido Trotter
    # the lock is acquired in shared mode...
390 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
391 162c1c1f Guido Trotter
    # ...but now an exclusive is waiting...
392 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
393 162c1c1f Guido Trotter
    # ...so the sharer should be blocked as well
394 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
395 162c1c1f Guido Trotter
    self.sl.release()
396 4607c978 Iustin Pop
    self._waitThreads()
397 162c1c1f Guido Trotter
    # The exclusive passed before
398 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'EXC')
399 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'SHR')
400 162c1c1f Guido Trotter
401 4607c978 Iustin Pop
  @_Repeat
402 162c1c1f Guido Trotter
  def testWaitingSharerBlocksExclusive(self):
403 a143be68 Iustin Pop
    """SKIPPED testWaitingSharerBlocksExclusive"""
404 a143be68 Iustin Pop
    return
405 a143be68 Iustin Pop
406 162c1c1f Guido Trotter
    self.sl.acquire()
407 162c1c1f Guido Trotter
    # the lock is acquired in exclusive mode...
408 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
409 162c1c1f Guido Trotter
    # ...but now a sharer is waiting...
410 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
411 162c1c1f Guido Trotter
    # ...the exclusive is waiting too...
412 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
413 162c1c1f Guido Trotter
    self.sl.release()
414 4607c978 Iustin Pop
    self._waitThreads()
415 162c1c1f Guido Trotter
    # The sharer passed before
416 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'SHR')
417 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'EXC')
418 162c1c1f Guido Trotter
419 a95fd5d7 Guido Trotter
  def testDelete(self):
420 a95fd5d7 Guido Trotter
    self.sl.delete()
421 a95fd5d7 Guido Trotter
    self.assertRaises(errors.LockError, self.sl.acquire)
422 84152b96 Guido Trotter
    self.assertRaises(errors.LockError, self.sl.acquire, shared=1)
423 a95fd5d7 Guido Trotter
    self.assertRaises(errors.LockError, self.sl.delete)
424 a95fd5d7 Guido Trotter
425 a66bd91b Michael Hanselmann
  def testDeleteTimeout(self):
426 a66bd91b Michael Hanselmann
    self.sl.delete(timeout=60)
427 a66bd91b Michael Hanselmann
428 84152b96 Guido Trotter
  def testNoDeleteIfSharer(self):
429 84152b96 Guido Trotter
    self.sl.acquire(shared=1)
430 84152b96 Guido Trotter
    self.assertRaises(AssertionError, self.sl.delete)
431 84152b96 Guido Trotter
432 4607c978 Iustin Pop
  @_Repeat
433 a95fd5d7 Guido Trotter
  def testDeletePendingSharersExclusiveDelete(self):
434 a95fd5d7 Guido Trotter
    self.sl.acquire()
435 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
436 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
437 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
438 4607c978 Iustin Pop
    self._addThread(target=self._doItDelete)
439 a95fd5d7 Guido Trotter
    self.sl.delete()
440 4607c978 Iustin Pop
    self._waitThreads()
441 4607c978 Iustin Pop
    # The threads who were pending return ERR
442 4607c978 Iustin Pop
    for _ in range(4):
443 4607c978 Iustin Pop
      self.assertEqual(self.done.get_nowait(), 'ERR')
444 4607c978 Iustin Pop
    self.sl = locking.SharedLock()
445 a95fd5d7 Guido Trotter
446 4607c978 Iustin Pop
  @_Repeat
447 a95fd5d7 Guido Trotter
  def testDeletePendingDeleteExclusiveSharers(self):
448 a95fd5d7 Guido Trotter
    self.sl.acquire()
449 4607c978 Iustin Pop
    self._addThread(target=self._doItDelete)
450 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
451 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
452 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
453 a95fd5d7 Guido Trotter
    self.sl.delete()
454 4607c978 Iustin Pop
    self._waitThreads()
455 a95fd5d7 Guido Trotter
    # The two threads who were pending return both ERR
456 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'ERR')
457 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'ERR')
458 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'ERR')
459 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'ERR')
460 4607c978 Iustin Pop
    self.sl = locking.SharedLock()
461 a95fd5d7 Guido Trotter
462 84e344d4 Michael Hanselmann
  @_Repeat
463 84e344d4 Michael Hanselmann
  def testExclusiveAcquireTimeout(self):
464 84e344d4 Michael Hanselmann
    for shared in [0, 1]:
465 008b92fa Michael Hanselmann
      on_queue = threading.Event()
466 008b92fa Michael Hanselmann
      release_exclusive = threading.Event()
467 008b92fa Michael Hanselmann
468 008b92fa Michael Hanselmann
      def _LockExclusive():
469 008b92fa Michael Hanselmann
        self.sl.acquire(shared=0, test_notify=on_queue.set)
470 008b92fa Michael Hanselmann
        self.done.put("A: start wait")
471 008b92fa Michael Hanselmann
        release_exclusive.wait()
472 008b92fa Michael Hanselmann
        self.done.put("A: end wait")
473 008b92fa Michael Hanselmann
        self.sl.release()
474 008b92fa Michael Hanselmann
475 008b92fa Michael Hanselmann
      # Start thread to hold lock in exclusive mode
476 008b92fa Michael Hanselmann
      self._addThread(target=_LockExclusive)
477 84e344d4 Michael Hanselmann
478 008b92fa Michael Hanselmann
      # Wait for wait to begin
479 008b92fa Michael Hanselmann
      self.assertEqual(self.done.get(timeout=60), "A: start wait")
480 008b92fa Michael Hanselmann
481 008b92fa Michael Hanselmann
      # Wait up to 60s to get lock, but release exclusive lock as soon as we're
482 008b92fa Michael Hanselmann
      # on the queue
483 008b92fa Michael Hanselmann
      self.failUnless(self.sl.acquire(shared=shared, timeout=60,
484 008b92fa Michael Hanselmann
                                      test_notify=release_exclusive.set))
485 2042aa94 Michael Hanselmann
486 84e344d4 Michael Hanselmann
      self.done.put("got 2nd")
487 84e344d4 Michael Hanselmann
      self.sl.release()
488 84e344d4 Michael Hanselmann
489 84e344d4 Michael Hanselmann
      self._waitThreads()
490 84e344d4 Michael Hanselmann
491 008b92fa Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "A: end wait")
492 84e344d4 Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "got 2nd")
493 84e344d4 Michael Hanselmann
      self.assertRaises(Queue.Empty, self.done.get_nowait)
494 84e344d4 Michael Hanselmann
495 84e344d4 Michael Hanselmann
  @_Repeat
496 84e344d4 Michael Hanselmann
  def testAcquireExpiringTimeout(self):
497 84e344d4 Michael Hanselmann
    def _AcquireWithTimeout(shared, timeout):
498 84e344d4 Michael Hanselmann
      if not self.sl.acquire(shared=shared, timeout=timeout):
499 84e344d4 Michael Hanselmann
        self.done.put("timeout")
500 84e344d4 Michael Hanselmann
501 84e344d4 Michael Hanselmann
    for shared in [0, 1]:
502 84e344d4 Michael Hanselmann
      # Lock exclusively
503 84e344d4 Michael Hanselmann
      self.sl.acquire()
504 84e344d4 Michael Hanselmann
505 84e344d4 Michael Hanselmann
      # Start shared acquires with timeout between 0 and 20 ms
506 f1501b3f Michael Hanselmann
      for i in range(11):
507 84e344d4 Michael Hanselmann
        self._addThread(target=_AcquireWithTimeout,
508 84e344d4 Michael Hanselmann
                        args=(shared, i * 2.0 / 1000.0))
509 84e344d4 Michael Hanselmann
510 84e344d4 Michael Hanselmann
      # Wait for threads to finish (makes sure the acquire timeout expires
511 84e344d4 Michael Hanselmann
      # before releasing the lock)
512 84e344d4 Michael Hanselmann
      self._waitThreads()
513 84e344d4 Michael Hanselmann
514 84e344d4 Michael Hanselmann
      # Release lock
515 84e344d4 Michael Hanselmann
      self.sl.release()
516 84e344d4 Michael Hanselmann
517 f1501b3f Michael Hanselmann
      for _ in range(11):
518 84e344d4 Michael Hanselmann
        self.assertEqual(self.done.get_nowait(), "timeout")
519 84e344d4 Michael Hanselmann
520 84e344d4 Michael Hanselmann
      self.assertRaises(Queue.Empty, self.done.get_nowait)
521 84e344d4 Michael Hanselmann
522 84e344d4 Michael Hanselmann
  @_Repeat
523 84e344d4 Michael Hanselmann
  def testSharedSkipExclusiveAcquires(self):
524 84e344d4 Michael Hanselmann
    # Tests whether shared acquires jump in front of exclusive acquires in the
525 84e344d4 Michael Hanselmann
    # queue.
526 84e344d4 Michael Hanselmann
527 008b92fa Michael Hanselmann
    def _Acquire(shared, name, notify_ev, wait_ev):
528 008b92fa Michael Hanselmann
      if notify_ev:
529 008b92fa Michael Hanselmann
        notify_fn = notify_ev.set
530 008b92fa Michael Hanselmann
      else:
531 008b92fa Michael Hanselmann
        notify_fn = None
532 84e344d4 Michael Hanselmann
533 008b92fa Michael Hanselmann
      if wait_ev:
534 008b92fa Michael Hanselmann
        wait_ev.wait()
535 008b92fa Michael Hanselmann
536 008b92fa Michael Hanselmann
      if not self.sl.acquire(shared=shared, test_notify=notify_fn):
537 84e344d4 Michael Hanselmann
        return
538 84e344d4 Michael Hanselmann
539 84e344d4 Michael Hanselmann
      self.done.put(name)
540 84e344d4 Michael Hanselmann
      self.sl.release()
541 84e344d4 Michael Hanselmann
542 008b92fa Michael Hanselmann
    # Get exclusive lock while we fill the queue
543 008b92fa Michael Hanselmann
    self.sl.acquire()
544 84e344d4 Michael Hanselmann
545 008b92fa Michael Hanselmann
    shrcnt1 = 5
546 008b92fa Michael Hanselmann
    shrcnt2 = 7
547 008b92fa Michael Hanselmann
    shrcnt3 = 9
548 008b92fa Michael Hanselmann
    shrcnt4 = 2
549 84e344d4 Michael Hanselmann
550 008b92fa Michael Hanselmann
    # Add acquires using threading.Event for synchronization. They'll be
551 008b92fa Michael Hanselmann
    # acquired exactly in the order defined in this list.
552 008b92fa Michael Hanselmann
    acquires = (shrcnt1 * [(1, "shared 1")] +
553 008b92fa Michael Hanselmann
                3 * [(0, "exclusive 1")] +
554 008b92fa Michael Hanselmann
                shrcnt2 * [(1, "shared 2")] +
555 008b92fa Michael Hanselmann
                shrcnt3 * [(1, "shared 3")] +
556 008b92fa Michael Hanselmann
                shrcnt4 * [(1, "shared 4")] +
557 008b92fa Michael Hanselmann
                3 * [(0, "exclusive 2")])
558 84e344d4 Michael Hanselmann
559 008b92fa Michael Hanselmann
    ev_cur = None
560 008b92fa Michael Hanselmann
    ev_prev = None
561 008b92fa Michael Hanselmann
562 008b92fa Michael Hanselmann
    for args in acquires:
563 008b92fa Michael Hanselmann
      ev_cur = threading.Event()
564 008b92fa Michael Hanselmann
      self._addThread(target=_Acquire, args=args + (ev_cur, ev_prev))
565 008b92fa Michael Hanselmann
      ev_prev = ev_cur
566 008b92fa Michael Hanselmann
567 008b92fa Michael Hanselmann
    # Wait for last acquire to start
568 008b92fa Michael Hanselmann
    ev_prev.wait()
569 84e344d4 Michael Hanselmann
570 84e344d4 Michael Hanselmann
    # Expect 6 pending exclusive acquires and 1 for all shared acquires
571 008b92fa Michael Hanselmann
    # together
572 008b92fa Michael Hanselmann
    self.assertEqual(self.sl._count_pending(), 7)
573 84e344d4 Michael Hanselmann
574 84e344d4 Michael Hanselmann
    # Release exclusive lock and wait
575 84e344d4 Michael Hanselmann
    self.sl.release()
576 84e344d4 Michael Hanselmann
577 84e344d4 Michael Hanselmann
    self._waitThreads()
578 84e344d4 Michael Hanselmann
579 84e344d4 Michael Hanselmann
    # Check sequence
580 008b92fa Michael Hanselmann
    for _ in range(shrcnt1 + shrcnt2 + shrcnt3 + shrcnt4):
581 84e344d4 Michael Hanselmann
      # Shared locks aren't guaranteed to be notified in order, but they'll be
582 84e344d4 Michael Hanselmann
      # first
583 2042aa94 Michael Hanselmann
      tmp = self.done.get_nowait()
584 008b92fa Michael Hanselmann
      if tmp == "shared 1":
585 008b92fa Michael Hanselmann
        shrcnt1 -= 1
586 008b92fa Michael Hanselmann
      elif tmp == "shared 2":
587 008b92fa Michael Hanselmann
        shrcnt2 -= 1
588 008b92fa Michael Hanselmann
      elif tmp == "shared 3":
589 008b92fa Michael Hanselmann
        shrcnt3 -= 1
590 008b92fa Michael Hanselmann
      elif tmp == "shared 4":
591 008b92fa Michael Hanselmann
        shrcnt4 -= 1
592 008b92fa Michael Hanselmann
    self.assertEqual(shrcnt1, 0)
593 008b92fa Michael Hanselmann
    self.assertEqual(shrcnt2, 0)
594 008b92fa Michael Hanselmann
    self.assertEqual(shrcnt3, 0)
595 008b92fa Michael Hanselmann
    self.assertEqual(shrcnt3, 0)
596 84e344d4 Michael Hanselmann
597 f1501b3f Michael Hanselmann
    for _ in range(3):
598 008b92fa Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "exclusive 1")
599 84e344d4 Michael Hanselmann
600 f1501b3f Michael Hanselmann
    for _ in range(3):
601 008b92fa Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "exclusive 2")
602 84e344d4 Michael Hanselmann
603 84e344d4 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
604 84e344d4 Michael Hanselmann
605 84e344d4 Michael Hanselmann
  @_Repeat
606 84e344d4 Michael Hanselmann
  def testMixedAcquireTimeout(self):
607 51e3bb92 Michael Hanselmann
    sync = threading.Event()
608 84e344d4 Michael Hanselmann
609 84e344d4 Michael Hanselmann
    def _AcquireShared(ev):
610 84e344d4 Michael Hanselmann
      if not self.sl.acquire(shared=1, timeout=None):
611 84e344d4 Michael Hanselmann
        return
612 84e344d4 Michael Hanselmann
613 84e344d4 Michael Hanselmann
      self.done.put("shared")
614 84e344d4 Michael Hanselmann
615 84e344d4 Michael Hanselmann
      # Notify main thread
616 84e344d4 Michael Hanselmann
      ev.set()
617 84e344d4 Michael Hanselmann
618 51e3bb92 Michael Hanselmann
      # Wait for notification from main thread
619 51e3bb92 Michael Hanselmann
      sync.wait()
620 84e344d4 Michael Hanselmann
621 84e344d4 Michael Hanselmann
      # Release lock
622 84e344d4 Michael Hanselmann
      self.sl.release()
623 84e344d4 Michael Hanselmann
624 84e344d4 Michael Hanselmann
    acquires = []
625 f1501b3f Michael Hanselmann
    for _ in range(3):
626 84e344d4 Michael Hanselmann
      ev = threading.Event()
627 84e344d4 Michael Hanselmann
      self._addThread(target=_AcquireShared, args=(ev, ))
628 84e344d4 Michael Hanselmann
      acquires.append(ev)
629 84e344d4 Michael Hanselmann
630 84e344d4 Michael Hanselmann
    # Wait for all acquires to finish
631 84e344d4 Michael Hanselmann
    for i in acquires:
632 84e344d4 Michael Hanselmann
      i.wait()
633 84e344d4 Michael Hanselmann
634 84e344d4 Michael Hanselmann
    self.assertEqual(self.sl._count_pending(), 0)
635 84e344d4 Michael Hanselmann
636 84e344d4 Michael Hanselmann
    # Try to get exclusive lock
637 84e344d4 Michael Hanselmann
    self.failIf(self.sl.acquire(shared=0, timeout=0.02))
638 84e344d4 Michael Hanselmann
639 84e344d4 Michael Hanselmann
    # Acquire exclusive without timeout
640 51e3bb92 Michael Hanselmann
    exclsync = threading.Event()
641 84e344d4 Michael Hanselmann
    exclev = threading.Event()
642 84e344d4 Michael Hanselmann
643 84e344d4 Michael Hanselmann
    def _AcquireExclusive():
644 84e344d4 Michael Hanselmann
      if not self.sl.acquire(shared=0):
645 84e344d4 Michael Hanselmann
        return
646 84e344d4 Michael Hanselmann
647 84e344d4 Michael Hanselmann
      self.done.put("exclusive")
648 84e344d4 Michael Hanselmann
649 84e344d4 Michael Hanselmann
      # Notify main thread
650 84e344d4 Michael Hanselmann
      exclev.set()
651 84e344d4 Michael Hanselmann
652 51e3bb92 Michael Hanselmann
      # Wait for notification from main thread
653 51e3bb92 Michael Hanselmann
      exclsync.wait()
654 84e344d4 Michael Hanselmann
655 84e344d4 Michael Hanselmann
      self.sl.release()
656 84e344d4 Michael Hanselmann
657 84e344d4 Michael Hanselmann
    self._addThread(target=_AcquireExclusive)
658 84e344d4 Michael Hanselmann
659 84e344d4 Michael Hanselmann
    # Try to get exclusive lock
660 84e344d4 Michael Hanselmann
    self.failIf(self.sl.acquire(shared=0, timeout=0.02))
661 84e344d4 Michael Hanselmann
662 84e344d4 Michael Hanselmann
    # Make all shared holders release their locks
663 51e3bb92 Michael Hanselmann
    sync.set()
664 84e344d4 Michael Hanselmann
665 84e344d4 Michael Hanselmann
    # Wait for exclusive acquire to succeed
666 84e344d4 Michael Hanselmann
    exclev.wait()
667 84e344d4 Michael Hanselmann
668 84e344d4 Michael Hanselmann
    self.assertEqual(self.sl._count_pending(), 0)
669 84e344d4 Michael Hanselmann
670 84e344d4 Michael Hanselmann
    # Try to get exclusive lock
671 84e344d4 Michael Hanselmann
    self.failIf(self.sl.acquire(shared=0, timeout=0.02))
672 84e344d4 Michael Hanselmann
673 84e344d4 Michael Hanselmann
    def _AcquireSharedSimple():
674 84e344d4 Michael Hanselmann
      if self.sl.acquire(shared=1, timeout=None):
675 84e344d4 Michael Hanselmann
        self.done.put("shared2")
676 84e344d4 Michael Hanselmann
        self.sl.release()
677 84e344d4 Michael Hanselmann
678 f1501b3f Michael Hanselmann
    for _ in range(10):
679 84e344d4 Michael Hanselmann
      self._addThread(target=_AcquireSharedSimple)
680 84e344d4 Michael Hanselmann
681 84e344d4 Michael Hanselmann
    # Tell exclusive lock to release
682 51e3bb92 Michael Hanselmann
    exclsync.set()
683 84e344d4 Michael Hanselmann
684 84e344d4 Michael Hanselmann
    # Wait for everything to finish
685 84e344d4 Michael Hanselmann
    self._waitThreads()
686 84e344d4 Michael Hanselmann
687 84e344d4 Michael Hanselmann
    self.assertEqual(self.sl._count_pending(), 0)
688 84e344d4 Michael Hanselmann
689 84e344d4 Michael Hanselmann
    # Check sequence
690 f1501b3f Michael Hanselmann
    for _ in range(3):
691 84e344d4 Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "shared")
692 84e344d4 Michael Hanselmann
693 84e344d4 Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "exclusive")
694 84e344d4 Michael Hanselmann
695 f1501b3f Michael Hanselmann
    for _ in range(10):
696 84e344d4 Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "shared2")
697 84e344d4 Michael Hanselmann
698 84e344d4 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
699 84e344d4 Michael Hanselmann
700 162c1c1f Guido Trotter
701 1a4e32d0 Guido Trotter
class TestSharedLockInCondition(_ThreadedTestCase):
702 1a4e32d0 Guido Trotter
  """SharedLock as a condition lock tests"""
703 1a4e32d0 Guido Trotter
704 1a4e32d0 Guido Trotter
  def setUp(self):
705 1a4e32d0 Guido Trotter
    _ThreadedTestCase.setUp(self)
706 1a4e32d0 Guido Trotter
    self.sl = locking.SharedLock()
707 7f890059 Guido Trotter
    self.setCondition()
708 7f890059 Guido Trotter
709 7f890059 Guido Trotter
  def setCondition(self):
710 1a4e32d0 Guido Trotter
    self.cond = threading.Condition(self.sl)
711 1a4e32d0 Guido Trotter
712 1a4e32d0 Guido Trotter
  def testKeepMode(self):
713 1a4e32d0 Guido Trotter
    self.cond.acquire(shared=1)
714 1a4e32d0 Guido Trotter
    self.assert_(self.sl._is_owned(shared=1))
715 1a4e32d0 Guido Trotter
    self.cond.wait(0)
716 1a4e32d0 Guido Trotter
    self.assert_(self.sl._is_owned(shared=1))
717 1a4e32d0 Guido Trotter
    self.cond.release()
718 1a4e32d0 Guido Trotter
    self.cond.acquire(shared=0)
719 1a4e32d0 Guido Trotter
    self.assert_(self.sl._is_owned(shared=0))
720 1a4e32d0 Guido Trotter
    self.cond.wait(0)
721 1a4e32d0 Guido Trotter
    self.assert_(self.sl._is_owned(shared=0))
722 1a4e32d0 Guido Trotter
    self.cond.release()
723 1a4e32d0 Guido Trotter
724 1a4e32d0 Guido Trotter
725 7f890059 Guido Trotter
class TestSharedLockInPipeCondition(TestSharedLockInCondition):
726 7f890059 Guido Trotter
  """SharedLock as a pipe condition lock tests"""
727 7f890059 Guido Trotter
728 7f890059 Guido Trotter
  def setCondition(self):
729 7f890059 Guido Trotter
    self.cond = locking.PipeCondition(self.sl)
730 7f890059 Guido Trotter
731 7f890059 Guido Trotter
732 4607c978 Iustin Pop
class TestSSynchronizedDecorator(_ThreadedTestCase):
733 42a999d1 Guido Trotter
  """Shared Lock Synchronized decorator test"""
734 42a999d1 Guido Trotter
735 42a999d1 Guido Trotter
  def setUp(self):
736 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
737 42a999d1 Guido Trotter
738 42a999d1 Guido Trotter
  @locking.ssynchronized(_decoratorlock)
739 42a999d1 Guido Trotter
  def _doItExclusive(self):
740 42a999d1 Guido Trotter
    self.assert_(_decoratorlock._is_owned())
741 42a999d1 Guido Trotter
    self.done.put('EXC')
742 42a999d1 Guido Trotter
743 42a999d1 Guido Trotter
  @locking.ssynchronized(_decoratorlock, shared=1)
744 42a999d1 Guido Trotter
  def _doItSharer(self):
745 42a999d1 Guido Trotter
    self.assert_(_decoratorlock._is_owned(shared=1))
746 42a999d1 Guido Trotter
    self.done.put('SHR')
747 42a999d1 Guido Trotter
748 42a999d1 Guido Trotter
  def testDecoratedFunctions(self):
749 42a999d1 Guido Trotter
    self._doItExclusive()
750 158206e0 Manuel Franceschini
    self.assertFalse(_decoratorlock._is_owned())
751 42a999d1 Guido Trotter
    self._doItSharer()
752 158206e0 Manuel Franceschini
    self.assertFalse(_decoratorlock._is_owned())
753 42a999d1 Guido Trotter
754 42a999d1 Guido Trotter
  def testSharersCanCoexist(self):
755 42a999d1 Guido Trotter
    _decoratorlock.acquire(shared=1)
756 84e344d4 Michael Hanselmann
    threading.Thread(target=self._doItSharer).start()
757 42a999d1 Guido Trotter
    self.assert_(self.done.get(True, 1))
758 42a999d1 Guido Trotter
    _decoratorlock.release()
759 42a999d1 Guido Trotter
760 4607c978 Iustin Pop
  @_Repeat
761 42a999d1 Guido Trotter
  def testExclusiveBlocksExclusive(self):
762 42a999d1 Guido Trotter
    _decoratorlock.acquire()
763 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
764 42a999d1 Guido Trotter
    # give it a bit of time to check that it's not actually doing anything
765 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
766 42a999d1 Guido Trotter
    _decoratorlock.release()
767 4607c978 Iustin Pop
    self._waitThreads()
768 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'EXC')
769 42a999d1 Guido Trotter
770 4607c978 Iustin Pop
  @_Repeat
771 42a999d1 Guido Trotter
  def testExclusiveBlocksSharer(self):
772 42a999d1 Guido Trotter
    _decoratorlock.acquire()
773 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
774 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
775 42a999d1 Guido Trotter
    _decoratorlock.release()
776 4607c978 Iustin Pop
    self._waitThreads()
777 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'SHR')
778 42a999d1 Guido Trotter
779 4607c978 Iustin Pop
  @_Repeat
780 42a999d1 Guido Trotter
  def testSharerBlocksExclusive(self):
781 42a999d1 Guido Trotter
    _decoratorlock.acquire(shared=1)
782 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
783 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
784 42a999d1 Guido Trotter
    _decoratorlock.release()
785 4607c978 Iustin Pop
    self._waitThreads()
786 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'EXC')
787 42a999d1 Guido Trotter
788 42a999d1 Guido Trotter
789 4607c978 Iustin Pop
class TestLockSet(_ThreadedTestCase):
790 aaae9bc0 Guido Trotter
  """LockSet tests"""
791 aaae9bc0 Guido Trotter
792 aaae9bc0 Guido Trotter
  def setUp(self):
793 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
794 4607c978 Iustin Pop
    self._setUpLS()
795 aaae9bc0 Guido Trotter
796 4607c978 Iustin Pop
  def _setUpLS(self):
797 4607c978 Iustin Pop
    """Helper to (re)initialize the lock set"""
798 4607c978 Iustin Pop
    self.resources = ['one', 'two', 'three']
799 4607c978 Iustin Pop
    self.ls = locking.LockSet(members=self.resources)
800 4607c978 Iustin Pop
801 aaae9bc0 Guido Trotter
  def testResources(self):
802 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._names(), set(self.resources))
803 aaae9bc0 Guido Trotter
    newls = locking.LockSet()
804 aaae9bc0 Guido Trotter
    self.assertEquals(newls._names(), set())
805 aaae9bc0 Guido Trotter
806 aaae9bc0 Guido Trotter
  def testAcquireRelease(self):
807 0cc00929 Guido Trotter
    self.assert_(self.ls.acquire('one'))
808 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['one']))
809 aaae9bc0 Guido Trotter
    self.ls.release()
810 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
811 0cc00929 Guido Trotter
    self.assertEquals(self.ls.acquire(['one']), set(['one']))
812 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['one']))
813 aaae9bc0 Guido Trotter
    self.ls.release()
814 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
815 aaae9bc0 Guido Trotter
    self.ls.acquire(['one', 'two', 'three'])
816 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['one', 'two', 'three']))
817 aaae9bc0 Guido Trotter
    self.ls.release('one')
818 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['two', 'three']))
819 aaae9bc0 Guido Trotter
    self.ls.release(['three'])
820 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['two']))
821 aaae9bc0 Guido Trotter
    self.ls.release()
822 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
823 0cc00929 Guido Trotter
    self.assertEquals(self.ls.acquire(['one', 'three']), set(['one', 'three']))
824 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['one', 'three']))
825 aaae9bc0 Guido Trotter
    self.ls.release()
826 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
827 aaae9bc0 Guido Trotter
828 aaae9bc0 Guido Trotter
  def testNoDoubleAcquire(self):
829 aaae9bc0 Guido Trotter
    self.ls.acquire('one')
830 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.acquire, 'one')
831 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.acquire, ['two'])
832 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.acquire, ['two', 'three'])
833 aaae9bc0 Guido Trotter
    self.ls.release()
834 aaae9bc0 Guido Trotter
    self.ls.acquire(['one', 'three'])
835 aaae9bc0 Guido Trotter
    self.ls.release('one')
836 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.acquire, ['two'])
837 aaae9bc0 Guido Trotter
    self.ls.release('three')
838 aaae9bc0 Guido Trotter
839 aaae9bc0 Guido Trotter
  def testNoWrongRelease(self):
840 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.release)
841 aaae9bc0 Guido Trotter
    self.ls.acquire('one')
842 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.release, 'two')
843 aaae9bc0 Guido Trotter
844 aaae9bc0 Guido Trotter
  def testAddRemove(self):
845 aaae9bc0 Guido Trotter
    self.ls.add('four')
846 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
847 aaae9bc0 Guido Trotter
    self.assert_('four' in self.ls._names())
848 aaae9bc0 Guido Trotter
    self.ls.add(['five', 'six', 'seven'], acquired=1)
849 aaae9bc0 Guido Trotter
    self.assert_('five' in self.ls._names())
850 aaae9bc0 Guido Trotter
    self.assert_('six' in self.ls._names())
851 aaae9bc0 Guido Trotter
    self.assert_('seven' in self.ls._names())
852 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['five', 'six', 'seven']))
853 3f404fc5 Guido Trotter
    self.assertEquals(self.ls.remove(['five', 'six']), ['five', 'six'])
854 aaae9bc0 Guido Trotter
    self.assert_('five' not in self.ls._names())
855 aaae9bc0 Guido Trotter
    self.assert_('six' not in self.ls._names())
856 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['seven']))
857 d2aff862 Guido Trotter
    self.assertRaises(AssertionError, self.ls.add, 'eight', acquired=1)
858 aaae9bc0 Guido Trotter
    self.ls.remove('seven')
859 aaae9bc0 Guido Trotter
    self.assert_('seven' not in self.ls._names())
860 d2aff862 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set([]))
861 d2aff862 Guido Trotter
    self.ls.acquire(None, shared=1)
862 d2aff862 Guido Trotter
    self.assertRaises(AssertionError, self.ls.add, 'eight')
863 d2aff862 Guido Trotter
    self.ls.release()
864 d2aff862 Guido Trotter
    self.ls.acquire(None)
865 d2aff862 Guido Trotter
    self.ls.add('eight', acquired=1)
866 d2aff862 Guido Trotter
    self.assert_('eight' in self.ls._names())
867 d2aff862 Guido Trotter
    self.assert_('eight' in self.ls._list_owned())
868 d2aff862 Guido Trotter
    self.ls.add('nine')
869 d2aff862 Guido Trotter
    self.assert_('nine' in self.ls._names())
870 d2aff862 Guido Trotter
    self.assert_('nine' not in self.ls._list_owned())
871 aaae9bc0 Guido Trotter
    self.ls.release()
872 aaae9bc0 Guido Trotter
    self.ls.remove(['two'])
873 aaae9bc0 Guido Trotter
    self.assert_('two' not in self.ls._names())
874 aaae9bc0 Guido Trotter
    self.ls.acquire('three')
875 3f404fc5 Guido Trotter
    self.assertEquals(self.ls.remove(['three']), ['three'])
876 aaae9bc0 Guido Trotter
    self.assert_('three' not in self.ls._names())
877 3f404fc5 Guido Trotter
    self.assertEquals(self.ls.remove('three'), [])
878 3f404fc5 Guido Trotter
    self.assertEquals(self.ls.remove(['one', 'three', 'six']), ['one'])
879 aaae9bc0 Guido Trotter
    self.assert_('one' not in self.ls._names())
880 aaae9bc0 Guido Trotter
881 aaae9bc0 Guido Trotter
  def testRemoveNonBlocking(self):
882 aaae9bc0 Guido Trotter
    self.ls.acquire('one')
883 5e0a6daf Michael Hanselmann
    self.assertEquals(self.ls.remove('one'), ['one'])
884 aaae9bc0 Guido Trotter
    self.ls.acquire(['two', 'three'])
885 5e0a6daf Michael Hanselmann
    self.assertEquals(self.ls.remove(['two', 'three']),
886 3f404fc5 Guido Trotter
                      ['two', 'three'])
887 aaae9bc0 Guido Trotter
888 aaae9bc0 Guido Trotter
  def testNoDoubleAdd(self):
889 aaae9bc0 Guido Trotter
    self.assertRaises(errors.LockError, self.ls.add, 'two')
890 aaae9bc0 Guido Trotter
    self.ls.add('four')
891 aaae9bc0 Guido Trotter
    self.assertRaises(errors.LockError, self.ls.add, 'four')
892 aaae9bc0 Guido Trotter
893 aaae9bc0 Guido Trotter
  def testNoWrongRemoves(self):
894 aaae9bc0 Guido Trotter
    self.ls.acquire(['one', 'three'], shared=1)
895 aaae9bc0 Guido Trotter
    # Cannot remove 'two' while holding something which is not a superset
896 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.remove, 'two')
897 aaae9bc0 Guido Trotter
    # Cannot remove 'three' as we are sharing it
898 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.remove, 'three')
899 aaae9bc0 Guido Trotter
900 3b7ed473 Guido Trotter
  def testAcquireSetLock(self):
901 3b7ed473 Guido Trotter
    # acquire the set-lock exclusively
902 3b7ed473 Guido Trotter
    self.assertEquals(self.ls.acquire(None), set(['one', 'two', 'three']))
903 d4803c24 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['one', 'two', 'three']))
904 d4803c24 Guido Trotter
    self.assertEquals(self.ls._is_owned(), True)
905 d4803c24 Guido Trotter
    self.assertEquals(self.ls._names(), set(['one', 'two', 'three']))
906 3b7ed473 Guido Trotter
    # I can still add/remove elements...
907 3b7ed473 Guido Trotter
    self.assertEquals(self.ls.remove(['two', 'three']), ['two', 'three'])
908 3b7ed473 Guido Trotter
    self.assert_(self.ls.add('six'))
909 3b7ed473 Guido Trotter
    self.ls.release()
910 3b7ed473 Guido Trotter
    # share the set-lock
911 3b7ed473 Guido Trotter
    self.assertEquals(self.ls.acquire(None, shared=1), set(['one', 'six']))
912 3b7ed473 Guido Trotter
    # adding new elements is not possible
913 3b7ed473 Guido Trotter
    self.assertRaises(AssertionError, self.ls.add, 'five')
914 3b7ed473 Guido Trotter
    self.ls.release()
915 3b7ed473 Guido Trotter
916 d4f6a91c Guido Trotter
  def testAcquireWithRepetitions(self):
917 d4f6a91c Guido Trotter
    self.assertEquals(self.ls.acquire(['two', 'two', 'three'], shared=1),
918 d4f6a91c Guido Trotter
                      set(['two', 'two', 'three']))
919 d4f6a91c Guido Trotter
    self.ls.release(['two', 'two'])
920 d4f6a91c Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['three']))
921 d4f6a91c Guido Trotter
922 2e1d6d96 Guido Trotter
  def testEmptyAcquire(self):
923 2e1d6d96 Guido Trotter
    # Acquire an empty list of locks...
924 2e1d6d96 Guido Trotter
    self.assertEquals(self.ls.acquire([]), set())
925 2e1d6d96 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
926 2e1d6d96 Guido Trotter
    # New locks can still be addded
927 2e1d6d96 Guido Trotter
    self.assert_(self.ls.add('six'))
928 2e1d6d96 Guido Trotter
    # "re-acquiring" is not an issue, since we had really acquired nothing
929 2e1d6d96 Guido Trotter
    self.assertEquals(self.ls.acquire([], shared=1), set())
930 2e1d6d96 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
931 2e1d6d96 Guido Trotter
    # We haven't really acquired anything, so we cannot release
932 2e1d6d96 Guido Trotter
    self.assertRaises(AssertionError, self.ls.release)
933 2e1d6d96 Guido Trotter
934 84e344d4 Michael Hanselmann
  def _doLockSet(self, names, shared):
935 aaae9bc0 Guido Trotter
    try:
936 84e344d4 Michael Hanselmann
      self.ls.acquire(names, shared=shared)
937 aaae9bc0 Guido Trotter
      self.done.put('DONE')
938 aaae9bc0 Guido Trotter
      self.ls.release()
939 aaae9bc0 Guido Trotter
    except errors.LockError:
940 aaae9bc0 Guido Trotter
      self.done.put('ERR')
941 aaae9bc0 Guido Trotter
942 84e344d4 Michael Hanselmann
  def _doAddSet(self, names):
943 3b7ed473 Guido Trotter
    try:
944 84e344d4 Michael Hanselmann
      self.ls.add(names, acquired=1)
945 3b7ed473 Guido Trotter
      self.done.put('DONE')
946 3b7ed473 Guido Trotter
      self.ls.release()
947 3b7ed473 Guido Trotter
    except errors.LockError:
948 3b7ed473 Guido Trotter
      self.done.put('ERR')
949 3b7ed473 Guido Trotter
950 84e344d4 Michael Hanselmann
  def _doRemoveSet(self, names):
951 84e344d4 Michael Hanselmann
    self.done.put(self.ls.remove(names))
952 aaae9bc0 Guido Trotter
953 4607c978 Iustin Pop
  @_Repeat
954 aaae9bc0 Guido Trotter
  def testConcurrentSharedAcquire(self):
955 aaae9bc0 Guido Trotter
    self.ls.acquire(['one', 'two'], shared=1)
956 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two'], 1))
957 4607c978 Iustin Pop
    self._waitThreads()
958 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
959 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two', 'three'], 1))
960 4607c978 Iustin Pop
    self._waitThreads()
961 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
962 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=('three', 1))
963 4607c978 Iustin Pop
    self._waitThreads()
964 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
965 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two'], 0))
966 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['two', 'three'], 0))
967 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
968 aaae9bc0 Guido Trotter
    self.ls.release()
969 4607c978 Iustin Pop
    self._waitThreads()
970 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
971 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
972 aaae9bc0 Guido Trotter
973 4607c978 Iustin Pop
  @_Repeat
974 aaae9bc0 Guido Trotter
  def testConcurrentExclusiveAcquire(self):
975 aaae9bc0 Guido Trotter
    self.ls.acquire(['one', 'two'])
976 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=('three', 1))
977 4607c978 Iustin Pop
    self._waitThreads()
978 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
979 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=('three', 0))
980 4607c978 Iustin Pop
    self._waitThreads()
981 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
982 84e344d4 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
983 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two'], 0))
984 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two'], 1))
985 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=('one', 0))
986 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=('one', 1))
987 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['two', 'three'], 0))
988 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['two', 'three'], 1))
989 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
990 aaae9bc0 Guido Trotter
    self.ls.release()
991 4607c978 Iustin Pop
    self._waitThreads()
992 4607c978 Iustin Pop
    for _ in range(6):
993 4607c978 Iustin Pop
      self.failUnlessEqual(self.done.get_nowait(), 'DONE')
994 aaae9bc0 Guido Trotter
995 4607c978 Iustin Pop
  @_Repeat
996 5aab242c Michael Hanselmann
  def testSimpleAcquireTimeoutExpiring(self):
997 5aab242c Michael Hanselmann
    names = sorted(self.ls._names())
998 5aab242c Michael Hanselmann
    self.assert_(len(names) >= 3)
999 5aab242c Michael Hanselmann
1000 5aab242c Michael Hanselmann
    # Get name of first lock
1001 5aab242c Michael Hanselmann
    first = names[0]
1002 5aab242c Michael Hanselmann
1003 5aab242c Michael Hanselmann
    # Get name of last lock
1004 5aab242c Michael Hanselmann
    last = names.pop()
1005 5aab242c Michael Hanselmann
1006 5aab242c Michael Hanselmann
    checks = [
1007 5aab242c Michael Hanselmann
      # Block first and try to lock it again
1008 5aab242c Michael Hanselmann
      (first, first),
1009 5aab242c Michael Hanselmann
1010 5aab242c Michael Hanselmann
      # Block last and try to lock all locks
1011 5aab242c Michael Hanselmann
      (None, first),
1012 5aab242c Michael Hanselmann
1013 5aab242c Michael Hanselmann
      # Block last and try to lock it again
1014 5aab242c Michael Hanselmann
      (last, last),
1015 5aab242c Michael Hanselmann
      ]
1016 5aab242c Michael Hanselmann
1017 5aab242c Michael Hanselmann
    for (wanted, block) in checks:
1018 5aab242c Michael Hanselmann
      # Lock in exclusive mode
1019 5aab242c Michael Hanselmann
      self.assert_(self.ls.acquire(block, shared=0))
1020 5aab242c Michael Hanselmann
1021 5aab242c Michael Hanselmann
      def _AcquireOne():
1022 5aab242c Michael Hanselmann
        # Try to get the same lock again with a timeout (should never succeed)
1023 23683c26 Michael Hanselmann
        acquired = self.ls.acquire(wanted, timeout=0.1, shared=0)
1024 23683c26 Michael Hanselmann
        if acquired:
1025 5aab242c Michael Hanselmann
          self.done.put("acquired")
1026 5aab242c Michael Hanselmann
          self.ls.release()
1027 5aab242c Michael Hanselmann
        else:
1028 23683c26 Michael Hanselmann
          self.assert_(acquired is None)
1029 158206e0 Manuel Franceschini
          self.assertFalse(self.ls._list_owned())
1030 158206e0 Manuel Franceschini
          self.assertFalse(self.ls._is_owned())
1031 5aab242c Michael Hanselmann
          self.done.put("not acquired")
1032 5aab242c Michael Hanselmann
1033 5aab242c Michael Hanselmann
      self._addThread(target=_AcquireOne)
1034 5aab242c Michael Hanselmann
1035 5aab242c Michael Hanselmann
      # Wait for timeout in thread to expire
1036 5aab242c Michael Hanselmann
      self._waitThreads()
1037 5aab242c Michael Hanselmann
1038 5aab242c Michael Hanselmann
      # Release exclusive lock again
1039 5aab242c Michael Hanselmann
      self.ls.release()
1040 5aab242c Michael Hanselmann
1041 5aab242c Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "not acquired")
1042 5aab242c Michael Hanselmann
      self.assertRaises(Queue.Empty, self.done.get_nowait)
1043 5aab242c Michael Hanselmann
1044 5aab242c Michael Hanselmann
  @_Repeat
1045 5aab242c Michael Hanselmann
  def testDelayedAndExpiringLockAcquire(self):
1046 5aab242c Michael Hanselmann
    self._setUpLS()
1047 5aab242c Michael Hanselmann
    self.ls.add(['five', 'six', 'seven', 'eight', 'nine'])
1048 5aab242c Michael Hanselmann
1049 5aab242c Michael Hanselmann
    for expire in (False, True):
1050 5aab242c Michael Hanselmann
      names = sorted(self.ls._names())
1051 5aab242c Michael Hanselmann
      self.assertEqual(len(names), 8)
1052 5aab242c Michael Hanselmann
1053 5aab242c Michael Hanselmann
      lock_ev = dict([(i, threading.Event()) for i in names])
1054 5aab242c Michael Hanselmann
1055 5aab242c Michael Hanselmann
      # Lock all in exclusive mode
1056 5aab242c Michael Hanselmann
      self.assert_(self.ls.acquire(names, shared=0))
1057 5aab242c Michael Hanselmann
1058 5aab242c Michael Hanselmann
      if expire:
1059 5aab242c Michael Hanselmann
        # We'll wait at least 300ms per lock
1060 5aab242c Michael Hanselmann
        lockwait = len(names) * [0.3]
1061 5aab242c Michael Hanselmann
1062 5aab242c Michael Hanselmann
        # Fail if we can't acquire all locks in 400ms. There are 8 locks, so
1063 5aab242c Michael Hanselmann
        # this gives us up to 2.4s to fail.
1064 5aab242c Michael Hanselmann
        lockall_timeout = 0.4
1065 5aab242c Michael Hanselmann
      else:
1066 5aab242c Michael Hanselmann
        # This should finish rather quickly
1067 5aab242c Michael Hanselmann
        lockwait = None
1068 5aab242c Michael Hanselmann
        lockall_timeout = len(names) * 5.0
1069 5aab242c Michael Hanselmann
1070 5aab242c Michael Hanselmann
      def _LockAll():
1071 5aab242c Michael Hanselmann
        def acquire_notification(name):
1072 5aab242c Michael Hanselmann
          if not expire:
1073 5aab242c Michael Hanselmann
            self.done.put("getting %s" % name)
1074 5aab242c Michael Hanselmann
1075 5aab242c Michael Hanselmann
          # Kick next lock
1076 5aab242c Michael Hanselmann
          lock_ev[name].set()
1077 5aab242c Michael Hanselmann
1078 5aab242c Michael Hanselmann
        if self.ls.acquire(names, shared=0, timeout=lockall_timeout,
1079 5aab242c Michael Hanselmann
                           test_notify=acquire_notification):
1080 5aab242c Michael Hanselmann
          self.done.put("got all")
1081 5aab242c Michael Hanselmann
          self.ls.release()
1082 5aab242c Michael Hanselmann
        else:
1083 5aab242c Michael Hanselmann
          self.done.put("timeout on all")
1084 5aab242c Michael Hanselmann
1085 5aab242c Michael Hanselmann
        # Notify all locks
1086 5aab242c Michael Hanselmann
        for ev in lock_ev.values():
1087 5aab242c Michael Hanselmann
          ev.set()
1088 5aab242c Michael Hanselmann
1089 5aab242c Michael Hanselmann
      t = self._addThread(target=_LockAll)
1090 5aab242c Michael Hanselmann
1091 5aab242c Michael Hanselmann
      for idx, name in enumerate(names):
1092 5aab242c Michael Hanselmann
        # Wait for actual acquire on this lock to start
1093 5aab242c Michael Hanselmann
        lock_ev[name].wait(10.0)
1094 5aab242c Michael Hanselmann
1095 5aab242c Michael Hanselmann
        if expire and t.isAlive():
1096 5aab242c Michael Hanselmann
          # Wait some time after getting the notification to make sure the lock
1097 5aab242c Michael Hanselmann
          # acquire will expire
1098 5aab242c Michael Hanselmann
          SafeSleep(lockwait[idx])
1099 5aab242c Michael Hanselmann
1100 5aab242c Michael Hanselmann
        self.ls.release(names=name)
1101 5aab242c Michael Hanselmann
1102 158206e0 Manuel Franceschini
      self.assertFalse(self.ls._list_owned())
1103 5aab242c Michael Hanselmann
1104 5aab242c Michael Hanselmann
      self._waitThreads()
1105 5aab242c Michael Hanselmann
1106 5aab242c Michael Hanselmann
      if expire:
1107 5aab242c Michael Hanselmann
        # Not checking which locks were actually acquired. Doing so would be
1108 5aab242c Michael Hanselmann
        # too timing-dependant.
1109 5aab242c Michael Hanselmann
        self.assertEqual(self.done.get_nowait(), "timeout on all")
1110 5aab242c Michael Hanselmann
      else:
1111 5aab242c Michael Hanselmann
        for i in names:
1112 5aab242c Michael Hanselmann
          self.assertEqual(self.done.get_nowait(), "getting %s" % i)
1113 5aab242c Michael Hanselmann
        self.assertEqual(self.done.get_nowait(), "got all")
1114 5aab242c Michael Hanselmann
      self.assertRaises(Queue.Empty, self.done.get_nowait)
1115 5aab242c Michael Hanselmann
1116 5aab242c Michael Hanselmann
  @_Repeat
1117 aaae9bc0 Guido Trotter
  def testConcurrentRemove(self):
1118 aaae9bc0 Guido Trotter
    self.ls.add('four')
1119 aaae9bc0 Guido Trotter
    self.ls.acquire(['one', 'two', 'four'])
1120 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'four'], 0))
1121 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'four'], 1))
1122 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two'], 0))
1123 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two'], 1))
1124 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1125 aaae9bc0 Guido Trotter
    self.ls.remove('one')
1126 aaae9bc0 Guido Trotter
    self.ls.release()
1127 4607c978 Iustin Pop
    self._waitThreads()
1128 4607c978 Iustin Pop
    for i in range(4):
1129 4607c978 Iustin Pop
      self.failUnlessEqual(self.done.get_nowait(), 'ERR')
1130 aaae9bc0 Guido Trotter
    self.ls.add(['five', 'six'], acquired=1)
1131 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['three', 'six'], 1))
1132 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['three', 'six'], 0))
1133 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['four', 'six'], 1))
1134 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['four', 'six'], 0))
1135 aaae9bc0 Guido Trotter
    self.ls.remove('five')
1136 aaae9bc0 Guido Trotter
    self.ls.release()
1137 4607c978 Iustin Pop
    self._waitThreads()
1138 4607c978 Iustin Pop
    for i in range(4):
1139 4607c978 Iustin Pop
      self.failUnlessEqual(self.done.get_nowait(), 'DONE')
1140 aaae9bc0 Guido Trotter
    self.ls.acquire(['three', 'four'])
1141 4607c978 Iustin Pop
    self._addThread(target=self._doRemoveSet, args=(['four', 'six'], ))
1142 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1143 aaae9bc0 Guido Trotter
    self.ls.remove('four')
1144 4607c978 Iustin Pop
    self._waitThreads()
1145 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), ['six'])
1146 4607c978 Iustin Pop
    self._addThread(target=self._doRemoveSet, args=(['two']))
1147 4607c978 Iustin Pop
    self._waitThreads()
1148 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), ['two'])
1149 aaae9bc0 Guido Trotter
    self.ls.release()
1150 4607c978 Iustin Pop
    # reset lockset
1151 4607c978 Iustin Pop
    self._setUpLS()
1152 aaae9bc0 Guido Trotter
1153 4607c978 Iustin Pop
  @_Repeat
1154 3b7ed473 Guido Trotter
  def testConcurrentSharedSetLock(self):
1155 3b7ed473 Guido Trotter
    # share the set-lock...
1156 3b7ed473 Guido Trotter
    self.ls.acquire(None, shared=1)
1157 3b7ed473 Guido Trotter
    # ...another thread can share it too
1158 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1159 4607c978 Iustin Pop
    self._waitThreads()
1160 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1161 3b7ed473 Guido Trotter
    # ...or just share some elements
1162 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'three'], 1))
1163 4607c978 Iustin Pop
    self._waitThreads()
1164 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1165 3b7ed473 Guido Trotter
    # ...but not add new ones or remove any
1166 4607c978 Iustin Pop
    t = self._addThread(target=self._doAddSet, args=(['nine']))
1167 4607c978 Iustin Pop
    self._addThread(target=self._doRemoveSet, args=(['two'], ))
1168 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1169 3b7ed473 Guido Trotter
    # this just releases the set-lock
1170 3b7ed473 Guido Trotter
    self.ls.release([])
1171 4607c978 Iustin Pop
    t.join(60)
1172 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1173 3b7ed473 Guido Trotter
    # release the lock on the actual elements so remove() can proceed too
1174 3b7ed473 Guido Trotter
    self.ls.release()
1175 4607c978 Iustin Pop
    self._waitThreads()
1176 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), ['two'])
1177 4607c978 Iustin Pop
    # reset lockset
1178 4607c978 Iustin Pop
    self._setUpLS()
1179 3b7ed473 Guido Trotter
1180 4607c978 Iustin Pop
  @_Repeat
1181 3b7ed473 Guido Trotter
  def testConcurrentExclusiveSetLock(self):
1182 3b7ed473 Guido Trotter
    # acquire the set-lock...
1183 3b7ed473 Guido Trotter
    self.ls.acquire(None, shared=0)
1184 3b7ed473 Guido Trotter
    # ...no one can do anything else
1185 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1186 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 0))
1187 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['three'], 0))
1188 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['two'], 1))
1189 4607c978 Iustin Pop
    self._addThread(target=self._doAddSet, args=(['nine']))
1190 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1191 3b7ed473 Guido Trotter
    self.ls.release()
1192 4607c978 Iustin Pop
    self._waitThreads()
1193 4607c978 Iustin Pop
    for _ in range(5):
1194 4607c978 Iustin Pop
      self.assertEqual(self.done.get(True, 1), 'DONE')
1195 4607c978 Iustin Pop
    # cleanup
1196 4607c978 Iustin Pop
    self._setUpLS()
1197 3b7ed473 Guido Trotter
1198 4607c978 Iustin Pop
  @_Repeat
1199 d2aff862 Guido Trotter
  def testConcurrentSetLockAdd(self):
1200 d2aff862 Guido Trotter
    self.ls.acquire('one')
1201 d2aff862 Guido Trotter
    # Another thread wants the whole SetLock
1202 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 0))
1203 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1204 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1205 d2aff862 Guido Trotter
    self.assertRaises(AssertionError, self.ls.add, 'four')
1206 d2aff862 Guido Trotter
    self.ls.release()
1207 4607c978 Iustin Pop
    self._waitThreads()
1208 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1209 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1210 d2aff862 Guido Trotter
    self.ls.acquire(None)
1211 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 0))
1212 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1213 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1214 d2aff862 Guido Trotter
    self.ls.add('four')
1215 d2aff862 Guido Trotter
    self.ls.add('five', acquired=1)
1216 d2aff862 Guido Trotter
    self.ls.add('six', acquired=1, shared=1)
1217 d2aff862 Guido Trotter
    self.assertEquals(self.ls._list_owned(),
1218 d2aff862 Guido Trotter
      set(['one', 'two', 'three', 'five', 'six']))
1219 d2aff862 Guido Trotter
    self.assertEquals(self.ls._is_owned(), True)
1220 d2aff862 Guido Trotter
    self.assertEquals(self.ls._names(),
1221 d2aff862 Guido Trotter
      set(['one', 'two', 'three', 'four', 'five', 'six']))
1222 d2aff862 Guido Trotter
    self.ls.release()
1223 4607c978 Iustin Pop
    self._waitThreads()
1224 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1225 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1226 4607c978 Iustin Pop
    self._setUpLS()
1227 d2aff862 Guido Trotter
1228 4607c978 Iustin Pop
  @_Repeat
1229 b2dabfd6 Guido Trotter
  def testEmptyLockSet(self):
1230 b2dabfd6 Guido Trotter
    # get the set-lock
1231 b2dabfd6 Guido Trotter
    self.assertEqual(self.ls.acquire(None), set(['one', 'two', 'three']))
1232 b2dabfd6 Guido Trotter
    # now empty it...
1233 b2dabfd6 Guido Trotter
    self.ls.remove(['one', 'two', 'three'])
1234 b2dabfd6 Guido Trotter
    # and adds/locks by another thread still wait
1235 4607c978 Iustin Pop
    self._addThread(target=self._doAddSet, args=(['nine']))
1236 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1237 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 0))
1238 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1239 b2dabfd6 Guido Trotter
    self.ls.release()
1240 4607c978 Iustin Pop
    self._waitThreads()
1241 4607c978 Iustin Pop
    for _ in range(3):
1242 4607c978 Iustin Pop
      self.assertEqual(self.done.get_nowait(), 'DONE')
1243 b2dabfd6 Guido Trotter
    # empty it again...
1244 b2dabfd6 Guido Trotter
    self.assertEqual(self.ls.remove(['nine']), ['nine'])
1245 b2dabfd6 Guido Trotter
    # now share it...
1246 b2dabfd6 Guido Trotter
    self.assertEqual(self.ls.acquire(None, shared=1), set())
1247 b2dabfd6 Guido Trotter
    # other sharers can go, adds still wait
1248 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1249 4607c978 Iustin Pop
    self._waitThreads()
1250 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1251 4607c978 Iustin Pop
    self._addThread(target=self._doAddSet, args=(['nine']))
1252 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1253 b2dabfd6 Guido Trotter
    self.ls.release()
1254 4607c978 Iustin Pop
    self._waitThreads()
1255 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1256 4607c978 Iustin Pop
    self._setUpLS()
1257 b2dabfd6 Guido Trotter
1258 aaae9bc0 Guido Trotter
1259 4607c978 Iustin Pop
class TestGanetiLockManager(_ThreadedTestCase):
1260 7ee7c0c7 Guido Trotter
1261 7ee7c0c7 Guido Trotter
  def setUp(self):
1262 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
1263 7ee7c0c7 Guido Trotter
    self.nodes=['n1', 'n2']
1264 7ee7c0c7 Guido Trotter
    self.instances=['i1', 'i2', 'i3']
1265 7ee7c0c7 Guido Trotter
    self.GL = locking.GanetiLockManager(nodes=self.nodes,
1266 7ee7c0c7 Guido Trotter
                                        instances=self.instances)
1267 7ee7c0c7 Guido Trotter
1268 7ee7c0c7 Guido Trotter
  def tearDown(self):
1269 7ee7c0c7 Guido Trotter
    # Don't try this at home...
1270 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
1271 7ee7c0c7 Guido Trotter
1272 7ee7c0c7 Guido Trotter
  def testLockingConstants(self):
1273 7ee7c0c7 Guido Trotter
    # The locking library internally cheats by assuming its constants have some
1274 7ee7c0c7 Guido Trotter
    # relationships with each other. Check those hold true.
1275 b10b9d74 Guido Trotter
    # This relationship is also used in the Processor to recursively acquire
1276 b10b9d74 Guido Trotter
    # the right locks. Again, please don't break it.
1277 7ee7c0c7 Guido Trotter
    for i in range(len(locking.LEVELS)):
1278 7ee7c0c7 Guido Trotter
      self.assertEqual(i, locking.LEVELS[i])
1279 7ee7c0c7 Guido Trotter
1280 7ee7c0c7 Guido Trotter
  def testDoubleGLFails(self):
1281 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, locking.GanetiLockManager)
1282 7ee7c0c7 Guido Trotter
1283 7ee7c0c7 Guido Trotter
  def testLockNames(self):
1284 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
1285 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
1286 cdb08f44 Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
1287 cdb08f44 Michael Hanselmann
                     set(self.instances))
1288 7ee7c0c7 Guido Trotter
1289 7ee7c0c7 Guido Trotter
  def testInitAndResources(self):
1290 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
1291 7ee7c0c7 Guido Trotter
    self.GL = locking.GanetiLockManager()
1292 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
1293 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
1294 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
1295 7ee7c0c7 Guido Trotter
1296 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
1297 7ee7c0c7 Guido Trotter
    self.GL = locking.GanetiLockManager(nodes=self.nodes)
1298 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
1299 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
1300 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
1301 7ee7c0c7 Guido Trotter
1302 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
1303 7ee7c0c7 Guido Trotter
    self.GL = locking.GanetiLockManager(instances=self.instances)
1304 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
1305 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
1306 cdb08f44 Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
1307 cdb08f44 Michael Hanselmann
                     set(self.instances))
1308 7ee7c0c7 Guido Trotter
1309 7ee7c0c7 Guido Trotter
  def testAcquireRelease(self):
1310 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1311 7ee7c0c7 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_CLUSTER), set(['BGL']))
1312 04e1bfaf Guido Trotter
    self.GL.acquire(locking.LEVEL_INSTANCE, ['i1'])
1313 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_NODE, ['n1', 'n2'], shared=1)
1314 04e1bfaf Guido Trotter
    self.GL.release(locking.LEVEL_NODE, ['n2'])
1315 7ee7c0c7 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE), set(['n1']))
1316 7ee7c0c7 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE), set(['i1']))
1317 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
1318 04e1bfaf Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE), set())
1319 04e1bfaf Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE), set(['i1']))
1320 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1321 7ee7c0c7 Guido Trotter
    self.assertRaises(errors.LockError, self.GL.acquire,
1322 7ee7c0c7 Guido Trotter
                      locking.LEVEL_INSTANCE, ['i5'])
1323 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_INSTANCE, ['i3'], shared=1)
1324 7ee7c0c7 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE), set(['i3']))
1325 7ee7c0c7 Guido Trotter
1326 90c942d1 Guido Trotter
  def testAcquireWholeSets(self):
1327 90c942d1 Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1328 90c942d1 Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_INSTANCE, None),
1329 90c942d1 Guido Trotter
                      set(self.instances))
1330 90c942d1 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE),
1331 90c942d1 Guido Trotter
                      set(self.instances))
1332 90c942d1 Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODE, None, shared=1),
1333 90c942d1 Guido Trotter
                      set(self.nodes))
1334 90c942d1 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE),
1335 90c942d1 Guido Trotter
                      set(self.nodes))
1336 90c942d1 Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
1337 d4f6a91c Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1338 d4f6a91c Guido Trotter
    self.GL.release(locking.LEVEL_CLUSTER)
1339 d4f6a91c Guido Trotter
1340 d4f6a91c Guido Trotter
  def testAcquireWholeAndPartial(self):
1341 d4f6a91c Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1342 d4f6a91c Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_INSTANCE, None),
1343 d4f6a91c Guido Trotter
                      set(self.instances))
1344 d4f6a91c Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE),
1345 d4f6a91c Guido Trotter
                      set(self.instances))
1346 d4f6a91c Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODE, ['n2'], shared=1),
1347 d4f6a91c Guido Trotter
                      set(['n2']))
1348 d4f6a91c Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE),
1349 d4f6a91c Guido Trotter
                      set(['n2']))
1350 d4f6a91c Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
1351 90c942d1 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1352 90c942d1 Guido Trotter
    self.GL.release(locking.LEVEL_CLUSTER)
1353 90c942d1 Guido Trotter
1354 7ee7c0c7 Guido Trotter
  def testBGLDependency(self):
1355 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1356 7ee7c0c7 Guido Trotter
                      locking.LEVEL_NODE, ['n1', 'n2'])
1357 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1358 7ee7c0c7 Guido Trotter
                      locking.LEVEL_INSTANCE, ['i3'])
1359 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1360 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_NODE, ['n1'])
1361 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1362 7ee7c0c7 Guido Trotter
                      locking.LEVEL_CLUSTER, ['BGL'])
1363 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1364 7ee7c0c7 Guido Trotter
                      locking.LEVEL_CLUSTER)
1365 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
1366 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_INSTANCE, ['i1', 'i2'])
1367 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1368 7ee7c0c7 Guido Trotter
                      locking.LEVEL_CLUSTER, ['BGL'])
1369 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1370 7ee7c0c7 Guido Trotter
                      locking.LEVEL_CLUSTER)
1371 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1372 7ee7c0c7 Guido Trotter
1373 7ee7c0c7 Guido Trotter
  def testWrongOrder(self):
1374 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1375 04e1bfaf Guido Trotter
    self.GL.acquire(locking.LEVEL_NODE, ['n2'])
1376 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1377 7ee7c0c7 Guido Trotter
                      locking.LEVEL_NODE, ['n1'])
1378 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1379 7ee7c0c7 Guido Trotter
                      locking.LEVEL_INSTANCE, ['i2'])
1380 7ee7c0c7 Guido Trotter
1381 7ee7c0c7 Guido Trotter
  # Helper function to run as a thread that shared the BGL and then acquires
1382 7ee7c0c7 Guido Trotter
  # some locks at another level.
1383 7ee7c0c7 Guido Trotter
  def _doLock(self, level, names, shared):
1384 7ee7c0c7 Guido Trotter
    try:
1385 7ee7c0c7 Guido Trotter
      self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1386 7ee7c0c7 Guido Trotter
      self.GL.acquire(level, names, shared=shared)
1387 7ee7c0c7 Guido Trotter
      self.done.put('DONE')
1388 7ee7c0c7 Guido Trotter
      self.GL.release(level)
1389 7ee7c0c7 Guido Trotter
      self.GL.release(locking.LEVEL_CLUSTER)
1390 7ee7c0c7 Guido Trotter
    except errors.LockError:
1391 7ee7c0c7 Guido Trotter
      self.done.put('ERR')
1392 7ee7c0c7 Guido Trotter
1393 4607c978 Iustin Pop
  @_Repeat
1394 7ee7c0c7 Guido Trotter
  def testConcurrency(self):
1395 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1396 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
1397 4607c978 Iustin Pop
                    args=(locking.LEVEL_INSTANCE, 'i1', 1))
1398 4607c978 Iustin Pop
    self._waitThreads()
1399 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1400 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_INSTANCE, ['i3'])
1401 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
1402 4607c978 Iustin Pop
                    args=(locking.LEVEL_INSTANCE, 'i1', 1))
1403 4607c978 Iustin Pop
    self._waitThreads()
1404 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1405 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
1406 4607c978 Iustin Pop
                    args=(locking.LEVEL_INSTANCE, 'i3', 1))
1407 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1408 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1409 4607c978 Iustin Pop
    self._waitThreads()
1410 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1411 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_INSTANCE, ['i2'], shared=1)
1412 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
1413 4607c978 Iustin Pop
                    args=(locking.LEVEL_INSTANCE, 'i2', 1))
1414 4607c978 Iustin Pop
    self._waitThreads()
1415 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1416 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
1417 4607c978 Iustin Pop
                    args=(locking.LEVEL_INSTANCE, 'i2', 0))
1418 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1419 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1420 4607c978 Iustin Pop
    self._waitThreads()
1421 7ee7c0c7 Guido Trotter
    self.assertEqual(self.done.get(True, 1), 'DONE')
1422 4607c978 Iustin Pop
    self.GL.release(locking.LEVEL_CLUSTER, ['BGL'])
1423 7ee7c0c7 Guido Trotter
1424 7ee7c0c7 Guido Trotter
1425 162c1c1f Guido Trotter
if __name__ == '__main__':
1426 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()