Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.locking_unittest.py @ 8572f1fe

History | View | Annotate | Download (63.8 kB)

1 162c1c1f Guido Trotter
#!/usr/bin/python
2 162c1c1f Guido Trotter
#
3 162c1c1f Guido Trotter
4 7f93570a Iustin Pop
# Copyright (C) 2006, 2007, 2010 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 19b9ba9a Michael Hanselmann
import random
31 887c7aa6 Michael Hanselmann
import itertools
32 162c1c1f Guido Trotter
33 24d16f76 Michael Hanselmann
from ganeti import constants
34 162c1c1f Guido Trotter
from ganeti import locking
35 a95fd5d7 Guido Trotter
from ganeti import errors
36 19b9ba9a Michael Hanselmann
from ganeti import utils
37 887c7aa6 Michael Hanselmann
from ganeti import compat
38 24d16f76 Michael Hanselmann
from ganeti import objects
39 24d16f76 Michael Hanselmann
from ganeti import query
40 162c1c1f Guido Trotter
41 25231ec5 Michael Hanselmann
import testutils
42 25231ec5 Michael Hanselmann
43 162c1c1f Guido Trotter
44 42a999d1 Guido Trotter
# This is used to test the ssynchronize decorator.
45 42a999d1 Guido Trotter
# Since it's passed as input to a decorator it must be declared as a global.
46 7f93570a Iustin Pop
_decoratorlock = locking.SharedLock("decorator lock")
47 42a999d1 Guido Trotter
48 4607c978 Iustin Pop
#: List for looping tests
49 4607c978 Iustin Pop
ITERATIONS = range(8)
50 4607c978 Iustin Pop
51 84e344d4 Michael Hanselmann
52 4607c978 Iustin Pop
def _Repeat(fn):
53 4607c978 Iustin Pop
  """Decorator for executing a function many times"""
54 4607c978 Iustin Pop
  def wrapper(*args, **kwargs):
55 4607c978 Iustin Pop
    for i in ITERATIONS:
56 4607c978 Iustin Pop
      fn(*args, **kwargs)
57 4607c978 Iustin Pop
  return wrapper
58 4607c978 Iustin Pop
59 84e344d4 Michael Hanselmann
60 5aab242c Michael Hanselmann
def SafeSleep(duration):
61 5aab242c Michael Hanselmann
  start = time.time()
62 5aab242c Michael Hanselmann
  while True:
63 5aab242c Michael Hanselmann
    delay = start + duration - time.time()
64 5aab242c Michael Hanselmann
    if delay <= 0.0:
65 5aab242c Michael Hanselmann
      break
66 5aab242c Michael Hanselmann
    time.sleep(delay)
67 5aab242c Michael Hanselmann
68 5aab242c Michael Hanselmann
69 4607c978 Iustin Pop
class _ThreadedTestCase(unittest.TestCase):
70 4607c978 Iustin Pop
  """Test class that supports adding/waiting on threads"""
71 4607c978 Iustin Pop
  def setUp(self):
72 4607c978 Iustin Pop
    unittest.TestCase.setUp(self)
73 63f2e724 Guido Trotter
    self.done = Queue.Queue(0)
74 4607c978 Iustin Pop
    self.threads = []
75 4607c978 Iustin Pop
76 4607c978 Iustin Pop
  def _addThread(self, *args, **kwargs):
77 4607c978 Iustin Pop
    """Create and remember a new thread"""
78 84e344d4 Michael Hanselmann
    t = threading.Thread(*args, **kwargs)
79 4607c978 Iustin Pop
    self.threads.append(t)
80 4607c978 Iustin Pop
    t.start()
81 4607c978 Iustin Pop
    return t
82 4607c978 Iustin Pop
83 4607c978 Iustin Pop
  def _waitThreads(self):
84 4607c978 Iustin Pop
    """Wait for all our threads to finish"""
85 4607c978 Iustin Pop
    for t in self.threads:
86 4607c978 Iustin Pop
      t.join(60)
87 4607c978 Iustin Pop
      self.failIf(t.isAlive())
88 4607c978 Iustin Pop
    self.threads = []
89 42a999d1 Guido Trotter
90 4607c978 Iustin Pop
91 c5fe2a67 Guido Trotter
class _ConditionTestCase(_ThreadedTestCase):
92 c5fe2a67 Guido Trotter
  """Common test case for conditions"""
93 48dabc6a Michael Hanselmann
94 c5fe2a67 Guido Trotter
  def setUp(self, cls):
95 48dabc6a Michael Hanselmann
    _ThreadedTestCase.setUp(self)
96 48dabc6a Michael Hanselmann
    self.lock = threading.Lock()
97 c5fe2a67 Guido Trotter
    self.cond = cls(self.lock)
98 48dabc6a Michael Hanselmann
99 c5fe2a67 Guido Trotter
  def _testAcquireRelease(self):
100 158206e0 Manuel Franceschini
    self.assertFalse(self.cond._is_owned())
101 48dabc6a Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.wait)
102 48dabc6a Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.notifyAll)
103 48dabc6a Michael Hanselmann
104 48dabc6a Michael Hanselmann
    self.cond.acquire()
105 48dabc6a Michael Hanselmann
    self.assert_(self.cond._is_owned())
106 48dabc6a Michael Hanselmann
    self.cond.notifyAll()
107 48dabc6a Michael Hanselmann
    self.assert_(self.cond._is_owned())
108 48dabc6a Michael Hanselmann
    self.cond.release()
109 48dabc6a Michael Hanselmann
110 158206e0 Manuel Franceschini
    self.assertFalse(self.cond._is_owned())
111 48dabc6a Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.wait)
112 48dabc6a Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.notifyAll)
113 48dabc6a Michael Hanselmann
114 c5fe2a67 Guido Trotter
  def _testNotification(self):
115 48dabc6a Michael Hanselmann
    def _NotifyAll():
116 b8140229 Guido Trotter
      self.done.put("NE")
117 48dabc6a Michael Hanselmann
      self.cond.acquire()
118 b8140229 Guido Trotter
      self.done.put("NA")
119 48dabc6a Michael Hanselmann
      self.cond.notifyAll()
120 b8140229 Guido Trotter
      self.done.put("NN")
121 48dabc6a Michael Hanselmann
      self.cond.release()
122 48dabc6a Michael Hanselmann
123 48dabc6a Michael Hanselmann
    self.cond.acquire()
124 48dabc6a Michael Hanselmann
    self._addThread(target=_NotifyAll)
125 b8140229 Guido Trotter
    self.assertEqual(self.done.get(True, 1), "NE")
126 b8140229 Guido Trotter
    self.assertRaises(Queue.Empty, self.done.get_nowait)
127 48dabc6a Michael Hanselmann
    self.cond.wait()
128 b8140229 Guido Trotter
    self.assertEqual(self.done.get(True, 1), "NA")
129 b8140229 Guido Trotter
    self.assertEqual(self.done.get(True, 1), "NN")
130 48dabc6a Michael Hanselmann
    self.assert_(self.cond._is_owned())
131 48dabc6a Michael Hanselmann
    self.cond.release()
132 158206e0 Manuel Franceschini
    self.assertFalse(self.cond._is_owned())
133 48dabc6a Michael Hanselmann
134 c5fe2a67 Guido Trotter
135 34cb5617 Guido Trotter
class TestSingleNotifyPipeCondition(_ConditionTestCase):
136 34cb5617 Guido Trotter
  """SingleNotifyPipeCondition tests"""
137 34cb5617 Guido Trotter
138 34cb5617 Guido Trotter
  def setUp(self):
139 34cb5617 Guido Trotter
    _ConditionTestCase.setUp(self, locking.SingleNotifyPipeCondition)
140 34cb5617 Guido Trotter
141 34cb5617 Guido Trotter
  def testAcquireRelease(self):
142 34cb5617 Guido Trotter
    self._testAcquireRelease()
143 34cb5617 Guido Trotter
144 34cb5617 Guido Trotter
  def testNotification(self):
145 34cb5617 Guido Trotter
    self._testNotification()
146 34cb5617 Guido Trotter
147 34cb5617 Guido Trotter
  def testWaitReuse(self):
148 34cb5617 Guido Trotter
    self.cond.acquire()
149 34cb5617 Guido Trotter
    self.cond.wait(0)
150 34cb5617 Guido Trotter
    self.cond.wait(0.1)
151 34cb5617 Guido Trotter
    self.cond.release()
152 34cb5617 Guido Trotter
153 34cb5617 Guido Trotter
  def testNoNotifyReuse(self):
154 34cb5617 Guido Trotter
    self.cond.acquire()
155 34cb5617 Guido Trotter
    self.cond.notifyAll()
156 34cb5617 Guido Trotter
    self.assertRaises(RuntimeError, self.cond.wait)
157 34cb5617 Guido Trotter
    self.assertRaises(RuntimeError, self.cond.notifyAll)
158 34cb5617 Guido Trotter
    self.cond.release()
159 34cb5617 Guido Trotter
160 34cb5617 Guido Trotter
161 c5fe2a67 Guido Trotter
class TestPipeCondition(_ConditionTestCase):
162 34cb5617 Guido Trotter
  """PipeCondition tests"""
163 c5fe2a67 Guido Trotter
164 c5fe2a67 Guido Trotter
  def setUp(self):
165 34cb5617 Guido Trotter
    _ConditionTestCase.setUp(self, locking.PipeCondition)
166 c5fe2a67 Guido Trotter
167 c5fe2a67 Guido Trotter
  def testAcquireRelease(self):
168 c5fe2a67 Guido Trotter
    self._testAcquireRelease()
169 c5fe2a67 Guido Trotter
170 c5fe2a67 Guido Trotter
  def testNotification(self):
171 c5fe2a67 Guido Trotter
    self._testNotification()
172 c5fe2a67 Guido Trotter
173 48dabc6a Michael Hanselmann
  def _TestWait(self, fn):
174 c31825f7 Michael Hanselmann
    threads = [
175 c31825f7 Michael Hanselmann
      self._addThread(target=fn),
176 c31825f7 Michael Hanselmann
      self._addThread(target=fn),
177 c31825f7 Michael Hanselmann
      self._addThread(target=fn),
178 c31825f7 Michael Hanselmann
      ]
179 48dabc6a Michael Hanselmann
180 48dabc6a Michael Hanselmann
    # Wait for threads to be waiting
181 c31825f7 Michael Hanselmann
    for _ in threads:
182 c31825f7 Michael Hanselmann
      self.assertEqual(self.done.get(True, 1), "A")
183 48dabc6a Michael Hanselmann
184 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
185 48dabc6a Michael Hanselmann
186 48dabc6a Michael Hanselmann
    self.cond.acquire()
187 c31825f7 Michael Hanselmann
    self.assertEqual(len(self.cond._waiters), 3)
188 c31825f7 Michael Hanselmann
    self.assertEqual(self.cond._waiters, set(threads))
189 c31825f7 Michael Hanselmann
    # This new thread can't acquire the lock, and thus call wait, before we
190 48dabc6a Michael Hanselmann
    # release it
191 48dabc6a Michael Hanselmann
    self._addThread(target=fn)
192 48dabc6a Michael Hanselmann
    self.cond.notifyAll()
193 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
194 48dabc6a Michael Hanselmann
    self.cond.release()
195 48dabc6a Michael Hanselmann
196 48dabc6a Michael Hanselmann
    # We should now get 3 W and 1 A (for the new thread) in whatever order
197 48dabc6a Michael Hanselmann
    w = 0
198 48dabc6a Michael Hanselmann
    a = 0
199 48dabc6a Michael Hanselmann
    for i in range(4):
200 48dabc6a Michael Hanselmann
      got = self.done.get(True, 1)
201 48dabc6a Michael Hanselmann
      if got == "W":
202 48dabc6a Michael Hanselmann
        w += 1
203 48dabc6a Michael Hanselmann
      elif got == "A":
204 48dabc6a Michael Hanselmann
        a += 1
205 48dabc6a Michael Hanselmann
      else:
206 48dabc6a Michael Hanselmann
        self.fail("Got %s on the done queue" % got)
207 48dabc6a Michael Hanselmann
208 48dabc6a Michael Hanselmann
    self.assertEqual(w, 3)
209 48dabc6a Michael Hanselmann
    self.assertEqual(a, 1)
210 48dabc6a Michael Hanselmann
211 48dabc6a Michael Hanselmann
    self.cond.acquire()
212 48dabc6a Michael Hanselmann
    self.cond.notifyAll()
213 48dabc6a Michael Hanselmann
    self.cond.release()
214 48dabc6a Michael Hanselmann
    self._waitThreads()
215 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "W")
216 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
217 48dabc6a Michael Hanselmann
218 48dabc6a Michael Hanselmann
  def testBlockingWait(self):
219 48dabc6a Michael Hanselmann
    def _BlockingWait():
220 48dabc6a Michael Hanselmann
      self.cond.acquire()
221 48dabc6a Michael Hanselmann
      self.done.put("A")
222 48dabc6a Michael Hanselmann
      self.cond.wait()
223 48dabc6a Michael Hanselmann
      self.cond.release()
224 48dabc6a Michael Hanselmann
      self.done.put("W")
225 48dabc6a Michael Hanselmann
226 48dabc6a Michael Hanselmann
    self._TestWait(_BlockingWait)
227 48dabc6a Michael Hanselmann
228 48dabc6a Michael Hanselmann
  def testLongTimeoutWait(self):
229 48dabc6a Michael Hanselmann
    def _Helper():
230 48dabc6a Michael Hanselmann
      self.cond.acquire()
231 48dabc6a Michael Hanselmann
      self.done.put("A")
232 48dabc6a Michael Hanselmann
      self.cond.wait(15.0)
233 48dabc6a Michael Hanselmann
      self.cond.release()
234 48dabc6a Michael Hanselmann
      self.done.put("W")
235 48dabc6a Michael Hanselmann
236 48dabc6a Michael Hanselmann
    self._TestWait(_Helper)
237 48dabc6a Michael Hanselmann
238 48dabc6a Michael Hanselmann
  def _TimeoutWait(self, timeout, check):
239 48dabc6a Michael Hanselmann
    self.cond.acquire()
240 48dabc6a Michael Hanselmann
    self.cond.wait(timeout)
241 48dabc6a Michael Hanselmann
    self.cond.release()
242 48dabc6a Michael Hanselmann
    self.done.put(check)
243 48dabc6a Michael Hanselmann
244 48dabc6a Michael Hanselmann
  def testShortTimeoutWait(self):
245 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0.1, "T1"))
246 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0.1, "T1"))
247 48dabc6a Michael Hanselmann
    self._waitThreads()
248 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T1")
249 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T1")
250 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
251 48dabc6a Michael Hanselmann
252 48dabc6a Michael Hanselmann
  def testZeroTimeoutWait(self):
253 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0, "T0"))
254 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0, "T0"))
255 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0, "T0"))
256 48dabc6a Michael Hanselmann
    self._waitThreads()
257 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T0")
258 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T0")
259 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T0")
260 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
261 48dabc6a Michael Hanselmann
262 48dabc6a Michael Hanselmann
263 4607c978 Iustin Pop
class TestSharedLock(_ThreadedTestCase):
264 d6646186 Guido Trotter
  """SharedLock tests"""
265 162c1c1f Guido Trotter
266 162c1c1f Guido Trotter
  def setUp(self):
267 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
268 7f93570a Iustin Pop
    self.sl = locking.SharedLock("TestSharedLock")
269 162c1c1f Guido Trotter
270 162c1c1f Guido Trotter
  def testSequenceAndOwnership(self):
271 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned())
272 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
273 162c1c1f Guido Trotter
    self.assert_(self.sl._is_owned())
274 162c1c1f Guido Trotter
    self.assert_(self.sl._is_owned(shared=1))
275 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned(shared=0))
276 162c1c1f Guido Trotter
    self.sl.release()
277 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned())
278 162c1c1f Guido Trotter
    self.sl.acquire()
