Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.locking_unittest.py @ d01e51a5

History | View | Annotate | Download (92 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 fd7b69c0 Michael Hanselmann
# 02110-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 e4e35357 Michael Hanselmann
import gc
32 887c7aa6 Michael Hanselmann
import itertools
33 162c1c1f Guido Trotter
34 24d16f76 Michael Hanselmann
from ganeti import constants
35 162c1c1f Guido Trotter
from ganeti import locking
36 a95fd5d7 Guido Trotter
from ganeti import errors
37 19b9ba9a Michael Hanselmann
from ganeti import utils
38 887c7aa6 Michael Hanselmann
from ganeti import compat
39 24d16f76 Michael Hanselmann
from ganeti import objects
40 24d16f76 Michael Hanselmann
from ganeti import query
41 162c1c1f Guido Trotter
42 25231ec5 Michael Hanselmann
import testutils
43 25231ec5 Michael Hanselmann
44 162c1c1f Guido Trotter
45 42a999d1 Guido Trotter
# This is used to test the ssynchronize decorator.
46 42a999d1 Guido Trotter
# Since it's passed as input to a decorator it must be declared as a global.
47 7f93570a Iustin Pop
_decoratorlock = locking.SharedLock("decorator lock")
48 42a999d1 Guido Trotter
49 4607c978 Iustin Pop
#: List for looping tests
50 4607c978 Iustin Pop
ITERATIONS = range(8)
51 4607c978 Iustin Pop
52 84e344d4 Michael Hanselmann
53 4607c978 Iustin Pop
def _Repeat(fn):
54 4607c978 Iustin Pop
  """Decorator for executing a function many times"""
55 4607c978 Iustin Pop
  def wrapper(*args, **kwargs):
56 4607c978 Iustin Pop
    for i in ITERATIONS:
57 4607c978 Iustin Pop
      fn(*args, **kwargs)
58 4607c978 Iustin Pop
  return wrapper
59 4607c978 Iustin Pop
60 84e344d4 Michael Hanselmann
61 5aab242c Michael Hanselmann
def SafeSleep(duration):
62 5aab242c Michael Hanselmann
  start = time.time()
63 5aab242c Michael Hanselmann
  while True:
64 5aab242c Michael Hanselmann
    delay = start + duration - time.time()
65 5aab242c Michael Hanselmann
    if delay <= 0.0:
66 5aab242c Michael Hanselmann
      break
67 5aab242c Michael Hanselmann
    time.sleep(delay)
68 5aab242c Michael Hanselmann
69 5aab242c Michael Hanselmann
70 4607c978 Iustin Pop
class _ThreadedTestCase(unittest.TestCase):
71 4607c978 Iustin Pop
  """Test class that supports adding/waiting on threads"""
72 4607c978 Iustin Pop
  def setUp(self):
73 4607c978 Iustin Pop
    unittest.TestCase.setUp(self)
74 63f2e724 Guido Trotter
    self.done = Queue.Queue(0)
75 4607c978 Iustin Pop
    self.threads = []
76 4607c978 Iustin Pop
77 4607c978 Iustin Pop
  def _addThread(self, *args, **kwargs):
78 4607c978 Iustin Pop
    """Create and remember a new thread"""
79 84e344d4 Michael Hanselmann
    t = threading.Thread(*args, **kwargs)
80 4607c978 Iustin Pop
    self.threads.append(t)
81 4607c978 Iustin Pop
    t.start()
82 4607c978 Iustin Pop
    return t
83 4607c978 Iustin Pop
84 4607c978 Iustin Pop
  def _waitThreads(self):
85 4607c978 Iustin Pop
    """Wait for all our threads to finish"""
86 4607c978 Iustin Pop
    for t in self.threads:
87 4607c978 Iustin Pop
      t.join(60)
88 4607c978 Iustin Pop
      self.failIf(t.isAlive())
89 4607c978 Iustin Pop
    self.threads = []
90 42a999d1 Guido Trotter
91 4607c978 Iustin Pop
92 c5fe2a67 Guido Trotter
class _ConditionTestCase(_ThreadedTestCase):
93 c5fe2a67 Guido Trotter
  """Common test case for conditions"""
94 48dabc6a Michael Hanselmann
95 c5fe2a67 Guido Trotter
  def setUp(self, cls):
96 48dabc6a Michael Hanselmann
    _ThreadedTestCase.setUp(self)
97 48dabc6a Michael Hanselmann
    self.lock = threading.Lock()
98 c5fe2a67 Guido Trotter
    self.cond = cls(self.lock)
99 48dabc6a Michael Hanselmann
100 c5fe2a67 Guido Trotter
  def _testAcquireRelease(self):
101 158206e0 Manuel Franceschini
    self.assertFalse(self.cond._is_owned())
102 83f2d5f6 Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.wait, None)
103 48dabc6a Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.notifyAll)
104 48dabc6a Michael Hanselmann
105 48dabc6a Michael Hanselmann
    self.cond.acquire()
106 48dabc6a Michael Hanselmann
    self.assert_(self.cond._is_owned())
107 48dabc6a Michael Hanselmann
    self.cond.notifyAll()
108 48dabc6a Michael Hanselmann
    self.assert_(self.cond._is_owned())
109 48dabc6a Michael Hanselmann
    self.cond.release()
110 48dabc6a Michael Hanselmann
111 158206e0 Manuel Franceschini
    self.assertFalse(self.cond._is_owned())
112 83f2d5f6 Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.wait, None)
113 48dabc6a Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.notifyAll)
114 48dabc6a Michael Hanselmann
115 c5fe2a67 Guido Trotter
  def _testNotification(self):
116 48dabc6a Michael Hanselmann
    def _NotifyAll():
117 b8140229 Guido Trotter
      self.done.put("NE")
118 48dabc6a Michael Hanselmann
      self.cond.acquire()
119 b8140229 Guido Trotter
      self.done.put("NA")
120 48dabc6a Michael Hanselmann
      self.cond.notifyAll()
121 b8140229 Guido Trotter
      self.done.put("NN")
122 48dabc6a Michael Hanselmann
      self.cond.release()
123 48dabc6a Michael Hanselmann
124 48dabc6a Michael Hanselmann
    self.cond.acquire()
125 48dabc6a Michael Hanselmann
    self._addThread(target=_NotifyAll)
126 b8140229 Guido Trotter
    self.assertEqual(self.done.get(True, 1), "NE")
127 b8140229 Guido Trotter
    self.assertRaises(Queue.Empty, self.done.get_nowait)
128 83f2d5f6 Michael Hanselmann
    self.cond.wait(None)
129 b8140229 Guido Trotter
    self.assertEqual(self.done.get(True, 1), "NA")
130 b8140229 Guido Trotter
    self.assertEqual(self.done.get(True, 1), "NN")
131 48dabc6a Michael Hanselmann
    self.assert_(self.cond._is_owned())
132 48dabc6a Michael Hanselmann
    self.cond.release()
133 158206e0 Manuel Franceschini
    self.assertFalse(self.cond._is_owned())
134 48dabc6a Michael Hanselmann
135 c5fe2a67 Guido Trotter
136 34cb5617 Guido Trotter
class TestSingleNotifyPipeCondition(_ConditionTestCase):
137 34cb5617 Guido Trotter
  """SingleNotifyPipeCondition tests"""
138 34cb5617 Guido Trotter
139 34cb5617 Guido Trotter
  def setUp(self):
140 34cb5617 Guido Trotter
    _ConditionTestCase.setUp(self, locking.SingleNotifyPipeCondition)
141 34cb5617 Guido Trotter
142 34cb5617 Guido Trotter
  def testAcquireRelease(self):
143 34cb5617 Guido Trotter
    self._testAcquireRelease()
144 34cb5617 Guido Trotter
145 34cb5617 Guido Trotter
  def testNotification(self):
146 34cb5617 Guido Trotter
    self._testNotification()
147 34cb5617 Guido Trotter
148 34cb5617 Guido Trotter
  def testWaitReuse(self):
149 34cb5617 Guido Trotter
    self.cond.acquire()
150 34cb5617 Guido Trotter
    self.cond.wait(0)
151 34cb5617 Guido Trotter
    self.cond.wait(0.1)
152 34cb5617 Guido Trotter
    self.cond.release()
153 34cb5617 Guido Trotter
154 34cb5617 Guido Trotter
  def testNoNotifyReuse(self):
155 34cb5617 Guido Trotter
    self.cond.acquire()
156 34cb5617 Guido Trotter
    self.cond.notifyAll()
157 83f2d5f6 Michael Hanselmann
    self.assertRaises(RuntimeError, self.cond.wait, None)
158 34cb5617 Guido Trotter
    self.assertRaises(RuntimeError, self.cond.notifyAll)
159 34cb5617 Guido Trotter
    self.cond.release()
160 34cb5617 Guido Trotter
161 34cb5617 Guido Trotter
162 c5fe2a67 Guido Trotter
class TestPipeCondition(_ConditionTestCase):
163 34cb5617 Guido Trotter
  """PipeCondition tests"""
164 c5fe2a67 Guido Trotter
165 c5fe2a67 Guido Trotter
  def setUp(self):
166 34cb5617 Guido Trotter
    _ConditionTestCase.setUp(self, locking.PipeCondition)
167 c5fe2a67 Guido Trotter
168 c5fe2a67 Guido Trotter
  def testAcquireRelease(self):
169 c5fe2a67 Guido Trotter
    self._testAcquireRelease()
170 c5fe2a67 Guido Trotter
171 c5fe2a67 Guido Trotter
  def testNotification(self):
172 c5fe2a67 Guido Trotter
    self._testNotification()
173 c5fe2a67 Guido Trotter
174 48dabc6a Michael Hanselmann
  def _TestWait(self, fn):
175 c31825f7 Michael Hanselmann
    threads = [
176 c31825f7 Michael Hanselmann
      self._addThread(target=fn),
177 c31825f7 Michael Hanselmann
      self._addThread(target=fn),
178 c31825f7 Michael Hanselmann
      self._addThread(target=fn),
179 c31825f7 Michael Hanselmann
      ]
180 48dabc6a Michael Hanselmann
181 48dabc6a Michael Hanselmann
    # Wait for threads to be waiting
182 c31825f7 Michael Hanselmann
    for _ in threads:
183 c31825f7 Michael Hanselmann
      self.assertEqual(self.done.get(True, 1), "A")
184 48dabc6a Michael Hanselmann
185 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
186 48dabc6a Michael Hanselmann
187 48dabc6a Michael Hanselmann
    self.cond.acquire()
188 c31825f7 Michael Hanselmann
    self.assertEqual(len(self.cond._waiters), 3)
189 c31825f7 Michael Hanselmann
    self.assertEqual(self.cond._waiters, set(threads))
190 6252c0bd Michael Hanselmann
191 6252c0bd Michael Hanselmann
    self.assertTrue(repr(self.cond).startswith("<"))
192 6252c0bd Michael Hanselmann
    self.assertTrue("waiters=" in repr(self.cond))
193 6252c0bd Michael Hanselmann
194 c31825f7 Michael Hanselmann
    # This new thread can't acquire the lock, and thus call wait, before we
195 48dabc6a Michael Hanselmann
    # release it
196 48dabc6a Michael Hanselmann
    self._addThread(target=fn)
197 48dabc6a Michael Hanselmann
    self.cond.notifyAll()
198 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
199 48dabc6a Michael Hanselmann
    self.cond.release()
200 48dabc6a Michael Hanselmann
201 48dabc6a Michael Hanselmann
    # We should now get 3 W and 1 A (for the new thread) in whatever order
202 48dabc6a Michael Hanselmann
    w = 0
203 48dabc6a Michael Hanselmann
    a = 0
204 48dabc6a Michael Hanselmann
    for i in range(4):
205 48dabc6a Michael Hanselmann
      got = self.done.get(True, 1)
206 48dabc6a Michael Hanselmann
      if got == "W":
207 48dabc6a Michael Hanselmann
        w += 1
208 48dabc6a Michael Hanselmann
      elif got == "A":
209 48dabc6a Michael Hanselmann
        a += 1
210 48dabc6a Michael Hanselmann
      else:
211 48dabc6a Michael Hanselmann
        self.fail("Got %s on the done queue" % got)
212 48dabc6a Michael Hanselmann
213 48dabc6a Michael Hanselmann
    self.assertEqual(w, 3)
214 48dabc6a Michael Hanselmann
    self.assertEqual(a, 1)
215 48dabc6a Michael Hanselmann
216 48dabc6a Michael Hanselmann
    self.cond.acquire()
217 48dabc6a Michael Hanselmann
    self.cond.notifyAll()
218 48dabc6a Michael Hanselmann
    self.cond.release()
219 48dabc6a Michael Hanselmann
    self._waitThreads()
220 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "W")
221 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
222 48dabc6a Michael Hanselmann
223 48dabc6a Michael Hanselmann
  def testBlockingWait(self):
224 48dabc6a Michael Hanselmann
    def _BlockingWait():
225 48dabc6a Michael Hanselmann
      self.cond.acquire()
226 48dabc6a Michael Hanselmann
      self.done.put("A")
227 83f2d5f6 Michael Hanselmann
      self.cond.wait(None)
228 48dabc6a Michael Hanselmann
      self.cond.release()
229 48dabc6a Michael Hanselmann
      self.done.put("W")
230 48dabc6a Michael Hanselmann
231 48dabc6a Michael Hanselmann
    self._TestWait(_BlockingWait)
232 48dabc6a Michael Hanselmann
233 48dabc6a Michael Hanselmann
  def testLongTimeoutWait(self):
234 48dabc6a Michael Hanselmann
    def _Helper():
235 48dabc6a Michael Hanselmann
      self.cond.acquire()
236 48dabc6a Michael Hanselmann
      self.done.put("A")
237 48dabc6a Michael Hanselmann
      self.cond.wait(15.0)
238 48dabc6a Michael Hanselmann
      self.cond.release()
239 48dabc6a Michael Hanselmann
      self.done.put("W")
240 48dabc6a Michael Hanselmann
241 48dabc6a Michael Hanselmann
    self._TestWait(_Helper)
242 48dabc6a Michael Hanselmann
243 48dabc6a Michael Hanselmann
  def _TimeoutWait(self, timeout, check):
244 48dabc6a Michael Hanselmann
    self.cond.acquire()
245 48dabc6a Michael Hanselmann
    self.cond.wait(timeout)
246 48dabc6a Michael Hanselmann
    self.cond.release()
247 48dabc6a Michael Hanselmann
    self.done.put(check)
248 48dabc6a Michael Hanselmann
249 48dabc6a Michael Hanselmann
  def testShortTimeoutWait(self):
250 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0.1, "T1"))
251 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0.1, "T1"))
252 48dabc6a Michael Hanselmann
    self._waitThreads()
253 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T1")
254 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T1")
255 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
256 48dabc6a Michael Hanselmann
257 48dabc6a Michael Hanselmann
  def testZeroTimeoutWait(self):
258 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0, "T0"))
259 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0, "T0"))
260 48dabc6a Michael Hanselmann
    self._addThread(target=self._TimeoutWait, args=(0, "T0"))
261 48dabc6a Michael Hanselmann
    self._waitThreads()
262 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T0")
263 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T0")
264 48dabc6a Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "T0")
265 48dabc6a Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
266 48dabc6a Michael Hanselmann
267 48dabc6a Michael Hanselmann
268 4607c978 Iustin Pop
class TestSharedLock(_ThreadedTestCase):
269 d6646186 Guido Trotter
  """SharedLock tests"""
270 162c1c1f Guido Trotter
271 162c1c1f Guido Trotter
  def setUp(self):
272 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
273 7f93570a Iustin Pop
    self.sl = locking.SharedLock("TestSharedLock")
274 162c1c1f Guido Trotter
275 6252c0bd Michael Hanselmann
    self.assertTrue(repr(self.sl).startswith("<"))
276 6252c0bd Michael Hanselmann
    self.assertTrue("name=TestSharedLock" in repr(self.sl))
277 6252c0bd Michael Hanselmann
278 162c1c1f Guido Trotter
  def testSequenceAndOwnership(self):
279 ee2b99e3 Michael Hanselmann
    self.assertFalse(self.sl.is_owned())
280 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
281 ee2b99e3 Michael Hanselmann
    self.assert_(self.sl.is_owned())
282 ee2b99e3 Michael Hanselmann
    self.assert_(self.sl.is_owned(shared=1))
283 ee2b99e3 Michael Hanselmann
    self.assertFalse(self.sl.is_owned(shared=0))
284 162c1c1f Guido Trotter
    self.sl.release()
285 ee2b99e3 Michael Hanselmann
    self.assertFalse(self.sl.is_owned())
286 162c1c1f Guido Trotter
    self.sl.acquire()
287 ee2b99e3 Michael Hanselmann
    self.assert_(self.sl.is_owned())
288 ee2b99e3 Michael Hanselmann
    self.assertFalse(self.sl.is_owned(shared=1))
289 ee2b99e3 Michael Hanselmann
    self.assert_(self.sl.is_owned(shared=0))
290 162c1c1f Guido Trotter
    self.sl.release()
291 ee2b99e3 Michael Hanselmann
    self.assertFalse(self.sl.is_owned())
292 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
293 ee2b99e3 Michael Hanselmann
    self.assert_(self.sl.is_owned())
294 ee2b99e3 Michael Hanselmann
    self.assert_(self.sl.is_owned(shared=1))
295 ee2b99e3 Michael Hanselmann
    self.assertFalse(self.sl.is_owned(shared=0))
296 162c1c1f Guido Trotter
    self.sl.release()
297 ee2b99e3 Michael Hanselmann
    self.assertFalse(self.sl.is_owned())
298 162c1c1f Guido Trotter
299 162c1c1f Guido Trotter
  def testBooleanValue(self):
300 162c1c1f Guido Trotter
    # semaphores are supposed to return a true value on a successful acquire
301 162c1c1f Guido Trotter
    self.assert_(self.sl.acquire(shared=1))
302 162c1c1f Guido Trotter
    self.sl.release()
303 162c1c1f Guido Trotter
    self.assert_(self.sl.acquire())
304 162c1c1f Guido Trotter
    self.sl.release()
305 162c1c1f Guido Trotter
306 162c1c1f Guido Trotter
  def testDoubleLockingStoE(self):
307 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
308 162c1c1f Guido Trotter
    self.assertRaises(AssertionError, self.sl.acquire)
309 162c1c1f Guido Trotter
310 162c1c1f Guido Trotter
  def testDoubleLockingEtoS(self):
311 162c1c1f Guido Trotter
    self.sl.acquire()
312 162c1c1f Guido Trotter
    self.assertRaises(AssertionError, self.sl.acquire, shared=1)
313 162c1c1f Guido Trotter
314 162c1c1f Guido Trotter
  def testDoubleLockingStoS(self):
315 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
316 162c1c1f Guido Trotter
    self.assertRaises(AssertionError, self.sl.acquire, shared=1)
317 162c1c1f Guido Trotter
318 162c1c1f Guido Trotter
  def testDoubleLockingEtoE(self):
319 162c1c1f Guido Trotter
    self.sl.acquire()
320 162c1c1f Guido Trotter
    self.assertRaises(AssertionError, self.sl.acquire)
321 162c1c1f Guido Trotter
322 162c1c1f Guido Trotter
  # helper functions: called in a separate thread they acquire the lock, send
323 162c1c1f Guido Trotter
  # their identifier on the done queue, then release it.
324 162c1c1f Guido Trotter
  def _doItSharer(self):
325 a95fd5d7 Guido Trotter
    try:
326 a95fd5d7 Guido Trotter
      self.sl.acquire(shared=1)
327 8c114acd Michael Hanselmann
      self.done.put("SHR")
328 a95fd5d7 Guido Trotter
      self.sl.release()
329 a95fd5d7 Guido Trotter
    except errors.LockError:
330 8c114acd Michael Hanselmann
      self.done.put("ERR")
331 162c1c1f Guido Trotter
332 162c1c1f Guido Trotter
  def _doItExclusive(self):
333 a95fd5d7 Guido Trotter
    try:
334 a95fd5d7 Guido Trotter
      self.sl.acquire()
335 8c114acd Michael Hanselmann
      self.done.put("EXC")
336 a95fd5d7 Guido Trotter
      self.sl.release()
337 a95fd5d7 Guido Trotter
    except errors.LockError:
338 8c114acd Michael Hanselmann
      self.done.put("ERR")
339 a95fd5d7 Guido Trotter
340 a95fd5d7 Guido Trotter
  def _doItDelete(self):
341 a95fd5d7 Guido Trotter
    try:
342 4354ab03 Guido Trotter
      self.sl.delete()
343 8c114acd Michael Hanselmann
      self.done.put("DEL")
344 a95fd5d7 Guido Trotter
    except errors.LockError:
345 8c114acd Michael Hanselmann
      self.done.put("ERR")
346 162c1c1f Guido Trotter
347 162c1c1f Guido Trotter
  def testSharersCanCoexist(self):
348 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
349 84e344d4 Michael Hanselmann
    threading.Thread(target=self._doItSharer).start()
350 162c1c1f Guido Trotter
    self.assert_(self.done.get(True, 1))
351 162c1c1f Guido Trotter
    self.sl.release()
352 162c1c1f Guido Trotter
353 4607c978 Iustin Pop
  @_Repeat
354 162c1c1f Guido Trotter
  def testExclusiveBlocksExclusive(self):
355 162c1c1f Guido Trotter
    self.sl.acquire()
356 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
357 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
358 162c1c1f Guido Trotter
    self.sl.release()
359 4607c978 Iustin Pop
    self._waitThreads()
360 8c114acd Michael Hanselmann
    self.failUnlessEqual(self.done.get_nowait(), "EXC")
361 162c1c1f Guido Trotter
362 4607c978 Iustin Pop
  @_Repeat
363 a95fd5d7 Guido Trotter
  def testExclusiveBlocksDelete(self):
364 a95fd5d7 Guido Trotter
    self.sl.acquire()
365 4607c978 Iustin Pop
    self._addThread(target=self._doItDelete)
366 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
367 a95fd5d7 Guido Trotter
    self.sl.release()
368 4607c978 Iustin Pop
    self._waitThreads()
369 8c114acd Michael Hanselmann
    self.failUnlessEqual(self.done.get_nowait(), "DEL")
370 7f93570a Iustin Pop
    self.sl = locking.SharedLock(self.sl.name)
371 a95fd5d7 Guido Trotter
372 4607c978 Iustin Pop
  @_Repeat
373 162c1c1f Guido Trotter
  def testExclusiveBlocksSharer(self):
374 162c1c1f Guido Trotter
    self.sl.acquire()
375 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
376 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
377 162c1c1f Guido Trotter
    self.sl.release()
378 4607c978 Iustin Pop
    self._waitThreads()
379 8c114acd Michael Hanselmann
    self.failUnlessEqual(self.done.get_nowait(), "SHR")
380 162c1c1f Guido Trotter
381 4607c978 Iustin Pop
  @_Repeat
382 162c1c1f Guido Trotter
  def testSharerBlocksExclusive(self):
383 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
384 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
385 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
386 162c1c1f Guido Trotter
    self.sl.release()
387 4607c978 Iustin Pop
    self._waitThreads()
