Revision aaae9bc0 test/ganeti.locking_unittest.py

b/test/ganeti.locking_unittest.py
230 230
    self.assertEqual(self.done.get(True, 1), 'ERR')
231 231

  
232 232

  
233
class TestLockSet(unittest.TestCase):
234
  """LockSet tests"""
235

  
236
  def setUp(self):
237
    self.resources = ['one', 'two', 'three']
238
    self.ls = locking.LockSet(self.resources)
239
    # helper threads use the 'done' queue to tell the master they finished.
240
    self.done = Queue.Queue(0)
241

  
242
  def testResources(self):
243
    self.assertEquals(self.ls._names(), set(self.resources))
244
    newls = locking.LockSet()
245
    self.assertEquals(newls._names(), set())
246

  
247
  def testAcquireRelease(self):
248
    self.ls.acquire('one')
249
    self.assertEquals(self.ls._list_owned(), set(['one']))
250
    self.ls.release()
251
    self.assertEquals(self.ls._list_owned(), set())
252
    self.ls.acquire(['one'])
253
    self.assertEquals(self.ls._list_owned(), set(['one']))
254
    self.ls.release()
255
    self.assertEquals(self.ls._list_owned(), set())
256
    self.ls.acquire(['one', 'two', 'three'])
257
    self.assertEquals(self.ls._list_owned(), set(['one', 'two', 'three']))
258
    self.ls.release('one')
259
    self.assertEquals(self.ls._list_owned(), set(['two', 'three']))
260
    self.ls.release(['three'])
261
    self.assertEquals(self.ls._list_owned(), set(['two']))
262
    self.ls.release()
263
    self.assertEquals(self.ls._list_owned(), set())
264
    self.ls.acquire(['one', 'three'])
265
    self.assertEquals(self.ls._list_owned(), set(['one', 'three']))
266
    self.ls.release()
267
    self.assertEquals(self.ls._list_owned(), set())
268

  
269
  def testNoDoubleAcquire(self):
270
    self.ls.acquire('one')
271
    self.assertRaises(AssertionError, self.ls.acquire, 'one')
272
    self.assertRaises(AssertionError, self.ls.acquire, ['two'])
273
    self.assertRaises(AssertionError, self.ls.acquire, ['two', 'three'])
274
    self.ls.release()
275
    self.ls.acquire(['one', 'three'])
276
    self.ls.release('one')
277
    self.assertRaises(AssertionError, self.ls.acquire, ['two'])
278
    self.ls.release('three')
279

  
280
  def testNoWrongRelease(self):
281
    self.assertRaises(AssertionError, self.ls.release)
282
    self.ls.acquire('one')
283
    self.assertRaises(AssertionError, self.ls.release, 'two')
284

  
285
  def testAddRemove(self):
286
    self.ls.add('four')
287
    self.assertEquals(self.ls._list_owned(), set())
288
    self.assert_('four' in self.ls._names())
289
    self.ls.add(['five', 'six', 'seven'], acquired=1)
290
    self.assert_('five' in self.ls._names())
291
    self.assert_('six' in self.ls._names())
292
    self.assert_('seven' in self.ls._names())
293
    self.assertEquals(self.ls._list_owned(), set(['five', 'six', 'seven']))
294
    self.ls.remove(['five', 'six'])
295
    self.assert_('five' not in self.ls._names())
296
    self.assert_('six' not in self.ls._names())
297
    self.assertEquals(self.ls._list_owned(), set(['seven']))
298
    self.ls.add('eight', acquired=1, shared=1)
299
    self.assert_('eight' in self.ls._names())
300
    self.assertEquals(self.ls._list_owned(), set(['seven', 'eight']))
301
    self.ls.remove('seven')
302
    self.assert_('seven' not in self.ls._names())
303
    self.assertEquals(self.ls._list_owned(), set(['eight']))
304
    self.ls.release()
305
    self.ls.remove(['two'])
306
    self.assert_('two' not in self.ls._names())
307
    self.ls.acquire('three')
308
    self.ls.remove(['three'])
309
    self.assert_('three' not in self.ls._names())
310
    self.assertEquals(self.ls.remove('three'), ['three'])
311
    self.assertEquals(self.ls.remove(['one', 'three', 'six']), ['three', 'six'])
312
    self.assert_('one' not in self.ls._names())
313

  
314
  def testRemoveNonBlocking(self):
315
    self.assertRaises(NotImplementedError, self.ls.remove, 'one', blocking=0)
316
    self.ls.acquire('one')
317
    self.assertEquals(self.ls.remove('one', blocking=0), [])
318
    self.ls.acquire(['two', 'three'])
319
    self.assertEquals(self.ls.remove(['two', 'three'], blocking=0), [])
320

  
321
  def testNoDoubleAdd(self):
322
    self.assertRaises(errors.LockError, self.ls.add, 'two')
323
    self.ls.add('four')
324
    self.assertRaises(errors.LockError, self.ls.add, 'four')
325

  
326
  def testNoWrongRemoves(self):
327
    self.ls.acquire(['one', 'three'], shared=1)
328
    # Cannot remove 'two' while holding something which is not a superset
329
    self.assertRaises(AssertionError, self.ls.remove, 'two')