279 162c1c1f Guido Trotter
    self.assert_(self.sl._is_owned())
280 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned(shared=1))
281 162c1c1f Guido Trotter
    self.assert_(self.sl._is_owned(shared=0))
282 162c1c1f Guido Trotter
    self.sl.release()
283 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned())
284 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
285 162c1c1f Guido Trotter
    self.assert_(self.sl._is_owned())
286 162c1c1f Guido Trotter
    self.assert_(self.sl._is_owned(shared=1))
287 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned(shared=0))
288 162c1c1f Guido Trotter
    self.sl.release()
289 158206e0 Manuel Franceschini
    self.assertFalse(self.sl._is_owned())
290 162c1c1f Guido Trotter
291 162c1c1f Guido Trotter
  def testBooleanValue(self):
292 162c1c1f Guido Trotter
    # semaphores are supposed to return a true value on a successful acquire
293 162c1c1f Guido Trotter
    self.assert_(self.sl.acquire(shared=1))
294 162c1c1f Guido Trotter
    self.sl.release()
295 162c1c1f Guido Trotter
    self.assert_(self.sl.acquire())
296 162c1c1f Guido Trotter
    self.sl.release()
297 162c1c1f Guido Trotter
298 162c1c1f Guido Trotter
  def testDoubleLockingStoE(self):
299 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
300 162c1c1f Guido Trotter
    self.assertRaises(AssertionError, self.sl.acquire)
301 162c1c1f Guido Trotter
302 162c1c1f Guido Trotter
  def testDoubleLockingEtoS(self):
303 162c1c1f Guido Trotter
    self.sl.acquire()
304 162c1c1f Guido Trotter
    self.assertRaises(AssertionError, self.sl.acquire, shared=1)
305 162c1c1f Guido Trotter
306 162c1c1f Guido Trotter
  def testDoubleLockingStoS(self):
307 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
308 162c1c1f Guido Trotter
    self.assertRaises(AssertionError, self.sl.acquire, shared=1)
309 162c1c1f Guido Trotter
310 162c1c1f Guido Trotter
  def testDoubleLockingEtoE(self):
311 162c1c1f Guido Trotter
    self.sl.acquire()
312 162c1c1f Guido Trotter
    self.assertRaises(AssertionError, self.sl.acquire)
313 162c1c1f Guido Trotter
314 162c1c1f Guido Trotter
  # helper functions: called in a separate thread they acquire the lock, send
315 162c1c1f Guido Trotter
  # their identifier on the done queue, then release it.
316 162c1c1f Guido Trotter
  def _doItSharer(self):
317 a95fd5d7 Guido Trotter
    try:
318 a95fd5d7 Guido Trotter
      self.sl.acquire(shared=1)
319 a95fd5d7 Guido Trotter
      self.done.put('SHR')
320 a95fd5d7 Guido Trotter
      self.sl.release()
321 a95fd5d7 Guido Trotter
    except errors.LockError:
322 a95fd5d7 Guido Trotter
      self.done.put('ERR')
323 162c1c1f Guido Trotter
324 162c1c1f Guido Trotter
  def _doItExclusive(self):
325 a95fd5d7 Guido Trotter
    try:
326 a95fd5d7 Guido Trotter
      self.sl.acquire()
327 a95fd5d7 Guido Trotter
      self.done.put('EXC')
328 a95fd5d7 Guido Trotter
      self.sl.release()
329 a95fd5d7 Guido Trotter
    except errors.LockError:
330 a95fd5d7 Guido Trotter
      self.done.put('ERR')
331 a95fd5d7 Guido Trotter
332 a95fd5d7 Guido Trotter
  def _doItDelete(self):
333 a95fd5d7 Guido Trotter
    try:
334 4354ab03 Guido Trotter
      self.sl.delete()
335 a95fd5d7 Guido Trotter
      self.done.put('DEL')
336 a95fd5d7 Guido Trotter
    except errors.LockError:
337 a95fd5d7 Guido Trotter
      self.done.put('ERR')
338 162c1c1f Guido Trotter
339 162c1c1f Guido Trotter
  def testSharersCanCoexist(self):
340 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
341 84e344d4 Michael Hanselmann
    threading.Thread(target=self._doItSharer).start()
342 162c1c1f Guido Trotter
    self.assert_(self.done.get(True, 1))
343 162c1c1f Guido Trotter
    self.sl.release()
344 162c1c1f Guido Trotter
345 4607c978 Iustin Pop
  @_Repeat
346 162c1c1f Guido Trotter
  def testExclusiveBlocksExclusive(self):
347 162c1c1f Guido Trotter
    self.sl.acquire()
348 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
349 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
350 162c1c1f Guido Trotter
    self.sl.release()
351 4607c978 Iustin Pop
    self._waitThreads()
352 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'EXC')
353 162c1c1f Guido Trotter
354 4607c978 Iustin Pop
  @_Repeat
355 a95fd5d7 Guido Trotter
  def testExclusiveBlocksDelete(self):
356 a95fd5d7 Guido Trotter
    self.sl.acquire()
357 4607c978 Iustin Pop
    self._addThread(target=self._doItDelete)
358 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
359 a95fd5d7 Guido Trotter
    self.sl.release()
360 4607c978 Iustin Pop
    self._waitThreads()
361 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'DEL')
362 7f93570a Iustin Pop
    self.sl = locking.SharedLock(self.sl.name)
363 a95fd5d7 Guido Trotter
364 4607c978 Iustin Pop
  @_Repeat
365 162c1c1f Guido Trotter
  def testExclusiveBlocksSharer(self):
366 162c1c1f Guido Trotter
    self.sl.acquire()
367 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
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(), 'SHR')
372 162c1c1f Guido Trotter
373 4607c978 Iustin Pop
  @_Repeat
374 162c1c1f Guido Trotter
  def testSharerBlocksExclusive(self):
375 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
376 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
377 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
378 162c1c1f Guido Trotter
    self.sl.release()
379 4607c978 Iustin Pop
    self._waitThreads()
380 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'EXC')
381 162c1c1f Guido Trotter
382 4607c978 Iustin Pop
  @_Repeat
383 a95fd5d7 Guido Trotter
  def testSharerBlocksDelete(self):
384 a95fd5d7 Guido Trotter
    self.sl.acquire(shared=1)
385 4607c978 Iustin Pop
    self._addThread(target=self._doItDelete)
386 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
387 a95fd5d7 Guido Trotter
    self.sl.release()
388 4607c978 Iustin Pop
    self._waitThreads()
389 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'DEL')
390 7f93570a Iustin Pop
    self.sl = locking.SharedLock(self.sl.name)
391 a95fd5d7 Guido Trotter
392 4607c978 Iustin Pop
  @_Repeat
393 162c1c1f Guido Trotter
  def testWaitingExclusiveBlocksSharer(self):
394 e6416152 Iustin Pop
    """SKIPPED testWaitingExclusiveBlockSharer"""
395 e6416152 Iustin Pop
    return
396 e6416152 Iustin Pop
397 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
398 162c1c1f Guido Trotter
    # the lock is acquired in shared mode...
399 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
400 162c1c1f Guido Trotter
    # ...but now an exclusive is waiting...
401 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
402 162c1c1f Guido Trotter
    # ...so the sharer should be blocked as well
403 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
404 162c1c1f Guido Trotter
    self.sl.release()
405 4607c978 Iustin Pop
    self._waitThreads()
406 162c1c1f Guido Trotter
    # The exclusive passed before
407 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'EXC')
408 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'SHR')
409 162c1c1f Guido Trotter
410 4607c978 Iustin Pop
  @_Repeat
411 162c1c1f Guido Trotter
  def testWaitingSharerBlocksExclusive(self):
412 a143be68 Iustin Pop
    """SKIPPED testWaitingSharerBlocksExclusive"""
413 a143be68 Iustin Pop
    return
414 a143be68 Iustin Pop
415 162c1c1f Guido Trotter
    self.sl.acquire()
416 162c1c1f Guido Trotter
    # the lock is acquired in exclusive mode...
417 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
418 162c1c1f Guido Trotter
    # ...but now a sharer is waiting...
419 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
420 162c1c1f Guido Trotter
    # ...the exclusive is waiting too...
421 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
422 162c1c1f Guido Trotter
    self.sl.release()
423 4607c978 Iustin Pop
    self._waitThreads()
424 162c1c1f Guido Trotter
    # The sharer passed before
425 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'SHR')
426 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'EXC')
427 162c1c1f Guido Trotter
428 a95fd5d7 Guido Trotter
  def testDelete(self):
429 a95fd5d7 Guido Trotter
    self.sl.delete()
430 a95fd5d7 Guido Trotter
    self.assertRaises(errors.LockError, self.sl.acquire)
431 84152b96 Guido Trotter
    self.assertRaises(errors.LockError, self.sl.acquire, shared=1)
432 a95fd5d7 Guido Trotter
    self.assertRaises(errors.LockError, self.sl.delete)
433 a95fd5d7 Guido Trotter
434 a66bd91b Michael Hanselmann
  def testDeleteTimeout(self):
435 a66bd91b Michael Hanselmann
    self.sl.delete(timeout=60)
436 a66bd91b Michael Hanselmann
437 84152b96 Guido Trotter
  def testNoDeleteIfSharer(self):
438 84152b96 Guido Trotter
    self.sl.acquire(shared=1)
439 84152b96 Guido Trotter
    self.assertRaises(AssertionError, self.sl.delete)
440 84152b96 Guido Trotter
441 4607c978 Iustin Pop
  @_Repeat
442 a95fd5d7 Guido Trotter
  def testDeletePendingSharersExclusiveDelete(self):
443 a95fd5d7 Guido Trotter
    self.sl.acquire()
444 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
445 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
446 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
447 4607c978 Iustin Pop
    self._addThread(target=self._doItDelete)
448 a95fd5d7 Guido Trotter
    self.sl.delete()
449 4607c978 Iustin Pop
    self._waitThreads()
450 4607c978 Iustin Pop
    # The threads who were pending return ERR
451 4607c978 Iustin Pop
    for _ in range(4):
452 4607c978 Iustin Pop
      self.assertEqual(self.done.get_nowait(), 'ERR')
453 7f93570a Iustin Pop
    self.sl = locking.SharedLock(self.sl.name)
454 a95fd5d7 Guido Trotter
455 4607c978 Iustin Pop
  @_Repeat
456 a95fd5d7 Guido Trotter
  def testDeletePendingDeleteExclusiveSharers(self):
457 a95fd5d7 Guido Trotter
    self.sl.acquire()
458 4607c978 Iustin Pop
    self._addThread(target=self._doItDelete)
459 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
460 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
461 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
462 a95fd5d7 Guido Trotter
    self.sl.delete()
463 4607c978 Iustin Pop
    self._waitThreads()
464 a95fd5d7 Guido Trotter
    # The two threads who were pending return both ERR
465 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'ERR')
466 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'ERR')
467 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'ERR')
468 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'ERR')
469 7f93570a Iustin Pop
    self.sl = locking.SharedLock(self.sl.name)
470 a95fd5d7 Guido Trotter
471 84e344d4 Michael Hanselmann
  @_Repeat
472 84e344d4 Michael Hanselmann
  def testExclusiveAcquireTimeout(self):
473 84e344d4 Michael Hanselmann
    for shared in [0, 1]:
474 008b92fa Michael Hanselmann
      on_queue = threading.Event()
475 008b92fa Michael Hanselmann
      release_exclusive = threading.Event()
476 008b92fa Michael Hanselmann
477 008b92fa Michael Hanselmann
      def _LockExclusive():
478 008b92fa Michael Hanselmann
        self.sl.acquire(shared=0, test_notify=on_queue.set)
479 008b92fa Michael Hanselmann
        self.done.put("A: start wait")
480 008b92fa Michael Hanselmann
        release_exclusive.wait()
481 008b92fa Michael Hanselmann
        self.done.put("A: end wait")
482 008b92fa Michael Hanselmann
        self.sl.release()
483 008b92fa Michael Hanselmann
484 008b92fa Michael Hanselmann
      # Start thread to hold lock in exclusive mode
485 008b92fa Michael Hanselmann
      self._addThread(target=_LockExclusive)
486 84e344d4 Michael Hanselmann
487 008b92fa Michael Hanselmann
      # Wait for wait to begin
488 008b92fa Michael Hanselmann
      self.assertEqual(self.done.get(timeout=60), "A: start wait")
489 008b92fa Michael Hanselmann
490 008b92fa Michael Hanselmann
      # Wait up to 60s to get lock, but release exclusive lock as soon as we're
491 008b92fa Michael Hanselmann
      # on the queue
492 008b92fa Michael Hanselmann
      self.failUnless(self.sl.acquire(shared=shared, timeout=60,
493 008b92fa Michael Hanselmann
                                      test_notify=release_exclusive.set))
494 2042aa94 Michael Hanselmann
495 84e344d4 Michael Hanselmann
      self.done.put("got 2nd")
496 84e344d4 Michael Hanselmann
      self.sl.release()
497 84e344d4 Michael Hanselmann
498 84e344d4 Michael Hanselmann
      self._waitThreads()
499 84e344d4 Michael Hanselmann
500 008b92fa Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "A: end wait")
501 84e344d4 Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "got 2nd")
502 84e344d4 Michael Hanselmann
      self.assertRaises(Queue.Empty, self.done.get_nowait)
503 84e344d4 Michael Hanselmann
504 84e344d4 Michael Hanselmann
  @_Repeat
505 84e344d4 Michael Hanselmann
  def testAcquireExpiringTimeout(self):
506 84e344d4 Michael Hanselmann
    def _AcquireWithTimeout(shared, timeout):
507 84e344d4 Michael Hanselmann
      if not self.sl.acquire(shared=shared, timeout=timeout):
508 84e344d4 Michael Hanselmann
        self.done.put("timeout")
509 84e344d4 Michael Hanselmann
510 84e344d4 Michael Hanselmann
    for shared in [0, 1]:
511 84e344d4 Michael Hanselmann
      # Lock exclusively
512 84e344d4 Michael Hanselmann
      self.sl.acquire()
513 84e344d4 Michael Hanselmann
514 84e344d4 Michael Hanselmann
      # Start shared acquires with timeout between 0 and 20 ms
515 f1501b3f Michael Hanselmann
      for i in range(11):
516 84e344d4 Michael Hanselmann
        self._addThread(target=_AcquireWithTimeout,
517 84e344d4 Michael Hanselmann
                        args=(shared, i * 2.0 / 1000.0))
518 84e344d4 Michael Hanselmann
519 84e344d4 Michael Hanselmann
      # Wait for threads to finish (makes sure the acquire timeout expires
520 84e344d4 Michael Hanselmann
      # before releasing the lock)
521 84e344d4 Michael Hanselmann
      self._waitThreads()
522 84e344d4 Michael Hanselmann
523 84e344d4 Michael Hanselmann
      # Release lock
524 84e344d4 Michael Hanselmann
      self.sl.release()
525 84e344d4 Michael Hanselmann
526 f1501b3f Michael Hanselmann
      for _ in range(11):
527 84e344d4 Michael Hanselmann
        self.assertEqual(self.done.get_nowait(), "timeout")
528 84e344d4 Michael Hanselmann
529 84e344d4 Michael Hanselmann
      self.assertRaises(Queue.Empty, self.done.get_nowait)
530 84e344d4 Michael Hanselmann
531 84e344d4 Michael Hanselmann
  @_Repeat
532 84e344d4 Michael Hanselmann
  def testSharedSkipExclusiveAcquires(self):
533 84e344d4 Michael Hanselmann
    # Tests whether shared acquires jump in front of exclusive acquires in the
534 84e344d4 Michael Hanselmann
    # queue.
535 84e344d4 Michael Hanselmann
536 008b92fa Michael Hanselmann
    def _Acquire(shared, name, notify_ev, wait_ev):
537 008b92fa Michael Hanselmann
      if notify_ev:
538 008b92fa Michael Hanselmann
        notify_fn = notify_ev.set
539 008b92fa Michael Hanselmann
      else:
540 008b92fa Michael Hanselmann
        notify_fn = None
541 84e344d4 Michael Hanselmann
542 008b92fa Michael Hanselmann
      if wait_ev:
543 008b92fa Michael Hanselmann
        wait_ev.wait()
544 008b92fa Michael Hanselmann
545 008b92fa Michael Hanselmann
      if not self.sl.acquire(shared=shared, test_notify=notify_fn):
546 84e344d4 Michael Hanselmann
        return
547 84e344d4 Michael Hanselmann
548 84e344d4 Michael Hanselmann
      self.done.put(name)
549 84e344d4 Michael Hanselmann
      self.sl.release()
550 84e344d4 Michael Hanselmann
551 008b92fa Michael Hanselmann
    # Get exclusive lock while we fill the queue
552 008b92fa Michael Hanselmann
    self.sl.acquire()
553 84e344d4 Michael Hanselmann
554 008b92fa Michael Hanselmann
    shrcnt1 = 5
555 008b92fa Michael Hanselmann
    shrcnt2 = 7
556 008b92fa Michael Hanselmann
    shrcnt3 = 9
557 008b92fa Michael Hanselmann
    shrcnt4 = 2
558 84e344d4 Michael Hanselmann
559 008b92fa Michael Hanselmann
    # Add acquires using threading.Event for synchronization. They'll be
560 008b92fa Michael Hanselmann
    # acquired exactly in the order defined in this list.
561 008b92fa Michael Hanselmann
    acquires = (shrcnt1 * [(1, "shared 1")] +
562 008b92fa Michael Hanselmann
                3 * [(0, "exclusive 1")] +
563 008b92fa Michael Hanselmann
                shrcnt2 * [(1, "shared 2")] +
564 008b92fa Michael Hanselmann
                shrcnt3 * [(1, "shared 3")] +
565 008b92fa Michael Hanselmann
                shrcnt4 * [(1, "shared 4")] +
566 008b92fa Michael Hanselmann
                3 * [(0, "exclusive 2")])
567 84e344d4 Michael Hanselmann
568 008b92fa Michael Hanselmann
    ev_cur = None
569 008b92fa Michael Hanselmann
    ev_prev = None
570 008b92fa Michael Hanselmann
571 008b92fa Michael Hanselmann
    for args in acquires:
572 008b92fa Michael Hanselmann
      ev_cur = threading.Event()
573 008b92fa Michael Hanselmann
      self._addThread(target=_Acquire, args=args + (ev_cur, ev_prev))
574 008b92fa Michael Hanselmann
      ev_prev = ev_cur
575 008b92fa Michael Hanselmann
576 008b92fa Michael Hanselmann
    # Wait for last acquire to start
577 008b92fa Michael Hanselmann
    ev_prev.wait()
578 84e344d4 Michael Hanselmann
579 84e344d4 Michael Hanselmann
    # Expect 6 pending exclusive acquires and 1 for all shared acquires
580 008b92fa Michael Hanselmann
    # together
581 008b92fa Michael Hanselmann
    self.assertEqual(self.sl._count_pending(), 7)
582 84e344d4 Michael Hanselmann
583 84e344d4 Michael Hanselmann
    # Release exclusive lock and wait
584 84e344d4 Michael Hanselmann
    self.sl.release()
585 84e344d4 Michael Hanselmann
586 84e344d4 Michael Hanselmann
    self._waitThreads()
587 84e344d4 Michael Hanselmann
588 84e344d4 Michael Hanselmann
    # Check sequence
589 008b92fa Michael Hanselmann
    for _ in range(shrcnt1 + shrcnt2 + shrcnt3 + shrcnt4):
590 84e344d4 Michael Hanselmann
      # Shared locks aren't guaranteed to be notified in order, but they'll be
591 84e344d4 Michael Hanselmann
      # first
592 2042aa94 Michael Hanselmann
      tmp = self.done.get_nowait()
593 008b92fa Michael Hanselmann
      if tmp == "shared 1":
594 008b92fa Michael Hanselmann
        shrcnt1 -= 1
595 008b92fa Michael Hanselmann
      elif tmp == "shared 2":
596 008b92fa Michael Hanselmann
        shrcnt2 -= 1
597 008b92fa Michael Hanselmann
      elif tmp == "shared 3":
598 008b92fa Michael Hanselmann
        shrcnt3 -= 1
599 008b92fa Michael Hanselmann
      elif tmp == "shared 4":
600 008b92fa Michael Hanselmann
        shrcnt4 -= 1
601 008b92fa Michael Hanselmann
    self.assertEqual(shrcnt1, 0)
602 008b92fa Michael Hanselmann
    self.assertEqual(shrcnt2, 0)
603 008b92fa Michael Hanselmann
    self.assertEqual(shrcnt3, 0)
604 008b92fa Michael Hanselmann
    self.assertEqual(shrcnt3, 0)
605 84e344d4 Michael Hanselmann
606 f1501b3f Michael Hanselmann
    for _ in range(3):
607 008b92fa Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "exclusive 1")
608 84e344d4 Michael Hanselmann
609 f1501b3f Michael Hanselmann
    for _ in range(3):
610 008b92fa Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "exclusive 2")
611 84e344d4 Michael Hanselmann
612 84e344d4 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
613 84e344d4 Michael Hanselmann
614 84e344d4 Michael Hanselmann
  @_Repeat
615 84e344d4 Michael Hanselmann
  def testMixedAcquireTimeout(self):
616 51e3bb92 Michael Hanselmann
    sync = threading.Event()
617 84e344d4 Michael Hanselmann
618 84e344d4 Michael Hanselmann
    def _AcquireShared(ev):
619 84e344d4 Michael Hanselmann
      if not self.sl.acquire(shared=1, timeout=None):
620 84e344d4 Michael Hanselmann
        return
621 84e344d4 Michael Hanselmann
622 84e344d4 Michael Hanselmann
      self.done.put("shared")
623 84e344d4 Michael Hanselmann
624 84e344d4 Michael Hanselmann
      # Notify main thread
625 84e344d4 Michael Hanselmann
      ev.set()
626 84e344d4 Michael Hanselmann
627 51e3bb92 Michael Hanselmann
      # Wait for notification from main thread
628 51e3bb92 Michael Hanselmann
      sync.wait()
629 84e344d4 Michael Hanselmann
630 84e344d4 Michael Hanselmann
      # Release lock
631 84e344d4 Michael Hanselmann
      self.sl.release()
632 84e344d4 Michael Hanselmann
633 84e344d4 Michael Hanselmann
    acquires = []
634 f1501b3f Michael Hanselmann
    for _ in range(3):
635 84e344d4 Michael Hanselmann
      ev = threading.Event()
636 84e344d4 Michael Hanselmann
      self._addThread(target=_AcquireShared, args=(ev, ))
637 84e344d4 Michael Hanselmann
      acquires.append(ev)
638 84e344d4 Michael Hanselmann
639 84e344d4 Michael Hanselmann
    # Wait for all acquires to finish
640 84e344d4 Michael Hanselmann
    for i in acquires:
641 84e344d4 Michael Hanselmann
      i.wait()
642 84e344d4 Michael Hanselmann
643 84e344d4 Michael Hanselmann
    self.assertEqual(self.sl._count_pending(), 0)
644 84e344d4 Michael Hanselmann
645 84e344d4 Michael Hanselmann
    # Try to get exclusive lock
646 84e344d4 Michael Hanselmann
    self.failIf(self.sl.acquire(shared=0, timeout=0.02))
647 84e344d4 Michael Hanselmann
648 84e344d4 Michael Hanselmann
    # Acquire exclusive without timeout
649 51e3bb92 Michael Hanselmann
    exclsync = threading.Event()
650 84e344d4 Michael Hanselmann
    exclev = threading.Event()
651 84e344d4 Michael Hanselmann
652 84e344d4 Michael Hanselmann
    def _AcquireExclusive():
653 84e344d4 Michael Hanselmann
      if not self.sl.acquire(shared=0):
654 84e344d4 Michael Hanselmann
        return
655 84e344d4 Michael Hanselmann
656 84e344d4 Michael Hanselmann
      self.done.put("exclusive")
657 84e344d4 Michael Hanselmann
658 84e344d4 Michael Hanselmann
      # Notify main thread
659 84e344d4 Michael Hanselmann
      exclev.set()
660 84e344d4 Michael Hanselmann
661 51e3bb92 Michael Hanselmann
      # Wait for notification from main thread
662 51e3bb92 Michael Hanselmann
      exclsync.wait()
663 84e344d4 Michael Hanselmann
664 84e344d4 Michael Hanselmann
      self.sl.release()
665 84e344d4 Michael Hanselmann
666 84e344d4 Michael Hanselmann
    self._addThread(target=_AcquireExclusive)
667 84e344d4 Michael Hanselmann
668 84e344d4 Michael Hanselmann
    # Try to get exclusive lock
669 84e344d4 Michael Hanselmann
    self.failIf(self.sl.acquire(shared=0, timeout=0.02))
670 84e344d4 Michael Hanselmann
671 84e344d4 Michael Hanselmann
    # Make all shared holders release their locks
672 51e3bb92 Michael Hanselmann
    sync.set()
673 84e344d4 Michael Hanselmann
674 84e344d4 Michael Hanselmann
    # Wait for exclusive acquire to succeed
675 84e344d4 Michael Hanselmann
    exclev.wait()
676 84e344d4 Michael Hanselmann
677 84e344d4 Michael Hanselmann
    self.assertEqual(self.sl._count_pending(), 0)
678 84e344d4 Michael Hanselmann
679 84e344d4 Michael Hanselmann
    # Try to get exclusive lock
680 84e344d4 Michael Hanselmann
    self.failIf(self.sl.acquire(shared=0, timeout=0.02))
681 84e344d4 Michael Hanselmann
682 84e344d4 Michael Hanselmann
    def _AcquireSharedSimple():
683 84e344d4 Michael Hanselmann
      if self.sl.acquire(shared=1, timeout=None):
684 84e344d4 Michael Hanselmann
        self.done.put("shared2")
685 84e344d4 Michael Hanselmann
        self.sl.release()
686 84e344d4 Michael Hanselmann
687 f1501b3f Michael Hanselmann
    for _ in range(10):
688 84e344d4 Michael Hanselmann
      self._addThread(target=_AcquireSharedSimple)
689 84e344d4 Michael Hanselmann
690 84e344d4 Michael Hanselmann
    # Tell exclusive lock to release
691 51e3bb92 Michael Hanselmann
    exclsync.set()
692 84e344d4 Michael Hanselmann
693 84e344d4 Michael Hanselmann
    # Wait for everything to finish
694 84e344d4 Michael Hanselmann
    self._waitThreads()
695 84e344d4 Michael Hanselmann
696 84e344d4 Michael Hanselmann
    self.assertEqual(self.sl._count_pending(), 0)
697 84e344d4 Michael Hanselmann
698 84e344d4 Michael Hanselmann
    # Check sequence
699 f1501b3f Michael Hanselmann
    for _ in range(3):
700 84e344d4 Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "shared")
701 84e344d4 Michael Hanselmann
702 84e344d4 Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "exclusive")
703 84e344d4 Michael Hanselmann
704 f1501b3f Michael Hanselmann
    for _ in range(10):
705 84e344d4 Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "shared2")
706 84e344d4 Michael Hanselmann
707 84e344d4 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
708 84e344d4 Michael Hanselmann
709 887c7aa6 Michael Hanselmann
  def testPriority(self):
710 887c7aa6 Michael Hanselmann
    # Acquire in exclusive mode
711 887c7aa6 Michael Hanselmann
    self.assert_(self.sl.acquire(shared=0))
712 887c7aa6 Michael Hanselmann
713 887c7aa6 Michael Hanselmann
    # Queue acquires
714 887c7aa6 Michael Hanselmann
    def _Acquire(prev, next, shared, priority, result):
715 887c7aa6 Michael Hanselmann
      prev.wait()
716 887c7aa6 Michael Hanselmann
      self.sl.acquire(shared=shared, priority=priority, test_notify=next.set)
717 887c7aa6 Michael Hanselmann
      try:
718 887c7aa6 Michael Hanselmann
        self.done.put(result)
719 887c7aa6 Michael Hanselmann
      finally:
720 887c7aa6 Michael Hanselmann
        self.sl.release()
721 887c7aa6 Michael Hanselmann
722 887c7aa6 Michael Hanselmann
    counter = itertools.count(0)
723 887c7aa6 Michael Hanselmann
    priorities = range(-20, 30)
724 887c7aa6 Michael Hanselmann
    first = threading.Event()
725 887c7aa6 Michael Hanselmann
    prev = first
726 887c7aa6 Michael Hanselmann
727 887c7aa6 Michael Hanselmann
    # Data structure:
728 887c7aa6 Michael Hanselmann
    # {
729 887c7aa6 Michael Hanselmann
    #   priority:
730 887c7aa6 Michael Hanselmann
    #     [(shared/exclusive, set(acquire names), set(pending threads)),
731 887c7aa6 Michael Hanselmann
    #      (shared/exclusive, ...),
732 887c7aa6 Michael Hanselmann
    #      ...,
733 887c7aa6 Michael Hanselmann
    #     ],
734 887c7aa6 Michael Hanselmann
    # }
735 887c7aa6 Michael Hanselmann
    perprio = {}
736 887c7aa6 Michael Hanselmann
737 887c7aa6 Michael Hanselmann
    # References shared acquire per priority in L{perprio}. Data structure:
738 887c7aa6 Michael Hanselmann
    # {
739 887c7aa6 Michael Hanselmann
    #   priority: (shared=1, set(acquire names), set(pending threads)),
740 887c7aa6 Michael Hanselmann
    # }
741 887c7aa6 Michael Hanselmann
    prioshared = {}
742 887c7aa6 Michael Hanselmann
743 887c7aa6 Michael Hanselmann
    for seed in [4979, 9523, 14902, 32440]:
744 887c7aa6 Michael Hanselmann
      # Use a deterministic random generator
745 887c7aa6 Michael Hanselmann
      rnd = random.Random(seed)
746 887c7aa6 Michael Hanselmann
      for priority in [rnd.choice(priorities) for _ in range(30)]:
747 887c7aa6 Michael Hanselmann
        modes = [0, 1]
748 887c7aa6 Michael Hanselmann
        rnd.shuffle(modes)
749 887c7aa6 Michael Hanselmann
        for shared in modes:
750 887c7aa6 Michael Hanselmann
          # Unique name
751 887c7aa6 Michael Hanselmann
          acqname = "%s/shr=%s/prio=%s" % (counter.next(), shared, priority)
752 887c7aa6 Michael Hanselmann
753 887c7aa6 Michael Hanselmann
          ev = threading.Event()
754 887c7aa6 Michael Hanselmann
          thread = self._addThread(target=_Acquire,
755 887c7aa6 Michael Hanselmann
                                   args=(prev, ev, shared, priority, acqname))
756 887c7aa6 Michael Hanselmann
          prev = ev
757 887c7aa6 Michael Hanselmann
758 887c7aa6 Michael Hanselmann
          # Record expected aqcuire, see above for structure
759 887c7aa6 Michael Hanselmann
          data = (shared, set([acqname]), set([thread]))
760 887c7aa6 Michael Hanselmann
          priolist = perprio.setdefault(priority, [])
761 887c7aa6 Michael Hanselmann
          if shared:
762 887c7aa6 Michael Hanselmann
            priosh = prioshared.get(priority, None)
763 887c7aa6 Michael Hanselmann
            if priosh:
764 887c7aa6 Michael Hanselmann
              # Shared acquires are merged
765 887c7aa6 Michael Hanselmann
              for i, j in zip(priosh[1:], data[1:]):
766 887c7aa6 Michael Hanselmann
                i.update(j)