388 8c114acd Michael Hanselmann
    self.failUnlessEqual(self.done.get_nowait(), "EXC")
389 162c1c1f Guido Trotter
390 4607c978 Iustin Pop
  @_Repeat
391 a95fd5d7 Guido Trotter
  def testSharerBlocksDelete(self):
392 a95fd5d7 Guido Trotter
    self.sl.acquire(shared=1)
393 4607c978 Iustin Pop
    self._addThread(target=self._doItDelete)
394 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
395 a95fd5d7 Guido Trotter
    self.sl.release()
396 4607c978 Iustin Pop
    self._waitThreads()
397 8c114acd Michael Hanselmann
    self.failUnlessEqual(self.done.get_nowait(), "DEL")
398 7f93570a Iustin Pop
    self.sl = locking.SharedLock(self.sl.name)
399 a95fd5d7 Guido Trotter
400 4607c978 Iustin Pop
  @_Repeat
401 162c1c1f Guido Trotter
  def testWaitingExclusiveBlocksSharer(self):
402 e6416152 Iustin Pop
    """SKIPPED testWaitingExclusiveBlockSharer"""
403 e6416152 Iustin Pop
    return
404 e6416152 Iustin Pop
405 162c1c1f Guido Trotter
    self.sl.acquire(shared=1)
406 162c1c1f Guido Trotter
    # the lock is acquired in shared mode...
407 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
408 162c1c1f Guido Trotter
    # ...but now an exclusive is waiting...
409 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
410 162c1c1f Guido Trotter
    # ...so the sharer should be blocked as well
411 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
412 162c1c1f Guido Trotter
    self.sl.release()
413 4607c978 Iustin Pop
    self._waitThreads()
414 162c1c1f Guido Trotter
    # The exclusive passed before
415 8c114acd Michael Hanselmann
    self.failUnlessEqual(self.done.get_nowait(), "EXC")
416 8c114acd Michael Hanselmann
    self.failUnlessEqual(self.done.get_nowait(), "SHR")
417 162c1c1f Guido Trotter
418 4607c978 Iustin Pop
  @_Repeat
419 162c1c1f Guido Trotter
  def testWaitingSharerBlocksExclusive(self):
420 a143be68 Iustin Pop
    """SKIPPED testWaitingSharerBlocksExclusive"""
421 a143be68 Iustin Pop
    return
422 a143be68 Iustin Pop
423 162c1c1f Guido Trotter
    self.sl.acquire()
424 162c1c1f Guido Trotter
    # the lock is acquired in exclusive mode...
425 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
426 162c1c1f Guido Trotter
    # ...but now a sharer is waiting...
427 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
428 162c1c1f Guido Trotter
    # ...the exclusive is waiting too...
429 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
430 162c1c1f Guido Trotter
    self.sl.release()
431 4607c978 Iustin Pop
    self._waitThreads()
432 162c1c1f Guido Trotter
    # The sharer passed before
433 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "SHR")
434 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "EXC")
435 162c1c1f Guido Trotter
436 a95fd5d7 Guido Trotter
  def testDelete(self):
437 a95fd5d7 Guido Trotter
    self.sl.delete()
438 a95fd5d7 Guido Trotter
    self.assertRaises(errors.LockError, self.sl.acquire)
439 84152b96 Guido Trotter
    self.assertRaises(errors.LockError, self.sl.acquire, shared=1)
440 a95fd5d7 Guido Trotter
    self.assertRaises(errors.LockError, self.sl.delete)
441 a95fd5d7 Guido Trotter
442 a66bd91b Michael Hanselmann
  def testDeleteTimeout(self):
443 26082b7e Michael Hanselmann
    self.assertTrue(self.sl.delete(timeout=60))
444 26082b7e Michael Hanselmann
445 26082b7e Michael Hanselmann
  def testDeleteTimeoutFail(self):
446 26082b7e Michael Hanselmann
    ready = threading.Event()
447 26082b7e Michael Hanselmann
    finish = threading.Event()
448 26082b7e Michael Hanselmann
449 26082b7e Michael Hanselmann
    def fn():
450 26082b7e Michael Hanselmann
      self.sl.acquire(shared=0)
451 26082b7e Michael Hanselmann
      ready.set()
452 26082b7e Michael Hanselmann
453 26082b7e Michael Hanselmann
      finish.wait()
454 26082b7e Michael Hanselmann
      self.sl.release()
455 26082b7e Michael Hanselmann
456 26082b7e Michael Hanselmann
    self._addThread(target=fn)
457 26082b7e Michael Hanselmann
    ready.wait()
458 26082b7e Michael Hanselmann
459 26082b7e Michael Hanselmann
    # Test if deleting a lock owned in exclusive mode by another thread fails
460 26082b7e Michael Hanselmann
    # to delete when a timeout is used
461 26082b7e Michael Hanselmann
    self.assertFalse(self.sl.delete(timeout=0.02))
462 26082b7e Michael Hanselmann
463 26082b7e Michael Hanselmann
    finish.set()
464 26082b7e Michael Hanselmann
    self._waitThreads()
465 26082b7e Michael Hanselmann
466 26082b7e Michael Hanselmann
    self.assertTrue(self.sl.delete())
467 26082b7e Michael Hanselmann
    self.assertRaises(errors.LockError, self.sl.acquire)
468 a66bd91b Michael Hanselmann
469 84152b96 Guido Trotter
  def testNoDeleteIfSharer(self):
470 84152b96 Guido Trotter
    self.sl.acquire(shared=1)
471 84152b96 Guido Trotter
    self.assertRaises(AssertionError, self.sl.delete)
472 84152b96 Guido Trotter
473 4607c978 Iustin Pop
  @_Repeat
474 a95fd5d7 Guido Trotter
  def testDeletePendingSharersExclusiveDelete(self):
475 a95fd5d7 Guido Trotter
    self.sl.acquire()
476 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
477 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
478 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
479 4607c978 Iustin Pop
    self._addThread(target=self._doItDelete)
480 a95fd5d7 Guido Trotter
    self.sl.delete()
481 4607c978 Iustin Pop
    self._waitThreads()
482 4607c978 Iustin Pop
    # The threads who were pending return ERR
483 4607c978 Iustin Pop
    for _ in range(4):
484 8c114acd Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "ERR")
485 7f93570a Iustin Pop
    self.sl = locking.SharedLock(self.sl.name)
486 a95fd5d7 Guido Trotter
487 4607c978 Iustin Pop
  @_Repeat
488 a95fd5d7 Guido Trotter
  def testDeletePendingDeleteExclusiveSharers(self):
489 a95fd5d7 Guido Trotter
    self.sl.acquire()
490 4607c978 Iustin Pop
    self._addThread(target=self._doItDelete)
491 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
492 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
493 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
494 a95fd5d7 Guido Trotter
    self.sl.delete()
495 4607c978 Iustin Pop
    self._waitThreads()
496 a95fd5d7 Guido Trotter
    # The two threads who were pending return both ERR
497 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "ERR")
498 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "ERR")
499 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "ERR")
500 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "ERR")
501 7f93570a Iustin Pop
    self.sl = locking.SharedLock(self.sl.name)
502 a95fd5d7 Guido Trotter
503 84e344d4 Michael Hanselmann
  @_Repeat
504 84e344d4 Michael Hanselmann
  def testExclusiveAcquireTimeout(self):
505 84e344d4 Michael Hanselmann
    for shared in [0, 1]:
506 008b92fa Michael Hanselmann
      on_queue = threading.Event()
507 008b92fa Michael Hanselmann
      release_exclusive = threading.Event()
508 008b92fa Michael Hanselmann
509 008b92fa Michael Hanselmann
      def _LockExclusive():
510 008b92fa Michael Hanselmann
        self.sl.acquire(shared=0, test_notify=on_queue.set)
511 008b92fa Michael Hanselmann
        self.done.put("A: start wait")
512 008b92fa Michael Hanselmann
        release_exclusive.wait()
513 008b92fa Michael Hanselmann
        self.done.put("A: end wait")
514 008b92fa Michael Hanselmann
        self.sl.release()
515 008b92fa Michael Hanselmann
516 008b92fa Michael Hanselmann
      # Start thread to hold lock in exclusive mode
517 008b92fa Michael Hanselmann
      self._addThread(target=_LockExclusive)
518 84e344d4 Michael Hanselmann
519 008b92fa Michael Hanselmann
      # Wait for wait to begin
520 008b92fa Michael Hanselmann
      self.assertEqual(self.done.get(timeout=60), "A: start wait")
521 008b92fa Michael Hanselmann
522 008b92fa Michael Hanselmann
      # Wait up to 60s to get lock, but release exclusive lock as soon as we're
523 008b92fa Michael Hanselmann
      # on the queue
524 008b92fa Michael Hanselmann
      self.failUnless(self.sl.acquire(shared=shared, timeout=60,
525 008b92fa Michael Hanselmann
                                      test_notify=release_exclusive.set))
526 2042aa94 Michael Hanselmann
527 84e344d4 Michael Hanselmann
      self.done.put("got 2nd")
528 84e344d4 Michael Hanselmann
      self.sl.release()
529 84e344d4 Michael Hanselmann
530 84e344d4 Michael Hanselmann
      self._waitThreads()
531 84e344d4 Michael Hanselmann
532 008b92fa Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "A: end wait")
533 84e344d4 Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "got 2nd")
534 84e344d4 Michael Hanselmann
      self.assertRaises(Queue.Empty, self.done.get_nowait)
535 84e344d4 Michael Hanselmann
536 84e344d4 Michael Hanselmann
  @_Repeat
537 84e344d4 Michael Hanselmann
  def testAcquireExpiringTimeout(self):
538 84e344d4 Michael Hanselmann
    def _AcquireWithTimeout(shared, timeout):
539 84e344d4 Michael Hanselmann
      if not self.sl.acquire(shared=shared, timeout=timeout):
540 84e344d4 Michael Hanselmann
        self.done.put("timeout")
541 84e344d4 Michael Hanselmann
542 84e344d4 Michael Hanselmann
    for shared in [0, 1]:
543 84e344d4 Michael Hanselmann
      # Lock exclusively
544 84e344d4 Michael Hanselmann
      self.sl.acquire()
545 84e344d4 Michael Hanselmann
546 84e344d4 Michael Hanselmann
      # Start shared acquires with timeout between 0 and 20 ms
547 f1501b3f Michael Hanselmann
      for i in range(11):
548 84e344d4 Michael Hanselmann
        self._addThread(target=_AcquireWithTimeout,
549 84e344d4 Michael Hanselmann
                        args=(shared, i * 2.0 / 1000.0))
550 84e344d4 Michael Hanselmann
551 84e344d4 Michael Hanselmann
      # Wait for threads to finish (makes sure the acquire timeout expires
552 84e344d4 Michael Hanselmann
      # before releasing the lock)
553 84e344d4 Michael Hanselmann
      self._waitThreads()
554 84e344d4 Michael Hanselmann
555 84e344d4 Michael Hanselmann
      # Release lock
556 84e344d4 Michael Hanselmann
      self.sl.release()
557 84e344d4 Michael Hanselmann
558 f1501b3f Michael Hanselmann
      for _ in range(11):
559 84e344d4 Michael Hanselmann
        self.assertEqual(self.done.get_nowait(), "timeout")
560 84e344d4 Michael Hanselmann
561 84e344d4 Michael Hanselmann
      self.assertRaises(Queue.Empty, self.done.get_nowait)
562 84e344d4 Michael Hanselmann
563 84e344d4 Michael Hanselmann
  @_Repeat
564 84e344d4 Michael Hanselmann
  def testSharedSkipExclusiveAcquires(self):
565 84e344d4 Michael Hanselmann
    # Tests whether shared acquires jump in front of exclusive acquires in the
566 84e344d4 Michael Hanselmann
    # queue.
567 84e344d4 Michael Hanselmann
568 008b92fa Michael Hanselmann
    def _Acquire(shared, name, notify_ev, wait_ev):
569 008b92fa Michael Hanselmann
      if notify_ev:
570 008b92fa Michael Hanselmann
        notify_fn = notify_ev.set
571 008b92fa Michael Hanselmann
      else:
572 008b92fa Michael Hanselmann
        notify_fn = None
573 84e344d4 Michael Hanselmann
574 008b92fa Michael Hanselmann
      if wait_ev:
575 008b92fa Michael Hanselmann
        wait_ev.wait()
576 008b92fa Michael Hanselmann
577 008b92fa Michael Hanselmann
      if not self.sl.acquire(shared=shared, test_notify=notify_fn):
578 84e344d4 Michael Hanselmann
        return
579 84e344d4 Michael Hanselmann
580 84e344d4 Michael Hanselmann
      self.done.put(name)
581 84e344d4 Michael Hanselmann
      self.sl.release()
582 84e344d4 Michael Hanselmann
583 008b92fa Michael Hanselmann
    # Get exclusive lock while we fill the queue
584 008b92fa Michael Hanselmann
    self.sl.acquire()
585 84e344d4 Michael Hanselmann
586 008b92fa Michael Hanselmann
    shrcnt1 = 5
587 008b92fa Michael Hanselmann
    shrcnt2 = 7
588 008b92fa Michael Hanselmann
    shrcnt3 = 9
589 008b92fa Michael Hanselmann
    shrcnt4 = 2
590 84e344d4 Michael Hanselmann
591 008b92fa Michael Hanselmann
    # Add acquires using threading.Event for synchronization. They'll be
592 008b92fa Michael Hanselmann
    # acquired exactly in the order defined in this list.
593 008b92fa Michael Hanselmann
    acquires = (shrcnt1 * [(1, "shared 1")] +
594 008b92fa Michael Hanselmann
                3 * [(0, "exclusive 1")] +
595 008b92fa Michael Hanselmann
                shrcnt2 * [(1, "shared 2")] +
596 008b92fa Michael Hanselmann
                shrcnt3 * [(1, "shared 3")] +
597 008b92fa Michael Hanselmann
                shrcnt4 * [(1, "shared 4")] +
598 008b92fa Michael Hanselmann
                3 * [(0, "exclusive 2")])
599 84e344d4 Michael Hanselmann
600 008b92fa Michael Hanselmann
    ev_cur = None
601 008b92fa Michael Hanselmann
    ev_prev = None
602 008b92fa Michael Hanselmann
603 008b92fa Michael Hanselmann
    for args in acquires:
604 008b92fa Michael Hanselmann
      ev_cur = threading.Event()
605 008b92fa Michael Hanselmann
      self._addThread(target=_Acquire, args=args + (ev_cur, ev_prev))
606 008b92fa Michael Hanselmann
      ev_prev = ev_cur
607 008b92fa Michael Hanselmann
608 008b92fa Michael Hanselmann
    # Wait for last acquire to start
609 008b92fa Michael Hanselmann
    ev_prev.wait()
610 84e344d4 Michael Hanselmann
611 84e344d4 Michael Hanselmann
    # Expect 6 pending exclusive acquires and 1 for all shared acquires
612 008b92fa Michael Hanselmann
    # together
613 008b92fa Michael Hanselmann
    self.assertEqual(self.sl._count_pending(), 7)
614 84e344d4 Michael Hanselmann
615 84e344d4 Michael Hanselmann
    # Release exclusive lock and wait
616 84e344d4 Michael Hanselmann
    self.sl.release()
617 84e344d4 Michael Hanselmann
618 84e344d4 Michael Hanselmann
    self._waitThreads()
619 84e344d4 Michael Hanselmann
620 84e344d4 Michael Hanselmann
    # Check sequence
621 008b92fa Michael Hanselmann
    for _ in range(shrcnt1 + shrcnt2 + shrcnt3 + shrcnt4):
622 84e344d4 Michael Hanselmann
      # Shared locks aren't guaranteed to be notified in order, but they'll be
623 84e344d4 Michael Hanselmann
      # first
624 2042aa94 Michael Hanselmann
      tmp = self.done.get_nowait()
625 008b92fa Michael Hanselmann
      if tmp == "shared 1":
626 008b92fa Michael Hanselmann
        shrcnt1 -= 1
627 008b92fa Michael Hanselmann
      elif tmp == "shared 2":
628 008b92fa Michael Hanselmann
        shrcnt2 -= 1
629 008b92fa Michael Hanselmann
      elif tmp == "shared 3":
630 008b92fa Michael Hanselmann
        shrcnt3 -= 1
631 008b92fa Michael Hanselmann
      elif tmp == "shared 4":
632 008b92fa Michael Hanselmann
        shrcnt4 -= 1
633 008b92fa Michael Hanselmann
    self.assertEqual(shrcnt1, 0)
634 008b92fa Michael Hanselmann
    self.assertEqual(shrcnt2, 0)
635 008b92fa Michael Hanselmann
    self.assertEqual(shrcnt3, 0)
636 008b92fa Michael Hanselmann
    self.assertEqual(shrcnt3, 0)
637 84e344d4 Michael Hanselmann
638 f1501b3f Michael Hanselmann
    for _ in range(3):
639 008b92fa Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "exclusive 1")
640 84e344d4 Michael Hanselmann
641 f1501b3f Michael Hanselmann
    for _ in range(3):
642 008b92fa Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "exclusive 2")
643 84e344d4 Michael Hanselmann
644 84e344d4 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
645 84e344d4 Michael Hanselmann
646 3dbe3ddf Michael Hanselmann
  def testIllegalDowngrade(self):
647 3dbe3ddf Michael Hanselmann
    # Not yet acquired
648 3dbe3ddf Michael Hanselmann
    self.assertRaises(AssertionError, self.sl.downgrade)
649 3dbe3ddf Michael Hanselmann
650 3dbe3ddf Michael Hanselmann
    # Acquire in shared mode, downgrade should be no-op
651 3dbe3ddf Michael Hanselmann
    self.assertTrue(self.sl.acquire(shared=1))
652 ee2b99e3 Michael Hanselmann
    self.assertTrue(self.sl.is_owned(shared=1))
653 3dbe3ddf Michael Hanselmann
    self.assertTrue(self.sl.downgrade())
654 ee2b99e3 Michael Hanselmann
    self.assertTrue(self.sl.is_owned(shared=1))
655 3dbe3ddf Michael Hanselmann
    self.sl.release()
656 3dbe3ddf Michael Hanselmann
657 3dbe3ddf Michael Hanselmann
  def testDowngrade(self):
658 3dbe3ddf Michael Hanselmann
    self.assertTrue(self.sl.acquire())
659 ee2b99e3 Michael Hanselmann
    self.assertTrue(self.sl.is_owned(shared=0))
660 3dbe3ddf Michael Hanselmann
    self.assertTrue(self.sl.downgrade())
661 ee2b99e3 Michael Hanselmann
    self.assertTrue(self.sl.is_owned(shared=1))
662 3dbe3ddf Michael Hanselmann
    self.sl.release()
663 3dbe3ddf Michael Hanselmann
664 3dbe3ddf Michael Hanselmann
  @_Repeat
665 3dbe3ddf Michael Hanselmann
  def testDowngradeJumpsAheadOfExclusive(self):
666 3dbe3ddf Michael Hanselmann
    def _KeepExclusive(ev_got, ev_downgrade, ev_release):
667 3dbe3ddf Michael Hanselmann
      self.assertTrue(self.sl.acquire())
668 ee2b99e3 Michael Hanselmann
      self.assertTrue(self.sl.is_owned(shared=0))
669 3dbe3ddf Michael Hanselmann
      ev_got.set()
670 3dbe3ddf Michael Hanselmann
      ev_downgrade.wait()
671 ee2b99e3 Michael Hanselmann
      self.assertTrue(self.sl.is_owned(shared=0))
672 3dbe3ddf Michael Hanselmann
      self.assertTrue(self.sl.downgrade())
673 ee2b99e3 Michael Hanselmann
      self.assertTrue(self.sl.is_owned(shared=1))
674 3dbe3ddf Michael Hanselmann
      ev_release.wait()
675 ee2b99e3 Michael Hanselmann
      self.assertTrue(self.sl.is_owned(shared=1))
676 3dbe3ddf Michael Hanselmann
      self.sl.release()
677 3dbe3ddf Michael Hanselmann
678 3dbe3ddf Michael Hanselmann
    def _KeepExclusive2(ev_started, ev_release):
679 3dbe3ddf Michael Hanselmann
      self.assertTrue(self.sl.acquire(test_notify=ev_started.set))
680 ee2b99e3 Michael Hanselmann
      self.assertTrue(self.sl.is_owned(shared=0))
681 3dbe3ddf Michael Hanselmann
      ev_release.wait()
682 ee2b99e3 Michael Hanselmann
      self.assertTrue(self.sl.is_owned(shared=0))
683 3dbe3ddf Michael Hanselmann
      self.sl.release()
684 3dbe3ddf Michael Hanselmann
685 3dbe3ddf Michael Hanselmann
    def _KeepShared(ev_started, ev_got, ev_release):
686 3dbe3ddf Michael Hanselmann
      self.assertTrue(self.sl.acquire(shared=1, test_notify=ev_started.set))
687 ee2b99e3 Michael Hanselmann
      self.assertTrue(self.sl.is_owned(shared=1))
688 3dbe3ddf Michael Hanselmann
      ev_got.set()
689 3dbe3ddf Michael Hanselmann
      ev_release.wait()
690 ee2b99e3 Michael Hanselmann
      self.assertTrue(self.sl.is_owned(shared=1))
691 3dbe3ddf Michael Hanselmann
      self.sl.release()
692 3dbe3ddf Michael Hanselmann
693 3dbe3ddf Michael Hanselmann
    # Acquire lock in exclusive mode
694 3dbe3ddf Michael Hanselmann
    ev_got_excl1 = threading.Event()
695 3dbe3ddf Michael Hanselmann
    ev_downgrade_excl1 = threading.Event()
696 3dbe3ddf Michael Hanselmann
    ev_release_excl1 = threading.Event()
697 3dbe3ddf Michael Hanselmann
    th_excl1 = self._addThread(target=_KeepExclusive,
698 3dbe3ddf Michael Hanselmann
                               args=(ev_got_excl1, ev_downgrade_excl1,
699 3dbe3ddf Michael Hanselmann
                                     ev_release_excl1))
700 3dbe3ddf Michael Hanselmann
    ev_got_excl1.wait()
701 3dbe3ddf Michael Hanselmann
702 3dbe3ddf Michael Hanselmann
    # Start a second exclusive acquire
703 3dbe3ddf Michael Hanselmann
    ev_started_excl2 = threading.Event()
704 3dbe3ddf Michael Hanselmann
    ev_release_excl2 = threading.Event()
705 3dbe3ddf Michael Hanselmann
    th_excl2 = self._addThread(target=_KeepExclusive2,
706 3dbe3ddf Michael Hanselmann
                               args=(ev_started_excl2, ev_release_excl2))
707 3dbe3ddf Michael Hanselmann
    ev_started_excl2.wait()
708 3dbe3ddf Michael Hanselmann
709 3dbe3ddf Michael Hanselmann
    # Start shared acquires, will jump ahead of second exclusive acquire when
710 3dbe3ddf Michael Hanselmann
    # first exclusive acquire downgrades
711 3dbe3ddf Michael Hanselmann
    ev_shared = [(threading.Event(), threading.Event()) for _ in range(5)]
712 3dbe3ddf Michael Hanselmann
    ev_release_shared = threading.Event()