330
    # Cannot remove 'three' as we are sharing it
331
    self.assertRaises(AssertionError, self.ls.remove, 'three')
332

  
333
  def _doLockSet(self, set, shared):
334
    try:
335
      self.ls.acquire(set, shared=shared)
336
      self.done.put('DONE')
337
      self.ls.release()
338
    except errors.LockError:
339
      self.done.put('ERR')
340

  
341
  def _doRemoveSet(self, set):
342
    self.done.put(self.ls.remove(set))
343

  
344
  def testConcurrentSharedAcquire(self):
345
    self.ls.acquire(['one', 'two'], shared=1)
346
    Thread(target=self._doLockSet, args=(['one', 'two'], 1)).start()
347
    self.assertEqual(self.done.get(True, 1), 'DONE')
348
    Thread(target=self._doLockSet, args=(['one', 'two', 'three'], 1)).start()
349
    self.assertEqual(self.done.get(True, 1), 'DONE')
350
    Thread(target=self._doLockSet, args=('three', 1)).start()
351
    self.assertEqual(self.done.get(True, 1), 'DONE')
352
    Thread(target=self._doLockSet, args=(['one', 'two'], 0)).start()
353
    Thread(target=self._doLockSet, args=(['two', 'three'], 0)).start()
354
    self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
355
    self.ls.release()
356
    self.assertEqual(self.done.get(True, 1), 'DONE')
357
    self.assertEqual(self.done.get(True, 1), 'DONE')
358

  
359
  def testConcurrentExclusiveAcquire(self):
360
    self.ls.acquire(['one', 'two'])
361
    Thread(target=self._doLockSet, args=('three', 1)).start()
362
    self.assertEqual(self.done.get(True, 1), 'DONE')
363
    Thread(target=self._doLockSet, args=('three', 0)).start()
364
    self.assertEqual(self.done.get(True, 1), 'DONE')
365
    Thread(target=self._doLockSet, args=(['one', 'two'], 0)).start()
366
    Thread(target=self._doLockSet, args=(['one', 'two'], 1)).start()
367
    Thread(target=self._doLockSet, args=('one', 0)).start()
368
    Thread(target=self._doLockSet, args=('one', 1)).start()
369
    Thread(target=self._doLockSet, args=(['two', 'three'], 0)).start()
370
    Thread(target=self._doLockSet, args=(['two', 'three'], 1)).start()
371
    self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
372
    self.ls.release()
373
    self.assertEqual(self.done.get(True, 1), 'DONE')
374
    self.assertEqual(self.done.get(True, 1), 'DONE')
375
    self.assertEqual(self.done.get(True, 1), 'DONE')
376
    self.assertEqual(self.done.get(True, 1), 'DONE')
377
    self.assertEqual(self.done.get(True, 1), 'DONE')
378
    self.assertEqual(self.done.get(True, 1), 'DONE')
379

  
380
  def testConcurrentRemove(self):
381
    self.ls.add('four')
382
    self.ls.acquire(['one', 'two', 'four'])
383
    Thread(target=self._doLockSet, args=(['one', 'four'], 0)).start()
384
    Thread(target=self._doLockSet, args=(['one', 'four'], 1)).start()
385
    Thread(target=self._doLockSet, args=(['one', 'two'], 0)).start()
386
    Thread(target=self._doLockSet, args=(['one', 'two'], 1)).start()
387
    self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
388
    self.ls.remove('one')
389
    self.ls.release()
390
    self.assertEqual(self.done.get(True, 1), 'ERR')
391
    self.assertEqual(self.done.get(True, 1), 'ERR')
392
    self.assertEqual(self.done.get(True, 1), 'ERR')
393
    self.assertEqual(self.done.get(True, 1), 'ERR')
394
    self.ls.add(['five', 'six'], acquired=1)
395
    Thread(target=self._doLockSet, args=(['three', 'six'], 1)).start()
396
    Thread(target=self._doLockSet, args=(['three', 'six'], 0)).start()
397
    Thread(target=self._doLockSet, args=(['four', 'six'], 1)).start()
398
    Thread(target=self._doLockSet, args=(['four', 'six'], 0)).start()
399
    self.ls.remove('five')
400
    self.ls.release()
401
    self.assertEqual(self.done.get(True, 1), 'DONE')
402
    self.assertEqual(self.done.get(True, 1), 'DONE')
403
    self.assertEqual(self.done.get(True, 1), 'DONE')
404
    self.assertEqual(self.done.get(True, 1), 'DONE')
405
    self.ls.acquire(['three', 'four'])
406
    Thread(target=self._doRemoveSet, args=(['four', 'six'], )).start()
407
    self.assertRaises(Queue.Empty, self.done.get, True, 0.2)
408
    self.ls.remove('four')
409
    self.assertEqual(self.done.get(True, 1), ['four'])
410
    Thread(target=self._doRemoveSet, args=(['two'])).start()
411
    self.assertEqual(self.done.get(True, 1), [])
412
    self.ls.release()
413

  
414

  
233 415
if __name__ == '__main__':
234 416
  unittest.main()
235 417
  #suite = unittest.TestLoader().loadTestsFromTestCase(TestSharedLock)

Also available in: Unified diff