767 887c7aa6 Michael Hanselmann
              assert data[0] == priosh[0]
768 887c7aa6 Michael Hanselmann
            else:
769 887c7aa6 Michael Hanselmann
              prioshared[priority] = data
770 887c7aa6 Michael Hanselmann
              priolist.append(data)
771 887c7aa6 Michael Hanselmann
          else:
772 887c7aa6 Michael Hanselmann
            priolist.append(data)
773 887c7aa6 Michael Hanselmann
774 887c7aa6 Michael Hanselmann
    # Start all acquires and wait for them
775 887c7aa6 Michael Hanselmann
    first.set()
776 887c7aa6 Michael Hanselmann
    prev.wait()
777 887c7aa6 Michael Hanselmann
778 887c7aa6 Michael Hanselmann
    # Check lock information
779 24d16f76 Michael Hanselmann
    self.assertEqual(self.sl.GetInfo(set()), (self.sl.name, None, None, None))
780 24d16f76 Michael Hanselmann
    self.assertEqual(self.sl.GetInfo(set([query.LQ_MODE, query.LQ_OWNER])),
781 24d16f76 Michael Hanselmann
                     (self.sl.name, "exclusive",
782 24d16f76 Michael Hanselmann
                      [threading.currentThread().getName()], None))
783 24d16f76 Michael Hanselmann
784 24d16f76 Michael Hanselmann
    self._VerifyPrioPending(self.sl.GetInfo(set([query.LQ_PENDING])), perprio)
785 887c7aa6 Michael Hanselmann
786 887c7aa6 Michael Hanselmann
    # Let threads acquire the lock
787 887c7aa6 Michael Hanselmann
    self.sl.release()
788 887c7aa6 Michael Hanselmann
789 887c7aa6 Michael Hanselmann
    # Wait for everything to finish
790 887c7aa6 Michael Hanselmann
    self._waitThreads()
791 887c7aa6 Michael Hanselmann
792 887c7aa6 Michael Hanselmann
    self.assert_(self.sl._check_empty())
793 887c7aa6 Michael Hanselmann
794 887c7aa6 Michael Hanselmann
    # Check acquires by priority
795 887c7aa6 Michael Hanselmann
    for acquires in [perprio[i] for i in sorted(perprio.keys())]:
796 887c7aa6 Michael Hanselmann
      for (_, names, _) in acquires:
797 887c7aa6 Michael Hanselmann
        # For shared acquires, the set will contain 1..n entries. For exclusive
798 887c7aa6 Michael Hanselmann
        # acquires only one.
799 887c7aa6 Michael Hanselmann
        while names:
800 887c7aa6 Michael Hanselmann
          names.remove(self.done.get_nowait())
801 887c7aa6 Michael Hanselmann
      self.assertFalse(compat.any(names for (_, names, _) in acquires))
802 887c7aa6 Michael Hanselmann
803 887c7aa6 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
804 887c7aa6 Michael Hanselmann
805 24d16f76 Michael Hanselmann
  def _VerifyPrioPending(self, (name, mode, owner, pending), perprio):
806 24d16f76 Michael Hanselmann
    self.assertEqual(name, self.sl.name)
807 24d16f76 Michael Hanselmann
    self.assert_(mode is None)
808 24d16f76 Michael Hanselmann
    self.assert_(owner is None)
809 24d16f76 Michael Hanselmann
810 24d16f76 Michael Hanselmann
    self.assertEqual([(pendmode, sorted(waiting))
811 24d16f76 Michael Hanselmann
                      for (pendmode, waiting) in pending],
812 24d16f76 Michael Hanselmann
                     [(["exclusive", "shared"][int(bool(shared))],
813 24d16f76 Michael Hanselmann
                       sorted(t.getName() for t in threads))
814 24d16f76 Michael Hanselmann
                      for acquires in [perprio[i]
815 24d16f76 Michael Hanselmann
                                       for i in sorted(perprio.keys())]
816 24d16f76 Michael Hanselmann
                      for (shared, _, threads) in acquires])
817 24d16f76 Michael Hanselmann
818 162c1c1f Guido Trotter
819 1a4e32d0 Guido Trotter
class TestSharedLockInCondition(_ThreadedTestCase):
820 1a4e32d0 Guido Trotter
  """SharedLock as a condition lock tests"""
821 1a4e32d0 Guido Trotter
822 1a4e32d0 Guido Trotter
  def setUp(self):
823 1a4e32d0 Guido Trotter
    _ThreadedTestCase.setUp(self)
824 7f93570a Iustin Pop
    self.sl = locking.SharedLock("TestSharedLockInCondition")
825 7f890059 Guido Trotter
    self.setCondition()
826 7f890059 Guido Trotter
827 7f890059 Guido Trotter
  def setCondition(self):
828 1a4e32d0 Guido Trotter
    self.cond = threading.Condition(self.sl)
829 1a4e32d0 Guido Trotter
830 1a4e32d0 Guido Trotter
  def testKeepMode(self):
831 1a4e32d0 Guido Trotter
    self.cond.acquire(shared=1)
832 1a4e32d0 Guido Trotter
    self.assert_(self.sl._is_owned(shared=1))
833 1a4e32d0 Guido Trotter
    self.cond.wait(0)
834 1a4e32d0 Guido Trotter
    self.assert_(self.sl._is_owned(shared=1))
835 1a4e32d0 Guido Trotter
    self.cond.release()
836 1a4e32d0 Guido Trotter
    self.cond.acquire(shared=0)
837 1a4e32d0 Guido Trotter
    self.assert_(self.sl._is_owned(shared=0))
838 1a4e32d0 Guido Trotter
    self.cond.wait(0)
839 1a4e32d0 Guido Trotter
    self.assert_(self.sl._is_owned(shared=0))
840 1a4e32d0 Guido Trotter
    self.cond.release()
841 1a4e32d0 Guido Trotter
842 1a4e32d0 Guido Trotter
843 7f890059 Guido Trotter
class TestSharedLockInPipeCondition(TestSharedLockInCondition):
844 7f890059 Guido Trotter
  """SharedLock as a pipe condition lock tests"""
845 7f890059 Guido Trotter
846 7f890059 Guido Trotter
  def setCondition(self):
847 7f890059 Guido Trotter
    self.cond = locking.PipeCondition(self.sl)
848 7f890059 Guido Trotter
849 7f890059 Guido Trotter
850 4607c978 Iustin Pop
class TestSSynchronizedDecorator(_ThreadedTestCase):
851 42a999d1 Guido Trotter
  """Shared Lock Synchronized decorator test"""
852 42a999d1 Guido Trotter
853 42a999d1 Guido Trotter
  def setUp(self):
854 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
855 42a999d1 Guido Trotter
856 42a999d1 Guido Trotter
  @locking.ssynchronized(_decoratorlock)
857 42a999d1 Guido Trotter
  def _doItExclusive(self):
858 42a999d1 Guido Trotter
    self.assert_(_decoratorlock._is_owned())
859 42a999d1 Guido Trotter
    self.done.put('EXC')
860 42a999d1 Guido Trotter
861 42a999d1 Guido Trotter
  @locking.ssynchronized(_decoratorlock, shared=1)
862 42a999d1 Guido Trotter
  def _doItSharer(self):
863 42a999d1 Guido Trotter
    self.assert_(_decoratorlock._is_owned(shared=1))
864 42a999d1 Guido Trotter
    self.done.put('SHR')
865 42a999d1 Guido Trotter
866 42a999d1 Guido Trotter
  def testDecoratedFunctions(self):
867 42a999d1 Guido Trotter
    self._doItExclusive()
868 158206e0 Manuel Franceschini
    self.assertFalse(_decoratorlock._is_owned())
869 42a999d1 Guido Trotter
    self._doItSharer()
870 158206e0 Manuel Franceschini
    self.assertFalse(_decoratorlock._is_owned())
871 42a999d1 Guido Trotter
872 42a999d1 Guido Trotter
  def testSharersCanCoexist(self):
873 42a999d1 Guido Trotter
    _decoratorlock.acquire(shared=1)
874 84e344d4 Michael Hanselmann
    threading.Thread(target=self._doItSharer).start()
875 42a999d1 Guido Trotter
    self.assert_(self.done.get(True, 1))
876 42a999d1 Guido Trotter
    _decoratorlock.release()
877 42a999d1 Guido Trotter
878 4607c978 Iustin Pop
  @_Repeat
879 42a999d1 Guido Trotter
  def testExclusiveBlocksExclusive(self):
880 42a999d1 Guido Trotter
    _decoratorlock.acquire()
881 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
882 42a999d1 Guido Trotter
    # give it a bit of time to check that it's not actually doing anything
883 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
884 42a999d1 Guido Trotter
    _decoratorlock.release()
885 4607c978 Iustin Pop
    self._waitThreads()
886 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'EXC')
887 42a999d1 Guido Trotter
888 4607c978 Iustin Pop
  @_Repeat
889 42a999d1 Guido Trotter
  def testExclusiveBlocksSharer(self):
890 42a999d1 Guido Trotter
    _decoratorlock.acquire()
891 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
892 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
893 42a999d1 Guido Trotter
    _decoratorlock.release()
894 4607c978 Iustin Pop
    self._waitThreads()
895 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'SHR')
896 42a999d1 Guido Trotter
897 4607c978 Iustin Pop
  @_Repeat
898 42a999d1 Guido Trotter
  def testSharerBlocksExclusive(self):
899 42a999d1 Guido Trotter
    _decoratorlock.acquire(shared=1)
900 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
901 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
902 42a999d1 Guido Trotter
    _decoratorlock.release()
903 4607c978 Iustin Pop
    self._waitThreads()
904 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), 'EXC')
905 42a999d1 Guido Trotter
906 42a999d1 Guido Trotter
907 4607c978 Iustin Pop
class TestLockSet(_ThreadedTestCase):
908 aaae9bc0 Guido Trotter
  """LockSet tests"""
909 aaae9bc0 Guido Trotter
910 aaae9bc0 Guido Trotter
  def setUp(self):
911 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
912 4607c978 Iustin Pop
    self._setUpLS()
913 aaae9bc0 Guido Trotter
914 4607c978 Iustin Pop
  def _setUpLS(self):
915 4607c978 Iustin Pop
    """Helper to (re)initialize the lock set"""
916 4607c978 Iustin Pop
    self.resources = ['one', 'two', 'three']
917 7f93570a Iustin Pop
    self.ls = locking.LockSet(self.resources, "TestLockSet")
918 4607c978 Iustin Pop
919 aaae9bc0 Guido Trotter
  def testResources(self):
920 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._names(), set(self.resources))
921 7f93570a Iustin Pop
    newls = locking.LockSet([], "TestLockSet.testResources")
922 aaae9bc0 Guido Trotter
    self.assertEquals(newls._names(), set())
923 aaae9bc0 Guido Trotter
924 aaae9bc0 Guido Trotter
  def testAcquireRelease(self):
925 0cc00929 Guido Trotter
    self.assert_(self.ls.acquire('one'))
926 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['one']))
927 aaae9bc0 Guido Trotter
    self.ls.release()
928 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
929 0cc00929 Guido Trotter
    self.assertEquals(self.ls.acquire(['one']), set(['one']))
930 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['one']))
931 aaae9bc0 Guido Trotter
    self.ls.release()
932 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
933 aaae9bc0 Guido Trotter
    self.ls.acquire(['one', 'two', 'three'])
934 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['one', 'two', 'three']))
935 aaae9bc0 Guido Trotter
    self.ls.release('one')
936 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['two', 'three']))
937 aaae9bc0 Guido Trotter
    self.ls.release(['three'])
938 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['two']))
939 aaae9bc0 Guido Trotter
    self.ls.release()
940 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
941 0cc00929 Guido Trotter
    self.assertEquals(self.ls.acquire(['one', 'three']), set(['one', 'three']))
942 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['one', 'three']))
943 aaae9bc0 Guido Trotter
    self.ls.release()
944 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
945 aaae9bc0 Guido Trotter
946 aaae9bc0 Guido Trotter
  def testNoDoubleAcquire(self):
947 aaae9bc0 Guido Trotter
    self.ls.acquire('one')
948 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.acquire, 'one')
949 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.acquire, ['two'])
950 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.acquire, ['two', 'three'])
951 aaae9bc0 Guido Trotter
    self.ls.release()
952 aaae9bc0 Guido Trotter
    self.ls.acquire(['one', 'three'])
953 aaae9bc0 Guido Trotter
    self.ls.release('one')
954 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.acquire, ['two'])
955 aaae9bc0 Guido Trotter
    self.ls.release('three')
956 aaae9bc0 Guido Trotter
957 aaae9bc0 Guido Trotter
  def testNoWrongRelease(self):
958 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.release)
959 aaae9bc0 Guido Trotter
    self.ls.acquire('one')
960 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.release, 'two')
961 aaae9bc0 Guido Trotter
962 aaae9bc0 Guido Trotter
  def testAddRemove(self):
963 aaae9bc0 Guido Trotter
    self.ls.add('four')
964 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
965 aaae9bc0 Guido Trotter
    self.assert_('four' in self.ls._names())
966 aaae9bc0 Guido Trotter
    self.ls.add(['five', 'six', 'seven'], acquired=1)
967 aaae9bc0 Guido Trotter
    self.assert_('five' in self.ls._names())
968 aaae9bc0 Guido Trotter
    self.assert_('six' in self.ls._names())
969 aaae9bc0 Guido Trotter
    self.assert_('seven' in self.ls._names())
970 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['five', 'six', 'seven']))
971 3f404fc5 Guido Trotter
    self.assertEquals(self.ls.remove(['five', 'six']), ['five', 'six'])
972 aaae9bc0 Guido Trotter
    self.assert_('five' not in self.ls._names())
973 aaae9bc0 Guido Trotter
    self.assert_('six' not in self.ls._names())
974 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['seven']))
975 d2aff862 Guido Trotter
    self.assertRaises(AssertionError, self.ls.add, 'eight', acquired=1)
976 aaae9bc0 Guido Trotter
    self.ls.remove('seven')
977 aaae9bc0 Guido Trotter
    self.assert_('seven' not in self.ls._names())
978 d2aff862 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set([]))
979 d2aff862 Guido Trotter
    self.ls.acquire(None, shared=1)
980 d2aff862 Guido Trotter
    self.assertRaises(AssertionError, self.ls.add, 'eight')
981 d2aff862 Guido Trotter
    self.ls.release()
982 d2aff862 Guido Trotter
    self.ls.acquire(None)
983 d2aff862 Guido Trotter
    self.ls.add('eight', acquired=1)
984 d2aff862 Guido Trotter
    self.assert_('eight' in self.ls._names())
985 d2aff862 Guido Trotter
    self.assert_('eight' in self.ls._list_owned())
986 d2aff862 Guido Trotter
    self.ls.add('nine')
987 d2aff862 Guido Trotter
    self.assert_('nine' in self.ls._names())
988 d2aff862 Guido Trotter
    self.assert_('nine' not in self.ls._list_owned())
989 aaae9bc0 Guido Trotter
    self.ls.release()
990 aaae9bc0 Guido Trotter
    self.ls.remove(['two'])
991 aaae9bc0 Guido Trotter
    self.assert_('two' not in self.ls._names())
992 aaae9bc0 Guido Trotter
    self.ls.acquire('three')
993 3f404fc5 Guido Trotter
    self.assertEquals(self.ls.remove(['three']), ['three'])
994 aaae9bc0 Guido Trotter
    self.assert_('three' not in self.ls._names())
995 3f404fc5 Guido Trotter
    self.assertEquals(self.ls.remove('three'), [])
996 3f404fc5 Guido Trotter
    self.assertEquals(self.ls.remove(['one', 'three', 'six']), ['one'])
997 aaae9bc0 Guido Trotter
    self.assert_('one' not in self.ls._names())
998 aaae9bc0 Guido Trotter
999 aaae9bc0 Guido Trotter
  def testRemoveNonBlocking(self):