713 3dbe3ddf Michael Hanselmann
714 3dbe3ddf Michael Hanselmann
    th_shared = [self._addThread(target=_KeepShared,
715 3dbe3ddf Michael Hanselmann
                                 args=(ev_started, ev_got, ev_release_shared))
716 3dbe3ddf Michael Hanselmann
                 for (ev_started, ev_got) in ev_shared]
717 3dbe3ddf Michael Hanselmann
718 3dbe3ddf Michael Hanselmann
    # Wait for all shared acquires to start
719 3dbe3ddf Michael Hanselmann
    for (ev, _) in ev_shared:
720 3dbe3ddf Michael Hanselmann
      ev.wait()
721 3dbe3ddf Michael Hanselmann
722 3dbe3ddf Michael Hanselmann
    # Check lock information
723 44b4eddc Michael Hanselmann
    self.assertEqual(self.sl.GetLockInfo(set([query.LQ_MODE, query.LQ_OWNER])),
724 44b4eddc Michael Hanselmann
                     [(self.sl.name, "exclusive", [th_excl1.getName()], None)])
725 44b4eddc Michael Hanselmann
    [(_, _, _, pending), ] = self.sl.GetLockInfo(set([query.LQ_PENDING]))
726 3dbe3ddf Michael Hanselmann
    self.assertEqual([(pendmode, sorted(waiting))
727 3dbe3ddf Michael Hanselmann
                      for (pendmode, waiting) in pending],
728 3dbe3ddf Michael Hanselmann
                     [("exclusive", [th_excl2.getName()]),
729 3dbe3ddf Michael Hanselmann
                      ("shared", sorted(th.getName() for th in th_shared))])
730 3dbe3ddf Michael Hanselmann
731 3dbe3ddf Michael Hanselmann
    # Shared acquires won't start until the exclusive lock is downgraded
732 3dbe3ddf Michael Hanselmann
    ev_downgrade_excl1.set()
733 3dbe3ddf Michael Hanselmann
734 3dbe3ddf Michael Hanselmann
    # Wait for all shared acquires to be successful
735 3dbe3ddf Michael Hanselmann
    for (_, ev) in ev_shared:
736 3dbe3ddf Michael Hanselmann
      ev.wait()
737 3dbe3ddf Michael Hanselmann
738 3dbe3ddf Michael Hanselmann
    # Check lock information again
739 44b4eddc Michael Hanselmann
    self.assertEqual(self.sl.GetLockInfo(set([query.LQ_MODE,
740 44b4eddc Michael Hanselmann
                                              query.LQ_PENDING])),
741 44b4eddc Michael Hanselmann
                     [(self.sl.name, "shared", None,
742 44b4eddc Michael Hanselmann
                       [("exclusive", [th_excl2.getName()])])])
743 44b4eddc Michael Hanselmann
    [(_, _, owner, _), ] = self.sl.GetLockInfo(set([query.LQ_OWNER]))
744 3dbe3ddf Michael Hanselmann
    self.assertEqual(set(owner), set([th_excl1.getName()] +
745 3dbe3ddf Michael Hanselmann
                                     [th.getName() for th in th_shared]))
746 3dbe3ddf Michael Hanselmann
747 3dbe3ddf Michael Hanselmann
    ev_release_excl1.set()
748 3dbe3ddf Michael Hanselmann
    ev_release_excl2.set()
749 3dbe3ddf Michael Hanselmann
    ev_release_shared.set()
750 3dbe3ddf Michael Hanselmann
751 3dbe3ddf Michael Hanselmann
    self._waitThreads()
752 3dbe3ddf Michael Hanselmann
753 44b4eddc Michael Hanselmann
    self.assertEqual(self.sl.GetLockInfo(set([query.LQ_MODE, query.LQ_OWNER,
754 44b4eddc Michael Hanselmann
                                              query.LQ_PENDING])),
755 44b4eddc Michael Hanselmann
                     [(self.sl.name, None, None, [])])
756 3dbe3ddf Michael Hanselmann
757 84e344d4 Michael Hanselmann
  @_Repeat
758 84e344d4 Michael Hanselmann
  def testMixedAcquireTimeout(self):
759 51e3bb92 Michael Hanselmann
    sync = threading.Event()
760 84e344d4 Michael Hanselmann
761 84e344d4 Michael Hanselmann
    def _AcquireShared(ev):
762 84e344d4 Michael Hanselmann
      if not self.sl.acquire(shared=1, timeout=None):
763 84e344d4 Michael Hanselmann
        return
764 84e344d4 Michael Hanselmann
765 84e344d4 Michael Hanselmann
      self.done.put("shared")
766 84e344d4 Michael Hanselmann
767 84e344d4 Michael Hanselmann
      # Notify main thread
768 84e344d4 Michael Hanselmann
      ev.set()
769 84e344d4 Michael Hanselmann
770 51e3bb92 Michael Hanselmann
      # Wait for notification from main thread
771 51e3bb92 Michael Hanselmann
      sync.wait()
772 84e344d4 Michael Hanselmann
773 84e344d4 Michael Hanselmann
      # Release lock
774 84e344d4 Michael Hanselmann
      self.sl.release()
775 84e344d4 Michael Hanselmann
776 84e344d4 Michael Hanselmann
    acquires = []
777 f1501b3f Michael Hanselmann
    for _ in range(3):
778 84e344d4 Michael Hanselmann
      ev = threading.Event()
779 84e344d4 Michael Hanselmann
      self._addThread(target=_AcquireShared, args=(ev, ))
780 84e344d4 Michael Hanselmann
      acquires.append(ev)
781 84e344d4 Michael Hanselmann
782 84e344d4 Michael Hanselmann
    # Wait for all acquires to finish
783 84e344d4 Michael Hanselmann
    for i in acquires:
784 84e344d4 Michael Hanselmann
      i.wait()
785 84e344d4 Michael Hanselmann
786 84e344d4 Michael Hanselmann
    self.assertEqual(self.sl._count_pending(), 0)
787 84e344d4 Michael Hanselmann
788 84e344d4 Michael Hanselmann
    # Try to get exclusive lock
789 84e344d4 Michael Hanselmann
    self.failIf(self.sl.acquire(shared=0, timeout=0.02))
790 84e344d4 Michael Hanselmann
791 84e344d4 Michael Hanselmann
    # Acquire exclusive without timeout
792 51e3bb92 Michael Hanselmann
    exclsync = threading.Event()
793 84e344d4 Michael Hanselmann
    exclev = threading.Event()
794 84e344d4 Michael Hanselmann
795 84e344d4 Michael Hanselmann
    def _AcquireExclusive():
796 84e344d4 Michael Hanselmann
      if not self.sl.acquire(shared=0):
797 84e344d4 Michael Hanselmann
        return
798 84e344d4 Michael Hanselmann
799 84e344d4 Michael Hanselmann
      self.done.put("exclusive")
800 84e344d4 Michael Hanselmann
801 84e344d4 Michael Hanselmann
      # Notify main thread
802 84e344d4 Michael Hanselmann
      exclev.set()
803 84e344d4 Michael Hanselmann
804 51e3bb92 Michael Hanselmann
      # Wait for notification from main thread
805 51e3bb92 Michael Hanselmann
      exclsync.wait()
806 84e344d4 Michael Hanselmann
807 84e344d4 Michael Hanselmann
      self.sl.release()
808 84e344d4 Michael Hanselmann
809 84e344d4 Michael Hanselmann
    self._addThread(target=_AcquireExclusive)
810 84e344d4 Michael Hanselmann
811 84e344d4 Michael Hanselmann
    # Try to get exclusive lock
812 84e344d4 Michael Hanselmann
    self.failIf(self.sl.acquire(shared=0, timeout=0.02))
813 84e344d4 Michael Hanselmann
814 84e344d4 Michael Hanselmann
    # Make all shared holders release their locks
815 51e3bb92 Michael Hanselmann
    sync.set()
816 84e344d4 Michael Hanselmann
817 84e344d4 Michael Hanselmann
    # Wait for exclusive acquire to succeed
818 84e344d4 Michael Hanselmann
    exclev.wait()
819 84e344d4 Michael Hanselmann
820 84e344d4 Michael Hanselmann
    self.assertEqual(self.sl._count_pending(), 0)
821 84e344d4 Michael Hanselmann
822 84e344d4 Michael Hanselmann
    # Try to get exclusive lock
823 84e344d4 Michael Hanselmann
    self.failIf(self.sl.acquire(shared=0, timeout=0.02))
824 84e344d4 Michael Hanselmann
825 84e344d4 Michael Hanselmann
    def _AcquireSharedSimple():
826 84e344d4 Michael Hanselmann
      if self.sl.acquire(shared=1, timeout=None):
827 84e344d4 Michael Hanselmann
        self.done.put("shared2")
828 84e344d4 Michael Hanselmann
        self.sl.release()
829 84e344d4 Michael Hanselmann
830 f1501b3f Michael Hanselmann
    for _ in range(10):
831 84e344d4 Michael Hanselmann
      self._addThread(target=_AcquireSharedSimple)
832 84e344d4 Michael Hanselmann
833 84e344d4 Michael Hanselmann
    # Tell exclusive lock to release
834 51e3bb92 Michael Hanselmann
    exclsync.set()
835 84e344d4 Michael Hanselmann
836 84e344d4 Michael Hanselmann
    # Wait for everything to finish
837 84e344d4 Michael Hanselmann
    self._waitThreads()
838 84e344d4 Michael Hanselmann
839 84e344d4 Michael Hanselmann
    self.assertEqual(self.sl._count_pending(), 0)
840 84e344d4 Michael Hanselmann
841 84e344d4 Michael Hanselmann
    # Check sequence
842 f1501b3f Michael Hanselmann
    for _ in range(3):
843 84e344d4 Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "shared")
844 84e344d4 Michael Hanselmann
845 84e344d4 Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "exclusive")
846 84e344d4 Michael Hanselmann
847 f1501b3f Michael Hanselmann
    for _ in range(10):
848 84e344d4 Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "shared2")
849 84e344d4 Michael Hanselmann
850 84e344d4 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
851 84e344d4 Michael Hanselmann
852 887c7aa6 Michael Hanselmann
  def testPriority(self):
853 887c7aa6 Michael Hanselmann
    # Acquire in exclusive mode
854 887c7aa6 Michael Hanselmann
    self.assert_(self.sl.acquire(shared=0))
855 887c7aa6 Michael Hanselmann
856 887c7aa6 Michael Hanselmann
    # Queue acquires
857 887c7aa6 Michael Hanselmann
    def _Acquire(prev, next, shared, priority, result):
858 887c7aa6 Michael Hanselmann
      prev.wait()
859 887c7aa6 Michael Hanselmann
      self.sl.acquire(shared=shared, priority=priority, test_notify=next.set)
860 887c7aa6 Michael Hanselmann
      try:
861 887c7aa6 Michael Hanselmann
        self.done.put(result)
862 887c7aa6 Michael Hanselmann
      finally:
863 887c7aa6 Michael Hanselmann
        self.sl.release()
864 887c7aa6 Michael Hanselmann
865 887c7aa6 Michael Hanselmann
    counter = itertools.count(0)
866 887c7aa6 Michael Hanselmann
    priorities = range(-20, 30)
867 887c7aa6 Michael Hanselmann
    first = threading.Event()
868 887c7aa6 Michael Hanselmann
    prev = first
869 887c7aa6 Michael Hanselmann
870 887c7aa6 Michael Hanselmann
    # Data structure:
871 887c7aa6 Michael Hanselmann
    # {
872 887c7aa6 Michael Hanselmann
    #   priority:
873 887c7aa6 Michael Hanselmann
    #     [(shared/exclusive, set(acquire names), set(pending threads)),
874 887c7aa6 Michael Hanselmann
    #      (shared/exclusive, ...),
875 887c7aa6 Michael Hanselmann
    #      ...,
876 887c7aa6 Michael Hanselmann
    #     ],
877 887c7aa6 Michael Hanselmann
    # }
878 887c7aa6 Michael Hanselmann
    perprio = {}
879 887c7aa6 Michael Hanselmann
880 887c7aa6 Michael Hanselmann
    # References shared acquire per priority in L{perprio}. Data structure:
881 887c7aa6 Michael Hanselmann
    # {
882 887c7aa6 Michael Hanselmann
    #   priority: (shared=1, set(acquire names), set(pending threads)),
883 887c7aa6 Michael Hanselmann
    # }
884 887c7aa6 Michael Hanselmann
    prioshared = {}
885 887c7aa6 Michael Hanselmann
886 887c7aa6 Michael Hanselmann
    for seed in [4979, 9523, 14902, 32440]:
887 887c7aa6 Michael Hanselmann
      # Use a deterministic random generator
888 887c7aa6 Michael Hanselmann
      rnd = random.Random(seed)
889 887c7aa6 Michael Hanselmann
      for priority in [rnd.choice(priorities) for _ in range(30)]:
890 887c7aa6 Michael Hanselmann
        modes = [0, 1]
891 887c7aa6 Michael Hanselmann
        rnd.shuffle(modes)
892 887c7aa6 Michael Hanselmann
        for shared in modes:
893 887c7aa6 Michael Hanselmann
          # Unique name
894 887c7aa6 Michael Hanselmann
          acqname = "%s/shr=%s/prio=%s" % (counter.next(), shared, priority)
895 887c7aa6 Michael Hanselmann
896 887c7aa6 Michael Hanselmann
          ev = threading.Event()
897 887c7aa6 Michael Hanselmann
          thread = self._addThread(target=_Acquire,
898 887c7aa6 Michael Hanselmann
                                   args=(prev, ev, shared, priority, acqname))
899 887c7aa6 Michael Hanselmann
          prev = ev
900 887c7aa6 Michael Hanselmann
901 887c7aa6 Michael Hanselmann
          # Record expected aqcuire, see above for structure
902 887c7aa6 Michael Hanselmann
          data = (shared, set([acqname]), set([thread]))
903 887c7aa6 Michael Hanselmann
          priolist = perprio.setdefault(priority, [])
904 887c7aa6 Michael Hanselmann
          if shared:
905 887c7aa6 Michael Hanselmann
            priosh = prioshared.get(priority, None)
906 887c7aa6 Michael Hanselmann
            if priosh:
907 887c7aa6 Michael Hanselmann
              # Shared acquires are merged
908 887c7aa6 Michael Hanselmann
              for i, j in zip(priosh[1:], data[1:]):
909 887c7aa6 Michael Hanselmann
                i.update(j)
910 887c7aa6 Michael Hanselmann
              assert data[0] == priosh[0]
911 887c7aa6 Michael Hanselmann
            else:
912 887c7aa6 Michael Hanselmann
              prioshared[priority] = data
913 887c7aa6 Michael Hanselmann
              priolist.append(data)
914 887c7aa6 Michael Hanselmann
          else:
915 887c7aa6 Michael Hanselmann
            priolist.append(data)
916 887c7aa6 Michael Hanselmann
917 887c7aa6 Michael Hanselmann
    # Start all acquires and wait for them
918 887c7aa6 Michael Hanselmann
    first.set()
919 887c7aa6 Michael Hanselmann
    prev.wait()
920 887c7aa6 Michael Hanselmann
921 887c7aa6 Michael Hanselmann
    # Check lock information
922 44b4eddc Michael Hanselmann
    self.assertEqual(self.sl.GetLockInfo(set()),
923 44b4eddc Michael Hanselmann
                     [(self.sl.name, None, None, None)])
924 44b4eddc Michael Hanselmann
    self.assertEqual(self.sl.GetLockInfo(set([query.LQ_MODE, query.LQ_OWNER])),
925 44b4eddc Michael Hanselmann
                     [(self.sl.name, "exclusive",
926 44b4eddc Michael Hanselmann
                       [threading.currentThread().getName()], None)])
927 24d16f76 Michael Hanselmann
928 44b4eddc Michael Hanselmann
    self._VerifyPrioPending(self.sl.GetLockInfo(set([query.LQ_PENDING])),
929 44b4eddc Michael Hanselmann
                            perprio)
930 887c7aa6 Michael Hanselmann
931 887c7aa6 Michael Hanselmann
    # Let threads acquire the lock
932 887c7aa6 Michael Hanselmann
    self.sl.release()
933 887c7aa6 Michael Hanselmann
934 887c7aa6 Michael Hanselmann
    # Wait for everything to finish
935 887c7aa6 Michael Hanselmann
    self._waitThreads()
936 887c7aa6 Michael Hanselmann
937 887c7aa6 Michael Hanselmann
    self.assert_(self.sl._check_empty())
938 887c7aa6 Michael Hanselmann
939 887c7aa6 Michael Hanselmann
    # Check acquires by priority
940 887c7aa6 Michael Hanselmann
    for acquires in [perprio[i] for i in sorted(perprio.keys())]:
941 887c7aa6 Michael Hanselmann
      for (_, names, _) in acquires:
942 887c7aa6 Michael Hanselmann
        # For shared acquires, the set will contain 1..n entries. For exclusive
943 887c7aa6 Michael Hanselmann
        # acquires only one.
944 887c7aa6 Michael Hanselmann
        while names:
945 887c7aa6 Michael Hanselmann
          names.remove(self.done.get_nowait())
946 887c7aa6 Michael Hanselmann
      self.assertFalse(compat.any(names for (_, names, _) in acquires))
947 887c7aa6 Michael Hanselmann
948 887c7aa6 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
949 887c7aa6 Michael Hanselmann
950 44b4eddc Michael Hanselmann
  def _VerifyPrioPending(self, ((name, mode, owner, pending), ), perprio):
951 24d16f76 Michael Hanselmann
    self.assertEqual(name, self.sl.name)
952 24d16f76 Michael Hanselmann
    self.assert_(mode is None)
953 24d16f76 Michael Hanselmann
    self.assert_(owner is None)
954 24d16f76 Michael Hanselmann
955 24d16f76 Michael Hanselmann
    self.assertEqual([(pendmode, sorted(waiting))
956 24d16f76 Michael Hanselmann
                      for (pendmode, waiting) in pending],
957 24d16f76 Michael Hanselmann
                     [(["exclusive", "shared"][int(bool(shared))],
958 24d16f76 Michael Hanselmann
                       sorted(t.getName() for t in threads))
959 24d16f76 Michael Hanselmann
                      for acquires in [perprio[i]
960 24d16f76 Michael Hanselmann
                                       for i in sorted(perprio.keys())]
961 24d16f76 Michael Hanselmann
                      for (shared, _, threads) in acquires])
962 24d16f76 Michael Hanselmann
963 8d7d8b57 Michael Hanselmann
  class _FakeTimeForSpuriousNotifications:
964 8d7d8b57 Michael Hanselmann
    def __init__(self, now, check_end):
965 8d7d8b57 Michael Hanselmann
      self.now = now
966 8d7d8b57 Michael Hanselmann
      self.check_end = check_end
967 8d7d8b57 Michael Hanselmann
968 8d7d8b57 Michael Hanselmann
      # Deterministic random number generator
969 8d7d8b57 Michael Hanselmann
      self.rnd = random.Random(15086)
970 8d7d8b57 Michael Hanselmann
971 8d7d8b57 Michael Hanselmann
    def time(self):
972 8d7d8b57 Michael Hanselmann
      # Advance time if the random number generator thinks so (this is to test
973 8d7d8b57 Michael Hanselmann
      # multiple notifications without advancing the time)
974 8d7d8b57 Michael Hanselmann
      if self.rnd.random() < 0.3:
975 8d7d8b57 Michael Hanselmann
        self.now += self.rnd.random()
976 8d7d8b57 Michael Hanselmann
977 8d7d8b57 Michael Hanselmann
      self.check_end(self.now)
978 8d7d8b57 Michael Hanselmann
979 8d7d8b57 Michael Hanselmann
      return self.now
980 8d7d8b57 Michael Hanselmann
981 8d7d8b57 Michael Hanselmann
  @_Repeat
982 8d7d8b57 Michael Hanselmann
  def testAcquireTimeoutWithSpuriousNotifications(self):
983 8d7d8b57 Michael Hanselmann
    ready = threading.Event()
984 8d7d8b57 Michael Hanselmann
    locked = threading.Event()
985 8d7d8b57 Michael Hanselmann
    req = Queue.Queue(0)
986 8d7d8b57 Michael Hanselmann
987 8d7d8b57 Michael Hanselmann
    epoch = 4000.0
988 8d7d8b57 Michael Hanselmann
    timeout = 60.0
989 8d7d8b57 Michael Hanselmann
990 8d7d8b57 Michael Hanselmann
    def check_end(now):
991 8d7d8b57 Michael Hanselmann
      self.assertFalse(locked.isSet())
992 8d7d8b57 Michael Hanselmann
993 8d7d8b57 Michael Hanselmann
      # If we waited long enough (in virtual time), tell main thread to release
994 8d7d8b57 Michael Hanselmann
      # lock, otherwise tell it to notify once more
995 8d7d8b57 Michael Hanselmann
      req.put(now < (epoch + (timeout * 0.8)))
996 8d7d8b57 Michael Hanselmann
997 8d7d8b57 Michael Hanselmann
    time_fn = self._FakeTimeForSpuriousNotifications(epoch, check_end).time
998 8d7d8b57 Michael Hanselmann
999 8d7d8b57 Michael Hanselmann
    sl = locking.SharedLock("test", _time_fn=time_fn)
1000 8d7d8b57 Michael Hanselmann
1001 8d7d8b57 Michael Hanselmann
    # Acquire in exclusive mode
1002 8d7d8b57 Michael Hanselmann
    sl.acquire(shared=0)
1003 8d7d8b57 Michael Hanselmann
1004 8d7d8b57 Michael Hanselmann
    def fn():
1005 8d7d8b57 Michael Hanselmann
      self.assertTrue(sl.acquire(shared=0, timeout=timeout,
1006 8d7d8b57 Michael Hanselmann
                                 test_notify=ready.set))
1007 8d7d8b57 Michael Hanselmann
      locked.set()
1008 8d7d8b57 Michael Hanselmann
      sl.release()
1009 8d7d8b57 Michael Hanselmann
      self.done.put("success")
1010 8d7d8b57 Michael Hanselmann
1011 8d7d8b57 Michael Hanselmann
    # Start acquire with timeout and wait for it to be ready
1012 8d7d8b57 Michael Hanselmann
    self._addThread(target=fn)
1013 8d7d8b57 Michael Hanselmann
    ready.wait()
1014 8d7d8b57 Michael Hanselmann
1015 8d7d8b57 Michael Hanselmann
    # The separate thread is now waiting to acquire the lock, so start sending
1016 8d7d8b57 Michael Hanselmann
    # spurious notifications.
1017 8d7d8b57 Michael Hanselmann
1018 8d7d8b57 Michael Hanselmann
    # Wait for separate thread to ask for another notification
1019 8d7d8b57 Michael Hanselmann
    count = 0
1020 8d7d8b57 Michael Hanselmann
    while req.get():
1021 8d7d8b57 Michael Hanselmann
      # After sending the notification, the lock will take a short amount of
1022 8d7d8b57 Michael Hanselmann
      # time to notice and to retrieve the current time
1023 8d7d8b57 Michael Hanselmann
      sl._notify_topmost()
