Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.locking_unittest.py @ dffa96d6

History | View | Annotate | Download (84.2 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 aaae9bc0 Guido Trotter
1784 4607c978 Iustin Pop
class TestGanetiLockManager(_ThreadedTestCase):
1785 7ee7c0c7 Guido Trotter
  def setUp(self):
1786 4607c978 Iustin Pop
    _ThreadedTestCase.setUp(self)
1787 8c114acd Michael Hanselmann
    self.nodes = ["n1", "n2"]
1788 8c114acd Michael Hanselmann
    self.nodegroups = ["g1", "g2"]
1789 8c114acd Michael Hanselmann
    self.instances = ["i1", "i2", "i3"]
1790 8c114acd Michael Hanselmann
    self.networks = ["net1", "net2", "net3"]
1791 819ca990 Guido Trotter
    self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups,
1792 6e8091f9 Dimitris Aragiorgis
                                        self.instances, self.networks)
1793 7ee7c0c7 Guido Trotter
1794 7ee7c0c7 Guido Trotter
  def tearDown(self):
1795 7ee7c0c7 Guido Trotter
    # Don't try this at home...
1796 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
1797 7ee7c0c7 Guido Trotter
1798 7ee7c0c7 Guido Trotter
  def testLockingConstants(self):
1799 7ee7c0c7 Guido Trotter
    # The locking library internally cheats by assuming its constants have some
1800 7ee7c0c7 Guido Trotter
    # relationships with each other. Check those hold true.
1801 b10b9d74 Guido Trotter
    # This relationship is also used in the Processor to recursively acquire
1802 b10b9d74 Guido Trotter
    # the right locks. Again, please don't break it.
1803 7ee7c0c7 Guido Trotter
    for i in range(len(locking.LEVELS)):
1804 7ee7c0c7 Guido Trotter
      self.assertEqual(i, locking.LEVELS[i])
1805 7ee7c0c7 Guido Trotter
1806 7ee7c0c7 Guido Trotter
  def testDoubleGLFails(self):
1807 6e8091f9 Dimitris Aragiorgis
    self.assertRaises(AssertionError, locking.GanetiLockManager, [], [], [], [])
1808 7ee7c0c7 Guido Trotter
1809 7ee7c0c7 Guido Trotter
  def testLockNames(self):
1810 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
1811 8716b1db Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
1812 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
1813 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP),
1814 819ca990 Guido Trotter
                     set(self.nodegroups))
1815 cdb08f44 Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
1816 cdb08f44 Michael Hanselmann
                     set(self.instances))
1817 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_NETWORK),
1818 6e8091f9 Dimitris Aragiorgis
                     set(self.networks))
1819 7ee7c0c7 Guido Trotter
1820 7ee7c0c7 Guido Trotter
  def testInitAndResources(self):
1821 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
1822 6e8091f9 Dimitris Aragiorgis
    self.GL = locking.GanetiLockManager([], [], [], [])
1823 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
1824 8716b1db Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
1825 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
1826 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
1827 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
1828 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_NETWORK), set())
1829 7ee7c0c7 Guido Trotter
1830 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
1831 6e8091f9 Dimitris Aragiorgis
    self.GL = locking.GanetiLockManager(self.nodes, self.nodegroups, [], [])
1832 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
1833 8716b1db Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
1834 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(self.nodes))
1835 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP),
1836 819ca990 Guido Trotter
                                    set(self.nodegroups))
1837 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
1838 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_NETWORK), set())
1839 7ee7c0c7 Guido Trotter
1840 7ee7c0c7 Guido Trotter
    locking.GanetiLockManager._instance = None
1841 6e8091f9 Dimitris Aragiorgis
    self.GL = locking.GanetiLockManager([], [], self.instances, [])
1842 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
1843 8716b1db Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
1844 7ee7c0c7 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
1845 819ca990 Guido Trotter
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
1846 cdb08f44 Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE),
1847 cdb08f44 Michael Hanselmann
                     set(self.instances))
1848 7ee7c0c7 Guido Trotter
1849 6e8091f9 Dimitris Aragiorgis
    locking.GanetiLockManager._instance = None
1850 6e8091f9 Dimitris Aragiorgis
    self.GL = locking.GanetiLockManager([], [], [], self.networks)
1851 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_CLUSTER), set(["BGL"]))
1852 8716b1db Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODE_ALLOC), set(["NAL"]))
1853 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set())
1854 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set())
1855 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set())
1856 6e8091f9 Dimitris Aragiorgis
    self.assertEqual(self.GL._names(locking.LEVEL_NETWORK),
1857 6e8091f9 Dimitris Aragiorgis
                     set(self.networks))
1858 6e8091f9 Dimitris Aragiorgis
1859 7ee7c0c7 Guido Trotter
  def testAcquireRelease(self):
1860 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
1861 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_CLUSTER), set(["BGL"]))
1862 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_INSTANCE, ["i1"])
1863 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_NODEGROUP, ["g2"])
1864 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_NODE, ["n1", "n2"], shared=1)
1865 c6a622cf Michael Hanselmann
    self.assertTrue(self.GL.check_owned(locking.LEVEL_NODE, ["n1", "n2"],
1866 c6a622cf Michael Hanselmann
                                        shared=1))
1867 c6a622cf Michael Hanselmann
    self.assertFalse(self.GL.check_owned(locking.LEVEL_INSTANCE, ["i1", "i3"]))
1868 8c114acd Michael Hanselmann
    self.GL.release(locking.LEVEL_NODE, ["n2"])
1869 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODE), set(["n1"]))
1870 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODEGROUP), set(["g2"]))
1871 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_INSTANCE), set(["i1"]))
1872 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
1873 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODE), set())
1874 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODEGROUP), set(["g2"]))
1875 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_INSTANCE), set(["i1"]))
1876 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_NODEGROUP)
1877 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1878 7ee7c0c7 Guido Trotter
    self.assertRaises(errors.LockError, self.GL.acquire,
1879 8c114acd Michael Hanselmann
                      locking.LEVEL_INSTANCE, ["i5"])
1880 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_INSTANCE, ["i3"], shared=1)
1881 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_INSTANCE), set(["i3"]))
1882 7ee7c0c7 Guido Trotter
1883 90c942d1 Guido Trotter
  def testAcquireWholeSets(self):