1000 aaae9bc0 Guido Trotter
    self.ls.acquire('one')
1001 5e0a6daf Michael Hanselmann
    self.assertEquals(self.ls.remove('one'), ['one'])
1002 aaae9bc0 Guido Trotter
    self.ls.acquire(['two', 'three'])
1003 5e0a6daf Michael Hanselmann
    self.assertEquals(self.ls.remove(['two', 'three']),
1004 3f404fc5 Guido Trotter
                      ['two', 'three'])
1005 aaae9bc0 Guido Trotter
1006 aaae9bc0 Guido Trotter
  def testNoDoubleAdd(self):
1007 aaae9bc0 Guido Trotter
    self.assertRaises(errors.LockError, self.ls.add, 'two')
1008 aaae9bc0 Guido Trotter
    self.ls.add('four')
1009 aaae9bc0 Guido Trotter
    self.assertRaises(errors.LockError, self.ls.add, 'four')
1010 aaae9bc0 Guido Trotter
1011 aaae9bc0 Guido Trotter
  def testNoWrongRemoves(self):
1012 aaae9bc0 Guido Trotter
    self.ls.acquire(['one', 'three'], shared=1)
1013 aaae9bc0 Guido Trotter
    # Cannot remove 'two' while holding something which is not a superset
1014 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.remove, 'two')
1015 aaae9bc0 Guido Trotter
    # Cannot remove 'three' as we are sharing it
1016 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.remove, 'three')
1017 aaae9bc0 Guido Trotter
1018 3b7ed473 Guido Trotter
  def testAcquireSetLock(self):
1019 3b7ed473 Guido Trotter
    # acquire the set-lock exclusively
1020 3b7ed473 Guido Trotter
    self.assertEquals(self.ls.acquire(None), set(['one', 'two', 'three']))
1021 d4803c24 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['one', 'two', 'three']))
1022 d4803c24 Guido Trotter
    self.assertEquals(self.ls._is_owned(), True)
1023 d4803c24 Guido Trotter
    self.assertEquals(self.ls._names(), set(['one', 'two', 'three']))
1024 3b7ed473 Guido Trotter
    # I can still add/remove elements...
1025 3b7ed473 Guido Trotter
    self.assertEquals(self.ls.remove(['two', 'three']), ['two', 'three'])
1026 3b7ed473 Guido Trotter
    self.assert_(self.ls.add('six'))
1027 3b7ed473 Guido Trotter
    self.ls.release()
1028 3b7ed473 Guido Trotter
    # share the set-lock
1029 3b7ed473 Guido Trotter
    self.assertEquals(self.ls.acquire(None, shared=1), set(['one', 'six']))
1030 3b7ed473 Guido Trotter
    # adding new elements is not possible
1031 3b7ed473 Guido Trotter
    self.assertRaises(AssertionError, self.ls.add, 'five')
1032 3b7ed473 Guido Trotter
    self.ls.release()
1033 3b7ed473 Guido Trotter
1034 d4f6a91c Guido Trotter
  def testAcquireWithRepetitions(self):
1035 d4f6a91c Guido Trotter
    self.assertEquals(self.ls.acquire(['two', 'two', 'three'], shared=1),
1036 d4f6a91c Guido Trotter
                      set(['two', 'two', 'three']))
1037 d4f6a91c Guido Trotter
    self.ls.release(['two', 'two'])
1038 d4f6a91c Guido Trotter
    self.assertEquals(self.ls._list_owned(), set(['three']))
1039 d4f6a91c Guido Trotter
1040 2e1d6d96 Guido Trotter
  def testEmptyAcquire(self):
1041 2e1d6d96 Guido Trotter
    # Acquire an empty list of locks...
1042 2e1d6d96 Guido Trotter
    self.assertEquals(self.ls.acquire([]), set())
1043 2e1d6d96 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
1044 2e1d6d96 Guido Trotter
    # New locks can still be addded
1045 2e1d6d96 Guido Trotter
    self.assert_(self.ls.add('six'))
1046 2e1d6d96 Guido Trotter
    # "re-acquiring" is not an issue, since we had really acquired nothing
1047 2e1d6d96 Guido Trotter
    self.assertEquals(self.ls.acquire([], shared=1), set())
1048 2e1d6d96 Guido Trotter
    self.assertEquals(self.ls._list_owned(), set())
1049 2e1d6d96 Guido Trotter
    # We haven't really acquired anything, so we cannot release
1050 2e1d6d96 Guido Trotter
    self.assertRaises(AssertionError, self.ls.release)
1051 2e1d6d96 Guido Trotter
1052 84e344d4 Michael Hanselmann
  def _doLockSet(self, names, shared):
1053 aaae9bc0 Guido Trotter
    try:
1054 84e344d4 Michael Hanselmann
      self.ls.acquire(names, shared=shared)
1055 aaae9bc0 Guido Trotter
      self.done.put('DONE')
1056 aaae9bc0 Guido Trotter
      self.ls.release()
1057 aaae9bc0 Guido Trotter
    except errors.LockError:
1058 aaae9bc0 Guido Trotter
      self.done.put('ERR')
1059 aaae9bc0 Guido Trotter
1060 84e344d4 Michael Hanselmann
  def _doAddSet(self, names):
1061 3b7ed473 Guido Trotter
    try:
1062 84e344d4 Michael Hanselmann
      self.ls.add(names, acquired=1)
1063 3b7ed473 Guido Trotter
      self.done.put('DONE')
1064 3b7ed473 Guido Trotter
      self.ls.release()
1065 3b7ed473 Guido Trotter
    except errors.LockError:
1066 3b7ed473 Guido Trotter
      self.done.put('ERR')
1067 3b7ed473 Guido Trotter
1068 84e344d4 Michael Hanselmann
  def _doRemoveSet(self, names):
1069 84e344d4 Michael Hanselmann
    self.done.put(self.ls.remove(names))
1070 aaae9bc0 Guido Trotter
1071 4607c978 Iustin Pop
  @_Repeat
1072 aaae9bc0 Guido Trotter
  def testConcurrentSharedAcquire(self):
1073 aaae9bc0 Guido Trotter
    self.ls.acquire(['one', 'two'], shared=1)
1074 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two'], 1))
1075 4607c978 Iustin Pop
    self._waitThreads()
1076 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1077 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two', 'three'], 1))
1078 4607c978 Iustin Pop
    self._waitThreads()
1079 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1080 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=('three', 1))
1081 4607c978 Iustin Pop
    self._waitThreads()
1082 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1083 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two'], 0))
1084 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['two', 'three'], 0))
1085 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1086 aaae9bc0 Guido Trotter
    self.ls.release()
1087 4607c978 Iustin Pop
    self._waitThreads()
1088 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1089 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1090 aaae9bc0 Guido Trotter
1091 4607c978 Iustin Pop
  @_Repeat
1092 aaae9bc0 Guido Trotter
  def testConcurrentExclusiveAcquire(self):
1093 aaae9bc0 Guido Trotter
    self.ls.acquire(['one', 'two'])
1094 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=('three', 1))
1095 4607c978 Iustin Pop
    self._waitThreads()
1096 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1097 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=('three', 0))
1098 4607c978 Iustin Pop
    self._waitThreads()
1099 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1100 84e344d4 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1101 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two'], 0))
1102 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two'], 1))
1103 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=('one', 0))
1104 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=('one', 1))
1105 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['two', 'three'], 0))
1106 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['two', 'three'], 1))
1107 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1108 aaae9bc0 Guido Trotter
    self.ls.release()
1109 4607c978 Iustin Pop
    self._waitThreads()
1110 4607c978 Iustin Pop
    for _ in range(6):
1111 4607c978 Iustin Pop
      self.failUnlessEqual(self.done.get_nowait(), 'DONE')
1112 aaae9bc0 Guido Trotter
1113 4607c978 Iustin Pop
  @_Repeat
1114 5aab242c Michael Hanselmann
  def testSimpleAcquireTimeoutExpiring(self):
1115 5aab242c Michael Hanselmann
    names = sorted(self.ls._names())
1116 5aab242c Michael Hanselmann
    self.assert_(len(names) >= 3)
1117 5aab242c Michael Hanselmann
1118 5aab242c Michael Hanselmann
    # Get name of first lock
1119 5aab242c Michael Hanselmann
    first = names[0]
1120 5aab242c Michael Hanselmann
1121 5aab242c Michael Hanselmann
    # Get name of last lock
1122 5aab242c Michael Hanselmann
    last = names.pop()
1123 5aab242c Michael Hanselmann
1124 5aab242c Michael Hanselmann
    checks = [
1125 5aab242c Michael Hanselmann
      # Block first and try to lock it again
1126 5aab242c Michael Hanselmann
      (first, first),
1127 5aab242c Michael Hanselmann
1128 5aab242c Michael Hanselmann
      # Block last and try to lock all locks
1129 5aab242c Michael Hanselmann
      (None, first),
1130 5aab242c Michael Hanselmann
1131 5aab242c Michael Hanselmann
      # Block last and try to lock it again
1132 5aab242c Michael Hanselmann
      (last, last),
1133 5aab242c Michael Hanselmann
      ]
1134 5aab242c Michael Hanselmann
1135 5aab242c Michael Hanselmann
    for (wanted, block) in checks:
1136 5aab242c Michael Hanselmann
      # Lock in exclusive mode
1137 5aab242c Michael Hanselmann
      self.assert_(self.ls.acquire(block, shared=0))
1138 5aab242c Michael Hanselmann
1139 5aab242c Michael Hanselmann
      def _AcquireOne():
1140 5aab242c Michael Hanselmann
        # Try to get the same lock again with a timeout (should never succeed)
1141 23683c26 Michael Hanselmann
        acquired = self.ls.acquire(wanted, timeout=0.1, shared=0)
1142 23683c26 Michael Hanselmann
        if acquired:
1143 5aab242c Michael Hanselmann
          self.done.put("acquired")
1144 5aab242c Michael Hanselmann
          self.ls.release()
1145 5aab242c Michael Hanselmann
        else:
1146 23683c26 Michael Hanselmann
          self.assert_(acquired is None)
1147 158206e0 Manuel Franceschini
          self.assertFalse(self.ls._list_owned())
1148 158206e0 Manuel Franceschini
          self.assertFalse(self.ls._is_owned())
1149 5aab242c Michael Hanselmann
          self.done.put("not acquired")
1150 5aab242c Michael Hanselmann
1151 5aab242c Michael Hanselmann
      self._addThread(target=_AcquireOne)
1152 5aab242c Michael Hanselmann
1153 5aab242c Michael Hanselmann
      # Wait for timeout in thread to expire
1154 5aab242c Michael Hanselmann
      self._waitThreads()
1155 5aab242c Michael Hanselmann
1156 5aab242c Michael Hanselmann
      # Release exclusive lock again
1157 5aab242c Michael Hanselmann
      self.ls.release()
1158 5aab242c Michael Hanselmann
1159 5aab242c Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "not acquired")
1160 5aab242c Michael Hanselmann
      self.assertRaises(Queue.Empty, self.done.get_nowait)
1161 5aab242c Michael Hanselmann
1162 5aab242c Michael Hanselmann
  @_Repeat
1163 5aab242c Michael Hanselmann
  def testDelayedAndExpiringLockAcquire(self):
1164 5aab242c Michael Hanselmann
    self._setUpLS()
1165 5aab242c Michael Hanselmann
    self.ls.add(['five', 'six', 'seven', 'eight', 'nine'])
1166 5aab242c Michael Hanselmann
1167 5aab242c Michael Hanselmann
    for expire in (False, True):
1168 5aab242c Michael Hanselmann
      names = sorted(self.ls._names())
1169 5aab242c Michael Hanselmann
      self.assertEqual(len(names), 8)
1170 5aab242c Michael Hanselmann
1171 5aab242c Michael Hanselmann
      lock_ev = dict([(i, threading.Event()) for i in names])
1172 5aab242c Michael Hanselmann
1173 5aab242c Michael Hanselmann
      # Lock all in exclusive mode
1174 5aab242c Michael Hanselmann
      self.assert_(self.ls.acquire(names, shared=0))
1175 5aab242c Michael Hanselmann
1176 5aab242c Michael Hanselmann
      if expire:
1177 5aab242c Michael Hanselmann
        # We'll wait at least 300ms per lock
1178 5aab242c Michael Hanselmann
        lockwait = len(names) * [0.3]
1179 5aab242c Michael Hanselmann
1180 5aab242c Michael Hanselmann
        # Fail if we can't acquire all locks in 400ms. There are 8 locks, so
1181 5aab242c Michael Hanselmann
        # this gives us up to 2.4s to fail.
1182 5aab242c Michael Hanselmann
        lockall_timeout = 0.4
1183 5aab242c Michael Hanselmann
      else:
1184 5aab242c Michael Hanselmann
        # This should finish rather quickly
1185 5aab242c Michael Hanselmann
        lockwait = None
1186 5aab242c Michael Hanselmann
        lockall_timeout = len(names) * 5.0
1187 5aab242c Michael Hanselmann
1188 5aab242c Michael Hanselmann
      def _LockAll():
1189 5aab242c Michael Hanselmann
        def acquire_notification(name):
1190 5aab242c Michael Hanselmann
          if not expire:
1191 5aab242c Michael Hanselmann
            self.done.put("getting %s" % name)
1192 5aab242c Michael Hanselmann
1193 5aab242c Michael Hanselmann
          # Kick next lock
1194 5aab242c Michael Hanselmann
          lock_ev[name].set()
1195 5aab242c Michael Hanselmann
1196 5aab242c Michael Hanselmann
        if self.ls.acquire(names, shared=0, timeout=lockall_timeout,
1197 5aab242c Michael Hanselmann
                           test_notify=acquire_notification):
1198 5aab242c Michael Hanselmann
          self.done.put("got all")
1199 5aab242c Michael Hanselmann
          self.ls.release()
1200 5aab242c Michael Hanselmann
        else:
1201 5aab242c Michael Hanselmann
          self.done.put("timeout on all")
1202 5aab242c Michael Hanselmann
1203 5aab242c Michael Hanselmann
        # Notify all locks
1204 5aab242c Michael Hanselmann
        for ev in lock_ev.values():
1205 5aab242c Michael Hanselmann
          ev.set()
1206 5aab242c Michael Hanselmann
1207 5aab242c Michael Hanselmann
      t = self._addThread(target=_LockAll)
1208 5aab242c Michael Hanselmann
1209 5aab242c Michael Hanselmann
      for idx, name in enumerate(names):
1210 5aab242c Michael Hanselmann
        # Wait for actual acquire on this lock to start
1211 5aab242c Michael Hanselmann
        lock_ev[name].wait(10.0)
1212 5aab242c Michael Hanselmann
1213 5aab242c Michael Hanselmann
        if expire and t.isAlive():
1214 5aab242c Michael Hanselmann
          # Wait some time after getting the notification to make sure the lock
1215 5aab242c Michael Hanselmann
          # acquire will expire
1216 5aab242c Michael Hanselmann
          SafeSleep(lockwait[idx])
1217 5aab242c Michael Hanselmann
1218 5aab242c Michael Hanselmann
        self.ls.release(names=name)
1219 5aab242c Michael Hanselmann
1220 158206e0 Manuel Franceschini
      self.assertFalse(self.ls._list_owned())
1221 5aab242c Michael Hanselmann
1222 5aab242c Michael Hanselmann
      self._waitThreads()
1223 5aab242c Michael Hanselmann
1224 5aab242c Michael Hanselmann
      if expire:
1225 5aab242c Michael Hanselmann
        # Not checking which locks were actually acquired. Doing so would be
1226 5aab242c Michael Hanselmann
        # too timing-dependant.
1227 5aab242c Michael Hanselmann
        self.assertEqual(self.done.get_nowait(), "timeout on all")
1228 5aab242c Michael Hanselmann
      else:
1229 5aab242c Michael Hanselmann
        for i in names:
1230 5aab242c Michael Hanselmann
          self.assertEqual(self.done.get_nowait(), "getting %s" % i)
1231 5aab242c Michael Hanselmann
        self.assertEqual(self.done.get_nowait(), "got all")
1232 5aab242c Michael Hanselmann
      self.assertRaises(Queue.Empty, self.done.get_nowait)
1233 5aab242c Michael Hanselmann
1234 5aab242c Michael Hanselmann
  @_Repeat
1235 aaae9bc0 Guido Trotter
  def testConcurrentRemove(self):
1236 aaae9bc0 Guido Trotter
    self.ls.add('four')
1237 aaae9bc0 Guido Trotter
    self.ls.acquire(['one', 'two', 'four'])
1238 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'four'], 0))
1239 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'four'], 1))
1240 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two'], 0))
1241 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'two'], 1))
1242 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1243 aaae9bc0 Guido Trotter
    self.ls.remove('one')
1244 aaae9bc0 Guido Trotter
    self.ls.release()
1245 4607c978 Iustin Pop
    self._waitThreads()
1246 4607c978 Iustin Pop
    for i in range(4):
1247 4607c978 Iustin Pop
      self.failUnlessEqual(self.done.get_nowait(), 'ERR')
1248 aaae9bc0 Guido Trotter
    self.ls.add(['five', 'six'], acquired=1)
1249 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['three', 'six'], 1))
1250 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['three', 'six'], 0))
1251 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['four', 'six'], 1))
1252 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['four', 'six'], 0))
1253 aaae9bc0 Guido Trotter
    self.ls.remove('five')
1254 aaae9bc0 Guido Trotter
    self.ls.release()
1255 4607c978 Iustin Pop
    self._waitThreads()
1256 4607c978 Iustin Pop
    for i in range(4):
1257 4607c978 Iustin Pop
      self.failUnlessEqual(self.done.get_nowait(), 'DONE')
1258 aaae9bc0 Guido Trotter
    self.ls.acquire(['three', 'four'])
1259 4607c978 Iustin Pop
    self._addThread(target=self._doRemoveSet, args=(['four', 'six'], ))
1260 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1261 aaae9bc0 Guido Trotter
    self.ls.remove('four')
1262 4607c978 Iustin Pop
    self._waitThreads()
1263 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), ['six'])
1264 4607c978 Iustin Pop
    self._addThread(target=self._doRemoveSet, args=(['two']))
1265 4607c978 Iustin Pop
    self._waitThreads()
1266 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), ['two'])
1267 aaae9bc0 Guido Trotter
    self.ls.release()
1268 4607c978 Iustin Pop
    # reset lockset
1269 4607c978 Iustin Pop
    self._setUpLS()
1270 aaae9bc0 Guido Trotter
1271 4607c978 Iustin Pop
  @_Repeat
1272 3b7ed473 Guido Trotter
  def testConcurrentSharedSetLock(self):
1273 3b7ed473 Guido Trotter
    # share the set-lock...
1274 3b7ed473 Guido Trotter
    self.ls.acquire(None, shared=1)
1275 3b7ed473 Guido Trotter
    # ...another thread can share it too
1276 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1277 4607c978 Iustin Pop
    self._waitThreads()
1278 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1279 3b7ed473 Guido Trotter
    # ...or just share some elements
1280 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['one', 'three'], 1))
1281 4607c978 Iustin Pop
    self._waitThreads()
1282 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1283 3b7ed473 Guido Trotter
    # ...but not add new ones or remove any
1284 4607c978 Iustin Pop
    t = self._addThread(target=self._doAddSet, args=(['nine']))
1285 4607c978 Iustin Pop
    self._addThread(target=self._doRemoveSet, args=(['two'], ))
1286 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1287 3b7ed473 Guido Trotter
    # this just releases the set-lock
1288 3b7ed473 Guido Trotter
    self.ls.release([])
1289 4607c978 Iustin Pop
    t.join(60)
1290 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1291 3b7ed473 Guido Trotter
    # release the lock on the actual elements so remove() can proceed too
1292 3b7ed473 Guido Trotter
    self.ls.release()
1293 4607c978 Iustin Pop
    self._waitThreads()
1294 4607c978 Iustin Pop
    self.failUnlessEqual(self.done.get_nowait(), ['two'])
1295 4607c978 Iustin Pop
    # reset lockset
1296 4607c978 Iustin Pop
    self._setUpLS()
1297 3b7ed473 Guido Trotter
1298 4607c978 Iustin Pop
  @_Repeat
1299 3b7ed473 Guido Trotter
  def testConcurrentExclusiveSetLock(self):
1300 3b7ed473 Guido Trotter
    # acquire the set-lock...
1301 3b7ed473 Guido Trotter
    self.ls.acquire(None, shared=0)
1302 3b7ed473 Guido Trotter
    # ...no one can do anything else
1303 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1304 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 0))
1305 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['three'], 0))
1306 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(['two'], 1))
1307 4607c978 Iustin Pop
    self._addThread(target=self._doAddSet, args=(['nine']))
1308 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1309 3b7ed473 Guido Trotter
    self.ls.release()
1310 4607c978 Iustin Pop
    self._waitThreads()
1311 4607c978 Iustin Pop
    for _ in range(5):
1312 4607c978 Iustin Pop
      self.assertEqual(self.done.get(True, 1), 'DONE')
1313 4607c978 Iustin Pop
    # cleanup
1314 4607c978 Iustin Pop
    self._setUpLS()
1315 3b7ed473 Guido Trotter
1316 4607c978 Iustin Pop
  @_Repeat
1317 d2aff862 Guido Trotter
  def testConcurrentSetLockAdd(self):
1318 d2aff862 Guido Trotter
    self.ls.acquire('one')
1319 d2aff862 Guido Trotter
    # Another thread wants the whole SetLock
1320 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 0))
1321 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1322 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1323 d2aff862 Guido Trotter
    self.assertRaises(AssertionError, self.ls.add, 'four')
1324 d2aff862 Guido Trotter
    self.ls.release()
1325 4607c978 Iustin Pop
    self._waitThreads()
1326 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1327 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1328 d2aff862 Guido Trotter
    self.ls.acquire(None)
1329 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 0))
1330 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1331 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1332 d2aff862 Guido Trotter
    self.ls.add('four')
1333 d2aff862 Guido Trotter
    self.ls.add('five', acquired=1)
1334 d2aff862 Guido Trotter
    self.ls.add('six', acquired=1, shared=1)
1335 d2aff862 Guido Trotter
    self.assertEquals(self.ls._list_owned(),
1336 d2aff862 Guido Trotter
      set(['one', 'two', 'three', 'five', 'six']))
1337 d2aff862 Guido Trotter
    self.assertEquals(self.ls._is_owned(), True)
1338 d2aff862 Guido Trotter
    self.assertEquals(self.ls._names(),
1339 d2aff862 Guido Trotter
      set(['one', 'two', 'three', 'four', 'five', 'six']))
1340 d2aff862 Guido Trotter
    self.ls.release()
1341 4607c978 Iustin Pop
    self._waitThreads()
1342 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1343 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1344 4607c978 Iustin Pop
    self._setUpLS()
1345 d2aff862 Guido Trotter
1346 4607c978 Iustin Pop
  @_Repeat
1347 b2dabfd6 Guido Trotter
  def testEmptyLockSet(self):
1348 b2dabfd6 Guido Trotter
    # get the set-lock
1349 b2dabfd6 Guido Trotter
    self.assertEqual(self.ls.acquire(None), set(['one', 'two', 'three']))
1350 b2dabfd6 Guido Trotter
    # now empty it...
1351 b2dabfd6 Guido Trotter
    self.ls.remove(['one', 'two', 'three'])
1352 b2dabfd6 Guido Trotter
    # and adds/locks by another thread still wait
1353 4607c978 Iustin Pop
    self._addThread(target=self._doAddSet, args=(['nine']))
1354 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1355 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 0))
1356 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1357 b2dabfd6 Guido Trotter
    self.ls.release()
1358 4607c978 Iustin Pop
    self._waitThreads()
1359 4607c978 Iustin Pop
    for _ in range(3):
1360 4607c978 Iustin Pop
      self.assertEqual(self.done.get_nowait(), 'DONE')
1361 b2dabfd6 Guido Trotter
    # empty it again...
1362 b2dabfd6 Guido Trotter
    self.assertEqual(self.ls.remove(['nine']), ['nine'])
1363 b2dabfd6 Guido Trotter
    # now share it...
1364 b2dabfd6 Guido Trotter
    self.assertEqual(self.ls.acquire(None, shared=1), set())
1365 b2dabfd6 Guido Trotter
    # other sharers can go, adds still wait
1366 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1367 4607c978 Iustin Pop
    self._waitThreads()
1368 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1369 4607c978 Iustin Pop
    self._addThread(target=self._doAddSet, args=(['nine']))
1370 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1371 b2dabfd6 Guido Trotter
    self.ls.release()
1372 4607c978 Iustin Pop
    self._waitThreads()
1373 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1374 4607c978 Iustin Pop
    self._setUpLS()
1375 b2dabfd6 Guido Trotter
1376 887c7aa6 Michael Hanselmann
  def testPriority(self):
1377 887c7aa6 Michael Hanselmann
    def _Acquire(prev, next, name, priority, success_fn):
1378 887c7aa6 Michael Hanselmann
      prev.wait()
1379 887c7aa6 Michael Hanselmann
      self.assert_(self.ls.acquire(name, shared=0,
1380 887c7aa6 Michael Hanselmann
                                   priority=priority,
1381 887c7aa6 Michael Hanselmann
                                   test_notify=lambda _: next.set()))
1382 887c7aa6 Michael Hanselmann
      try:
1383 887c7aa6 Michael Hanselmann
        success_fn()
1384 887c7aa6 Michael Hanselmann
      finally:
1385 887c7aa6 Michael Hanselmann
        self.ls.release()
1386 887c7aa6 Michael Hanselmann
1387 887c7aa6 Michael Hanselmann
    # Get all in exclusive mode
1388 887c7aa6 Michael Hanselmann
    self.assert_(self.ls.acquire(locking.ALL_SET, shared=0))
1389 887c7aa6 Michael Hanselmann
1390 887c7aa6 Michael Hanselmann
    done_two = Queue.Queue(0)
1391 887c7aa6 Michael Hanselmann
1392 887c7aa6 Michael Hanselmann
    first = threading.Event()
1393 887c7aa6 Michael Hanselmann
    prev = first
1394 887c7aa6 Michael Hanselmann
1395 887c7aa6 Michael Hanselmann
    acquires = [("one", prio, self.done) for prio in range(1, 33)]
1396 887c7aa6 Michael Hanselmann
    acquires.extend([("two", prio, done_two) for prio in range(1, 33)])
1397 887c7aa6 Michael Hanselmann
1398 887c7aa6 Michael Hanselmann
    # Use a deterministic random generator
1399 887c7aa6 Michael Hanselmann
    random.Random(741).shuffle(acquires)
1400 887c7aa6 Michael Hanselmann
1401 887c7aa6 Michael Hanselmann
    for (name, prio, done) in acquires:
1402 887c7aa6 Michael Hanselmann
      ev = threading.Event()
1403 887c7aa6 Michael Hanselmann
      self._addThread(target=_Acquire,
1404 887c7aa6 Michael Hanselmann
                      args=(prev, ev, name, prio,
1405 887c7aa6 Michael Hanselmann
                            compat.partial(done.put, "Prio%s" % prio)))
1406 887c7aa6 Michael Hanselmann
      prev = ev
1407 887c7aa6 Michael Hanselmann
1408 887c7aa6 Michael Hanselmann
    # Start acquires
1409 887c7aa6 Michael Hanselmann
    first.set()
1410 887c7aa6 Michael Hanselmann
1411 887c7aa6 Michael Hanselmann
    # Wait for last acquire to start
1412 887c7aa6 Michael Hanselmann
    prev.wait()
1413 887c7aa6 Michael Hanselmann
1414 887c7aa6 Michael Hanselmann
    # Let threads acquire locks
1415 887c7aa6 Michael Hanselmann
    self.ls.release()
1416 887c7aa6 Michael Hanselmann
1417 887c7aa6 Michael Hanselmann
    # Wait for threads to finish
1418 887c7aa6 Michael Hanselmann
    self._waitThreads()
1419 887c7aa6 Michael Hanselmann
1420 887c7aa6 Michael Hanselmann
    for i in range(1, 33):
1421 887c7aa6 Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "Prio%s" % i)
1422 887c7aa6 Michael Hanselmann
      self.assertEqual(done_two.get_nowait(), "Prio%s" % i)
1423 887c7aa6 Michael Hanselmann
1424 887c7aa6 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1425 887c7aa6 Michael Hanselmann
    self.assertRaises(Queue.Empty, done_two.get_nowait)
1426 887c7aa6 Michael Hanselmann
1427 aaae9bc0 Guido Trotter
1428 4607c978 Iustin Pop
class TestGanetiLockManager(_ThreadedTestCase):
1429 7ee7c0c7 Guido Trotter
1430 7ee7c0c7 Guido Trotter
  def setUp(self):
1431 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
1432 7ee7c0c7 Guido Trotter
    self.nodes=['n1', 'n2']
1433 819ca990 Guido Trotter
    self.nodegroups=['g1', 'g2']
1434 7ee7c0c7 Guido Trotter
    self.instances=['i1', 'i2', 'i3']
1435 819ca990 Guido Trotter
    self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups,
1436 819ca990 Guido Trotter
                                        self.instances)
1437 7ee7c0c7 Guido Trotter
1438 7ee7c0c7 Guido Trotter
  def tearDown(self):
1439 7ee7c0c7 Guido Trotter
    # Don't try this at home...
1440 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
1441 7ee7c0c7 Guido Trotter
1442 7ee7c0c7 Guido Trotter
  def testLockingConstants(self):
1443 7ee7c0c7 Guido Trotter
    # The locking library internally cheats by assuming its constants have some
1444 7ee7c0c7 Guido Trotter
    # relationships with each other. Check those hold true.
1445 b10b9d74 Guido Trotter
    # This relationship is also used in the Processor to recursively acquire
1446 b10b9d74 Guido Trotter
    # the right locks. Again, please don't break it.
1447 7ee7c0c7 Guido Trotter
    for i in range(len(locking.LEVELS)):
1448 7ee7c0c7 Guido Trotter
      self.assertEqual(i, locking.LEVELS[i])
1449 7ee7c0c7 Guido Trotter
1450 7ee7c0c7 Guido Trotter
  def testDoubleGLFails(self):
1451 819ca990 Guido Trotter
    self.assertRaises(AssertionError, locking.GanetiLockManager, [], [], [])
1452 7ee7c0c7 Guido Trotter
1453 7ee7c0c7 Guido Trotter
  def testLockNames(self):
1454 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
1455 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
1456 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP),
1457 819ca990 Guido Trotter
                     set(self.nodegroups))
1458 cdb08f44 Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
1459 cdb08f44 Michael Hanselmann
                     set(self.instances))
1460 7ee7c0c7 Guido Trotter
1461 7ee7c0c7 Guido Trotter
  def testInitAndResources(self):
1462 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
1463 819ca990 Guido Trotter
    self.GL = locking.GanetiLockManager([], [], [])
1464 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
1465 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
1466 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
1467 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
1468 7ee7c0c7 Guido Trotter
1469 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
1470 819ca990 Guido Trotter
    self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups, [])
1471 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
1472 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
1473 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP),
1474 819ca990 Guido Trotter
                                    set(self.nodegroups))
1475 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
1476 7ee7c0c7 Guido Trotter
1477 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
1478 819ca990 Guido Trotter
    self.GL = locking.GanetiLockManager([], [], self.instances)
1479 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(['BGL']))
1480 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
1481 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
1482 cdb08f44 Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
1483 cdb08f44 Michael Hanselmann
                     set(self.instances))