1024 8d7d8b57 Michael Hanselmann
      count += 1
1025 8d7d8b57 Michael Hanselmann
1026 8d7d8b57 Michael Hanselmann
    self.assertTrue(count > 100, "Not enough notifications were sent")
1027 8d7d8b57 Michael Hanselmann
1028 8d7d8b57 Michael Hanselmann
    self.assertFalse(locked.isSet())
1029 8d7d8b57 Michael Hanselmann
1030 8d7d8b57 Michael Hanselmann
    # Some notifications have been sent, now actually release the lock
1031 8d7d8b57 Michael Hanselmann
    sl.release()
1032 8d7d8b57 Michael Hanselmann
1033 8d7d8b57 Michael Hanselmann
    # Wait for lock to be acquired
1034 8d7d8b57 Michael Hanselmann
    locked.wait()
1035 8d7d8b57 Michael Hanselmann
1036 8d7d8b57 Michael Hanselmann
    self._waitThreads()
1037 8d7d8b57 Michael Hanselmann
1038 8d7d8b57 Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "success")
1039 8d7d8b57 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1040 8d7d8b57 Michael Hanselmann
1041 162c1c1f Guido Trotter
1042 1a4e32d0 Guido Trotter
class TestSharedLockInCondition(_ThreadedTestCase):
1043 1a4e32d0 Guido Trotter
  """SharedLock as a condition lock tests"""
1044 1a4e32d0 Guido Trotter
1045 1a4e32d0 Guido Trotter
  def setUp(self):
1046 1a4e32d0 Guido Trotter
    _ThreadedTestCase.setUp(self)
1047 7f93570a Iustin Pop
    self.sl = locking.SharedLock("TestSharedLockInCondition")
1048 7f890059 Guido Trotter
    self.setCondition()
1049 7f890059 Guido Trotter
1050 7f890059 Guido Trotter
  def setCondition(self):
1051 1a4e32d0 Guido Trotter
    self.cond = threading.Condition(self.sl)
1052 1a4e32d0 Guido Trotter
1053 1a4e32d0 Guido Trotter
  def testKeepMode(self):
1054 1a4e32d0 Guido Trotter
    self.cond.acquire(shared=1)
1055 ee2b99e3 Michael Hanselmann
    self.assert_(self.sl.is_owned(shared=1))
1056 1a4e32d0 Guido Trotter
    self.cond.wait(0)
1057 ee2b99e3 Michael Hanselmann
    self.assert_(self.sl.is_owned(shared=1))
1058 1a4e32d0 Guido Trotter
    self.cond.release()
1059 1a4e32d0 Guido Trotter
    self.cond.acquire(shared=0)
1060 ee2b99e3 Michael Hanselmann
    self.assert_(self.sl.is_owned(shared=0))
1061 1a4e32d0 Guido Trotter
    self.cond.wait(0)
1062 ee2b99e3 Michael Hanselmann
    self.assert_(self.sl.is_owned(shared=0))
1063 1a4e32d0 Guido Trotter
    self.cond.release()
1064 1a4e32d0 Guido Trotter
1065 1a4e32d0 Guido Trotter
1066 7f890059 Guido Trotter
class TestSharedLockInPipeCondition(TestSharedLockInCondition):
1067 7f890059 Guido Trotter
  """SharedLock as a pipe condition lock tests"""
1068 7f890059 Guido Trotter
1069 7f890059 Guido Trotter
  def setCondition(self):
1070 7f890059 Guido Trotter
    self.cond = locking.PipeCondition(self.sl)
1071 7f890059 Guido Trotter
1072 7f890059 Guido Trotter
1073 4607c978 Iustin Pop
class TestSSynchronizedDecorator(_ThreadedTestCase):
1074 42a999d1 Guido Trotter
  """Shared Lock Synchronized decorator test"""
1075 42a999d1 Guido Trotter
1076 42a999d1 Guido Trotter
  def setUp(self):
1077 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
1078 42a999d1 Guido Trotter
1079 42a999d1 Guido Trotter
  @locking.ssynchronized(_decoratorlock)
1080 42a999d1 Guido Trotter
  def _doItExclusive(self):
1081 ee2b99e3 Michael Hanselmann
    self.assert_(_decoratorlock.is_owned())
1082 8c114acd Michael Hanselmann
    self.done.put("EXC")
1083 42a999d1 Guido Trotter
1084 42a999d1 Guido Trotter
  @locking.ssynchronized(_decoratorlock, shared=1)
1085 42a999d1 Guido Trotter
  def _doItSharer(self):
1086 ee2b99e3 Michael Hanselmann
    self.assert_(_decoratorlock.is_owned(shared=1))
1087 8c114acd Michael Hanselmann
    self.done.put("SHR")
1088 42a999d1 Guido Trotter
1089 42a999d1 Guido Trotter
  def testDecoratedFunctions(self):
1090 42a999d1 Guido Trotter
    self._doItExclusive()
1091 ee2b99e3 Michael Hanselmann
    self.assertFalse(_decoratorlock.is_owned())
1092 42a999d1 Guido Trotter
    self._doItSharer()
1093 ee2b99e3 Michael Hanselmann
    self.assertFalse(_decoratorlock.is_owned())
1094 42a999d1 Guido Trotter
1095 42a999d1 Guido Trotter
  def testSharersCanCoexist(self):
1096 42a999d1 Guido Trotter
    _decoratorlock.acquire(shared=1)
1097 84e344d4 Michael Hanselmann
    threading.Thread(target=self._doItSharer).start()
1098 42a999d1 Guido Trotter
    self.assert_(self.done.get(True, 1))
1099 42a999d1 Guido Trotter
    _decoratorlock.release()
1100 42a999d1 Guido Trotter
1101 4607c978 Iustin Pop
  @_Repeat
1102 42a999d1 Guido Trotter
  def testExclusiveBlocksExclusive(self):
1103 42a999d1 Guido Trotter
    _decoratorlock.acquire()
1104 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
1105 42a999d1 Guido Trotter
    # give it a bit of time to check that it's not actually doing anything
1106 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1107 42a999d1 Guido Trotter
    _decoratorlock.release()
1108 4607c978 Iustin Pop
    self._waitThreads()
1109 8c114acd Michael Hanselmann
    self.failUnlessEqual(self.done.get_nowait(), "EXC")
1110 42a999d1 Guido Trotter
1111 4607c978 Iustin Pop
  @_Repeat
1112 42a999d1 Guido Trotter
  def testExclusiveBlocksSharer(self):
1113 42a999d1 Guido Trotter
    _decoratorlock.acquire()
1114 4607c978 Iustin Pop
    self._addThread(target=self._doItSharer)
1115 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1116 42a999d1 Guido Trotter
    _decoratorlock.release()
1117 4607c978 Iustin Pop
    self._waitThreads()
1118 8c114acd Michael Hanselmann
    self.failUnlessEqual(self.done.get_nowait(), "SHR")
1119 42a999d1 Guido Trotter
1120 4607c978 Iustin Pop
  @_Repeat
1121 42a999d1 Guido Trotter
  def testSharerBlocksExclusive(self):
1122 42a999d1 Guido Trotter
    _decoratorlock.acquire(shared=1)
1123 4607c978 Iustin Pop
    self._addThread(target=self._doItExclusive)
1124 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1125 42a999d1 Guido Trotter
    _decoratorlock.release()
1126 4607c978 Iustin Pop
    self._waitThreads()
1127 8c114acd Michael Hanselmann
    self.failUnlessEqual(self.done.get_nowait(), "EXC")
1128 42a999d1 Guido Trotter
1129 42a999d1 Guido Trotter
1130 4607c978 Iustin Pop
class TestLockSet(_ThreadedTestCase):
1131 aaae9bc0 Guido Trotter
  """LockSet tests"""
1132 aaae9bc0 Guido Trotter
1133 aaae9bc0 Guido Trotter
  def setUp(self):
1134 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
1135 4607c978 Iustin Pop
    self._setUpLS()
1136 aaae9bc0 Guido Trotter
1137 4607c978 Iustin Pop
  def _setUpLS(self):
1138 4607c978 Iustin Pop
    """Helper to (re)initialize the lock set"""
1139 8c114acd Michael Hanselmann
    self.resources = ["one", "two", "three"]
1140 7f93570a Iustin Pop
    self.ls = locking.LockSet(self.resources, "TestLockSet")
1141 4607c978 Iustin Pop
1142 aaae9bc0 Guido Trotter
  def testResources(self):
1143 aaae9bc0 Guido Trotter
    self.assertEquals(self.ls._names(), set(self.resources))
1144 7f93570a Iustin Pop
    newls = locking.LockSet([], "TestLockSet.testResources")
1145 aaae9bc0 Guido Trotter
    self.assertEquals(newls._names(), set())
1146 aaae9bc0 Guido Trotter
1147 c6a622cf Michael Hanselmann
  def testCheckOwnedUnknown(self):
1148 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned("certainly-not-owning-this-one"))
1149 c6a622cf Michael Hanselmann
    for shared in [-1, 0, 1, 6378, 24255]:
1150 c6a622cf Michael Hanselmann
      self.assertFalse(self.ls.check_owned("certainly-not-owning-this-one",
1151 c6a622cf Michael Hanselmann
                                           shared=shared))
1152 c6a622cf Michael Hanselmann
1153 c6a622cf Michael Hanselmann
  def testCheckOwnedUnknownWhileHolding(self):
1154 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned([]))
1155 c6a622cf Michael Hanselmann
    self.ls.acquire("one", shared=1)
1156 c6a622cf Michael Hanselmann
    self.assertRaises(errors.LockError, self.ls.check_owned, "nonexist")
1157 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned("one", shared=1))
1158 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned("one", shared=0))
1159 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned(["one", "two"]))
1160 c6a622cf Michael Hanselmann
    self.assertRaises(errors.LockError, self.ls.check_owned,
1161 c6a622cf Michael Hanselmann
                      ["one", "nonexist"])
1162 c6a622cf Michael Hanselmann
    self.assertRaises(errors.LockError, self.ls.check_owned, "")
1163 c6a622cf Michael Hanselmann
    self.ls.release()
1164 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned([]))
1165 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned("one"))
1166 c6a622cf Michael Hanselmann
1167 aaae9bc0 Guido Trotter
  def testAcquireRelease(self):
1168 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned(self.ls._names()))
1169 8c114acd Michael Hanselmann
    self.assert_(self.ls.acquire("one"))
1170 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set(["one"]))
1171 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned("one"))
1172 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned("one", shared=0))
1173 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned("one", shared=1))
1174 aaae9bc0 Guido Trotter
    self.ls.release()
1175 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set())
1176 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned(self.ls._names()))
1177 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.acquire(["one"]), set(["one"]))
1178 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set(["one"]))
1179 aaae9bc0 Guido Trotter
    self.ls.release()
1180 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set())
1181 8c114acd Michael Hanselmann
    self.ls.acquire(["one", "two", "three"])
1182 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set(["one", "two", "three"]))
1183 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned(self.ls._names()))
1184 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned(self.ls._names(), shared=0))
1185 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned(self.ls._names(), shared=1))
1186 8c114acd Michael Hanselmann
    self.ls.release("one")
1187 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned(["one"]))
1188 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned(["two", "three"]))
1189 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned(["two", "three"], shared=0))
1190 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned(["two", "three"], shared=1))
1191 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set(["two", "three"]))
1192 8c114acd Michael Hanselmann
    self.ls.release(["three"])
1193 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set(["two"]))
1194 aaae9bc0 Guido Trotter
    self.ls.release()
1195 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set())
1196 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.acquire(["one", "three"]), set(["one", "three"]))
1197 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set(["one", "three"]))
1198 aaae9bc0 Guido Trotter
    self.ls.release()
1199 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set())
1200 c6a622cf Michael Hanselmann
    for name in self.ls._names():
1201 c6a622cf Michael Hanselmann
      self.assertFalse(self.ls.check_owned(name))
1202 aaae9bc0 Guido Trotter
1203 aaae9bc0 Guido Trotter
  def testNoDoubleAcquire(self):
1204 8c114acd Michael Hanselmann
    self.ls.acquire("one")
1205 8c114acd Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.acquire, "one")
1206 8c114acd Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.acquire, ["two"])
1207 8c114acd Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.acquire, ["two", "three"])
1208 aaae9bc0 Guido Trotter
    self.ls.release()
1209 8c114acd Michael Hanselmann
    self.ls.acquire(["one", "three"])
1210 8c114acd Michael Hanselmann
    self.ls.release("one")
1211 8c114acd Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.acquire, ["two"])
1212 8c114acd Michael Hanselmann
    self.ls.release("three")
1213 aaae9bc0 Guido Trotter
1214 aaae9bc0 Guido Trotter
  def testNoWrongRelease(self):
1215 aaae9bc0 Guido Trotter
    self.assertRaises(AssertionError, self.ls.release)
1216 8c114acd Michael Hanselmann
    self.ls.acquire("one")
1217 8c114acd Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.release, "two")
1218 aaae9bc0 Guido Trotter
1219 aaae9bc0 Guido Trotter
  def testAddRemove(self):
1220 8c114acd Michael Hanselmann
    self.ls.add("four")
1221 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set())
1222 8c114acd Michael Hanselmann
    self.assert_("four" in self.ls._names())
1223 8c114acd Michael Hanselmann
    self.ls.add(["five", "six", "seven"], acquired=1)
1224 8c114acd Michael Hanselmann
    self.assert_("five" in self.ls._names())
1225 8c114acd Michael Hanselmann
    self.assert_("six" in self.ls._names())
1226 8c114acd Michael Hanselmann
    self.assert_("seven" in self.ls._names())
1227 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set(["five", "six", "seven"]))
1228 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.remove(["five", "six"]), ["five", "six"])
1229 8c114acd Michael Hanselmann
    self.assert_("five" not in self.ls._names())
1230 8c114acd Michael Hanselmann
    self.assert_("six" not in self.ls._names())
1231 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set(["seven"]))
1232 8c114acd Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.add, "eight", acquired=1)
1233 8c114acd Michael Hanselmann
    self.ls.remove("seven")
1234 8c114acd Michael Hanselmann
    self.assert_("seven" not in self.ls._names())
1235 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set([]))
1236 d2aff862 Guido Trotter
    self.ls.acquire(None, shared=1)
1237 8c114acd Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.add, "eight")
1238 d2aff862 Guido Trotter
    self.ls.release()
1239 d2aff862 Guido Trotter
    self.ls.acquire(None)
1240 8c114acd Michael Hanselmann
    self.ls.add("eight", acquired=1)
1241 8c114acd Michael Hanselmann
    self.assert_("eight" in self.ls._names())
1242 8c114acd Michael Hanselmann
    self.assert_("eight" in self.ls.list_owned())
1243 8c114acd Michael Hanselmann
    self.ls.add("nine")
1244 8c114acd Michael Hanselmann
    self.assert_("nine" in self.ls._names())
1245 8c114acd Michael Hanselmann
    self.assert_("nine" not in self.ls.list_owned())
1246 aaae9bc0 Guido Trotter
    self.ls.release()
1247 8c114acd Michael Hanselmann
    self.ls.remove(["two"])
1248 8c114acd Michael Hanselmann
    self.assert_("two" not in self.ls._names())
1249 8c114acd Michael Hanselmann
    self.ls.acquire("three")
1250 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.remove(["three"]), ["three"])
1251 8c114acd Michael Hanselmann
    self.assert_("three" not in self.ls._names())
1252 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.remove("three"), [])
1253 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.remove(["one", "three", "six"]), ["one"])
1254 8c114acd Michael Hanselmann
    self.assert_("one" not in self.ls._names())
1255 aaae9bc0 Guido Trotter
1256 aaae9bc0 Guido Trotter
  def testRemoveNonBlocking(self):
1257 8c114acd Michael Hanselmann
    self.ls.acquire("one")
1258 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.remove("one"), ["one"])
1259 8c114acd Michael Hanselmann
    self.ls.acquire(["two", "three"])
1260 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.remove(["two", "three"]),
1261 8c114acd Michael Hanselmann
                      ["two", "three"])
1262 aaae9bc0 Guido Trotter
1263 aaae9bc0 Guido Trotter
  def testNoDoubleAdd(self):
1264 8c114acd Michael Hanselmann
    self.assertRaises(errors.LockError, self.ls.add, "two")
1265 8c114acd Michael Hanselmann
    self.ls.add("four")
1266 8c114acd Michael Hanselmann
    self.assertRaises(errors.LockError, self.ls.add, "four")
1267 aaae9bc0 Guido Trotter
1268 aaae9bc0 Guido Trotter
  def testNoWrongRemoves(self):
1269 8c114acd Michael Hanselmann
    self.ls.acquire(["one", "three"], shared=1)
1270 8c114acd Michael Hanselmann
    # Cannot remove "two" while holding something which is not a superset
1271 8c114acd Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.remove, "two")
1272 8c114acd Michael Hanselmann
    # Cannot remove "three" as we are sharing it
1273 8c114acd Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.remove, "three")
1274 aaae9bc0 Guido Trotter
1275 3b7ed473 Guido Trotter
  def testAcquireSetLock(self):
1276 3b7ed473 Guido Trotter
    # acquire the set-lock exclusively
1277 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.acquire(None), set(["one", "two", "three"]))
1278 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set(["one", "two", "three"]))
1279 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.ls.is_owned(), True)
1280 8c114acd Michael Hanselmann
    self.assertEquals(self.ls._names(), set(["one", "two", "three"]))
1281 3b7ed473 Guido Trotter
    # I can still add/remove elements...
1282 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.remove(["two", "three"]), ["two", "three"])
1283 8c114acd Michael Hanselmann
    self.assert_(self.ls.add("six"))
1284 3b7ed473 Guido Trotter
    self.ls.release()
1285 3b7ed473 Guido Trotter
    # share the set-lock
1286 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.acquire(None, shared=1), set(["one", "six"]))
1287 3b7ed473 Guido Trotter
    # adding new elements is not possible
1288 8c114acd Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.add, "five")
1289 3b7ed473 Guido Trotter
    self.ls.release()
1290 3b7ed473 Guido Trotter
1291 d4f6a91c Guido Trotter
  def testAcquireWithRepetitions(self):
1292 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.acquire(["two", "two", "three"], shared=1),
1293 8c114acd Michael Hanselmann
                      set(["two", "two", "three"]))
1294 8c114acd Michael Hanselmann
    self.ls.release(["two", "two"])
1295 8c114acd Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set(["three"]))
1296 d4f6a91c Guido Trotter
1297 2e1d6d96 Guido Trotter
  def testEmptyAcquire(self):
1298 2e1d6d96 Guido Trotter
    # Acquire an empty list of locks...
1299 2e1d6d96 Guido Trotter
    self.assertEquals(self.ls.acquire([]), set())
1300 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set())
1301 2e1d6d96 Guido Trotter
    # New locks can still be addded
1302 8c114acd Michael Hanselmann
    self.assert_(self.ls.add("six"))
1303 2e1d6d96 Guido Trotter
    # "re-acquiring" is not an issue, since we had really acquired nothing
1304 2e1d6d96 Guido Trotter
    self.assertEquals(self.ls.acquire([], shared=1), set())
1305 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.ls.list_owned(), set())
1306 2e1d6d96 Guido Trotter
    # We haven't really acquired anything, so we cannot release
1307 2e1d6d96 Guido Trotter
    self.assertRaises(AssertionError, self.ls.release)
1308 2e1d6d96 Guido Trotter
1309 84e344d4 Michael Hanselmann
  def _doLockSet(self, names, shared):
1310 aaae9bc0 Guido Trotter
    try:
1311 84e344d4 Michael Hanselmann
      self.ls.acquire(names, shared=shared)
1312 8c114acd Michael Hanselmann
      self.done.put("DONE")
1313 aaae9bc0 Guido Trotter
      self.ls.release()
1314 aaae9bc0 Guido Trotter
    except errors.LockError:
1315 8c114acd Michael Hanselmann
      self.done.put("ERR")
1316 aaae9bc0 Guido Trotter
1317 84e344d4 Michael Hanselmann
  def _doAddSet(self, names):
1318 3b7ed473 Guido Trotter
    try:
1319 84e344d4 Michael Hanselmann
      self.ls.add(names, acquired=1)
1320 8c114acd Michael Hanselmann
      self.done.put("DONE")
1321 3b7ed473 Guido Trotter
      self.ls.release()
1322 3b7ed473 Guido Trotter
    except errors.LockError:
1323 8c114acd Michael Hanselmann
      self.done.put("ERR")
1324 3b7ed473 Guido Trotter
1325 84e344d4 Michael Hanselmann
  def _doRemoveSet(self, names):
1326 84e344d4 Michael Hanselmann
    self.done.put(self.ls.remove(names))
1327 aaae9bc0 Guido Trotter
1328 4607c978 Iustin Pop
  @_Repeat
1329 aaae9bc0 Guido Trotter
  def testConcurrentSharedAcquire(self):
1330 8c114acd Michael Hanselmann
    self.ls.acquire(["one", "two"], shared=1)
1331 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["one", "two"], 1))
1332 4607c978 Iustin Pop
    self._waitThreads()
1333 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1334 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["one", "two", "three"], 1))
1335 4607c978 Iustin Pop
    self._waitThreads()
1336 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1337 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=("three", 1))
1338 4607c978 Iustin Pop
    self._waitThreads()
1339 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1340 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["one", "two"], 0))
1341 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["two", "three"], 0))
1342 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1343 aaae9bc0 Guido Trotter
    self.ls.release()
1344 4607c978 Iustin Pop
    self._waitThreads()
1345 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1346 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1347 aaae9bc0 Guido Trotter
1348 4607c978 Iustin Pop
  @_Repeat
1349 aaae9bc0 Guido Trotter
  def testConcurrentExclusiveAcquire(self):
1350 8c114acd Michael Hanselmann
    self.ls.acquire(["one", "two"])
1351 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=("three", 1))
1352 4607c978 Iustin Pop
    self._waitThreads()
1353 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1354 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=("three", 0))
1355 4607c978 Iustin Pop
    self._waitThreads()
1356 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1357 84e344d4 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1358 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["one", "two"], 0))
1359 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["one", "two"], 1))
1360 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=("one", 0))
1361 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=("one", 1))
1362 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["two", "three"], 0))
1363 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["two", "three"], 1))
1364 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1365 aaae9bc0 Guido Trotter
    self.ls.release()
1366 4607c978 Iustin Pop
    self._waitThreads()
1367 4607c978 Iustin Pop
    for _ in range(6):
1368 8c114acd Michael Hanselmann
      self.failUnlessEqual(self.done.get_nowait(), "DONE")
1369 aaae9bc0 Guido Trotter
1370 4607c978 Iustin Pop
  @_Repeat
1371 5aab242c Michael Hanselmann
  def testSimpleAcquireTimeoutExpiring(self):
1372 5aab242c Michael Hanselmann
    names = sorted(self.ls._names())
1373 5aab242c Michael Hanselmann
    self.assert_(len(names) >= 3)
1374 5aab242c Michael Hanselmann
1375 5aab242c Michael Hanselmann
    # Get name of first lock
1376 5aab242c Michael Hanselmann
    first = names[0]