1884 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
1885 90c942d1 Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_INSTANCE, None),
1886 90c942d1 Guido Trotter
                      set(self.instances))
1887 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_INSTANCE),
1888 90c942d1 Guido Trotter
                      set(self.instances))
1889 819ca990 Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODEGROUP, None),
1890 819ca990 Guido Trotter
                      set(self.nodegroups))
1891 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODEGROUP),
1892 819ca990 Guido Trotter
                      set(self.nodegroups))
1893 90c942d1 Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODE, None, shared=1),
1894 90c942d1 Guido Trotter
                      set(self.nodes))
1895 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODE),
1896 90c942d1 Guido Trotter
                      set(self.nodes))
1897 8c811986 Michael Hanselmann
    self.assertTrue(self.GL.owning_all(locking.LEVEL_INSTANCE))
1898 8c811986 Michael Hanselmann
    self.assertTrue(self.GL.owning_all(locking.LEVEL_NODEGROUP))
1899 8c811986 Michael Hanselmann
    self.assertTrue(self.GL.owning_all(locking.LEVEL_NODE))
1900 90c942d1 Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
1901 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_NODEGROUP)
1902 d4f6a91c Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1903 d4f6a91c Guido Trotter
    self.GL.release(locking.LEVEL_CLUSTER)
1904 d4f6a91c Guido Trotter
1905 d4f6a91c Guido Trotter
  def testAcquireWholeAndPartial(self):
1906 8c811986 Michael Hanselmann
    self.assertFalse(self.GL.owning_all(locking.LEVEL_INSTANCE))
1907 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
1908 d4f6a91c Guido Trotter
    self.assertEquals(self.GL.acquire(locking.LEVEL_INSTANCE, None),
1909 d4f6a91c Guido Trotter
                      set(self.instances))
1910 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_INSTANCE),
1911 d4f6a91c Guido Trotter
                      set(self.instances))
1912 8c114acd Michael Hanselmann
    self.assertEquals(self.GL.acquire(locking.LEVEL_NODE, ["n2"], shared=1),
1913 8c114acd Michael Hanselmann
                      set(["n2"]))
1914 ee2b99e3 Michael Hanselmann
    self.assertEquals(self.GL.list_owned(locking.LEVEL_NODE),
1915 8c114acd Michael Hanselmann
                      set(["n2"]))
1916 8c811986 Michael Hanselmann
    self.assertTrue(self.GL.owning_all(locking.LEVEL_INSTANCE))
1917 8c811986 Michael Hanselmann
    self.assertFalse(self.GL.owning_all(locking.LEVEL_NODE))
1918 d4f6a91c Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
1919 90c942d1 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1920 90c942d1 Guido Trotter
    self.GL.release(locking.LEVEL_CLUSTER)
1921 90c942d1 Guido Trotter
1922 7ee7c0c7 Guido Trotter
  def testBGLDependency(self):
1923 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1924 8c114acd Michael Hanselmann
                      locking.LEVEL_NODE, ["n1", "n2"])
1925 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1926 8c114acd Michael Hanselmann
                      locking.LEVEL_INSTANCE, ["i3"])
1927 819ca990 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1928 8c114acd Michael Hanselmann
                      locking.LEVEL_NODEGROUP, ["g1"])
1929 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
1930 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_NODE, ["n1"])
1931 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1932 8c114acd Michael Hanselmann
                      locking.LEVEL_CLUSTER, ["BGL"])
1933 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1934 7ee7c0c7 Guido Trotter
                      locking.LEVEL_CLUSTER)
1935 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_NODE)
1936 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_INSTANCE, ["i1", "i2"])
1937 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1938 8c114acd Michael Hanselmann
                      locking.LEVEL_CLUSTER, ["BGL"])
1939 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1940 7ee7c0c7 Guido Trotter
                      locking.LEVEL_CLUSTER)
1941 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
1942 819ca990 Guido Trotter
    self.GL.acquire(locking.LEVEL_NODEGROUP, None)
1943 8c114acd Michael Hanselmann
    self.GL.release(locking.LEVEL_NODEGROUP, ["g1"])
1944 819ca990 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1945 8c114acd Michael Hanselmann
                      locking.LEVEL_CLUSTER, ["BGL"])
1946 819ca990 Guido Trotter
    self.assertRaises(AssertionError, self.GL.release,
1947 819ca990 Guido Trotter
                      locking.LEVEL_CLUSTER)
1948 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_NODEGROUP)
1949 819ca990 Guido Trotter
    self.GL.release(locking.LEVEL_CLUSTER)
1950 7ee7c0c7 Guido Trotter
1951 7ee7c0c7 Guido Trotter
  def testWrongOrder(self):
1952 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
1953 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_NODE, ["n2"])
1954 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1955 8c114acd Michael Hanselmann
                      locking.LEVEL_NODE, ["n1"])
1956 7ee7c0c7 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1957 8c114acd Michael Hanselmann
                      locking.LEVEL_NODEGROUP, ["g1"])
1958 819ca990 Guido Trotter
    self.assertRaises(AssertionError, self.GL.acquire,
1959 8c114acd Michael Hanselmann
                      locking.LEVEL_INSTANCE, ["i2"])
1960 7ee7c0c7 Guido Trotter
1961 4badc36c Guido Trotter
  def testModifiableLevels(self):
1962 4badc36c Guido Trotter
    self.assertRaises(AssertionError, self.GL.add, locking.LEVEL_CLUSTER,
1963 8c114acd Michael Hanselmann
                      ["BGL2"])
1964 8716b1db Michael Hanselmann
    self.assertRaises(AssertionError, self.GL.add, locking.LEVEL_NODE_ALLOC,
1965 8716b1db Michael Hanselmann
                      ["NAL2"])
1966 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"])
1967 8c114acd Michael Hanselmann
    self.GL.add(locking.LEVEL_INSTANCE, ["i4"])
1968 8c114acd Michael Hanselmann
    self.GL.remove(locking.LEVEL_INSTANCE, ["i3"])
1969 8c114acd Michael Hanselmann
    self.GL.remove(locking.LEVEL_INSTANCE, ["i1"])
