Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.locking_unittest.py @ 256eb94b

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