1377 5aab242c Michael Hanselmann
1378 5aab242c Michael Hanselmann
    # Get name of last lock
1379 5aab242c Michael Hanselmann
    last = names.pop()
1380 5aab242c Michael Hanselmann
1381 5aab242c Michael Hanselmann
    checks = [
1382 5aab242c Michael Hanselmann
      # Block first and try to lock it again
1383 5aab242c Michael Hanselmann
      (first, first),
1384 5aab242c Michael Hanselmann
1385 5aab242c Michael Hanselmann
      # Block last and try to lock all locks
1386 5aab242c Michael Hanselmann
      (None, first),
1387 5aab242c Michael Hanselmann
1388 5aab242c Michael Hanselmann
      # Block last and try to lock it again
1389 5aab242c Michael Hanselmann
      (last, last),
1390 5aab242c Michael Hanselmann
      ]
1391 5aab242c Michael Hanselmann
1392 5aab242c Michael Hanselmann
    for (wanted, block) in checks:
1393 5aab242c Michael Hanselmann
      # Lock in exclusive mode
1394 5aab242c Michael Hanselmann
      self.assert_(self.ls.acquire(block, shared=0))
1395 5aab242c Michael Hanselmann
1396 5aab242c Michael Hanselmann
      def _AcquireOne():
1397 5aab242c Michael Hanselmann
        # Try to get the same lock again with a timeout (should never succeed)
1398 23683c26 Michael Hanselmann
        acquired = self.ls.acquire(wanted, timeout=0.1, shared=0)
1399 23683c26 Michael Hanselmann
        if acquired:
1400 5aab242c Michael Hanselmann
          self.done.put("acquired")
1401 5aab242c Michael Hanselmann
          self.ls.release()
1402 5aab242c Michael Hanselmann
        else:
1403 23683c26 Michael Hanselmann
          self.assert_(acquired is None)
1404 ee2b99e3 Michael Hanselmann
          self.assertFalse(self.ls.list_owned())
1405 ee2b99e3 Michael Hanselmann
          self.assertFalse(self.ls.is_owned())
1406 5aab242c Michael Hanselmann
          self.done.put("not acquired")
1407 5aab242c Michael Hanselmann
1408 5aab242c Michael Hanselmann
      self._addThread(target=_AcquireOne)
1409 5aab242c Michael Hanselmann
1410 5aab242c Michael Hanselmann
      # Wait for timeout in thread to expire
1411 5aab242c Michael Hanselmann
      self._waitThreads()
1412 5aab242c Michael Hanselmann
1413 5aab242c Michael Hanselmann
      # Release exclusive lock again
1414 5aab242c Michael Hanselmann
      self.ls.release()
1415 5aab242c Michael Hanselmann
1416 5aab242c Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "not acquired")
1417 5aab242c Michael Hanselmann
      self.assertRaises(Queue.Empty, self.done.get_nowait)
1418 5aab242c Michael Hanselmann
1419 5aab242c Michael Hanselmann
  @_Repeat
1420 5aab242c Michael Hanselmann
  def testDelayedAndExpiringLockAcquire(self):
1421 5aab242c Michael Hanselmann
    self._setUpLS()
1422 8c114acd Michael Hanselmann
    self.ls.add(["five", "six", "seven", "eight", "nine"])
1423 5aab242c Michael Hanselmann
1424 5aab242c Michael Hanselmann
    for expire in (False, True):
1425 5aab242c Michael Hanselmann
      names = sorted(self.ls._names())
1426 5aab242c Michael Hanselmann
      self.assertEqual(len(names), 8)
1427 5aab242c Michael Hanselmann
1428 5aab242c Michael Hanselmann
      lock_ev = dict([(i, threading.Event()) for i in names])
1429 5aab242c Michael Hanselmann
1430 5aab242c Michael Hanselmann
      # Lock all in exclusive mode
1431 5aab242c Michael Hanselmann
      self.assert_(self.ls.acquire(names, shared=0))
1432 5aab242c Michael Hanselmann
1433 5aab242c Michael Hanselmann
      if expire:
1434 5aab242c Michael Hanselmann
        # We'll wait at least 300ms per lock
1435 5aab242c Michael Hanselmann
        lockwait = len(names) * [0.3]
1436 5aab242c Michael Hanselmann
1437 5aab242c Michael Hanselmann
        # Fail if we can't acquire all locks in 400ms. There are 8 locks, so
1438 5aab242c Michael Hanselmann
        # this gives us up to 2.4s to fail.
1439 5aab242c Michael Hanselmann
        lockall_timeout = 0.4
1440 5aab242c Michael Hanselmann
      else:
1441 5aab242c Michael Hanselmann
        # This should finish rather quickly
1442 5aab242c Michael Hanselmann
        lockwait = None
1443 5aab242c Michael Hanselmann
        lockall_timeout = len(names) * 5.0
1444 5aab242c Michael Hanselmann
1445 5aab242c Michael Hanselmann
      def _LockAll():
1446 5aab242c Michael Hanselmann
        def acquire_notification(name):
1447 5aab242c Michael Hanselmann
          if not expire:
1448 5aab242c Michael Hanselmann
            self.done.put("getting %s" % name)
1449 5aab242c Michael Hanselmann
1450 5aab242c Michael Hanselmann
          # Kick next lock
1451 5aab242c Michael Hanselmann
          lock_ev[name].set()
1452 5aab242c Michael Hanselmann
1453 5aab242c Michael Hanselmann
        if self.ls.acquire(names, shared=0, timeout=lockall_timeout,
1454 5aab242c Michael Hanselmann
                           test_notify=acquire_notification):
1455 5aab242c Michael Hanselmann
          self.done.put("got all")
1456 5aab242c Michael Hanselmann
          self.ls.release()
1457 5aab242c Michael Hanselmann
        else:
1458 5aab242c Michael Hanselmann
          self.done.put("timeout on all")
1459 5aab242c Michael Hanselmann
1460 5aab242c Michael Hanselmann
        # Notify all locks
1461 5aab242c Michael Hanselmann
        for ev in lock_ev.values():
1462 5aab242c Michael Hanselmann
          ev.set()
1463 5aab242c Michael Hanselmann
1464 5aab242c Michael Hanselmann
      t = self._addThread(target=_LockAll)
1465 5aab242c Michael Hanselmann
1466 5aab242c Michael Hanselmann
      for idx, name in enumerate(names):
1467 5aab242c Michael Hanselmann
        # Wait for actual acquire on this lock to start
1468 5aab242c Michael Hanselmann
        lock_ev[name].wait(10.0)
1469 5aab242c Michael Hanselmann
1470 5aab242c Michael Hanselmann
        if expire and t.isAlive():
1471 5aab242c Michael Hanselmann
          # Wait some time after getting the notification to make sure the lock
1472 5aab242c Michael Hanselmann
          # acquire will expire
1473 5aab242c Michael Hanselmann
          SafeSleep(lockwait[idx])
1474 5aab242c Michael Hanselmann
1475 5aab242c Michael Hanselmann
        self.ls.release(names=name)
1476 5aab242c Michael Hanselmann
1477 ee2b99e3 Michael Hanselmann
      self.assertFalse(self.ls.list_owned())
1478 5aab242c Michael Hanselmann
1479 5aab242c Michael Hanselmann
      self._waitThreads()
1480 5aab242c Michael Hanselmann
1481 5aab242c Michael Hanselmann
      if expire:
1482 5aab242c Michael Hanselmann
        # Not checking which locks were actually acquired. Doing so would be
1483 5aab242c Michael Hanselmann
        # too timing-dependant.
1484 5aab242c Michael Hanselmann
        self.assertEqual(self.done.get_nowait(), "timeout on all")
1485 5aab242c Michael Hanselmann
      else:
1486 5aab242c Michael Hanselmann
        for i in names:
1487 5aab242c Michael Hanselmann
          self.assertEqual(self.done.get_nowait(), "getting %s" % i)
1488 5aab242c Michael Hanselmann
        self.assertEqual(self.done.get_nowait(), "got all")
1489 5aab242c Michael Hanselmann
      self.assertRaises(Queue.Empty, self.done.get_nowait)
1490 5aab242c Michael Hanselmann
1491 5aab242c Michael Hanselmann
  @_Repeat
1492 aaae9bc0 Guido Trotter
  def testConcurrentRemove(self):
1493 8c114acd Michael Hanselmann
    self.ls.add("four")
1494 8c114acd Michael Hanselmann
    self.ls.acquire(["one", "two", "four"])
1495 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["one", "four"], 0))
1496 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["one", "four"], 1))
1497 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["one", "two"], 0))
1498 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["one", "two"], 1))
1499 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1500 8c114acd Michael Hanselmann
    self.ls.remove("one")
1501 aaae9bc0 Guido Trotter
    self.ls.release()
1502 4607c978 Iustin Pop
    self._waitThreads()
1503 4607c978 Iustin Pop
    for i in range(4):
1504 8c114acd Michael Hanselmann
      self.failUnlessEqual(self.done.get_nowait(), "ERR")
1505 8c114acd Michael Hanselmann
    self.ls.add(["five", "six"], acquired=1)
1506 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["three", "six"], 1))
1507 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["three", "six"], 0))
1508 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["four", "six"], 1))
1509 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["four", "six"], 0))
1510 8c114acd Michael Hanselmann
    self.ls.remove("five")
1511 aaae9bc0 Guido Trotter
    self.ls.release()
1512 4607c978 Iustin Pop
    self._waitThreads()
1513 4607c978 Iustin Pop
    for i in range(4):
1514 8c114acd Michael Hanselmann
      self.failUnlessEqual(self.done.get_nowait(), "DONE")
1515 8c114acd Michael Hanselmann
    self.ls.acquire(["three", "four"])
1516 8c114acd Michael Hanselmann
    self._addThread(target=self._doRemoveSet, args=(["four", "six"], ))
1517 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1518 8c114acd Michael Hanselmann
    self.ls.remove("four")
1519 4607c978 Iustin Pop
    self._waitThreads()
1520 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), ["six"])
1521 8c114acd Michael Hanselmann
    self._addThread(target=self._doRemoveSet, args=(["two"]))
1522 4607c978 Iustin Pop
    self._waitThreads()
1523 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), ["two"])
1524 aaae9bc0 Guido Trotter
    self.ls.release()
1525 4607c978 Iustin Pop
    # reset lockset
1526 4607c978 Iustin Pop
    self._setUpLS()
1527 aaae9bc0 Guido Trotter
1528 4607c978 Iustin Pop
  @_Repeat
1529 3b7ed473 Guido Trotter
  def testConcurrentSharedSetLock(self):
1530 3b7ed473 Guido Trotter
    # share the set-lock...
1531 3b7ed473 Guido Trotter
    self.ls.acquire(None, shared=1)
1532 3b7ed473 Guido Trotter
    # ...another thread can share it too
1533 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1534 4607c978 Iustin Pop
    self._waitThreads()
1535 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1536 3b7ed473 Guido Trotter
    # ...or just share some elements
1537 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["one", "three"], 1))
1538 4607c978 Iustin Pop
    self._waitThreads()
1539 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1540 3b7ed473 Guido Trotter
    # ...but not add new ones or remove any
1541 8c114acd Michael Hanselmann
    t = self._addThread(target=self._doAddSet, args=(["nine"]))
1542 8c114acd Michael Hanselmann
    self._addThread(target=self._doRemoveSet, args=(["two"], ))
1543 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1544 3b7ed473 Guido Trotter
    # this just releases the set-lock
1545 3b7ed473 Guido Trotter
    self.ls.release([])
1546 4607c978 Iustin Pop
    t.join(60)
1547 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1548 3b7ed473 Guido Trotter
    # release the lock on the actual elements so remove() can proceed too
1549 3b7ed473 Guido Trotter
    self.ls.release()
1550 4607c978 Iustin Pop
    self._waitThreads()
1551 8c114acd Michael Hanselmann
    self.failUnlessEqual(self.done.get_nowait(), ["two"])
1552 4607c978 Iustin Pop
    # reset lockset
1553 4607c978 Iustin Pop
    self._setUpLS()
1554 3b7ed473 Guido Trotter
1555 4607c978 Iustin Pop
  @_Repeat
1556 3b7ed473 Guido Trotter
  def testConcurrentExclusiveSetLock(self):
1557 3b7ed473 Guido Trotter
    # acquire the set-lock...
1558 3b7ed473 Guido Trotter
    self.ls.acquire(None, shared=0)
1559 3b7ed473 Guido Trotter
    # ...no one can do anything else
1560 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1561 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 0))
1562 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["three"], 0))
1563 8c114acd Michael Hanselmann
    self._addThread(target=self._doLockSet, args=(["two"], 1))
1564 8c114acd Michael Hanselmann
    self._addThread(target=self._doAddSet, args=(["nine"]))
1565 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1566 3b7ed473 Guido Trotter
    self.ls.release()
1567 4607c978 Iustin Pop
    self._waitThreads()
1568 4607c978 Iustin Pop
    for _ in range(5):
1569 8c114acd Michael Hanselmann
      self.assertEqual(self.done.get(True, 1), "DONE")
1570 4607c978 Iustin Pop
    # cleanup
1571 4607c978 Iustin Pop
    self._setUpLS()
1572 3b7ed473 Guido Trotter
1573 4607c978 Iustin Pop
  @_Repeat
1574 d2aff862 Guido Trotter
  def testConcurrentSetLockAdd(self):
1575 8c114acd Michael Hanselmann
    self.ls.acquire("one")
1576 d2aff862 Guido Trotter
    # Another thread wants the whole SetLock
1577 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 0))
1578 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1579 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1580 8c114acd Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.add, "four")
1581 d2aff862 Guido Trotter
    self.ls.release()
1582 4607c978 Iustin Pop
    self._waitThreads()
1583 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1584 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1585 d2aff862 Guido Trotter
    self.ls.acquire(None)
1586 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 0))
1587 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1588 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1589 8c114acd Michael Hanselmann
    self.ls.add("four")
1590 8c114acd Michael Hanselmann
    self.ls.add("five", acquired=1)
1591 8c114acd Michael Hanselmann
    self.ls.add("six", acquired=1, shared=1)
1592 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.ls.list_owned(),
1593 8c114acd Michael Hanselmann
      set(["one", "two", "three", "five", "six"]))
1594 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.ls.is_owned(), True)
1595 d2aff862 Guido Trotter
    self.assertEquals(self.ls._names(),
1596 8c114acd Michael Hanselmann
      set(["one", "two", "three", "four", "five", "six"]))
1597 d2aff862 Guido Trotter
    self.ls.release()
1598 4607c978 Iustin Pop
    self._waitThreads()
1599 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1600 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1601 4607c978 Iustin Pop
    self._setUpLS()
1602 d2aff862 Guido Trotter
1603 4607c978 Iustin Pop
  @_Repeat
1604 b2dabfd6 Guido Trotter
  def testEmptyLockSet(self):
1605 b2dabfd6 Guido Trotter
    # get the set-lock
1606 8c114acd Michael Hanselmann
    self.assertEqual(self.ls.acquire(None), set(["one", "two", "three"]))
1607 b2dabfd6 Guido Trotter
    # now empty it...
1608 8c114acd Michael Hanselmann
    self.ls.remove(["one", "two", "three"])
1609 8c811986 Michael Hanselmann
    self.assertFalse(self.ls._names())
1610 b2dabfd6 Guido Trotter
    # and adds/locks by another thread still wait
1611 8c114acd Michael Hanselmann
    self._addThread(target=self._doAddSet, args=(["nine"]))
1612 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1613 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 0))
1614 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1615 b2dabfd6 Guido Trotter
    self.ls.release()
1616 4607c978 Iustin Pop
    self._waitThreads()
1617 4607c978 Iustin Pop
    for _ in range(3):
1618 8c114acd Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "DONE")
1619 b2dabfd6 Guido Trotter
    # empty it again...
1620 8c114acd Michael Hanselmann
    self.assertEqual(self.ls.remove(["nine"]), ["nine"])
1621 b2dabfd6 Guido Trotter
    # now share it...
1622 b2dabfd6 Guido Trotter
    self.assertEqual(self.ls.acquire(None, shared=1), set())
1623 b2dabfd6 Guido Trotter
    # other sharers can go, adds still wait
1624 4607c978 Iustin Pop
    self._addThread(target=self._doLockSet, args=(None, 1))
1625 4607c978 Iustin Pop
    self._waitThreads()
1626 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1627 8c114acd Michael Hanselmann
    self._addThread(target=self._doAddSet, args=(["nine"]))
1628 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1629 b2dabfd6 Guido Trotter
    self.ls.release()
1630 4607c978 Iustin Pop
    self._waitThreads()
1631 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
1632 4607c978 Iustin Pop
    self._setUpLS()
1633 b2dabfd6 Guido Trotter
1634 3dbe3ddf Michael Hanselmann
  def testAcquireWithNamesDowngrade(self):
1635 3dbe3ddf Michael Hanselmann
    self.assertEquals(self.ls.acquire("two", shared=0), set(["two"]))
1636 ee2b99e3 Michael Hanselmann
    self.assertTrue(self.ls.is_owned())
1637 ee2b99e3 Michael Hanselmann
    self.assertFalse(self.ls._get_lock().is_owned())
1638 3dbe3ddf Michael Hanselmann
    self.ls.release()
1639 ee2b99e3 Michael Hanselmann
    self.assertFalse(self.ls.is_owned())
1640 ee2b99e3 Michael Hanselmann
    self.assertFalse(self.ls._get_lock().is_owned())
1641 3dbe3ddf Michael Hanselmann
    # Can't downgrade after releasing
1642 3dbe3ddf Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.downgrade, "two")
1643 3dbe3ddf Michael Hanselmann
1644 3dbe3ddf Michael Hanselmann
  def testDowngrade(self):
1645 3dbe3ddf Michael Hanselmann
    # Not owning anything, must raise an exception
1646 ee2b99e3 Michael Hanselmann
    self.assertFalse(self.ls.is_owned())
1647 3dbe3ddf Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.downgrade)
1648 3dbe3ddf Michael Hanselmann
1649 ee2b99e3 Michael Hanselmann
    self.assertFalse(compat.any(i.is_owned()
1650 3dbe3ddf Michael Hanselmann
                                for i in self.ls._get_lockdict().values()))
1651 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned(self.ls._names()))
1652 c6a622cf Michael Hanselmann
    for name in self.ls._names():
1653 c6a622cf Michael Hanselmann
      self.assertFalse(self.ls.check_owned(name))
1654 3dbe3ddf Michael Hanselmann
1655 3dbe3ddf Michael Hanselmann
    self.assertEquals(self.ls.acquire(None, shared=0),
1656 3dbe3ddf Michael Hanselmann
                      set(["one", "two", "three"]))
1657 3dbe3ddf Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.downgrade, "unknown lock")
1658 3dbe3ddf Michael Hanselmann
1659 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned(self.ls._names(), shared=0))
1660 c6a622cf Michael Hanselmann
    for name in self.ls._names():
1661 c6a622cf Michael Hanselmann
      self.assertTrue(self.ls.check_owned(name))
1662 c6a622cf Michael Hanselmann
      self.assertTrue(self.ls.check_owned(name, shared=0))
1663 c6a622cf Michael Hanselmann
      self.assertFalse(self.ls.check_owned(name, shared=1))
1664 c6a622cf Michael Hanselmann
1665 ee2b99e3 Michael Hanselmann
    self.assertTrue(self.ls._get_lock().is_owned(shared=0))
1666 ee2b99e3 Michael Hanselmann
    self.assertTrue(compat.all(i.is_owned(shared=0)
1667 3dbe3ddf Michael Hanselmann
                               for i in self.ls._get_lockdict().values()))
1668 3dbe3ddf Michael Hanselmann
1669 3dbe3ddf Michael Hanselmann
    # Start downgrading locks
1670 3dbe3ddf Michael Hanselmann
    self.assertTrue(self.ls.downgrade(names=["one"]))
1671 ee2b99e3 Michael Hanselmann
    self.assertTrue(self.ls._get_lock().is_owned(shared=0))
1672 ee2b99e3 Michael Hanselmann
    self.assertTrue(compat.all(lock.is_owned(shared=[0, 1][int(name == "one")])
1673 3dbe3ddf Michael Hanselmann
                               for name, lock in
1674 3dbe3ddf Michael Hanselmann
                                 self.ls._get_lockdict().items()))
1675 3dbe3ddf Michael Hanselmann
1676 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned("one", shared=0))
1677 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned("one", shared=1))
1678 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned("two", shared=0))
1679 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned("three", shared=0))
1680 c6a622cf Michael Hanselmann
1681 c6a622cf Michael Hanselmann
    # Downgrade second lock
1682 3dbe3ddf Michael Hanselmann
    self.assertTrue(self.ls.downgrade(names="two"))
1683 ee2b99e3 Michael Hanselmann
    self.assertTrue(self.ls._get_lock().is_owned(shared=0))
1684 3dbe3ddf Michael Hanselmann
    should_share = lambda name: [0, 1][int(name in ("one", "two"))]
1685 ee2b99e3 Michael Hanselmann
    self.assertTrue(compat.all(lock.is_owned(shared=should_share(name))
1686 3dbe3ddf Michael Hanselmann
                               for name, lock in
1687 3dbe3ddf Michael Hanselmann
                                 self.ls._get_lockdict().items()))
1688 3dbe3ddf Michael Hanselmann
1689 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned("one", shared=0))
1690 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned("one", shared=1))
1691 c6a622cf Michael Hanselmann
    self.assertFalse(self.ls.check_owned("two", shared=0))
1692 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned("two", shared=1))
1693 c6a622cf Michael Hanselmann
    self.assertTrue(self.ls.check_owned("three", shared=0))
1694 c6a622cf Michael Hanselmann
1695 3dbe3ddf Michael Hanselmann
    # Downgrading the last exclusive lock to shared must downgrade the
1696 3dbe3ddf Michael Hanselmann
    # lockset-internal lock too
1697 3dbe3ddf Michael Hanselmann
    self.assertTrue(self.ls.downgrade(names="three"))
1698 ee2b99e3 Michael Hanselmann
    self.assertTrue(self.ls._get_lock().is_owned(shared=1))
1699 ee2b99e3 Michael Hanselmann
    self.assertTrue(compat.all(i.is_owned(shared=1)
1700 3dbe3ddf Michael Hanselmann
                               for i in self.ls._get_lockdict().values()))
1701 3dbe3ddf Michael Hanselmann
1702 c6a622cf Michael Hanselmann
    # Verify owned locks
1703 c6a622cf Michael Hanselmann
    for name in self.ls._names():
1704 c6a622cf Michael Hanselmann
      self.assertTrue(self.ls.check_owned(name, shared=1))
1705 c6a622cf Michael Hanselmann
1706 3dbe3ddf Michael Hanselmann
    # Downgrading a shared lock must be a no-op
1707 3dbe3ddf Michael Hanselmann
    self.assertTrue(self.ls.downgrade(names=["one", "three"]))
1708 ee2b99e3 Michael Hanselmann
    self.assertTrue(self.ls._get_lock().is_owned(shared=1))
1709 ee2b99e3 Michael Hanselmann
    self.assertTrue(compat.all(i.is_owned(shared=1)
1710 3dbe3ddf Michael Hanselmann
                               for i in self.ls._get_lockdict().values()))