1970 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_INSTANCE), set(["i2", "i4"]))
1971 8c114acd Michael Hanselmann
    self.GL.add(locking.LEVEL_NODE, ["n3"])
1972 8c114acd Michael Hanselmann
    self.GL.remove(locking.LEVEL_NODE, ["n1"])
1973 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODE), set(["n2", "n3"]))
1974 8c114acd Michael Hanselmann
    self.GL.add(locking.LEVEL_NODEGROUP, ["g3"])
1975 8c114acd Michael Hanselmann
    self.GL.remove(locking.LEVEL_NODEGROUP, ["g2"])
1976 8c114acd Michael Hanselmann
    self.GL.remove(locking.LEVEL_NODEGROUP, ["g1"])
1977 8c114acd Michael Hanselmann
    self.assertEqual(self.GL._names(locking.LEVEL_NODEGROUP), set(["g3"]))
1978 4badc36c Guido Trotter
    self.assertRaises(AssertionError, self.GL.remove, locking.LEVEL_CLUSTER,
1979 8c114acd Michael Hanselmann
                      ["BGL2"])
1980 4badc36c Guido Trotter
1981 7ee7c0c7 Guido Trotter
  # Helper function to run as a thread that shared the BGL and then acquires
1982 7ee7c0c7 Guido Trotter
  # some locks at another level.
1983 7ee7c0c7 Guido Trotter
  def _doLock(self, level, names, shared):
1984 7ee7c0c7 Guido Trotter
    try:
1985 8c114acd Michael Hanselmann
      self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
1986 7ee7c0c7 Guido Trotter
      self.GL.acquire(level, names, shared=shared)
1987 8c114acd Michael Hanselmann
      self.done.put("DONE")
1988 7ee7c0c7 Guido Trotter
      self.GL.release(level)
1989 7ee7c0c7 Guido Trotter
      self.GL.release(locking.LEVEL_CLUSTER)
1990 7ee7c0c7 Guido Trotter
    except errors.LockError:
1991 8c114acd Michael Hanselmann
      self.done.put("ERR")
1992 7ee7c0c7 Guido Trotter
1993 4607c978 Iustin Pop
  @_Repeat
1994 7ee7c0c7 Guido Trotter
  def testConcurrency(self):
1995 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
1996 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
1997 8c114acd Michael Hanselmann
                    args=(locking.LEVEL_INSTANCE, "i1", 1))
1998 4607c978 Iustin Pop
    self._waitThreads()
1999 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
2000 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_INSTANCE, ["i3"])
2001 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
2002 8c114acd Michael Hanselmann
                    args=(locking.LEVEL_INSTANCE, "i1", 1))
2003 4607c978 Iustin Pop
    self._waitThreads()
2004 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
2005 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
2006 8c114acd Michael Hanselmann
                    args=(locking.LEVEL_INSTANCE, "i3", 1))
2007 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
2008 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
2009 4607c978 Iustin Pop
    self._waitThreads()
2010 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
2011 8c114acd Michael Hanselmann
    self.GL.acquire(locking.LEVEL_INSTANCE, ["i2"], shared=1)
2012 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
2013 8c114acd Michael Hanselmann
                    args=(locking.LEVEL_INSTANCE, "i2", 1))
2014 4607c978 Iustin Pop
    self._waitThreads()
2015 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get_nowait(), "DONE")
2016 4607c978 Iustin Pop
    self._addThread(target=self._doLock,
2017 8c114acd Michael Hanselmann
                    args=(locking.LEVEL_INSTANCE, "i2", 0))
2018 4607c978 Iustin Pop
    self.assertRaises(Queue.Empty, self.done.get_nowait)
2019 7ee7c0c7 Guido Trotter
    self.GL.release(locking.LEVEL_INSTANCE)
2020 4607c978 Iustin Pop
    self._waitThreads()
2021 8c114acd Michael Hanselmann
    self.assertEqual(self.done.get(True, 1), "DONE")
2022 8c114acd Michael Hanselmann
    self.GL.release(locking.LEVEL_CLUSTER, ["BGL"])
2023 7ee7c0c7 Guido Trotter
2024 7ee7c0c7 Guido Trotter
2025 19b9ba9a Michael Hanselmann
class TestLockMonitor(_ThreadedTestCase):
2026 19b9ba9a Michael Hanselmann
  def setUp(self):
2027 19b9ba9a Michael Hanselmann
    _ThreadedTestCase.setUp(self)
2028 19b9ba9a Michael Hanselmann
    self.lm = locking.LockMonitor()
2029 19b9ba9a Michael Hanselmann
2030 19b9ba9a Michael Hanselmann
  def testSingleThread(self):
2031 19b9ba9a Michael Hanselmann
    locks = []
2032 19b9ba9a Michael Hanselmann
2033 19b9ba9a Michael Hanselmann
    for i in range(100):
2034 19b9ba9a Michael Hanselmann
      name = "TestLock%s" % i
2035 19b9ba9a Michael Hanselmann
      locks.append(locking.SharedLock(name, monitor=self.lm))
2036 19b9ba9a Michael Hanselmann
2037 19b9ba9a Michael Hanselmann
    self.assertEqual(len(self.lm._locks), len(locks))
2038 24d16f76 Michael Hanselmann
    result = objects.QueryResponse.FromDict(self.lm.QueryLocks(["name"]))
2039 24d16f76 Michael Hanselmann
    self.assertEqual(len(result.fields), 1)
2040 24d16f76 Michael Hanselmann
    self.assertEqual(len(result.data), 100)
2041 c31825f7 Michael Hanselmann
2042 19b9ba9a Michael Hanselmann
    # Delete all locks
2043 19b9ba9a Michael Hanselmann
    del locks[:]
2044 19b9ba9a Michael Hanselmann
2045 19b9ba9a Michael Hanselmann
    # The garbage collector might needs some time
2046 19b9ba9a Michael Hanselmann
    def _CheckLocks():
2047 19b9ba9a Michael Hanselmann
      if self.lm._locks:
2048 19b9ba9a Michael Hanselmann
        raise utils.RetryAgain()
2049 19b9ba9a Michael Hanselmann
2050 19b9ba9a Michael Hanselmann
    utils.Retry(_CheckLocks, 0.1, 30.0)
