Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.locking_unittest.py @ c5fe2a67

History | View | Annotate | Download (43.7 kB)

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