1484 7ee7c0c7 Guido Trotter
1485 7ee7c0c7 Guido Trotter
  def testAcquireRelease(self):
1486 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1487 7ee7c0c7 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_CLUSTER), set(['BGL']))
1488 04e1bfaf Guido Trotter
    self.GL.acquire(locking.LEVEL_INSTANCE, ['i1'])
1489 819ca990 Guido Trotter
    self.GL.acquire(locking.LEVEL_NODEGROUP, ['g2'])
1490 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_NODE, ['n1', 'n2'], shared=1)
1491 04e1bfaf Guido Trotter
    self.GL.release(locking.LEVEL_NODE, ['n2'])
1492 7ee7c0c7 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE), set(['n1']))
1493 819ca990 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODEGROUP), set(['g2']))
1494 7ee7c0c7 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE), set(['i1']))
1495 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
1496 04e1bfaf Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE), set())
1497 819ca990 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODEGROUP), set(['g2']))
1498 04e1bfaf Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE), set(['i1']))
1499 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_NODEGROUP)
1500 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1501 7ee7c0c7 Guido Trotter
    self.assertRaises(errors.LockError, self.GL.acquire,
1502 7ee7c0c7 Guido Trotter
                      locking.LEVEL_INSTANCE, ['i5'])
1503 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_INSTANCE, ['i3'], shared=1)
1504 7ee7c0c7 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE), set(['i3']))
1505 7ee7c0c7 Guido Trotter
1506 90c942d1 Guido Trotter
  def testAcquireWholeSets(self):
1507 90c942d1 Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1508 90c942d1 Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_INSTANCE, None),
1509 90c942d1 Guido Trotter
                      set(self.instances))
1510 90c942d1 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE),
1511 90c942d1 Guido Trotter
                      set(self.instances))
1512 819ca990 Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODEGROUP, None),
1513 819ca990 Guido Trotter
                      set(self.nodegroups))
1514 819ca990 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODEGROUP),
1515 819ca990 Guido Trotter
                      set(self.nodegroups))
1516 90c942d1 Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODE, None, shared=1),
1517 90c942d1 Guido Trotter
                      set(self.nodes))
1518 90c942d1 Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE),
1519 90c942d1 Guido Trotter
                      set(self.nodes))
1520 90c942d1 Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
1521 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_NODEGROUP)
1522 d4f6a91c Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1523 d4f6a91c Guido Trotter
    self.GL.release(locking.LEVEL_CLUSTER)
1524 d4f6a91c Guido Trotter
1525 d4f6a91c Guido Trotter
  def testAcquireWholeAndPartial(self):
1526 d4f6a91c Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1527 d4f6a91c Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_INSTANCE, None),
1528 d4f6a91c Guido Trotter
                      set(self.instances))
1529 d4f6a91c Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_INSTANCE),
1530 d4f6a91c Guido Trotter
                      set(self.instances))
1531 d4f6a91c Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODE, ['n2'], shared=1),
1532 d4f6a91c Guido Trotter
                      set(['n2']))
1533 d4f6a91c Guido Trotter
    self.assertEquals(self.GL._list_owned(locking.LEVEL_NODE),
1534 d4f6a91c Guido Trotter
                      set(['n2']))
1535 d4f6a91c Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
1536 90c942d1 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1537 90c942d1 Guido Trotter
    self.GL.release(locking.LEVEL_CLUSTER)
1538 90c942d1 Guido Trotter
1539 7ee7c0c7 Guido Trotter
  def testBGLDependency(self):
1540 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1541 7ee7c0c7 Guido Trotter
                      locking.LEVEL_NODE, ['n1', 'n2'])
1542 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1543 7ee7c0c7 Guido Trotter
                      locking.LEVEL_INSTANCE, ['i3'])
1544 819ca990 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1545 819ca990 Guido Trotter
                      locking.LEVEL_NODEGROUP, ['g1'])
1546 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1547 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_NODE, ['n1'])
1548 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1549 7ee7c0c7 Guido Trotter
                      locking.LEVEL_CLUSTER, ['BGL'])
1550 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1551 7ee7c0c7 Guido Trotter
                      locking.LEVEL_CLUSTER)
1552 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
1553 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_INSTANCE, ['i1', 'i2'])
1554 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1555 7ee7c0c7 Guido Trotter
                      locking.LEVEL_CLUSTER, ['BGL'])
1556 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1557 7ee7c0c7 Guido Trotter
                      locking.LEVEL_CLUSTER)
1558 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1559 819ca990 Guido Trotter
    self.GL.acquire(locking.LEVEL_NODEGROUP, None)
1560 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_NODEGROUP, ['g1'])
1561 819ca990 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1562 819ca990 Guido Trotter
                      locking.LEVEL_CLUSTER, ['BGL'])
1563 819ca990 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1564 819ca990 Guido Trotter
                      locking.LEVEL_CLUSTER)
1565 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_NODEGROUP)
1566 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_CLUSTER)
1567 7ee7c0c7 Guido Trotter
1568 7ee7c0c7 Guido Trotter
  def testWrongOrder(self):
1569 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1570 04e1bfaf Guido Trotter
    self.GL.acquire(locking.LEVEL_NODE, ['n2'])
1571 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1572 7ee7c0c7 Guido Trotter
                      locking.LEVEL_NODE, ['n1'])
1573 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1574 819ca990 Guido Trotter
                      locking.LEVEL_NODEGROUP, ['g1'])
1575 819ca990 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1576 7ee7c0c7 Guido Trotter
                      locking.LEVEL_INSTANCE, ['i2'])
1577 7ee7c0c7 Guido Trotter
1578 4badc36c Guido Trotter
  def testModifiableLevels(self):
1579 4badc36c Guido Trotter
    self.assertRaises(AssertionError, self.GL.add, locking.LEVEL_CLUSTER,
1580 4badc36c Guido Trotter
                      ['BGL2'])
1581 4badc36c Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'])
1582 4badc36c Guido Trotter
    self.GL.add(locking.LEVEL_INSTANCE, ['i4'])
1583 4badc36c Guido Trotter
    self.GL.remove(locking.LEVEL_INSTANCE, ['i3'])
1584 4badc36c Guido Trotter
    self.GL.remove(locking.LEVEL_INSTANCE, ['i1'])
1585 4badc36c Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set(['i2', 'i4']))
1586 4badc36c Guido Trotter
    self.GL.add(locking.LEVEL_NODE, ['n3'])
1587 4badc36c Guido Trotter
    self.GL.remove(locking.LEVEL_NODE, ['n1'])
1588 4badc36c Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(['n2', 'n3']))
1589 819ca990 Guido Trotter
    self.GL.add(locking.LEVEL_NODEGROUP, ['g3'])
1590 819ca990 Guido Trotter
    self.GL.remove(locking.LEVEL_NODEGROUP, ['g2'])
1591 819ca990 Guido Trotter
    self.GL.remove(locking.LEVEL_NODEGROUP, ['g1'])
1592 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set(['g3']))
1593 4badc36c Guido Trotter
    self.assertRaises(AssertionError, self.GL.remove, locking.LEVEL_CLUSTER,
1594 4badc36c Guido Trotter
                      ['BGL2'])
1595 4badc36c Guido Trotter
1596 7ee7c0c7 Guido Trotter
  # Helper function to run as a thread that shared the BGL and then acquires
1597 7ee7c0c7 Guido Trotter
  # some locks at another level.
1598 7ee7c0c7 Guido Trotter
  def _doLock(self, level, names, shared):
1599 7ee7c0c7 Guido Trotter
    try:
1600 7ee7c0c7 Guido Trotter
      self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1601 7ee7c0c7 Guido Trotter
      self.GL.acquire(level, names, shared=shared)
1602 7ee7c0c7 Guido Trotter
      self.done.put('DONE')
1603 7ee7c0c7 Guido Trotter
      self.GL.release(level)
1604 7ee7c0c7 Guido Trotter
      self.GL.release(locking.LEVEL_CLUSTER)
1605 7ee7c0c7 Guido Trotter
    except errors.LockError:
1606 7ee7c0c7 Guido Trotter
      self.done.put('ERR')
1607 7ee7c0c7 Guido Trotter
1608 4607c978 Iustin Pop
  @_Repeat
1609 7ee7c0c7 Guido Trotter
  def testConcurrency(self):
1610 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_CLUSTER, ['BGL'], shared=1)
1611 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
1612 4607c978 Iustin Pop
                    args=(locking.LEVEL_INSTANCE, 'i1', 1))
1613 4607c978 Iustin Pop
    self._waitThreads()
1614 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1615 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_INSTANCE, ['i3'])
1616 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
1617 4607c978 Iustin Pop
                    args=(locking.LEVEL_INSTANCE, 'i1', 1))
1618 4607c978 Iustin Pop
    self._waitThreads()
1619 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1620 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
1621 4607c978 Iustin Pop
                    args=(locking.LEVEL_INSTANCE, 'i3', 1))
1622 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1623 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1624 4607c978 Iustin Pop
    self._waitThreads()
1625 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1626 7ee7c0c7 Guido Trotter
    self.GL.acquire(locking.LEVEL_INSTANCE, ['i2'], shared=1)
1627 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
1628 4607c978 Iustin Pop
                    args=(locking.LEVEL_INSTANCE, 'i2', 1))
1629 4607c978 Iustin Pop
    self._waitThreads()
1630 4607c978 Iustin Pop
    self.assertEqual(self.done.get_nowait(), 'DONE')
1631 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
1632 4607c978 Iustin Pop
                    args=(locking.LEVEL_INSTANCE, 'i2', 0))
1633 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1634 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1635 4607c978 Iustin Pop
    self._waitThreads()
1636 7ee7c0c7 Guido Trotter
    self.assertEqual(self.done.get(True, 1), 'DONE')
1637 4607c978 Iustin Pop
    self.GL.release(locking.LEVEL_CLUSTER, ['BGL'])
1638 7ee7c0c7 Guido Trotter
1639 7ee7c0c7 Guido Trotter
1640 19b9ba9a Michael Hanselmann
class TestLockMonitor(_ThreadedTestCase):
1641 19b9ba9a Michael Hanselmann
  def setUp(self):
1642 19b9ba9a Michael Hanselmann
    _ThreadedTestCase.setUp(self)
1643 19b9ba9a Michael Hanselmann
    self.lm = locking.LockMonitor()
1644 19b9ba9a Michael Hanselmann
1645 19b9ba9a Michael Hanselmann
  def testSingleThread(self):
1646 19b9ba9a Michael Hanselmann
    locks = []
1647 19b9ba9a Michael Hanselmann
1648 19b9ba9a Michael Hanselmann
    for i in range(100):
1649 19b9ba9a Michael Hanselmann
      name = "TestLock%s" % i
1650 19b9ba9a Michael Hanselmann
      locks.append(locking.SharedLock(name, monitor=self.lm))
1651 19b9ba9a Michael Hanselmann
1652 19b9ba9a Michael Hanselmann
    self.assertEqual(len(self.lm._locks), len(locks))
1653 24d16f76 Michael Hanselmann
    result = objects.QueryResponse.FromDict(self.lm.QueryLocks(["name"]))
1654 24d16f76 Michael Hanselmann
    self.assertEqual(len(result.fields), 1)
1655 24d16f76 Michael Hanselmann
    self.assertEqual(len(result.data), 100)
1656 c31825f7 Michael Hanselmann
1657 19b9ba9a Michael Hanselmann
    # Delete all locks
1658 19b9ba9a Michael Hanselmann
    del locks[:]
1659 19b9ba9a Michael Hanselmann
1660 19b9ba9a Michael Hanselmann
    # The garbage collector might needs some time
1661 19b9ba9a Michael Hanselmann
    def _CheckLocks():
1662 19b9ba9a Michael Hanselmann
      if self.lm._locks:
1663 19b9ba9a Michael Hanselmann
        raise utils.RetryAgain()
1664 19b9ba9a Michael Hanselmann
1665 19b9ba9a Michael Hanselmann
    utils.Retry(_CheckLocks, 0.1, 30.0)
1666 19b9ba9a Michael Hanselmann
1667 19b9ba9a Michael Hanselmann
    self.assertFalse(self.lm._locks)
1668 19b9ba9a Michael Hanselmann
1669 19b9ba9a Michael Hanselmann
  def testMultiThread(self):
1670 19b9ba9a Michael Hanselmann
    locks = []
1671 19b9ba9a Michael Hanselmann
1672 19b9ba9a Michael Hanselmann
    def _CreateLock(prev, next, name):
1673 19b9ba9a Michael Hanselmann
      prev.wait()
1674 19b9ba9a Michael Hanselmann
      locks.append(locking.SharedLock(name, monitor=self.lm))
1675 19b9ba9a Michael Hanselmann
      if next:
1676 19b9ba9a Michael Hanselmann
        next.set()
1677 19b9ba9a Michael Hanselmann
1678 19b9ba9a Michael Hanselmann
    expnames = []
1679 19b9ba9a Michael Hanselmann
1680 19b9ba9a Michael Hanselmann
    first = threading.Event()
1681 19b9ba9a Michael Hanselmann
    prev = first
1682 19b9ba9a Michael Hanselmann
1683 19b9ba9a Michael Hanselmann
    # Use a deterministic random generator
1684 19b9ba9a Michael Hanselmann
    for i in random.Random(4263).sample(range(100), 33):
1685 19b9ba9a Michael Hanselmann
      name = "MtTestLock%s" % i
1686 19b9ba9a Michael Hanselmann
      expnames.append(name)
1687 19b9ba9a Michael Hanselmann
1688 19b9ba9a Michael Hanselmann
      ev = threading.Event()
1689 19b9ba9a Michael Hanselmann
      self._addThread(target=_CreateLock, args=(prev, ev, name))
1690 19b9ba9a Michael Hanselmann
      prev = ev
1691 19b9ba9a Michael Hanselmann
1692 19b9ba9a Michael Hanselmann
    # Add locks
1693 19b9ba9a Michael Hanselmann
    first.set()
1694 19b9ba9a Michael Hanselmann
    self._waitThreads()
1695 19b9ba9a Michael Hanselmann
1696 19b9ba9a Michael Hanselmann
    # Check order in which locks were added
1697 19b9ba9a Michael Hanselmann
    self.assertEqual([i.name for i in locks], expnames)
1698 19b9ba9a Michael Hanselmann
1699 19b9ba9a Michael Hanselmann
    # Check query result
1700 24d16f76 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner", "pending"])
1701 24d16f76 Michael Hanselmann
    self.assert_(isinstance(result, dict))
1702 24d16f76 Michael Hanselmann
    response = objects.QueryResponse.FromDict(result)
1703 24d16f76 Michael Hanselmann
    self.assertEqual(response.data,
1704 24d16f76 Michael Hanselmann
                     [[(constants.QRFS_NORMAL, name),
1705 24d16f76 Michael Hanselmann
                       (constants.QRFS_NORMAL, None),
1706 24d16f76 Michael Hanselmann
                       (constants.QRFS_NORMAL, None),
1707 24d16f76 Michael Hanselmann
                       (constants.QRFS_NORMAL, [])]
1708 c31825f7 Michael Hanselmann
                      for name in utils.NiceSort(expnames)])
1709 24d16f76 Michael Hanselmann
    self.assertEqual(len(response.fields), 4)
1710 24d16f76 Michael Hanselmann
    self.assertEqual(["name", "mode", "owner", "pending"],
1711 24d16f76 Michael Hanselmann
                     [fdef.name for fdef in response.fields])
1712 19b9ba9a Michael Hanselmann
1713 19b9ba9a Michael Hanselmann
    # Test exclusive acquire
1714 19b9ba9a Michael Hanselmann
    for tlock in locks[::4]:
1715 19b9ba9a Michael Hanselmann
      tlock.acquire(shared=0)
1716 19b9ba9a Michael Hanselmann
      try:
1717 19b9ba9a Michael Hanselmann
        def _GetExpResult(name):