2051 19b9ba9a Michael Hanselmann
2052 19b9ba9a Michael Hanselmann
    self.assertFalse(self.lm._locks)
2053 19b9ba9a Michael Hanselmann
2054 19b9ba9a Michael Hanselmann
  def testMultiThread(self):
2055 19b9ba9a Michael Hanselmann
    locks = []
2056 19b9ba9a Michael Hanselmann
2057 19b9ba9a Michael Hanselmann
    def _CreateLock(prev, next, name):
2058 19b9ba9a Michael Hanselmann
      prev.wait()
2059 19b9ba9a Michael Hanselmann
      locks.append(locking.SharedLock(name, monitor=self.lm))
2060 19b9ba9a Michael Hanselmann
      if next:
2061 19b9ba9a Michael Hanselmann
        next.set()
2062 19b9ba9a Michael Hanselmann
2063 19b9ba9a Michael Hanselmann
    expnames = []
2064 19b9ba9a Michael Hanselmann
2065 19b9ba9a Michael Hanselmann
    first = threading.Event()
2066 19b9ba9a Michael Hanselmann
    prev = first
2067 19b9ba9a Michael Hanselmann
2068 19b9ba9a Michael Hanselmann
    # Use a deterministic random generator
2069 19b9ba9a Michael Hanselmann
    for i in random.Random(4263).sample(range(100), 33):
2070 19b9ba9a Michael Hanselmann
      name = "MtTestLock%s" % i
2071 19b9ba9a Michael Hanselmann
      expnames.append(name)
2072 19b9ba9a Michael Hanselmann
2073 19b9ba9a Michael Hanselmann
      ev = threading.Event()
2074 19b9ba9a Michael Hanselmann
      self._addThread(target=_CreateLock, args=(prev, ev, name))
2075 19b9ba9a Michael Hanselmann
      prev = ev
2076 19b9ba9a Michael Hanselmann
2077 19b9ba9a Michael Hanselmann
    # Add locks
2078 19b9ba9a Michael Hanselmann
    first.set()
2079 19b9ba9a Michael Hanselmann
    self._waitThreads()
2080 19b9ba9a Michael Hanselmann
2081 19b9ba9a Michael Hanselmann
    # Check order in which locks were added
2082 19b9ba9a Michael Hanselmann
    self.assertEqual([i.name for i in locks], expnames)
2083 19b9ba9a Michael Hanselmann
2084 19b9ba9a Michael Hanselmann
    # Check query result
2085 24d16f76 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner", "pending"])
2086 24d16f76 Michael Hanselmann
    self.assert_(isinstance(result, dict))
2087 24d16f76 Michael Hanselmann
    response = objects.QueryResponse.FromDict(result)
2088 24d16f76 Michael Hanselmann
    self.assertEqual(response.data,
2089 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, name),
2090 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, None),
2091 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, None),
2092 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, [])]
2093 c31825f7 Michael Hanselmann
                      for name in utils.NiceSort(expnames)])
2094 24d16f76 Michael Hanselmann
    self.assertEqual(len(response.fields), 4)
2095 24d16f76 Michael Hanselmann
    self.assertEqual(["name", "mode", "owner", "pending"],
2096 24d16f76 Michael Hanselmann
                     [fdef.name for fdef in response.fields])
2097 19b9ba9a Michael Hanselmann
2098 19b9ba9a Michael Hanselmann
    # Test exclusive acquire
2099 19b9ba9a Michael Hanselmann
    for tlock in locks[::4]:
2100 19b9ba9a Michael Hanselmann
      tlock.acquire(shared=0)
2101 19b9ba9a Michael Hanselmann
      try:
2102 19b9ba9a Michael Hanselmann
        def _GetExpResult(name):
2103 19b9ba9a Michael Hanselmann
          if tlock.name == name:
2104 cfb084ae Renรฉ Nussbaumer
            return [(constants.RS_NORMAL, name),
2105 cfb084ae Renรฉ Nussbaumer
                    (constants.RS_NORMAL, "exclusive"),
2106 cfb084ae Renรฉ Nussbaumer
                    (constants.RS_NORMAL,
2107 24d16f76 Michael Hanselmann
                     [threading.currentThread().getName()]),
2108 cfb084ae Renรฉ Nussbaumer
                    (constants.RS_NORMAL, [])]
2109 cfb084ae Renรฉ Nussbaumer
          return [(constants.RS_NORMAL, name),
2110 cfb084ae Renรฉ Nussbaumer
                  (constants.RS_NORMAL, None),
2111 cfb084ae Renรฉ Nussbaumer
                  (constants.RS_NORMAL, None),
2112 cfb084ae Renรฉ Nussbaumer
                  (constants.RS_NORMAL, [])]
2113 24d16f76 Michael Hanselmann
2114 24d16f76 Michael Hanselmann
        result = self.lm.QueryLocks(["name", "mode", "owner", "pending"])
2115 24d16f76 Michael Hanselmann
        self.assertEqual(objects.QueryResponse.FromDict(result).data,
2116 19b9ba9a Michael Hanselmann
                         [_GetExpResult(name)
2117 19b9ba9a Michael Hanselmann
                          for name in utils.NiceSort(expnames)])
2118 19b9ba9a Michael Hanselmann
      finally:
2119 19b9ba9a Michael Hanselmann
        tlock.release()
2120 19b9ba9a Michael Hanselmann
2121 19b9ba9a Michael Hanselmann
    # Test shared acquire
2122 73c25d35 Michael Hanselmann
    def _Acquire(lock, shared, ev, notify):
2123 19b9ba9a Michael Hanselmann
      lock.acquire(shared=shared)
2124 19b9ba9a Michael Hanselmann
      try:
2125 73c25d35 Michael Hanselmann
        notify.set()
2126 19b9ba9a Michael Hanselmann
        ev.wait()
2127 19b9ba9a Michael Hanselmann
      finally:
2128 19b9ba9a Michael Hanselmann
        lock.release()
2129 19b9ba9a Michael Hanselmann
2130 19b9ba9a Michael Hanselmann
    for tlock1 in locks[::11]:
2131 19b9ba9a Michael Hanselmann
      for tlock2 in locks[::-15]:
2132 19b9ba9a Michael Hanselmann
        if tlock2 == tlock1:
2133 73c25d35 Michael Hanselmann
          # Avoid deadlocks
2134 19b9ba9a Michael Hanselmann
          continue
2135 19b9ba9a Michael Hanselmann
2136 19b9ba9a Michael Hanselmann
        for tlock3 in locks[::10]:
2137 73c25d35 Michael Hanselmann
          if tlock3 in (tlock2, tlock1):
2138 73c25d35 Michael Hanselmann
            # Avoid deadlocks
2139 19b9ba9a Michael Hanselmann
            continue
2140 19b9ba9a Michael Hanselmann
2141 73c25d35 Michael Hanselmann
          releaseev = threading.Event()
2142 19b9ba9a Michael Hanselmann
2143 19b9ba9a Michael Hanselmann
          # Acquire locks
2144 73c25d35 Michael Hanselmann
          acquireev = []
2145 19b9ba9a Michael Hanselmann
          tthreads1 = []
2146 19b9ba9a Michael Hanselmann
          for i in range(3):
2147 73c25d35 Michael Hanselmann
            ev = threading.Event()
2148 19b9ba9a Michael Hanselmann
            tthreads1.append(self._addThread(target=_Acquire,
2149 73c25d35 Michael Hanselmann
                                             args=(tlock1, 1, releaseev, ev)))
2150 73c25d35 Michael Hanselmann
            acquireev.append(ev)
2151 73c25d35 Michael Hanselmann
2152 73c25d35 Michael Hanselmann
          ev = threading.Event()
2153 73c25d35 Michael Hanselmann
          tthread2 = self._addThread(target=_Acquire,
2154 73c25d35 Michael Hanselmann
                                     args=(tlock2, 1, releaseev, ev))
2155 73c25d35 Michael Hanselmann
          acquireev.append(ev)
2156 73c25d35 Michael Hanselmann
2157 73c25d35 Michael Hanselmann
          ev = threading.Event()
2158 73c25d35 Michael Hanselmann
          tthread3 = self._addThread(target=_Acquire,
2159 73c25d35 Michael Hanselmann
                                     args=(tlock3, 0, releaseev, ev))
2160 73c25d35 Michael Hanselmann
          acquireev.append(ev)
2161 73c25d35 Michael Hanselmann
2162 73c25d35 Michael Hanselmann
          # Wait for all locks to be acquired
2163 73c25d35 Michael Hanselmann
          for i in acquireev:
2164 73c25d35 Michael Hanselmann
            i.wait()
2165 19b9ba9a Michael Hanselmann
2166 19b9ba9a Michael Hanselmann
          # Check query result
2167 24d16f76 Michael Hanselmann
          result = self.lm.QueryLocks(["name", "mode", "owner"])
2168 24d16f76 Michael Hanselmann
          response = objects.QueryResponse.FromDict(result)
2169 24d16f76 Michael Hanselmann
          for (name, mode, owner) in response.data:
2170 24d16f76 Michael Hanselmann
            (name_status, name_value) = name
2171 24d16f76 Michael Hanselmann
            (owner_status, owner_value) = owner
2172 24d16f76 Michael Hanselmann
2173 cfb084ae Renรฉ Nussbaumer
            self.assertEqual(name_status, constants.RS_NORMAL)
2174 cfb084ae Renรฉ Nussbaumer
            self.assertEqual(owner_status, constants.RS_NORMAL)
2175 24d16f76 Michael Hanselmann
2176 24d16f76 Michael Hanselmann
            if name_value == tlock1.name:
2177 cfb084ae Renรฉ Nussbaumer
              self.assertEqual(mode, (constants.RS_NORMAL, "shared"))
2178 24d16f76 Michael Hanselmann
              self.assertEqual(set(owner_value),
2179 24d16f76 Michael Hanselmann
                               set(i.getName() for i in tthreads1))
2180 19b9ba9a Michael Hanselmann
              continue
2181 19b9ba9a Michael Hanselmann
2182 24d16f76 Michael Hanselmann
            if name_value == tlock2.name:
2183 cfb084ae Renรฉ Nussbaumer
              self.assertEqual(mode, (constants.RS_NORMAL, "shared"))
2184 24d16f76 Michael Hanselmann
              self.assertEqual(owner_value, [tthread2.getName()])
2185 19b9ba9a Michael Hanselmann
              continue
2186 19b9ba9a Michael Hanselmann
2187 24d16f76 Michael Hanselmann
            if name_value == tlock3.name:
2188 cfb084ae Renรฉ Nussbaumer
              self.assertEqual(mode, (constants.RS_NORMAL, "exclusive"))
2189 24d16f76 Michael Hanselmann
              self.assertEqual(owner_value, [tthread3.getName()])
2190 19b9ba9a Michael Hanselmann
              continue
2191 19b9ba9a Michael Hanselmann
2192 24d16f76 Michael Hanselmann
            self.assert_(name_value in expnames)
2193 cfb084ae Renรฉ Nussbaumer
            self.assertEqual(mode, (constants.RS_NORMAL, None))
2194 24d16f76 Michael Hanselmann
            self.assert_(owner_value is None)
2195 19b9ba9a Michael Hanselmann
2196 19b9ba9a Michael Hanselmann
          # Release locks again
2197 73c25d35 Michael Hanselmann
          releaseev.set()
2198 19b9ba9a Michael Hanselmann
2199 19b9ba9a Michael Hanselmann
          self._waitThreads()
2200 19b9ba9a Michael Hanselmann
2201 24d16f76 Michael Hanselmann
          result = self.lm.QueryLocks(["name", "mode", "owner"])
2202 24d16f76 Michael Hanselmann
          self.assertEqual(objects.QueryResponse.FromDict(result).data,
2203 cfb084ae Renรฉ Nussbaumer
                           [[(constants.RS_NORMAL, name),
2204 cfb084ae Renรฉ Nussbaumer
                             (constants.RS_NORMAL, None),
2205 cfb084ae Renรฉ Nussbaumer
                             (constants.RS_NORMAL, None)]
2206 19b9ba9a Michael Hanselmann
                            for name in utils.NiceSort(expnames)])