1711 3dbe3ddf Michael Hanselmann
1712 3dbe3ddf Michael Hanselmann
    self.ls.release()
1713 3dbe3ddf Michael Hanselmann
1714 0ef4d576 Michael Hanselmann
  def testDowngradeEverything(self):
1715 0ef4d576 Michael Hanselmann
    self.assertEqual(self.ls.acquire(locking.ALL_SET, shared=0),
1716 0ef4d576 Michael Hanselmann
                     set(["one", "two", "three"]))
1717 8c811986 Michael Hanselmann
    self.assertTrue(self.ls.owning_all())
1718 0ef4d576 Michael Hanselmann
1719 0ef4d576 Michael Hanselmann
    # Ensure all locks are now owned in exclusive mode
1720 0ef4d576 Michael Hanselmann
    for name in self.ls._names():
1721 0ef4d576 Michael Hanselmann
      self.assertTrue(self.ls.check_owned(name, shared=0))
1722 0ef4d576 Michael Hanselmann
1723 0ef4d576 Michael Hanselmann
    # Downgrade everything
1724 0ef4d576 Michael Hanselmann
    self.assertTrue(self.ls.downgrade())
1725 0ef4d576 Michael Hanselmann
1726 0ef4d576 Michael Hanselmann
    # Ensure all locks are now owned in shared mode
1727 0ef4d576 Michael Hanselmann
    for name in self.ls._names():
1728 0ef4d576 Michael Hanselmann
      self.assertTrue(self.ls.check_owned(name, shared=1))
1729 0ef4d576 Michael Hanselmann
1730 8c811986 Michael Hanselmann
    self.assertTrue(self.ls.owning_all())
1731 8c811986 Michael Hanselmann
1732 887c7aa6 Michael Hanselmann
  def testPriority(self):
1733 887c7aa6 Michael Hanselmann
    def _Acquire(prev, next, name, priority, success_fn):
1734 887c7aa6 Michael Hanselmann
      prev.wait()
1735 887c7aa6 Michael Hanselmann
      self.assert_(self.ls.acquire(name, shared=0,
1736 887c7aa6 Michael Hanselmann
                                   priority=priority,
1737 887c7aa6 Michael Hanselmann
                                   test_notify=lambda _: next.set()))
1738 887c7aa6 Michael Hanselmann
      try:
1739 887c7aa6 Michael Hanselmann
        success_fn()
1740 887c7aa6 Michael Hanselmann
      finally:
1741 887c7aa6 Michael Hanselmann
        self.ls.release()
1742 887c7aa6 Michael Hanselmann
1743 887c7aa6 Michael Hanselmann
    # Get all in exclusive mode
1744 887c7aa6 Michael Hanselmann
    self.assert_(self.ls.acquire(locking.ALL_SET, shared=0))
1745 887c7aa6 Michael Hanselmann
1746 887c7aa6 Michael Hanselmann
    done_two = Queue.Queue(0)
1747 887c7aa6 Michael Hanselmann
1748 887c7aa6 Michael Hanselmann
    first = threading.Event()
1749 887c7aa6 Michael Hanselmann
    prev = first
1750 887c7aa6 Michael Hanselmann
1751 887c7aa6 Michael Hanselmann
    acquires = [("one", prio, self.done) for prio in range(1, 33)]
1752 887c7aa6 Michael Hanselmann
    acquires.extend([("two", prio, done_two) for prio in range(1, 33)])
1753 887c7aa6 Michael Hanselmann
1754 887c7aa6 Michael Hanselmann
    # Use a deterministic random generator
1755 887c7aa6 Michael Hanselmann
    random.Random(741).shuffle(acquires)
1756 887c7aa6 Michael Hanselmann
1757 887c7aa6 Michael Hanselmann
    for (name, prio, done) in acquires:
1758 887c7aa6 Michael Hanselmann
      ev = threading.Event()
1759 887c7aa6 Michael Hanselmann
      self._addThread(target=_Acquire,
1760 887c7aa6 Michael Hanselmann
                      args=(prev, ev, name, prio,
1761 887c7aa6 Michael Hanselmann
                            compat.partial(done.put, "Prio%s" % prio)))
1762 887c7aa6 Michael Hanselmann
      prev = ev
1763 887c7aa6 Michael Hanselmann
1764 887c7aa6 Michael Hanselmann
    # Start acquires
1765 887c7aa6 Michael Hanselmann
    first.set()
1766 887c7aa6 Michael Hanselmann
1767 887c7aa6 Michael Hanselmann
    # Wait for last acquire to start
1768 887c7aa6 Michael Hanselmann
    prev.wait()
1769 887c7aa6 Michael Hanselmann
1770 887c7aa6 Michael Hanselmann
    # Let threads acquire locks
1771 887c7aa6 Michael Hanselmann
    self.ls.release()
1772 887c7aa6 Michael Hanselmann
1773 887c7aa6 Michael Hanselmann
    # Wait for threads to finish
1774 887c7aa6 Michael Hanselmann
    self._waitThreads()
1775 887c7aa6 Michael Hanselmann
1776 887c7aa6 Michael Hanselmann
    for i in range(1, 33):
1777 887c7aa6 Michael Hanselmann
      self.assertEqual(self.done.get_nowait(), "Prio%s" % i)
1778 887c7aa6 Michael Hanselmann
      self.assertEqual(done_two.get_nowait(), "Prio%s" % i)
1779 887c7aa6 Michael Hanselmann
1780 887c7aa6 Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1781 887c7aa6 Michael Hanselmann
    self.assertRaises(Queue.Empty, done_two.get_nowait)
1782 887c7aa6 Michael Hanselmann
1783 a95c53ea Michael Hanselmann
  def testNamesWithOpportunisticAndTimeout(self):
1784 a95c53ea Michael Hanselmann
    self.assertRaises(AssertionError, self.ls.acquire,
1785 a95c53ea Michael Hanselmann
                      ["one", "two"], timeout=1.0, opportunistic=True)
1786 a95c53ea Michael Hanselmann
1787 a95c53ea Michael Hanselmann
  def testOpportunisticWithUnknownName(self):
1788 a95c53ea Michael Hanselmann
    name = "unknown"
1789 a95c53ea Michael Hanselmann
    self.assertFalse(name in self.ls._names())
1790 a95c53ea Michael Hanselmann
    result = self.ls.acquire(name, opportunistic=True)
1791 a95c53ea Michael Hanselmann
    self.assertFalse(result)
1792 a95c53ea Michael Hanselmann
    self.assertFalse(self.ls.list_owned())
1793 a95c53ea Michael Hanselmann
1794 a95c53ea Michael Hanselmann
    result = self.ls.acquire(["two", name], opportunistic=True)
1795 a95c53ea Michael Hanselmann
    self.assertEqual(result, set(["two"]))
1796 a95c53ea Michael Hanselmann
    self.assertEqual(self.ls.list_owned(), set(["two"]))
1797 a95c53ea Michael Hanselmann
1798 a95c53ea Michael Hanselmann
    self.ls.release()
1799 a95c53ea Michael Hanselmann
1800 a95c53ea Michael Hanselmann
  def testSimpleOpportunisticAcquisition(self):
1801 a95c53ea Michael Hanselmann
    self.assertEquals(self.ls._names(), set(["one", "two", "three"]))
1802 a95c53ea Michael Hanselmann
1803 a95c53ea Michael Hanselmann
    # Hold a lock in main thread
1804 a95c53ea Michael Hanselmann
    self.assertEqual(self.ls.acquire("two", shared=0), set(["two"]))
1805 a95c53ea Michael Hanselmann
1806 a95c53ea Michael Hanselmann
    def fn():
1807 a95c53ea Michael Hanselmann
      # The lock "two" is held by the main thread
1808 a95c53ea Michael Hanselmann
      result = self.ls.acquire(["one", "two"], shared=0, opportunistic=True)
1809 a95c53ea Michael Hanselmann
      self.assertEqual(result, set(["one"]))
1810 a95c53ea Michael Hanselmann
      self.assertEqual(self.ls.list_owned(), set(["one"]))
1811 a95c53ea Michael Hanselmann
      self.assertFalse(self.ls._get_lock().is_owned())
1812 a95c53ea Michael Hanselmann
1813 a95c53ea Michael Hanselmann
      self.ls.release()
1814 a95c53ea Michael Hanselmann
      self.assertFalse(self.ls.list_owned())
1815 a95c53ea Michael Hanselmann
1816 a95c53ea Michael Hanselmann
      # Try to acquire the lock held by the main thread
1817 a95c53ea Michael Hanselmann
      result = self.ls.acquire(["two"], shared=0, opportunistic=True)
1818 a95c53ea Michael Hanselmann
      self.assertFalse(self.ls._get_lock().is_owned())
1819 a95c53ea Michael Hanselmann
      self.assertFalse(result)
1820 a95c53ea Michael Hanselmann
      self.assertFalse(self.ls.list_owned())
1821 a95c53ea Michael Hanselmann
1822 a95c53ea Michael Hanselmann
      # Try to acquire all locks
1823 a95c53ea Michael Hanselmann
      result = self.ls.acquire(locking.ALL_SET, shared=0, opportunistic=True)
1824 a95c53ea Michael Hanselmann
      self.assertTrue(self.ls._get_lock().is_owned(),
1825 a95c53ea Michael Hanselmann
                      msg="Internal lock is not owned")
1826 a95c53ea Michael Hanselmann
      self.assertEqual(result, set(["one", "three"]))
1827 a95c53ea Michael Hanselmann
      self.assertEqual(self.ls.list_owned(), set(["one", "three"]))
1828 a95c53ea Michael Hanselmann
1829 a95c53ea Michael Hanselmann
      self.ls.release()
1830 a95c53ea Michael Hanselmann
1831 a95c53ea Michael Hanselmann
      self.assertFalse(self.ls.list_owned())
1832 a95c53ea Michael Hanselmann
1833 a95c53ea Michael Hanselmann
      self.done.put(True)
1834 a95c53ea Michael Hanselmann
1835 a95c53ea Michael Hanselmann
    self._addThread(target=fn)
1836 a95c53ea Michael Hanselmann
1837 a95c53ea Michael Hanselmann
    # Wait for threads to finish
1838 a95c53ea Michael Hanselmann
    self._waitThreads()
1839 a95c53ea Michael Hanselmann
1840 a95c53ea Michael Hanselmann
    self.assertEqual(self.ls.list_owned(), set(["two"]))
1841 a95c53ea Michael Hanselmann
1842 a95c53ea Michael Hanselmann
    self.ls.release()
1843 a95c53ea Michael Hanselmann
    self.assertFalse(self.ls.list_owned())
1844 a95c53ea Michael Hanselmann
    self.assertFalse(self.ls._get_lock().is_owned())
1845 a95c53ea Michael Hanselmann
1846 a95c53ea Michael Hanselmann
    self.assertTrue(self.done.get_nowait())
1847 a95c53ea Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1848 a95c53ea Michael Hanselmann
1849 a95c53ea Michael Hanselmann
  def testOpportunisticAcquisitionWithoutNamesExpires(self):
1850 a95c53ea Michael Hanselmann
    self.assertEquals(self.ls._names(), set(["one", "two", "three"]))
1851 a95c53ea Michael Hanselmann
1852 a95c53ea Michael Hanselmann
    # Hold all locks in main thread
1853 a95c53ea Michael Hanselmann
    self.ls.acquire(locking.ALL_SET, shared=0)
1854 a95c53ea Michael Hanselmann
    self.assertTrue(self.ls._get_lock().is_owned())
1855 a95c53ea Michael Hanselmann
1856 a95c53ea Michael Hanselmann
    def fn():
1857 a95c53ea Michael Hanselmann
      # Try to acquire all locks in separate thread
1858 a95c53ea Michael Hanselmann
      result = self.ls.acquire(locking.ALL_SET, shared=0, opportunistic=True,
1859 a95c53ea Michael Hanselmann
                               timeout=0.1)
1860 a95c53ea Michael Hanselmann
      self.assertFalse(result)
1861 a95c53ea Michael Hanselmann
      self.assertFalse(self.ls._get_lock().is_owned())
1862 a95c53ea Michael Hanselmann
      self.assertFalse(self.ls.list_owned())
1863 a95c53ea Michael Hanselmann
1864 a95c53ea Michael Hanselmann
      # Try once more without a timeout
1865 a95c53ea Michael Hanselmann
      self.assertFalse(self.ls.acquire("one", shared=0, opportunistic=True))
1866 a95c53ea Michael Hanselmann
1867 a95c53ea Michael Hanselmann
      self.done.put(True)
1868 a95c53ea Michael Hanselmann
1869 a95c53ea Michael Hanselmann
    self._addThread(target=fn)
1870 a95c53ea Michael Hanselmann
1871 a95c53ea Michael Hanselmann
    # Wait for threads to finish
1872 a95c53ea Michael Hanselmann
    self._waitThreads()
1873 a95c53ea Michael Hanselmann
1874 a95c53ea Michael Hanselmann
    self.assertEqual(self.ls.list_owned(), set(["one", "two", "three"]))
1875 a95c53ea Michael Hanselmann
1876 a95c53ea Michael Hanselmann
    self.ls.release()
1877 a95c53ea Michael Hanselmann
    self.assertFalse(self.ls.list_owned())
1878 a95c53ea Michael Hanselmann
    self.assertFalse(self.ls._get_lock().is_owned(shared=0))
1879 a95c53ea Michael Hanselmann
1880 a95c53ea Michael Hanselmann
    self.assertTrue(self.done.get_nowait())
1881 a95c53ea Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1882 a95c53ea Michael Hanselmann
1883 a95c53ea Michael Hanselmann
  def testSharedOpportunisticAcquisitionWithoutNames(self):
1884 a95c53ea Michael Hanselmann
    self.assertEquals(self.ls._names(), set(["one", "two", "three"]))
1885 a95c53ea Michael Hanselmann
1886 a95c53ea Michael Hanselmann
    # Hold all locks in main thread
1887 a95c53ea Michael Hanselmann
    self.ls.acquire(locking.ALL_SET, shared=1)
1888 a95c53ea Michael Hanselmann
    self.assertTrue(self.ls._get_lock().is_owned(shared=1))
1889 a95c53ea Michael Hanselmann
1890 a95c53ea Michael Hanselmann
    def fn():
1891 a95c53ea Michael Hanselmann
      # Try to acquire all locks in separate thread in shared mode
1892 a95c53ea Michael Hanselmann
      result = self.ls.acquire(locking.ALL_SET, shared=1, opportunistic=True,
1893 a95c53ea Michael Hanselmann
                               timeout=0.1)
1894 a95c53ea Michael Hanselmann
      self.assertEqual(result, set(["one", "two", "three"]))
1895 a95c53ea Michael Hanselmann
      self.assertTrue(self.ls._get_lock().is_owned(shared=1))
1896 a95c53ea Michael Hanselmann
      self.ls.release()
1897 a95c53ea Michael Hanselmann
      self.assertFalse(self.ls._get_lock().is_owned())
1898 a95c53ea Michael Hanselmann
1899 a95c53ea Michael Hanselmann
      # Try one in exclusive mode
1900 a95c53ea Michael Hanselmann
      self.assertFalse(self.ls.acquire("one", shared=0, opportunistic=True))
1901 a95c53ea Michael Hanselmann
1902 a95c53ea Michael Hanselmann
      self.done.put(True)
1903 a95c53ea Michael Hanselmann
1904 a95c53ea Michael Hanselmann
    self._addThread(target=fn)
1905 a95c53ea Michael Hanselmann
1906 a95c53ea Michael Hanselmann
    # Wait for threads to finish
1907 a95c53ea Michael Hanselmann
    self._waitThreads()
1908 a95c53ea Michael Hanselmann
1909 a95c53ea Michael Hanselmann
    self.assertEqual(self.ls.list_owned(), set(["one", "two", "three"]))
1910 a95c53ea Michael Hanselmann
1911 a95c53ea Michael Hanselmann
    self.ls.release()
1912 a95c53ea Michael Hanselmann
    self.assertFalse(self.ls.list_owned())
1913 a95c53ea Michael Hanselmann
    self.assertFalse(self.ls._get_lock().is_owned())
1914 a95c53ea Michael Hanselmann
1915 a95c53ea Michael Hanselmann
    self.assertTrue(self.done.get_nowait())
1916 a95c53ea Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1917 a95c53ea Michael Hanselmann
1918 a95c53ea Michael Hanselmann
  def testLockDeleteWithOpportunisticAcquisition(self):
1919 a95c53ea Michael Hanselmann
    # This test exercises some code handling LockError on acquisition, that is
1920 a95c53ea Michael Hanselmann
    # after all lock names have been gathered. This shouldn't happen in reality
1921 a95c53ea Michael Hanselmann
    # as removing locks from the set requires the lockset-internal lock, but
1922 a95c53ea Michael Hanselmann
    # the code should handle the situation anyway.
1923 a95c53ea Michael Hanselmann
    ready = threading.Event()
1924 a95c53ea Michael Hanselmann
    finished = threading.Event()
1925 a95c53ea Michael Hanselmann
1926 a95c53ea Michael Hanselmann
    self.assertEquals(self.ls._names(), set(["one", "two", "three"]))
1927 a95c53ea Michael Hanselmann
1928 a95c53ea Michael Hanselmann
    # Thread function to delete lock
1929 a95c53ea Michael Hanselmann
    def fn():
1930 a95c53ea Michael Hanselmann
      # Wait for notification
1931 a95c53ea Michael Hanselmann
      ready.wait()
1932 a95c53ea Michael Hanselmann
1933 a95c53ea Michael Hanselmann
      # Delete lock named "two" by accessing lockset-internal data
1934 a95c53ea Michael Hanselmann
      ld = self.ls._get_lockdict()
1935 a95c53ea Michael Hanselmann
      self.assertTrue(ld["two"].delete())
1936 a95c53ea Michael Hanselmann
1937 a95c53ea Michael Hanselmann
      self.done.put("deleted.two")
1938 a95c53ea Michael Hanselmann
1939 a95c53ea Michael Hanselmann
      # Notify helper
1940 a95c53ea Michael Hanselmann
      finished.set()
1941 a95c53ea Michael Hanselmann
1942 a95c53ea Michael Hanselmann
    self._addThread(target=fn)
1943 a95c53ea Michael Hanselmann
1944 a95c53ea Michael Hanselmann
    # Notification helper, called when lock already holds internal lock.
1945 a95c53ea Michael Hanselmann
    # Therefore only one of the locks not yet locked can be deleted.
1946 a95c53ea Michael Hanselmann
    def notify(name):
1947 a95c53ea Michael Hanselmann
      self.done.put("notify.%s" % name)
1948 a95c53ea Michael Hanselmann
1949 a95c53ea Michael Hanselmann
      if name == "one":
1950 a95c53ea Michael Hanselmann
        # Tell helper thread to delete lock "two"
1951 a95c53ea Michael Hanselmann
        ready.set()
1952 a95c53ea Michael Hanselmann
        finished.wait()
1953 a95c53ea Michael Hanselmann
1954 a95c53ea Michael Hanselmann
    # Hold all locks in main thread
1955 a95c53ea Michael Hanselmann
    self.ls.acquire(locking.ALL_SET, shared=0, test_notify=notify)
1956 a95c53ea Michael Hanselmann
    self.assertEqual(self.ls.list_owned(), set(["one", "three"]))
1957 a95c53ea Michael Hanselmann
1958 a95c53ea Michael Hanselmann
    # Wait for threads to finish
1959 a95c53ea Michael Hanselmann
    self._waitThreads()
1960 a95c53ea Michael Hanselmann
1961 a95c53ea Michael Hanselmann
    # Release all locks
1962 a95c53ea Michael Hanselmann
    self.ls.release()
1963 a95c53ea Michael Hanselmann
    self.assertFalse(self.ls.list_owned())
1964 a95c53ea Michael Hanselmann
    self.assertFalse(self.ls._get_lock().is_owned())
1965 a95c53ea Michael Hanselmann
1966 a95c53ea Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "notify.one")
1967 a95c53ea Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "deleted.two")
1968 a95c53ea Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "notify.three")
1969 a95c53ea Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "notify.two")
1970 a95c53ea Michael Hanselmann
    self.assertRaises(Queue.Empty, self.done.get_nowait)
1971 a95c53ea Michael Hanselmann
1972 a95c53ea Michael Hanselmann
1973 a95c53ea Michael Hanselmann
class TestGetLsAcquireModeAndTimeouts(unittest.TestCase):
1974 a95c53ea Michael Hanselmann
  def setUp(self):
1975 a95c53ea Michael Hanselmann
    self.fn = locking._GetLsAcquireModeAndTimeouts
1976 a95c53ea Michael Hanselmann
1977 a95c53ea Michael Hanselmann
  def testOpportunisticWithoutNames(self):
1978 a95c53ea Michael Hanselmann
    (mode, ls_timeout_fn, timeout_fn) = self.fn(False, None, True)
1979 a95c53ea Michael Hanselmann
    self.assertEqual(mode, locking._LS_ACQUIRE_OPPORTUNISTIC)
1980 a95c53ea Michael Hanselmann
    self.assertTrue(ls_timeout_fn is None)
1981 a95c53ea Michael Hanselmann
    self.assertEqual(timeout_fn(), 0)
1982 a95c53ea Michael Hanselmann
1983 a95c53ea Michael Hanselmann
  def testAllInputCombinations(self):
1984 a95c53ea Michael Hanselmann
    for want_all in [False, True]:
1985 a95c53ea Michael Hanselmann
      for timeout in [None, 0, 100]:
1986 a95c53ea Michael Hanselmann
        for opportunistic in [False, True]:
1987 a95c53ea Michael Hanselmann
          if (opportunistic and
1988 a95c53ea Michael Hanselmann
              not want_all and
1989 a95c53ea Michael Hanselmann
              timeout is not None):
1990 a95c53ea Michael Hanselmann
            # Can't accept a timeout when acquiring opportunistically
1991 a95c53ea Michael Hanselmann
            self.assertRaises(AssertionError, self.fn,
1992 a95c53ea Michael Hanselmann
                              want_all, timeout, opportunistic)
1993 a95c53ea Michael Hanselmann
          else:
1994 a95c53ea Michael Hanselmann
            (mode, ls_timeout_fn, timeout_fn) = \
1995 a95c53ea Michael Hanselmann
              self.fn(want_all, timeout, opportunistic)
1996 a95c53ea Michael Hanselmann
1997 a95c53ea Michael Hanselmann
            if opportunistic:
1998 a95c53ea Michael Hanselmann
              self.assertEqual(mode, locking._LS_ACQUIRE_OPPORTUNISTIC)
1999 a95c53ea Michael Hanselmann
              self.assertEqual(timeout_fn(), 0)
2000 a95c53ea Michael Hanselmann
            else:
2001 a95c53ea Michael Hanselmann
              self.assertTrue(callable(timeout_fn))
2002 a95c53ea Michael Hanselmann
              if want_all:
2003 a95c53ea Michael Hanselmann
                self.assertEqual(mode, locking._LS_ACQUIRE_ALL)
2004 a95c53ea Michael Hanselmann
              else:
2005 a95c53ea Michael Hanselmann
                self.assertEqual(mode, locking._LS_ACQUIRE_EXACT)
2006 a95c53ea Michael Hanselmann
2007 a95c53ea Michael Hanselmann
            if want_all:
2008 a95c53ea Michael Hanselmann
              self.assertTrue(callable(ls_timeout_fn))
2009 a95c53ea Michael Hanselmann
            else:
2010 a95c53ea Michael Hanselmann
              self.assertTrue(ls_timeout_fn is None)
2011 a95c53ea Michael Hanselmann
2012 aaae9bc0 Guido Trotter
2013 4607c978 Iustin Pop
class TestGanetiLockManager(_ThreadedTestCase):
2014 7ee7c0c7 Guido Trotter
  def setUp(self):
2015 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
2016 8c114acd Michael Hanselmann
    self.nodes = ["n1", "n2"]
2017 8c114acd Michael Hanselmann
    self.nodegroups = ["g1", "g2"]
2018 8c114acd Michael Hanselmann
    self.instances = ["i1", "i2", "i3"]
2019 8c114acd Michael Hanselmann
    self.networks = ["net1", "net2", "net3"]
2020 819ca990 Guido Trotter
    self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups,
2021 6e8091f9 Dimitris Aragiorgis
                                        self.instances, self.networks)
2022 7ee7c0c7 Guido Trotter
2023 7ee7c0c7 Guido Trotter
  def tearDown(self):
2024 7ee7c0c7 Guido Trotter
    # Don't try this at home...
2025 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
2026 7ee7c0c7 Guido Trotter
2027 7ee7c0c7 Guido Trotter
  def testLockingConstants(self):
2028 7ee7c0c7 Guido Trotter
    # The locking library internally cheats by assuming its constants have some
2029 7ee7c0c7 Guido Trotter
    # relationships with each other. Check those hold true.
2030 b10b9d74 Guido Trotter
    # This relationship is also used in the Processor to recursively acquire
2031 b10b9d74 Guido Trotter
    # the right locks. Again, please don't break it.
2032 7ee7c0c7 Guido Trotter
    for i in range(len(locking.LEVELS)):
2033 7ee7c0c7 Guido Trotter
      self.assertEqual(i, locking.LEVELS[i])
2034 7ee7c0c7 Guido Trotter
2035 7ee7c0c7 Guido Trotter
  def testDoubleGLFails(self):
2036 6e8091f9 Dimitris Aragiorgis
    self.assertRaises(AssertionError, locking.GanetiLockManager, [], [], [], [])
2037 7ee7c0c7 Guido Trotter
2038 7ee7c0c7 Guido Trotter
  def testLockNames(self):
2039 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
2040 8716b1db Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
2041 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
2042 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP),
2043 819ca990 Guido Trotter
                     set(self.nodegroups))
2044 cdb08f44 Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
2045 cdb08f44 Michael Hanselmann
                     set(self.instances))
2046 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_NETWORK),
2047 6e8091f9 Dimitris Aragiorgis
                     set(self.networks))
2048 7ee7c0c7 Guido Trotter
2049 7ee7c0c7 Guido Trotter
  def testInitAndResources(self):
2050 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
2051 6e8091f9 Dimitris Aragiorgis
    self.GL = locking.GanetiLockManager([], [], [], [])
2052 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
2053 8716b1db Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
2054 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
2055 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
2056 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
2057 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_NETWORK), set())
2058 7ee7c0c7 Guido Trotter
2059 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
2060 6e8091f9 Dimitris Aragiorgis
    self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups, [], [])
2061 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
2062 8716b1db Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
2063 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
2064 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP),
2065 819ca990 Guido Trotter
                                    set(self.nodegroups))
2066 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
2067 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_NETWORK), set())
2068 7ee7c0c7 Guido Trotter
2069 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
2070 6e8091f9 Dimitris Aragiorgis
    self.GL = locking.GanetiLockManager([], [], self.instances, [])
2071 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
2072 8716b1db Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
2073 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
2074 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
2075 cdb08f44 Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
2076 cdb08f44 Michael Hanselmann
                     set(self.instances))
2077 7ee7c0c7 Guido Trotter
2078 6e8091f9 Dimitris Aragiorgis
    locking.GanetiLockManager._instance = None
2079 6e8091f9 Dimitris Aragiorgis
    self.GL = locking.GanetiLockManager([], [], [], self.networks)
2080 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
2081 8716b1db Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
2082 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
2083 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
2084 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
2085 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_NETWORK),
2086 6e8091f9 Dimitris Aragiorgis
                     set(self.networks))
2087 6e8091f9 Dimitris Aragiorgis
2088 7ee7c0c7 Guido Trotter
  def testAcquireRelease(self):
2089 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
2090 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_CLUSTER), set(["BGL"]))
2091 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_INSTANCE, ["i1"])
2092 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_NODEGROUP, ["g2"])
2093 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_NODE, ["n1", "n2"], shared=1)
2094 c6a622cf Michael Hanselmann
    self.assertTrue(self.GL.check_owned(locking.LEVEL_NODE, ["n1", "n2"],
2095 c6a622cf Michael Hanselmann
                                        shared=1))
2096 c6a622cf Michael Hanselmann
    self.assertFalse(self.GL.check_owned(locking.LEVEL_INSTANCE, ["i1", "i3"]))
2097 8c114acd Michael Hanselmann
    self.GL.release(locking.LEVEL_NODE, ["n2"])
2098 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODE), set(["n1"]))
2099 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODEGROUP), set(["g2"]))
2100 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_INSTANCE), set(["i1"]))
2101 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
2102 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODE), set())
2103 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODEGROUP), set(["g2"]))
2104 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_INSTANCE), set(["i1"]))
2105 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_NODEGROUP)
2106 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
2107 7ee7c0c7 Guido Trotter
    self.assertRaises(errors.LockError, self.GL.acquire,
2108 8c114acd Michael Hanselmann
                      locking.LEVEL_INSTANCE, ["i5"])
2109 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_INSTANCE, ["i3"], shared=1)
2110 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_INSTANCE), set(["i3"]))
2111 7ee7c0c7 Guido Trotter
2112 90c942d1 Guido Trotter
  def testAcquireWholeSets(self):
2113 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
2114 90c942d1 Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_INSTANCE, None),
2115 90c942d1 Guido Trotter
                      set(self.instances))
2116 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_INSTANCE),
2117 90c942d1 Guido Trotter
                      set(self.instances))
2118 819ca990 Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODEGROUP, None),
2119 819ca990 Guido Trotter
                      set(self.nodegroups))
2120 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODEGROUP),
2121 819ca990 Guido Trotter
                      set(self.nodegroups))
2122 90c942d1 Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODE, None, shared=1),
2123 90c942d1 Guido Trotter
                      set(self.nodes))
2124 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODE),
2125 90c942d1 Guido Trotter
                      set(self.nodes))
2126 8c811986 Michael Hanselmann
    self.assertTrue(self.GL.owning_all(locking.LEVEL_INSTANCE))
2127 8c811986 Michael Hanselmann
    self.assertTrue(self.GL.owning_all(locking.LEVEL_NODEGROUP))
2128 8c811986 Michael Hanselmann
    self.assertTrue(self.GL.owning_all(locking.LEVEL_NODE))
2129 90c942d1 Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
2130 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_NODEGROUP)
2131 d4f6a91c Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
2132 d4f6a91c Guido Trotter
    self.GL.release(locking.LEVEL_CLUSTER)
2133 d4f6a91c Guido Trotter
2134 d4f6a91c Guido Trotter
  def testAcquireWholeAndPartial(self):
2135 8c811986 Michael Hanselmann
    self.assertFalse(self.GL.owning_all(locking.LEVEL_INSTANCE))
2136 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
2137 d4f6a91c Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_INSTANCE, None),
2138 d4f6a91c Guido Trotter
                      set(self.instances))
2139 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_INSTANCE),
2140 d4f6a91c Guido Trotter
                      set(self.instances))
2141 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODE, ["n2"], shared=1),
2142 8c114acd Michael Hanselmann
                      set(["n2"]))
2143 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODE),
2144 8c114acd Michael Hanselmann
                      set(["n2"]))
2145 8c811986 Michael Hanselmann
    self.assertTrue(self.GL.owning_all(locking.LEVEL_INSTANCE))
2146 8c811986 Michael Hanselmann
    self.assertFalse(self.GL.owning_all(locking.LEVEL_NODE))
2147 d4f6a91c Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
2148 90c942d1 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
2149 90c942d1 Guido Trotter
    self.GL.release(locking.LEVEL_CLUSTER)
2150 90c942d1 Guido Trotter
2151 7ee7c0c7 Guido Trotter
  def testBGLDependency(self):
2152 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
2153 8c114acd Michael Hanselmann
                      locking.LEVEL_NODE, ["n1", "n2"])
2154 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
2155 8c114acd Michael Hanselmann
                      locking.LEVEL_INSTANCE, ["i3"])
2156 819ca990 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
2157 8c114acd Michael Hanselmann
                      locking.LEVEL_NODEGROUP, ["g1"])
2158 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
2159 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_NODE, ["n1"])
2160 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
2161 8c114acd Michael Hanselmann
                      locking.LEVEL_CLUSTER, ["BGL"])
2162 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
2163 7ee7c0c7 Guido Trotter
                      locking.LEVEL_CLUSTER)
2164 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
2165 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_INSTANCE, ["i1", "i2"])
2166 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
2167 8c114acd Michael Hanselmann
                      locking.LEVEL_CLUSTER, ["BGL"])
2168 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
2169 7ee7c0c7 Guido Trotter
                      locking.LEVEL_CLUSTER)
2170 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
2171 819ca990 Guido Trotter
    self.GL.acquire(locking.LEVEL_NODEGROUP, None)
2172 8c114acd Michael Hanselmann
    self.GL.release(locking.LEVEL_NODEGROUP, ["g1"])
2173 819ca990 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
2174 8c114acd Michael Hanselmann
                      locking.LEVEL_CLUSTER, ["BGL"])
2175 819ca990 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
2176 819ca990 Guido Trotter
                      locking.LEVEL_CLUSTER)
2177 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_NODEGROUP)
2178 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_CLUSTER)
2179 7ee7c0c7 Guido Trotter
2180 7ee7c0c7 Guido Trotter
  def testWrongOrder(self):
2181 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
2182 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_NODE, ["n2"])
2183 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
2184 8c114acd Michael Hanselmann
                      locking.LEVEL_NODE, ["n1"])
2185 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
2186 8c114acd Michael Hanselmann
                      locking.LEVEL_NODEGROUP, ["g1"])
2187 819ca990 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
2188 8c114acd Michael Hanselmann
                      locking.LEVEL_INSTANCE, ["i2"])
2189 7ee7c0c7 Guido Trotter
2190 4badc36c Guido Trotter
  def testModifiableLevels(self):
2191 4badc36c Guido Trotter
    self.assertRaises(AssertionError, self.GL.add, locking.LEVEL_CLUSTER,
2192 8c114acd Michael Hanselmann
                      ["BGL2"])
2193 8716b1db Michael Hanselmann
    self.assertRaises(AssertionError, self.GL.add, locking.LEVEL_NODE_ALLOC,
2194 8716b1db Michael Hanselmann
                      ["NAL2"])
2195 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"])
2196 8c114acd Michael Hanselmann
    self.GL.add(locking.LEVEL_INSTANCE, ["i4"])
2197 8c114acd Michael Hanselmann
    self.GL.remove(locking.LEVEL_INSTANCE, ["i3"])
2198 8c114acd Michael Hanselmann
    self.GL.remove(locking.LEVEL_INSTANCE, ["i1"])
2199 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set(["i2", "i4"]))
2200 8c114acd Michael Hanselmann
    self.GL.add(locking.LEVEL_NODE, ["n3"])
2201 8c114acd Michael Hanselmann
    self.GL.remove(locking.LEVEL_NODE, ["n1"])
2202 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(["n2", "n3"]))
2203 8c114acd Michael Hanselmann
    self.GL.add(locking.LEVEL_NODEGROUP, ["g3"])
2204 8c114acd Michael Hanselmann
    self.GL.remove(locking.LEVEL_NODEGROUP, ["g2"])
2205 8c114acd Michael Hanselmann
    self.GL.remove(locking.LEVEL_NODEGROUP, ["g1"])
2206 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set(["g3"]))
2207 4badc36c Guido Trotter
    self.assertRaises(AssertionError, self.GL.remove, locking.LEVEL_CLUSTER,
2208 8c114acd Michael Hanselmann
                      ["BGL2"])
2209 4badc36c Guido Trotter
2210 7ee7c0c7 Guido Trotter
  # Helper function to run as a thread that shared the BGL and then acquires
2211 7ee7c0c7 Guido Trotter
  # some locks at another level.
2212 7ee7c0c7 Guido Trotter
  def _doLock(self, level, names, shared):
2213 7ee7c0c7 Guido Trotter
    try:
2214 8c114acd Michael Hanselmann
      self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
2215 7ee7c0c7 Guido Trotter
      self.GL.acquire(level, names, shared=shared)
2216 8c114acd Michael Hanselmann
      self.done.put("DONE")
2217 7ee7c0c7 Guido Trotter
      self.GL.release(level)
2218 7ee7c0c7 Guido Trotter
      self.GL.release(locking.LEVEL_CLUSTER)
2219 7ee7c0c7 Guido Trotter
    except errors.LockError:
2220 8c114acd Michael Hanselmann
      self.done.put("ERR")
2221 7ee7c0c7 Guido Trotter
2222 4607c978 Iustin Pop
  @_Repeat
2223 7ee7c0c7 Guido Trotter
  def testConcurrency(self):
2224 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
2225 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
2226 8c114acd Michael Hanselmann
                    args=(locking.LEVEL_INSTANCE, "i1", 1))
2227 4607c978 Iustin Pop
    self._waitThreads()
2228 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
2229 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_INSTANCE, ["i3"])
2230 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
2231 8c114acd Michael Hanselmann
                    args=(locking.LEVEL_INSTANCE, "i1", 1))
2232 4607c978 Iustin Pop
    self._waitThreads()
2233 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
2234 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
2235 8c114acd Michael Hanselmann
                    args=(locking.LEVEL_INSTANCE, "i3", 1))
2236 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
2237 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
2238 4607c978 Iustin Pop
    self._waitThreads()
2239 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
2240 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_INSTANCE, ["i2"], shared=1)
2241 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
2242 8c114acd Michael Hanselmann
                    args=(locking.LEVEL_INSTANCE, "i2", 1))
2243 4607c978 Iustin Pop
    self._waitThreads()
2244 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
2245 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
2246 8c114acd Michael Hanselmann
                    args=(locking.LEVEL_INSTANCE, "i2", 0))
2247 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
2248 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
2249 4607c978 Iustin Pop
    self._waitThreads()
2250 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get(True, 1), "DONE")
2251 8c114acd Michael Hanselmann
    self.GL.release(locking.LEVEL_CLUSTER, ["BGL"])
2252 7ee7c0c7 Guido Trotter
2253 7ee7c0c7 Guido Trotter
2254 19b9ba9a Michael Hanselmann
class TestLockMonitor(_ThreadedTestCase):
2255 19b9ba9a Michael Hanselmann
  def setUp(self):
2256 19b9ba9a Michael Hanselmann
    _ThreadedTestCase.setUp(self)
2257 19b9ba9a Michael Hanselmann
    self.lm = locking.LockMonitor()
2258 19b9ba9a Michael Hanselmann
2259 19b9ba9a Michael Hanselmann
  def testSingleThread(self):
2260 19b9ba9a Michael Hanselmann
    locks = []
2261 19b9ba9a Michael Hanselmann
2262 19b9ba9a Michael Hanselmann
    for i in range(100):
2263 19b9ba9a Michael Hanselmann
      name = "TestLock%s" % i
2264 19b9ba9a Michael Hanselmann
      locks.append(locking.SharedLock(name, monitor=self.lm))
2265 19b9ba9a Michael Hanselmann
2266 19b9ba9a Michael Hanselmann
    self.assertEqual(len(self.lm._locks), len(locks))
2267 24d16f76 Michael Hanselmann
    result = objects.QueryResponse.FromDict(self.lm.QueryLocks(["name"]))
2268 24d16f76 Michael Hanselmann
    self.assertEqual(len(result.fields), 1)
2269 24d16f76 Michael Hanselmann
    self.assertEqual(len(result.data), 100)
2270 c31825f7 Michael Hanselmann
2271 19b9ba9a Michael Hanselmann
    # Delete all locks
2272 19b9ba9a Michael Hanselmann
    del locks[:]
2273 19b9ba9a Michael Hanselmann
2274 19b9ba9a Michael Hanselmann
    # The garbage collector might needs some time
2275 19b9ba9a Michael Hanselmann
    def _CheckLocks():
2276 19b9ba9a Michael Hanselmann
      if self.lm._locks:
2277 19b9ba9a Michael Hanselmann
        raise utils.RetryAgain()
2278 19b9ba9a Michael Hanselmann
2279 19b9ba9a Michael Hanselmann
    utils.Retry(_CheckLocks, 0.1, 30.0)
2280 19b9ba9a Michael Hanselmann
2281 19b9ba9a Michael Hanselmann
    self.assertFalse(self.lm._locks)
2282 19b9ba9a Michael Hanselmann
2283 19b9ba9a Michael Hanselmann
  def testMultiThread(self):
2284 19b9ba9a Michael Hanselmann
    locks = []
2285 19b9ba9a Michael Hanselmann
2286 19b9ba9a Michael Hanselmann
    def _CreateLock(prev, next, name):
2287 19b9ba9a Michael Hanselmann
      prev.wait()
2288 19b9ba9a Michael Hanselmann
      locks.append(locking.SharedLock(name, monitor=self.lm))
2289 19b9ba9a Michael Hanselmann
      if next:
2290 19b9ba9a Michael Hanselmann
        next.set()
2291 19b9ba9a Michael Hanselmann
2292 19b9ba9a Michael Hanselmann
    expnames = []
2293 19b9ba9a Michael Hanselmann
2294 19b9ba9a Michael Hanselmann
    first = threading.Event()
2295 19b9ba9a Michael Hanselmann
    prev = first
2296 19b9ba9a Michael Hanselmann
2297 19b9ba9a Michael Hanselmann
    # Use a deterministic random generator
2298 19b9ba9a Michael Hanselmann
    for i in random.Random(4263).sample(range(100), 33):
2299 19b9ba9a Michael Hanselmann
      name = "MtTestLock%s" % i
2300 19b9ba9a Michael Hanselmann
      expnames.append(name)
2301 19b9ba9a Michael Hanselmann
2302 19b9ba9a Michael Hanselmann
      ev = threading.Event()
2303 19b9ba9a Michael Hanselmann
      self._addThread(target=_CreateLock, args=(prev, ev, name))
2304 19b9ba9a Michael Hanselmann
      prev = ev
2305 19b9ba9a Michael Hanselmann
2306 19b9ba9a Michael Hanselmann
    # Add locks
2307 19b9ba9a Michael Hanselmann
    first.set()
2308 19b9ba9a Michael Hanselmann
    self._waitThreads()
2309 19b9ba9a Michael Hanselmann
2310 19b9ba9a Michael Hanselmann
    # Check order in which locks were added
2311 19b9ba9a Michael Hanselmann
    self.assertEqual([i.name for i in locks], expnames)
2312 19b9ba9a Michael Hanselmann
2313 19b9ba9a Michael Hanselmann
    # Check query result
2314 24d16f76 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner", "pending"])
2315 24d16f76 Michael Hanselmann
    self.assert_(isinstance(result, dict))
2316 24d16f76 Michael Hanselmann
    response = objects.QueryResponse.FromDict(result)
2317 24d16f76 Michael Hanselmann
    self.assertEqual(response.data,
2318 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, name),
2319 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, None),
2320 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, None),
2321 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, [])]
2322 c31825f7 Michael Hanselmann
                      for name in utils.NiceSort(expnames)])
2323 24d16f76 Michael Hanselmann
    self.assertEqual(len(response.fields), 4)
2324 24d16f76 Michael Hanselmann
    self.assertEqual(["name", "mode", "owner", "pending"],
2325 24d16f76 Michael Hanselmann
                     [fdef.name for fdef in response.fields])
2326 19b9ba9a Michael Hanselmann
2327 19b9ba9a Michael Hanselmann
    # Test exclusive acquire
2328 19b9ba9a Michael Hanselmann
    for tlock in locks[::4]:
2329 19b9ba9a Michael Hanselmann
      tlock.acquire(shared=0)
2330 19b9ba9a Michael Hanselmann
      try:
2331 19b9ba9a Michael Hanselmann
        def _GetExpResult(name):
2332 19b9ba9a Michael Hanselmann
          if tlock.name == name:
2333 cfb084ae René Nussbaumer
            return [(constants.RS_NORMAL, name),
2334 cfb084ae René Nussbaumer
                    (constants.RS_NORMAL, "exclusive"),
2335 cfb084ae René Nussbaumer
                    (constants.RS_NORMAL,
2336 24d16f76 Michael Hanselmann
                     [threading.currentThread().getName()]),
2337 cfb084ae René Nussbaumer
                    (constants.RS_NORMAL, [])]
2338 cfb084ae René Nussbaumer
          return [(constants.RS_NORMAL, name),
2339 cfb084ae René Nussbaumer
                  (constants.RS_NORMAL, None),
2340 cfb084ae René Nussbaumer
                  (constants.RS_NORMAL, None),
2341 cfb084ae René Nussbaumer
                  (constants.RS_NORMAL, [])]
2342 24d16f76 Michael Hanselmann
2343 24d16f76 Michael Hanselmann
        result = self.lm.QueryLocks(["name", "mode", "owner", "pending"])
2344 24d16f76 Michael Hanselmann
        self.assertEqual(objects.QueryResponse.FromDict(result).data,
2345 19b9ba9a Michael Hanselmann
                         [_GetExpResult(name)
2346 19b9ba9a Michael Hanselmann
                          for name in utils.NiceSort(expnames)])
2347 19b9ba9a Michael Hanselmann
      finally:
2348 19b9ba9a Michael Hanselmann
        tlock.release()
2349 19b9ba9a Michael Hanselmann
2350 19b9ba9a Michael Hanselmann
    # Test shared acquire
2351 73c25d35 Michael Hanselmann
    def _Acquire(lock, shared, ev, notify):
2352 19b9ba9a Michael Hanselmann
      lock.acquire(shared=shared)
2353 19b9ba9a Michael Hanselmann
      try:
2354 73c25d35 Michael Hanselmann
        notify.set()
2355 19b9ba9a Michael Hanselmann
        ev.wait()
2356 19b9ba9a Michael Hanselmann
      finally:
2357 19b9ba9a Michael Hanselmann
        lock.release()
2358 19b9ba9a Michael Hanselmann
2359 19b9ba9a Michael Hanselmann
    for tlock1 in locks[::11]:
2360 19b9ba9a Michael Hanselmann
      for tlock2 in locks[::-15]:
2361 19b9ba9a Michael Hanselmann
        if tlock2 == tlock1:
2362 73c25d35 Michael Hanselmann
          # Avoid deadlocks
2363 19b9ba9a Michael Hanselmann
          continue