1718 19b9ba9a Michael Hanselmann
          if tlock.name == name:
1719 24d16f76 Michael Hanselmann
            return [(constants.QRFS_NORMAL, name),
1720 24d16f76 Michael Hanselmann
                    (constants.QRFS_NORMAL, "exclusive"),
1721 24d16f76 Michael Hanselmann
                    (constants.QRFS_NORMAL,
1722 24d16f76 Michael Hanselmann
                     [threading.currentThread().getName()]),
1723 24d16f76 Michael Hanselmann
                    (constants.QRFS_NORMAL, [])]
1724 24d16f76 Michael Hanselmann
          return [(constants.QRFS_NORMAL, name),
1725 24d16f76 Michael Hanselmann
                  (constants.QRFS_NORMAL, None),
1726 24d16f76 Michael Hanselmann
                  (constants.QRFS_NORMAL, None),
1727 24d16f76 Michael Hanselmann
                  (constants.QRFS_NORMAL, [])]
1728 24d16f76 Michael Hanselmann
1729 24d16f76 Michael Hanselmann
        result = self.lm.QueryLocks(["name", "mode", "owner", "pending"])
1730 24d16f76 Michael Hanselmann
        self.assertEqual(objects.QueryResponse.FromDict(result).data,
1731 19b9ba9a Michael Hanselmann
                         [_GetExpResult(name)
1732 19b9ba9a Michael Hanselmann
                          for name in utils.NiceSort(expnames)])
1733 19b9ba9a Michael Hanselmann
      finally:
1734 19b9ba9a Michael Hanselmann
        tlock.release()
1735 19b9ba9a Michael Hanselmann
1736 19b9ba9a Michael Hanselmann
    # Test shared acquire
1737 73c25d35 Michael Hanselmann
    def _Acquire(lock, shared, ev, notify):
1738 19b9ba9a Michael Hanselmann
      lock.acquire(shared=shared)
1739 19b9ba9a Michael Hanselmann
      try:
1740 73c25d35 Michael Hanselmann
        notify.set()
1741 19b9ba9a Michael Hanselmann
        ev.wait()
1742 19b9ba9a Michael Hanselmann
      finally:
1743 19b9ba9a Michael Hanselmann
        lock.release()
1744 19b9ba9a Michael Hanselmann
1745 19b9ba9a Michael Hanselmann
    for tlock1 in locks[::11]:
1746 19b9ba9a Michael Hanselmann
      for tlock2 in locks[::-15]:
1747 19b9ba9a Michael Hanselmann
        if tlock2 == tlock1:
1748 73c25d35 Michael Hanselmann
          # Avoid deadlocks
1749 19b9ba9a Michael Hanselmann
          continue
1750 19b9ba9a Michael Hanselmann
1751 19b9ba9a Michael Hanselmann
        for tlock3 in locks[::10]:
1752 73c25d35 Michael Hanselmann
          if tlock3 in (tlock2, tlock1):
1753 73c25d35 Michael Hanselmann
            # Avoid deadlocks
1754 19b9ba9a Michael Hanselmann
            continue
1755 19b9ba9a Michael Hanselmann
1756 73c25d35 Michael Hanselmann
          releaseev = threading.Event()
1757 19b9ba9a Michael Hanselmann
1758 19b9ba9a Michael Hanselmann
          # Acquire locks
1759 73c25d35 Michael Hanselmann
          acquireev = []
1760 19b9ba9a Michael Hanselmann
          tthreads1 = []
1761 19b9ba9a Michael Hanselmann
          for i in range(3):
1762 73c25d35 Michael Hanselmann
            ev = threading.Event()
1763 19b9ba9a Michael Hanselmann
            tthreads1.append(self._addThread(target=_Acquire,
1764 73c25d35 Michael Hanselmann
                                             args=(tlock1, 1, releaseev, ev)))
1765 73c25d35 Michael Hanselmann
            acquireev.append(ev)
1766 73c25d35 Michael Hanselmann
1767 73c25d35 Michael Hanselmann
          ev = threading.Event()
1768 73c25d35 Michael Hanselmann
          tthread2 = self._addThread(target=_Acquire,
1769 73c25d35 Michael Hanselmann
                                     args=(tlock2, 1, releaseev, ev))
1770 73c25d35 Michael Hanselmann
          acquireev.append(ev)
1771 73c25d35 Michael Hanselmann
1772 73c25d35 Michael Hanselmann
          ev = threading.Event()
1773 73c25d35 Michael Hanselmann
          tthread3 = self._addThread(target=_Acquire,
1774 73c25d35 Michael Hanselmann
                                     args=(tlock3, 0, releaseev, ev))
1775 73c25d35 Michael Hanselmann
          acquireev.append(ev)
1776 73c25d35 Michael Hanselmann
1777 73c25d35 Michael Hanselmann
          # Wait for all locks to be acquired
1778 73c25d35 Michael Hanselmann
          for i in acquireev:
1779 73c25d35 Michael Hanselmann
            i.wait()
1780 19b9ba9a Michael Hanselmann
1781 19b9ba9a Michael Hanselmann
          # Check query result
1782 24d16f76 Michael Hanselmann
          result = self.lm.QueryLocks(["name", "mode", "owner"])
1783 24d16f76 Michael Hanselmann
          response = objects.QueryResponse.FromDict(result)
1784 24d16f76 Michael Hanselmann
          for (name, mode, owner) in response.data:
1785 24d16f76 Michael Hanselmann
            (name_status, name_value) = name
1786 24d16f76 Michael Hanselmann
            (owner_status, owner_value) = owner
1787 24d16f76 Michael Hanselmann
1788 24d16f76 Michael Hanselmann
            self.assertEqual(name_status, constants.QRFS_NORMAL)
1789 24d16f76 Michael Hanselmann
            self.assertEqual(owner_status, constants.QRFS_NORMAL)
1790 24d16f76 Michael Hanselmann
1791 24d16f76 Michael Hanselmann
            if name_value == tlock1.name:
1792 24d16f76 Michael Hanselmann
              self.assertEqual(mode, (constants.QRFS_NORMAL, "shared"))
1793 24d16f76 Michael Hanselmann
              self.assertEqual(set(owner_value),
1794 24d16f76 Michael Hanselmann
                               set(i.getName() for i in tthreads1))
1795 19b9ba9a Michael Hanselmann
              continue
1796 19b9ba9a Michael Hanselmann
1797 24d16f76 Michael Hanselmann
            if name_value == tlock2.name:
1798 24d16f76 Michael Hanselmann
              self.assertEqual(mode, (constants.QRFS_NORMAL, "shared"))
1799 24d16f76 Michael Hanselmann
              self.assertEqual(owner_value, [tthread2.getName()])
1800 19b9ba9a Michael Hanselmann
              continue
1801 19b9ba9a Michael Hanselmann
1802 24d16f76 Michael Hanselmann
            if name_value == tlock3.name:
1803 24d16f76 Michael Hanselmann
              self.assertEqual(mode, (constants.QRFS_NORMAL, "exclusive"))
1804 24d16f76 Michael Hanselmann
              self.assertEqual(owner_value, [tthread3.getName()])
1805 19b9ba9a Michael Hanselmann
              continue
1806 19b9ba9a Michael Hanselmann
1807 24d16f76 Michael Hanselmann
            self.assert_(name_value in expnames)
1808 24d16f76 Michael Hanselmann
            self.assertEqual(mode, (constants.QRFS_NORMAL, None))
1809 24d16f76 Michael Hanselmann
            self.assert_(owner_value is None)
1810 19b9ba9a Michael Hanselmann
1811 19b9ba9a Michael Hanselmann
          # Release locks again
1812 73c25d35 Michael Hanselmann
          releaseev.set()
1813 19b9ba9a Michael Hanselmann
1814 19b9ba9a Michael Hanselmann
          self._waitThreads()
1815 19b9ba9a Michael Hanselmann
1816 24d16f76 Michael Hanselmann
          result = self.lm.QueryLocks(["name", "mode", "owner"])
1817 24d16f76 Michael Hanselmann
          self.assertEqual(objects.QueryResponse.FromDict(result).data,
1818 24d16f76 Michael Hanselmann
                           [[(constants.QRFS_NORMAL, name),
1819 24d16f76 Michael Hanselmann
                             (constants.QRFS_NORMAL, None),
1820 24d16f76 Michael Hanselmann
                             (constants.QRFS_NORMAL, None)]
1821 19b9ba9a Michael Hanselmann
                            for name in utils.NiceSort(expnames)])
1822 19b9ba9a Michael Hanselmann
1823 19b9ba9a Michael Hanselmann
  def testDelete(self):
1824 19b9ba9a Michael Hanselmann
    lock = locking.SharedLock("TestLock", monitor=self.lm)
1825 19b9ba9a Michael Hanselmann
1826 19b9ba9a Michael Hanselmann
    self.assertEqual(len(self.lm._locks), 1)
1827 24d16f76 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
1828 24d16f76 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data,
1829 24d16f76 Michael Hanselmann
                     [[(constants.QRFS_NORMAL, lock.name),
1830 24d16f76 Michael Hanselmann
                       (constants.QRFS_NORMAL, None),
1831 24d16f76 Michael Hanselmann
                       (constants.QRFS_NORMAL, None)]])
1832 19b9ba9a Michael Hanselmann
1833 19b9ba9a Michael Hanselmann
    lock.delete()
1834 19b9ba9a Michael Hanselmann
1835 24d16f76 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
1836 24d16f76 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data,
1837 24d16f76 Michael Hanselmann
                     [[(constants.QRFS_NORMAL, lock.name),
1838 24d16f76 Michael Hanselmann
                       (constants.QRFS_NORMAL, "deleted"),
1839 24d16f76 Michael Hanselmann
                       (constants.QRFS_NORMAL, None)]])
1840 19b9ba9a Michael Hanselmann
    self.assertEqual(len(self.lm._locks), 1)
1841 19b9ba9a Michael Hanselmann
1842 c31825f7 Michael Hanselmann
  def testPending(self):
1843 c31825f7 Michael Hanselmann
    def _Acquire(lock, shared, prev, next):
1844 c31825f7 Michael Hanselmann
      prev.wait()
1845 c31825f7 Michael Hanselmann
1846 c31825f7 Michael Hanselmann
      lock.acquire(shared=shared, test_notify=next.set)
1847 c31825f7 Michael Hanselmann
      try:
1848 c31825f7 Michael Hanselmann
        pass
1849 c31825f7 Michael Hanselmann
      finally:
1850 c31825f7 Michael Hanselmann
        lock.release()
1851 c31825f7 Michael Hanselmann
1852 c31825f7 Michael Hanselmann
    lock = locking.SharedLock("ExcLock", monitor=self.lm)
1853 c31825f7 Michael Hanselmann
1854 c31825f7 Michael Hanselmann
    for shared in [0, 1]:
1855 c31825f7 Michael Hanselmann
      lock.acquire()
1856 c31825f7 Michael Hanselmann
      try:
1857 c31825f7 Michael Hanselmann
        self.assertEqual(len(self.lm._locks), 1)
1858 24d16f76 Michael Hanselmann
        result = self.lm.QueryLocks(["name", "mode", "owner"])
1859 24d16f76 Michael Hanselmann
        self.assertEqual(objects.QueryResponse.FromDict(result).data,
1860 24d16f76 Michael Hanselmann
                         [[(constants.QRFS_NORMAL, lock.name),
1861 24d16f76 Michael Hanselmann
                           (constants.QRFS_NORMAL, "exclusive"),
1862 24d16f76 Michael Hanselmann
                           (constants.QRFS_NORMAL,
1863 24d16f76 Michael Hanselmann
                            [threading.currentThread().getName()])]])
1864 c31825f7 Michael Hanselmann
1865 c31825f7 Michael Hanselmann
        threads = []
1866 c31825f7 Michael Hanselmann
1867 c31825f7 Michael Hanselmann
        first = threading.Event()
1868 c31825f7 Michael Hanselmann
        prev = first
1869 c31825f7 Michael Hanselmann
1870 c31825f7 Michael Hanselmann
        for i in range(5):
1871 c31825f7 Michael Hanselmann
          ev = threading.Event()
1872 c31825f7 Michael Hanselmann
          threads.append(self._addThread(target=_Acquire,
1873 c31825f7 Michael Hanselmann
                                          args=(lock, shared, prev, ev)))
1874 c31825f7 Michael Hanselmann
          prev = ev
1875 c31825f7 Michael Hanselmann
1876 c31825f7 Michael Hanselmann
        # Start acquires
1877 c31825f7 Michael Hanselmann
        first.set()
1878 c31825f7 Michael Hanselmann
1879 c31825f7 Michael Hanselmann
        # Wait for last acquire to start waiting
1880 c31825f7 Michael Hanselmann
        prev.wait()
1881 c31825f7 Michael Hanselmann
1882 c31825f7 Michael Hanselmann
        # NOTE: This works only because QueryLocks will acquire the
1883 c31825f7 Michael Hanselmann
        # lock-internal lock again and won't be able to get the information
1884 c31825f7 Michael Hanselmann
        # until it has the lock. By then the acquire should be registered in
1885 c31825f7 Michael Hanselmann
        # SharedLock.__pending (otherwise it's a bug).
1886 c31825f7 Michael Hanselmann
1887 c31825f7 Michael Hanselmann
        # All acquires are waiting now
1888 c31825f7 Michael Hanselmann
        if shared:
1889 24d16f76 Michael Hanselmann
          pending = [("shared", utils.NiceSort(t.getName() for t in threads))]
1890 c31825f7 Michael Hanselmann
        else:
1891 c31825f7 Michael Hanselmann
          pending = [("exclusive", [t.getName()]) for t in threads]
1892 c31825f7 Michael Hanselmann
1893 24d16f76 Michael Hanselmann
        result = self.lm.QueryLocks(["name", "mode", "owner", "pending"])
1894 24d16f76 Michael Hanselmann
        self.assertEqual(objects.QueryResponse.FromDict(result).data,
1895 24d16f76 Michael Hanselmann
                         [[(constants.QRFS_NORMAL, lock.name),
1896 24d16f76 Michael Hanselmann
                           (constants.QRFS_NORMAL, "exclusive"),
1897 24d16f76 Michael Hanselmann
                           (constants.QRFS_NORMAL,
1898 24d16f76 Michael Hanselmann
                            [threading.currentThread().getName()]),
1899 24d16f76 Michael Hanselmann
                           (constants.QRFS_NORMAL, pending)]])
1900 c31825f7 Michael Hanselmann
1901 c31825f7 Michael Hanselmann
        self.assertEqual(len(self.lm._locks), 1)
1902 c31825f7 Michael Hanselmann
      finally:
1903 c31825f7 Michael Hanselmann
        lock.release()
1904 c31825f7 Michael Hanselmann
1905 c31825f7 Michael Hanselmann
      self._waitThreads()
1906 c31825f7 Michael Hanselmann
1907 c31825f7 Michael Hanselmann
      # No pending acquires
1908 24d16f76 Michael Hanselmann
      result = self.lm.QueryLocks(["name", "mode", "owner", "pending"])
1909 24d16f76 Michael Hanselmann
      self.assertEqual(objects.QueryResponse.FromDict(result).data,
1910 24d16f76 Michael Hanselmann
                       [[(constants.QRFS_NORMAL, lock.name),
1911 24d16f76 Michael Hanselmann
                         (constants.QRFS_NORMAL, None),
1912 24d16f76 Michael Hanselmann
                         (constants.QRFS_NORMAL, None),
1913 24d16f76 Michael Hanselmann
                         (constants.QRFS_NORMAL, [])]])
1914 c31825f7 Michael Hanselmann
1915 c31825f7 Michael Hanselmann
      self.assertEqual(len(self.lm._locks), 1)
1916 c31825f7 Michael Hanselmann
1917 19b9ba9a Michael Hanselmann
1918 162c1c1f Guido Trotter
if __name__ == '__main__':
1919 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()