2207 19b9ba9a Michael Hanselmann
2208 19b9ba9a Michael Hanselmann
  def testDelete(self):
2209 19b9ba9a Michael Hanselmann
    lock = locking.SharedLock("TestLock", monitor=self.lm)
2210 19b9ba9a Michael Hanselmann
2211 19b9ba9a Michael Hanselmann
    self.assertEqual(len(self.lm._locks), 1)
2212 24d16f76 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2213 24d16f76 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data,
2214 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, lock.name),
2215 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, None),
2216 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, None)]])
2217 19b9ba9a Michael Hanselmann
2218 19b9ba9a Michael Hanselmann
    lock.delete()
2219 19b9ba9a Michael Hanselmann
2220 24d16f76 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2221 24d16f76 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data,
2222 cfb084ae Renรฉ Nussbaumer
                     [[(constants.RS_NORMAL, lock.name),
2223 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, "deleted"),
2224 cfb084ae Renรฉ Nussbaumer
                       (constants.RS_NORMAL, None)]])
2225 19b9ba9a Michael Hanselmann
    self.assertEqual(len(self.lm._locks), 1)
2226 19b9ba9a Michael Hanselmann
2227 c31825f7 Michael Hanselmann
  def testPending(self):
2228 c31825f7 Michael Hanselmann
    def _Acquire(lock, shared, prev, next):
2229 c31825f7 Michael Hanselmann
      prev.wait()
2230 c31825f7 Michael Hanselmann
2231 c31825f7 Michael Hanselmann
      lock.acquire(shared=shared, test_notify=next.set)
2232 c31825f7 Michael Hanselmann
      try:
2233 c31825f7 Michael Hanselmann
        pass
2234 c31825f7 Michael Hanselmann
      finally:
2235 c31825f7 Michael Hanselmann
        lock.release()
2236 c31825f7 Michael Hanselmann
2237 c31825f7 Michael Hanselmann
    lock = locking.SharedLock("ExcLock", monitor=self.lm)
2238 c31825f7 Michael Hanselmann
2239 c31825f7 Michael Hanselmann
    for shared in [0, 1]:
2240 c31825f7 Michael Hanselmann
      lock.acquire()
2241 c31825f7 Michael Hanselmann
      try:
2242 c31825f7 Michael Hanselmann
        self.assertEqual(len(self.lm._locks), 1)
2243 24d16f76 Michael Hanselmann
        result = self.lm.QueryLocks(["name", "mode", "owner"])
2244 24d16f76 Michael Hanselmann
        self.assertEqual(objects.QueryResponse.FromDict(result).data,
2245 cfb084ae Renรฉ Nussbaumer
                         [[(constants.RS_NORMAL, lock.name),
2246 cfb084ae Renรฉ Nussbaumer
                           (constants.RS_NORMAL, "exclusive"),
2247 cfb084ae Renรฉ Nussbaumer
                           (constants.RS_NORMAL,
2248 24d16f76 Michael Hanselmann
                            [threading.currentThread().getName()])]])
2249 c31825f7 Michael Hanselmann
2250 c31825f7 Michael Hanselmann
        threads = []
2251 c31825f7 Michael Hanselmann
2252 c31825f7 Michael Hanselmann
        first = threading.Event()
2253 c31825f7 Michael Hanselmann
        prev = first
2254 c31825f7 Michael Hanselmann
2255 c31825f7 Michael Hanselmann
        for i in range(5):
2256 c31825f7 Michael Hanselmann
          ev = threading.Event()
2257 c31825f7 Michael Hanselmann
          threads.append(self._addThread(target=_Acquire,
2258 c31825f7 Michael Hanselmann
                                          args=(lock, shared, prev, ev)))
2259 c31825f7 Michael Hanselmann
          prev = ev
2260 c31825f7 Michael Hanselmann
2261 c31825f7 Michael Hanselmann
        # Start acquires
2262 c31825f7 Michael Hanselmann
        first.set()
2263 c31825f7 Michael Hanselmann
2264 c31825f7 Michael Hanselmann
        # Wait for last acquire to start waiting
2265 c31825f7 Michael Hanselmann
        prev.wait()
2266 c31825f7 Michael Hanselmann
2267 c31825f7 Michael Hanselmann
        # NOTE: This works only because QueryLocks will acquire the
2268 c31825f7 Michael Hanselmann
        # lock-internal lock again and won't be able to get the information
2269 c31825f7 Michael Hanselmann
        # until it has the lock. By then the acquire should be registered in
2270 c31825f7 Michael Hanselmann
        # SharedLock.__pending (otherwise it's a bug).
2271 c31825f7 Michael Hanselmann
2272 c31825f7 Michael Hanselmann
        # All acquires are waiting now
2273 c31825f7 Michael Hanselmann
        if shared:
2274 24d16f76 Michael Hanselmann
          pending = [("shared", utils.NiceSort(t.getName() for t in threads))]
2275 c31825f7 Michael Hanselmann
        else:
2276 c31825f7 Michael Hanselmann
          pending = [("exclusive", [t.getName()]) for t in threads]
2277 c31825f7 Michael Hanselmann
2278 24d16f76 Michael Hanselmann
        result = self.lm.QueryLocks(["name", "mode", "owner", "pending"])
2279 24d16f76 Michael Hanselmann
        self.assertEqual(objects.QueryResponse.FromDict(result).data,
2280 cfb084ae Renรฉ Nussbaumer
                         [[(constants.RS_NORMAL, lock.name),
2281 cfb084ae Renรฉ Nussbaumer
                           (constants.RS_NORMAL, "exclusive"),
2282 cfb084ae Renรฉ Nussbaumer
                           (constants.RS_NORMAL,
2283 24d16f76 Michael Hanselmann
                            [threading.currentThread().getName()]),
2284 cfb084ae Renรฉ Nussbaumer
                           (constants.RS_NORMAL, pending)]])
2285 c31825f7 Michael Hanselmann
2286 c31825f7 Michael Hanselmann
        self.assertEqual(len(self.lm._locks), 1)
2287 c31825f7 Michael Hanselmann
      finally:
2288 c31825f7 Michael Hanselmann
        lock.release()
2289 c31825f7 Michael Hanselmann
2290 c31825f7 Michael Hanselmann
      self._waitThreads()