2364 19b9ba9a Michael Hanselmann
2365 19b9ba9a Michael Hanselmann
        for tlock3 in locks[::10]:
2366 73c25d35 Michael Hanselmann
          if tlock3 in (tlock2, tlock1):
2367 73c25d35 Michael Hanselmann
            # Avoid deadlocks
2368 19b9ba9a Michael Hanselmann
            continue
2369 19b9ba9a Michael Hanselmann
2370 73c25d35 Michael Hanselmann
          releaseev = threading.Event()
2371 19b9ba9a Michael Hanselmann
2372 19b9ba9a Michael Hanselmann
          # Acquire locks
2373 73c25d35 Michael Hanselmann
          acquireev = []
2374 19b9ba9a Michael Hanselmann
          tthreads1 = []
2375 19b9ba9a Michael Hanselmann
          for i in range(3):
2376 73c25d35 Michael Hanselmann
            ev = threading.Event()
2377 19b9ba9a Michael Hanselmann
            tthreads1.append(self._addThread(target=_Acquire,
2378 73c25d35 Michael Hanselmann
                                             args=(tlock1, 1, releaseev, ev)))
2379 73c25d35 Michael Hanselmann
            acquireev.append(ev)
2380 73c25d35 Michael Hanselmann
2381 73c25d35 Michael Hanselmann
          ev = threading.Event()
2382 73c25d35 Michael Hanselmann
          tthread2 = self._addThread(target=_Acquire,
2383 73c25d35 Michael Hanselmann
                                     args=(tlock2, 1, releaseev, ev))
2384 73c25d35 Michael Hanselmann
          acquireev.append(ev)
2385 73c25d35 Michael Hanselmann
2386 73c25d35 Michael Hanselmann
          ev = threading.Event()
2387 73c25d35 Michael Hanselmann
          tthread3 = self._addThread(target=_Acquire,
2388 73c25d35 Michael Hanselmann
                                     args=(tlock3, 0, releaseev, ev))
2389 73c25d35 Michael Hanselmann
          acquireev.append(ev)
2390 73c25d35 Michael Hanselmann
2391 73c25d35 Michael Hanselmann
          # Wait for all locks to be acquired
2392 73c25d35 Michael Hanselmann
          for i in acquireev:
2393 73c25d35 Michael Hanselmann
            i.wait()
2394 19b9ba9a Michael Hanselmann
2395 19b9ba9a Michael Hanselmann
          # Check query result
2396 24d16f76 Michael Hanselmann
          result = self.lm.QueryLocks(["name", "mode", "owner"])
2397 24d16f76 Michael Hanselmann
          response = objects.QueryResponse.FromDict(result)
2398 24d16f76 Michael Hanselmann
          for (name, mode, owner) in response.data:
2399 24d16f76 Michael Hanselmann
            (name_status, name_value) = name
2400 24d16f76 Michael Hanselmann
            (owner_status, owner_value) = owner
2401 24d16f76 Michael Hanselmann
2402 cfb084ae René Nussbaumer
            self.assertEqual(name_status, constants.RS_NORMAL)
2403 cfb084ae René Nussbaumer
            self.assertEqual(owner_status, constants.RS_NORMAL)
2404 24d16f76 Michael Hanselmann
2405 24d16f76 Michael Hanselmann
            if name_value == tlock1.name:
2406 cfb084ae René Nussbaumer
              self.assertEqual(mode, (constants.RS_NORMAL, "shared"))
2407 24d16f76 Michael Hanselmann
              self.assertEqual(set(owner_value),
2408 24d16f76 Michael Hanselmann
                               set(i.getName() for i in tthreads1))
2409 19b9ba9a Michael Hanselmann
              continue
2410 19b9ba9a Michael Hanselmann
2411 24d16f76 Michael Hanselmann
            if name_value == tlock2.name:
2412 cfb084ae René Nussbaumer
              self.assertEqual(mode, (constants.RS_NORMAL, "shared"))
2413 24d16f76 Michael Hanselmann
              self.assertEqual(owner_value, [tthread2.getName()])
2414 19b9ba9a Michael Hanselmann
              continue
2415 19b9ba9a Michael Hanselmann
2416 24d16f76 Michael Hanselmann
            if name_value == tlock3.name:
2417 cfb084ae René Nussbaumer
              self.assertEqual(mode, (constants.RS_NORMAL, "exclusive"))
2418 24d16f76 Michael Hanselmann
              self.assertEqual(owner_value, [tthread3.getName()])
2419 19b9ba9a Michael Hanselmann
              continue
2420 19b9ba9a Michael Hanselmann
2421 24d16f76 Michael Hanselmann
            self.assert_(name_value in expnames)
2422 cfb084ae René Nussbaumer
            self.assertEqual(mode, (constants.RS_NORMAL, None))
2423 24d16f76 Michael Hanselmann
            self.assert_(owner_value is None)
2424 19b9ba9a Michael Hanselmann
2425 19b9ba9a Michael Hanselmann
          # Release locks again
2426 73c25d35 Michael Hanselmann
          releaseev.set()
2427 19b9ba9a Michael Hanselmann
2428 19b9ba9a Michael Hanselmann
          self._waitThreads()
2429 19b9ba9a Michael Hanselmann
2430 24d16f76 Michael Hanselmann
          result = self.lm.QueryLocks(["name", "mode", "owner"])
2431 24d16f76 Michael Hanselmann
          self.assertEqual(objects.QueryResponse.FromDict(result).data,
2432 cfb084ae René Nussbaumer
                           [[(constants.RS_NORMAL, name),
2433 cfb084ae René Nussbaumer
                             (constants.RS_NORMAL, None),
2434 cfb084ae René Nussbaumer
                             (constants.RS_NORMAL, None)]
2435 19b9ba9a Michael Hanselmann
                            for name in utils.NiceSort(expnames)])
2436 19b9ba9a Michael Hanselmann
2437 19b9ba9a Michael Hanselmann
  def testDelete(self):
2438 19b9ba9a Michael Hanselmann
    lock = locking.SharedLock("TestLock", monitor=self.lm)
2439 19b9ba9a Michael Hanselmann
2440 19b9ba9a Michael Hanselmann
    self.assertEqual(len(self.lm._locks), 1)
2441 24d16f76 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2442 24d16f76 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data,
2443 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, lock.name),
2444 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, None),
2445 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, None)]])
2446 19b9ba9a Michael Hanselmann
2447 19b9ba9a Michael Hanselmann
    lock.delete()
2448 19b9ba9a Michael Hanselmann
2449 24d16f76 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2450 24d16f76 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data,
2451 cfb084ae René Nussbaumer
                     [[(constants.RS_NORMAL, lock.name),
2452 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, "deleted"),
2453 cfb084ae René Nussbaumer
                       (constants.RS_NORMAL, None)]])
2454 19b9ba9a Michael Hanselmann
    self.assertEqual(len(self.lm._locks), 1)
2455 19b9ba9a Michael Hanselmann
2456 c31825f7 Michael Hanselmann
  def testPending(self):
2457 c31825f7 Michael Hanselmann
    def _Acquire(lock, shared, prev, next):
2458 c31825f7 Michael Hanselmann
      prev.wait()
2459 c31825f7 Michael Hanselmann
2460 c31825f7 Michael Hanselmann
      lock.acquire(shared=shared, test_notify=next.set)
2461 c31825f7 Michael Hanselmann
      try:
2462 c31825f7 Michael Hanselmann
        pass
2463 c31825f7 Michael Hanselmann
      finally:
2464 c31825f7 Michael Hanselmann
        lock.release()
2465 c31825f7 Michael Hanselmann
2466 c31825f7 Michael Hanselmann
    lock = locking.SharedLock("ExcLock", monitor=self.lm)
2467 c31825f7 Michael Hanselmann
2468 c31825f7 Michael Hanselmann
    for shared in [0, 1]:
2469 c31825f7 Michael Hanselmann
      lock.acquire()
2470 c31825f7 Michael Hanselmann
      try:
2471 c31825f7 Michael Hanselmann
        self.assertEqual(len(self.lm._locks), 1)
2472 24d16f76 Michael Hanselmann
        result = self.lm.QueryLocks(["name", "mode", "owner"])
2473 24d16f76 Michael Hanselmann
        self.assertEqual(objects.QueryResponse.FromDict(result).data,
2474 cfb084ae René Nussbaumer
                         [[(constants.RS_NORMAL, lock.name),
2475 cfb084ae René Nussbaumer
                           (constants.RS_NORMAL, "exclusive"),
2476 cfb084ae René Nussbaumer
                           (constants.RS_NORMAL,
2477 24d16f76 Michael Hanselmann
                            [threading.currentThread().getName()])]])
2478 c31825f7 Michael Hanselmann
2479 c31825f7 Michael Hanselmann
        threads = []
2480 c31825f7 Michael Hanselmann
2481 c31825f7 Michael Hanselmann
        first = threading.Event()
2482 c31825f7 Michael Hanselmann
        prev = first
2483 c31825f7 Michael Hanselmann
2484 c31825f7 Michael Hanselmann
        for i in range(5):
2485 c31825f7 Michael Hanselmann
          ev = threading.Event()
2486 c31825f7 Michael Hanselmann
          threads.append(self._addThread(target=_Acquire,
2487 c31825f7 Michael Hanselmann
                                          args=(lock, shared, prev, ev)))
2488 c31825f7 Michael Hanselmann
          prev = ev
2489 c31825f7 Michael Hanselmann
2490 c31825f7 Michael Hanselmann
        # Start acquires
2491 c31825f7 Michael Hanselmann
        first.set()
2492 c31825f7 Michael Hanselmann
2493 c31825f7 Michael Hanselmann
        # Wait for last acquire to start waiting
2494 c31825f7 Michael Hanselmann
        prev.wait()
2495 c31825f7 Michael Hanselmann
2496 c31825f7 Michael Hanselmann
        # NOTE: This works only because QueryLocks will acquire the
2497 c31825f7 Michael Hanselmann
        # lock-internal lock again and won't be able to get the information
2498 c31825f7 Michael Hanselmann
        # until it has the lock. By then the acquire should be registered in
2499 c31825f7 Michael Hanselmann
        # SharedLock.__pending (otherwise it's a bug).
2500 c31825f7 Michael Hanselmann
2501 c31825f7 Michael Hanselmann
        # All acquires are waiting now
2502 c31825f7 Michael Hanselmann
        if shared:
2503 24d16f76 Michael Hanselmann
          pending = [("shared", utils.NiceSort(t.getName() for t in threads))]
2504 c31825f7 Michael Hanselmann
        else:
2505 c31825f7 Michael Hanselmann
          pending = [("exclusive", [t.getName()]) for t in threads]
2506 c31825f7 Michael Hanselmann
2507 24d16f76 Michael Hanselmann
        result = self.lm.QueryLocks(["name", "mode", "owner", "pending"])
2508 24d16f76 Michael Hanselmann
        self.assertEqual(objects.QueryResponse.FromDict(result).data,
2509 cfb084ae René Nussbaumer
                         [[(constants.RS_NORMAL, lock.name),
2510 cfb084ae René Nussbaumer
                           (constants.RS_NORMAL, "exclusive"),
2511 cfb084ae René Nussbaumer
                           (constants.RS_NORMAL,
2512 24d16f76 Michael Hanselmann
                            [threading.currentThread().getName()]),
2513 cfb084ae René Nussbaumer
                           (constants.RS_NORMAL, pending)]])
2514 c31825f7 Michael Hanselmann
2515 c31825f7 Michael Hanselmann
        self.assertEqual(len(self.lm._locks), 1)
2516 c31825f7 Michael Hanselmann
      finally:
2517 c31825f7 Michael Hanselmann
        lock.release()
2518 c31825f7 Michael Hanselmann
2519 c31825f7 Michael Hanselmann
      self._waitThreads()
2520 c31825f7 Michael Hanselmann
2521 c31825f7 Michael Hanselmann
      # No pending acquires
2522 24d16f76 Michael Hanselmann
      result = self.lm.QueryLocks(["name", "mode", "owner", "pending"])
2523 24d16f76 Michael Hanselmann
      self.assertEqual(objects.QueryResponse.FromDict(result).data,
2524 cfb084ae René Nussbaumer
                       [[(constants.RS_NORMAL, lock.name),
2525 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, None),
2526 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, None),
2527 cfb084ae René Nussbaumer
                         (constants.RS_NORMAL, [])]])
2528 c31825f7 Michael Hanselmann
2529 c31825f7 Michael Hanselmann
      self.assertEqual(len(self.lm._locks), 1)
2530 c31825f7 Michael Hanselmann
2531 e4e35357 Michael Hanselmann
  def testDeleteAndRecreate(self):
2532 e4e35357 Michael Hanselmann
    lname = "TestLock101923193"
2533 e4e35357 Michael Hanselmann
2534 e4e35357 Michael Hanselmann
    # Create some locks with the same name and keep all references
2535 e4e35357 Michael Hanselmann
    locks = [locking.SharedLock(lname, monitor=self.lm)
2536 e4e35357 Michael Hanselmann
             for _ in range(5)]
2537 e4e35357 Michael Hanselmann
2538 e4e35357 Michael Hanselmann
    self.assertEqual(len(self.lm._locks), len(locks))
2539 e4e35357 Michael Hanselmann
2540 e4e35357 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2541 e4e35357 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data,
2542 e4e35357 Michael Hanselmann
                     [[(constants.RS_NORMAL, lname),
2543 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None),
2544 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None)]] * 5)
2545 e4e35357 Michael Hanselmann
2546 e4e35357 Michael Hanselmann
    locks[2].delete()
2547 e4e35357 Michael Hanselmann
2548 e4e35357 Michael Hanselmann
    # Check information order
2549 e4e35357 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2550 e4e35357 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data,
2551 e4e35357 Michael Hanselmann
                     [[(constants.RS_NORMAL, lname),
2552 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None),
2553 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None)]] * 2 +
2554 e4e35357 Michael Hanselmann
                     [[(constants.RS_NORMAL, lname),
2555 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, "deleted"),
2556 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None)]] +
2557 e4e35357 Michael Hanselmann
                     [[(constants.RS_NORMAL, lname),
2558 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None),
2559 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None)]] * 2)
2560 e4e35357 Michael Hanselmann
2561 e4e35357 Michael Hanselmann
    locks[1].acquire(shared=0)
2562 e4e35357 Michael Hanselmann
2563 e4e35357 Michael Hanselmann
    last_status = [
2564 e4e35357 Michael Hanselmann
      [(constants.RS_NORMAL, lname),
2565 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None),
2566 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None)],
2567 e4e35357 Michael Hanselmann
      [(constants.RS_NORMAL, lname),
2568 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, "exclusive"),
2569 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, [threading.currentThread().getName()])],
2570 e4e35357 Michael Hanselmann
      [(constants.RS_NORMAL, lname),
2571 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, "deleted"),
2572 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None)],
2573 e4e35357 Michael Hanselmann
      [(constants.RS_NORMAL, lname),
2574 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None),
2575 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None)],
2576 e4e35357 Michael Hanselmann
      [(constants.RS_NORMAL, lname),
2577 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None),
2578 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None)],
2579 e4e35357 Michael Hanselmann
      ]
2580 e4e35357 Michael Hanselmann
2581 e4e35357 Michael Hanselmann
    # Check information order
2582 e4e35357 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2583 e4e35357 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data, last_status)
2584 e4e35357 Michael Hanselmann
2585 e4e35357 Michael Hanselmann
    self.assertEqual(len(set(self.lm._locks.values())), len(locks))
2586 e4e35357 Michael Hanselmann
    self.assertEqual(len(self.lm._locks), len(locks))
2587 e4e35357 Michael Hanselmann
2588 e4e35357 Michael Hanselmann
    # Check lock deletion
2589 e4e35357 Michael Hanselmann
    for idx in range(len(locks)):
2590 e4e35357 Michael Hanselmann
      del locks[0]
2591 e4e35357 Michael Hanselmann
      assert gc.isenabled()
2592 e4e35357 Michael Hanselmann
      gc.collect()
2593 e4e35357 Michael Hanselmann
      self.assertEqual(len(self.lm._locks), len(locks))
2594 e4e35357 Michael Hanselmann
      result = self.lm.QueryLocks(["name", "mode", "owner"])
2595 e4e35357 Michael Hanselmann
      self.assertEqual(objects.QueryResponse.FromDict(result).data,
2596 e4e35357 Michael Hanselmann
                       last_status[idx + 1:])
2597 e4e35357 Michael Hanselmann
2598 e4e35357 Michael Hanselmann
    # All locks should have been deleted
2599 e4e35357 Michael Hanselmann
    assert not locks
2600 e4e35357 Michael Hanselmann
    self.assertFalse(self.lm._locks)
2601 e4e35357 Michael Hanselmann
2602 e4e35357 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2603 e4e35357 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data, [])
2604 e4e35357 Michael Hanselmann
2605 44b4eddc Michael Hanselmann
  class _FakeLock:
2606 44b4eddc Michael Hanselmann
    def __init__(self):
2607 44b4eddc Michael Hanselmann
      self._info = []
2608 44b4eddc Michael Hanselmann
2609 44b4eddc Michael Hanselmann
    def AddResult(self, *args):
2610 44b4eddc Michael Hanselmann
      self._info.append(args)
2611 44b4eddc Michael Hanselmann
2612 44b4eddc Michael Hanselmann
    def CountPending(self):
2613 44b4eddc Michael Hanselmann
      return len(self._info)
2614 44b4eddc Michael Hanselmann
2615 44b4eddc Michael Hanselmann
    def GetLockInfo(self, requested):
2616 44b4eddc Michael Hanselmann
      (exp_requested, result) = self._info.pop(0)
2617 44b4eddc Michael Hanselmann
2618 44b4eddc Michael Hanselmann
      if exp_requested != requested:
2619 44b4eddc Michael Hanselmann
        raise Exception("Requested information (%s) does not match"
2620 44b4eddc Michael Hanselmann
                        " expectations (%s)" % (requested, exp_requested))
2621 44b4eddc Michael Hanselmann
2622 44b4eddc Michael Hanselmann
      return result
2623 44b4eddc Michael Hanselmann
2624 44b4eddc Michael Hanselmann
  def testMultipleResults(self):
2625 44b4eddc Michael Hanselmann
    fl1 = self._FakeLock()
2626 44b4eddc Michael Hanselmann
    fl2 = self._FakeLock()
2627 44b4eddc Michael Hanselmann
2628 44b4eddc Michael Hanselmann
    self.lm.RegisterLock(fl1)
2629 44b4eddc Michael Hanselmann
    self.lm.RegisterLock(fl2)
2630 44b4eddc Michael Hanselmann
2631 44b4eddc Michael Hanselmann
    # Empty information
2632 44b4eddc Michael Hanselmann
    for i in [fl1, fl2]:
2633 44b4eddc Michael Hanselmann
      i.AddResult(set([query.LQ_MODE, query.LQ_OWNER]), [])
2634 44b4eddc Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2635 44b4eddc Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data, [])
2636 44b4eddc Michael Hanselmann
    for i in [fl1, fl2]:
2637 44b4eddc Michael Hanselmann
      self.assertEqual(i.CountPending(), 0)
2638 44b4eddc Michael Hanselmann
2639 44b4eddc Michael Hanselmann
    # Check ordering
2640 44b4eddc Michael Hanselmann
    for fn in [lambda x: x, reversed, sorted]:
2641 44b4eddc Michael Hanselmann
      fl1.AddResult(set(), list(fn([
2642 44b4eddc Michael Hanselmann
        ("aaa", None, None, None),
2643 44b4eddc Michael Hanselmann
        ("bbb", None, None, None),
2644 44b4eddc Michael Hanselmann
        ])))
2645 44b4eddc Michael Hanselmann
      fl2.AddResult(set(), [])
2646 44b4eddc Michael Hanselmann
      result = self.lm.QueryLocks(["name"])
2647 44b4eddc Michael Hanselmann
      self.assertEqual(objects.QueryResponse.FromDict(result).data, [
2648 44b4eddc Michael Hanselmann
        [(constants.RS_NORMAL, "aaa")],
2649 44b4eddc Michael Hanselmann
        [(constants.RS_NORMAL, "bbb")],
2650 44b4eddc Michael Hanselmann
        ])
2651 44b4eddc Michael Hanselmann
      for i in [fl1, fl2]:
2652 44b4eddc Michael Hanselmann
        self.assertEqual(i.CountPending(), 0)
2653 44b4eddc Michael Hanselmann
2654 44b4eddc Michael Hanselmann
      for fn2 in [lambda x: x, reversed, sorted]:
2655 44b4eddc Michael Hanselmann
        fl1.AddResult(set([query.LQ_MODE]), list(fn([
2656 44b4eddc Michael Hanselmann
          # Same name, but different information
2657 44b4eddc Michael Hanselmann
          ("aaa", "mode0", None, None),
2658 44b4eddc Michael Hanselmann
          ("aaa", "mode1", None, None),
2659 44b4eddc Michael Hanselmann
          ("aaa", "mode2", None, None),
2660 44b4eddc Michael Hanselmann
          ("aaa", "mode3", None, None),
2661 44b4eddc Michael Hanselmann
          ])))
2662 44b4eddc Michael Hanselmann
        fl2.AddResult(set([query.LQ_MODE]), [
2663 44b4eddc Michael Hanselmann
          ("zzz", "end", None, None),
2664 44b4eddc Michael Hanselmann
          ("000", "start", None, None),
2665 44b4eddc Michael Hanselmann
          ] + list(fn2([
2666 44b4eddc Michael Hanselmann
          ("aaa", "b200", None, None),
2667 44b4eddc Michael Hanselmann
          ("aaa", "b300", None, None),
2668 44b4eddc Michael Hanselmann
          ])))
2669 44b4eddc Michael Hanselmann
        result = self.lm.QueryLocks(["name", "mode"])
2670 44b4eddc Michael Hanselmann
        self.assertEqual(objects.QueryResponse.FromDict(result).data, [
2671 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "000"), (constants.RS_NORMAL, "start")],
2672 44b4eddc Michael Hanselmann
          ] + list(fn([
2673 44b4eddc Michael Hanselmann
          # Name is the same, so order must be equal to incoming order
2674 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "aaa"), (constants.RS_NORMAL, "mode0")],
2675 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "aaa"), (constants.RS_NORMAL, "mode1")],
2676 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "aaa"), (constants.RS_NORMAL, "mode2")],
2677 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "aaa"), (constants.RS_NORMAL, "mode3")],
2678 44b4eddc Michael Hanselmann
          ])) + list(fn2([
2679 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "aaa"), (constants.RS_NORMAL, "b200")],
2680 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "aaa"), (constants.RS_NORMAL, "b300")],
2681 44b4eddc Michael Hanselmann
          ])) + [
2682 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "zzz"), (constants.RS_NORMAL, "end")],
2683 44b4eddc Michael Hanselmann
          ])
2684 44b4eddc Michael Hanselmann
        for i in [fl1, fl2]:
2685 44b4eddc Michael Hanselmann
          self.assertEqual(i.CountPending(), 0)
2686 44b4eddc Michael Hanselmann
2687 19b9ba9a Michael Hanselmann
2688 2f96c43c Michael Hanselmann
if __name__ == "__main__":
2689 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()