2291 c31825f7 Michael Hanselmann
2292 c31825f7 Michael Hanselmann
      # No pending acquires
2293 24d16f76 Michael Hanselmann
      result = self.lm.QueryLocks(["name", "mode", "owner", "pending"])
2294 24d16f76 Michael Hanselmann
      self.assertEqual(objects.QueryResponse.FromDict(result).data,
2295 cfb084ae Renรฉ Nussbaumer
                       [[(constants.RS_NORMAL, lock.name),
2296 cfb084ae Renรฉ Nussbaumer
                         (constants.RS_NORMAL, None),
2297 cfb084ae Renรฉ Nussbaumer
                         (constants.RS_NORMAL, None),
2298 cfb084ae Renรฉ Nussbaumer
                         (constants.RS_NORMAL, [])]])
2299 c31825f7 Michael Hanselmann
2300 c31825f7 Michael Hanselmann
      self.assertEqual(len(self.lm._locks), 1)
2301 c31825f7 Michael Hanselmann
2302 e4e35357 Michael Hanselmann
  def testDeleteAndRecreate(self):
2303 e4e35357 Michael Hanselmann
    lname = "TestLock101923193"
2304 e4e35357 Michael Hanselmann
2305 e4e35357 Michael Hanselmann
    # Create some locks with the same name and keep all references
2306 e4e35357 Michael Hanselmann
    locks = [locking.SharedLock(lname, monitor=self.lm)
2307 e4e35357 Michael Hanselmann
             for _ in range(5)]
2308 e4e35357 Michael Hanselmann
2309 e4e35357 Michael Hanselmann
    self.assertEqual(len(self.lm._locks), len(locks))
2310 e4e35357 Michael Hanselmann
2311 e4e35357 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2312 e4e35357 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data,
2313 e4e35357 Michael Hanselmann
                     [[(constants.RS_NORMAL, lname),
2314 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None),
2315 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None)]] * 5)
2316 e4e35357 Michael Hanselmann
2317 e4e35357 Michael Hanselmann
    locks[2].delete()
2318 e4e35357 Michael Hanselmann
2319 e4e35357 Michael Hanselmann
    # Check information order
2320 e4e35357 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2321 e4e35357 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data,
2322 e4e35357 Michael Hanselmann
                     [[(constants.RS_NORMAL, lname),
2323 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None),
2324 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None)]] * 2 +
2325 e4e35357 Michael Hanselmann
                     [[(constants.RS_NORMAL, lname),
2326 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, "deleted"),
2327 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None)]] +
2328 e4e35357 Michael Hanselmann
                     [[(constants.RS_NORMAL, lname),
2329 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None),
2330 e4e35357 Michael Hanselmann
                       (constants.RS_NORMAL, None)]] * 2)
2331 e4e35357 Michael Hanselmann
2332 e4e35357 Michael Hanselmann
    locks[1].acquire(shared=0)
2333 e4e35357 Michael Hanselmann
2334 e4e35357 Michael Hanselmann
    last_status = [
2335 e4e35357 Michael Hanselmann
      [(constants.RS_NORMAL, lname),
2336 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None),
2337 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None)],
2338 e4e35357 Michael Hanselmann
      [(constants.RS_NORMAL, lname),
2339 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, "exclusive"),
2340 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, [threading.currentThread().getName()])],
2341 e4e35357 Michael Hanselmann
      [(constants.RS_NORMAL, lname),
2342 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, "deleted"),
2343 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None)],
2344 e4e35357 Michael Hanselmann
      [(constants.RS_NORMAL, lname),
2345 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None),
2346 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None)],
2347 e4e35357 Michael Hanselmann
      [(constants.RS_NORMAL, lname),
2348 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None),
2349 e4e35357 Michael Hanselmann
       (constants.RS_NORMAL, None)],
2350 e4e35357 Michael Hanselmann
      ]
2351 e4e35357 Michael Hanselmann
2352 e4e35357 Michael Hanselmann
    # Check information order
2353 e4e35357 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2354 e4e35357 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data, last_status)
2355 e4e35357 Michael Hanselmann
2356 e4e35357 Michael Hanselmann
    self.assertEqual(len(set(self.lm._locks.values())), len(locks))
2357 e4e35357 Michael Hanselmann
    self.assertEqual(len(self.lm._locks), len(locks))
2358 e4e35357 Michael Hanselmann
2359 e4e35357 Michael Hanselmann
    # Check lock deletion
2360 e4e35357 Michael Hanselmann
    for idx in range(len(locks)):
2361 e4e35357 Michael Hanselmann
      del locks[0]
2362 e4e35357 Michael Hanselmann
      assert gc.isenabled()
2363 e4e35357 Michael Hanselmann
      gc.collect()
2364 e4e35357 Michael Hanselmann
      self.assertEqual(len(self.lm._locks), len(locks))
2365 e4e35357 Michael Hanselmann
      result = self.lm.QueryLocks(["name", "mode", "owner"])
2366 e4e35357 Michael Hanselmann
      self.assertEqual(objects.QueryResponse.FromDict(result).data,
2367 e4e35357 Michael Hanselmann
                       last_status[idx + 1:])
2368 e4e35357 Michael Hanselmann
2369 e4e35357 Michael Hanselmann
    # All locks should have been deleted
2370 e4e35357 Michael Hanselmann
    assert not locks
2371 e4e35357 Michael Hanselmann
    self.assertFalse(self.lm._locks)
2372 e4e35357 Michael Hanselmann
2373 e4e35357 Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2374 e4e35357 Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data, [])
2375 e4e35357 Michael Hanselmann
2376 44b4eddc Michael Hanselmann
  class _FakeLock:
2377 44b4eddc Michael Hanselmann
    def __init__(self):
2378 44b4eddc Michael Hanselmann
      self._info = []
2379 44b4eddc Michael Hanselmann
2380 44b4eddc Michael Hanselmann
    def AddResult(self, *args):
2381 44b4eddc Michael Hanselmann
      self._info.append(args)
2382 44b4eddc Michael Hanselmann
2383 44b4eddc Michael Hanselmann
    def CountPending(self):
2384 44b4eddc Michael Hanselmann
      return len(self._info)
2385 44b4eddc Michael Hanselmann
2386 44b4eddc Michael Hanselmann
    def GetLockInfo(self, requested):
2387 44b4eddc Michael Hanselmann
      (exp_requested, result) = self._info.pop(0)
2388 44b4eddc Michael Hanselmann
2389 44b4eddc Michael Hanselmann
      if exp_requested != requested:
2390 44b4eddc Michael Hanselmann
        raise Exception("Requested information (%s) does not match"
2391 44b4eddc Michael Hanselmann
                        " expectations (%s)" % (requested, exp_requested))
2392 44b4eddc Michael Hanselmann
2393 44b4eddc Michael Hanselmann
      return result
2394 44b4eddc Michael Hanselmann
2395 44b4eddc Michael Hanselmann
  def testMultipleResults(self):
2396 44b4eddc Michael Hanselmann
    fl1 = self._FakeLock()
2397 44b4eddc Michael Hanselmann
    fl2 = self._FakeLock()
2398 44b4eddc Michael Hanselmann
2399 44b4eddc Michael Hanselmann
    self.lm.RegisterLock(fl1)
2400 44b4eddc Michael Hanselmann
    self.lm.RegisterLock(fl2)
2401 44b4eddc Michael Hanselmann
2402 44b4eddc Michael Hanselmann
    # Empty information
2403 44b4eddc Michael Hanselmann
    for i in [fl1, fl2]:
2404 44b4eddc Michael Hanselmann
      i.AddResult(set([query.LQ_MODE, query.LQ_OWNER]), [])
2405 44b4eddc Michael Hanselmann
    result = self.lm.QueryLocks(["name", "mode", "owner"])
2406 44b4eddc Michael Hanselmann
    self.assertEqual(objects.QueryResponse.FromDict(result).data, [])
2407 44b4eddc Michael Hanselmann
    for i in [fl1, fl2]:
2408 44b4eddc Michael Hanselmann
      self.assertEqual(i.CountPending(), 0)
2409 44b4eddc Michael Hanselmann
2410 44b4eddc Michael Hanselmann
    # Check ordering
2411 44b4eddc Michael Hanselmann
    for fn in [lambda x: x, reversed, sorted]:
2412 44b4eddc Michael Hanselmann
      fl1.AddResult(set(), list(fn([
2413 44b4eddc Michael Hanselmann
        ("aaa", None, None, None),
2414 44b4eddc Michael Hanselmann
        ("bbb", None, None, None),
2415 44b4eddc Michael Hanselmann
        ])))
2416 44b4eddc Michael Hanselmann
      fl2.AddResult(set(), [])
2417 44b4eddc Michael Hanselmann
      result = self.lm.QueryLocks(["name"])
2418 44b4eddc Michael Hanselmann
      self.assertEqual(objects.QueryResponse.FromDict(result).data, [
2419 44b4eddc Michael Hanselmann
        [(constants.RS_NORMAL, "aaa")],
2420 44b4eddc Michael Hanselmann
        [(constants.RS_NORMAL, "bbb")],
2421 44b4eddc Michael Hanselmann
        ])
2422 44b4eddc Michael Hanselmann
      for i in [fl1, fl2]:
2423 44b4eddc Michael Hanselmann
        self.assertEqual(i.CountPending(), 0)
2424 44b4eddc Michael Hanselmann
2425 44b4eddc Michael Hanselmann
      for fn2 in [lambda x: x, reversed, sorted]:
2426 44b4eddc Michael Hanselmann
        fl1.AddResult(set([query.LQ_MODE]), list(fn([
2427 44b4eddc Michael Hanselmann
          # Same name, but different information
2428 44b4eddc Michael Hanselmann
          ("aaa", "mode0", None, None),
2429 44b4eddc Michael Hanselmann
          ("aaa", "mode1", None, None),
2430 44b4eddc Michael Hanselmann
          ("aaa", "mode2", None, None),
2431 44b4eddc Michael Hanselmann
          ("aaa", "mode3", None, None),
2432 44b4eddc Michael Hanselmann
          ])))
2433 44b4eddc Michael Hanselmann
        fl2.AddResult(set([query.LQ_MODE]), [
2434 44b4eddc Michael Hanselmann
          ("zzz", "end", None, None),
2435 44b4eddc Michael Hanselmann
          ("000", "start", None, None),
2436 44b4eddc Michael Hanselmann
          ] + list(fn2([
2437 44b4eddc Michael Hanselmann
          ("aaa", "b200", None, None),
2438 44b4eddc Michael Hanselmann
          ("aaa", "b300", None, None),
2439 44b4eddc Michael Hanselmann
          ])))
2440 44b4eddc Michael Hanselmann
        result = self.lm.QueryLocks(["name", "mode"])
2441 44b4eddc Michael Hanselmann
        self.assertEqual(objects.QueryResponse.FromDict(result).data, [
2442 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "000"), (constants.RS_NORMAL, "start")],
2443 44b4eddc Michael Hanselmann
          ] + list(fn([
2444 44b4eddc Michael Hanselmann
          # Name is the same, so order must be equal to incoming order
2445 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "aaa"), (constants.RS_NORMAL, "mode0")],
2446 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "aaa"), (constants.RS_NORMAL, "mode1")],
2447 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "aaa"), (constants.RS_NORMAL, "mode2")],
2448 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "aaa"), (constants.RS_NORMAL, "mode3")],
2449 44b4eddc Michael Hanselmann
          ])) + list(fn2([
2450 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "aaa"), (constants.RS_NORMAL, "b200")],
2451 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "aaa"), (constants.RS_NORMAL, "b300")],
2452 44b4eddc Michael Hanselmann
          ])) + [
2453 44b4eddc Michael Hanselmann
          [(constants.RS_NORMAL, "zzz"), (constants.RS_NORMAL, "end")],
2454 44b4eddc Michael Hanselmann
          ])
2455 44b4eddc Michael Hanselmann
        for i in [fl1, fl2]:
2456 44b4eddc Michael Hanselmann
          self.assertEqual(i.CountPending(), 0)
2457 44b4eddc Michael Hanselmann
2458 19b9ba9a Michael Hanselmann
2459 2f96c43c Michael Hanselmann
if __name__ == "__main__":
2460 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()