Revision 3dbe3ddf test/ganeti.locking_unittest.py
b/test/ganeti.locking_unittest.py | ||
---|---|---|
612 | 612 |
|
613 | 613 |
self.assertRaises(Queue.Empty, self.done.get_nowait) |
614 | 614 |
|
615 |
def testIllegalDowngrade(self): |
|
616 |
# Not yet acquired |
|
617 |
self.assertRaises(AssertionError, self.sl.downgrade) |
|
618 |
|
|
619 |
# Acquire in shared mode, downgrade should be no-op |
|
620 |
self.assertTrue(self.sl.acquire(shared=1)) |
|
621 |
self.assertTrue(self.sl._is_owned(shared=1)) |
|
622 |
self.assertTrue(self.sl.downgrade()) |
|
623 |
self.assertTrue(self.sl._is_owned(shared=1)) |
|
624 |
self.sl.release() |
|
625 |
|
|
626 |
def testDowngrade(self): |
|
627 |
self.assertTrue(self.sl.acquire()) |
|
628 |
self.assertTrue(self.sl._is_owned(shared=0)) |
|
629 |
self.assertTrue(self.sl.downgrade()) |
|
630 |
self.assertTrue(self.sl._is_owned(shared=1)) |
|
631 |
self.sl.release() |
|
632 |
|
|
633 |
@_Repeat |
|
634 |
def testDowngradeJumpsAheadOfExclusive(self): |
|
635 |
def _KeepExclusive(ev_got, ev_downgrade, ev_release): |
|
636 |
self.assertTrue(self.sl.acquire()) |
|
637 |
self.assertTrue(self.sl._is_owned(shared=0)) |
|
638 |
ev_got.set() |
|
639 |
ev_downgrade.wait() |
|
640 |
self.assertTrue(self.sl._is_owned(shared=0)) |
|
641 |
self.assertTrue(self.sl.downgrade()) |
|
642 |
self.assertTrue(self.sl._is_owned(shared=1)) |
|
643 |
ev_release.wait() |
|
644 |
self.assertTrue(self.sl._is_owned(shared=1)) |
|
645 |
self.sl.release() |
|
646 |
|
|
647 |
def _KeepExclusive2(ev_started, ev_release): |
|
648 |
self.assertTrue(self.sl.acquire(test_notify=ev_started.set)) |
|
649 |
self.assertTrue(self.sl._is_owned(shared=0)) |
|
650 |
ev_release.wait() |
|
651 |
self.assertTrue(self.sl._is_owned(shared=0)) |
|
652 |
self.sl.release() |
|
653 |
|
|
654 |
def _KeepShared(ev_started, ev_got, ev_release): |
|
655 |
self.assertTrue(self.sl.acquire(shared=1, test_notify=ev_started.set)) |
|
656 |
self.assertTrue(self.sl._is_owned(shared=1)) |
|
657 |
ev_got.set() |
|
658 |
ev_release.wait() |
|
659 |
self.assertTrue(self.sl._is_owned(shared=1)) |
|
660 |
self.sl.release() |
|
661 |
|
|
662 |
# Acquire lock in exclusive mode |
|
663 |
ev_got_excl1 = threading.Event() |
|
664 |
ev_downgrade_excl1 = threading.Event() |
|
665 |
ev_release_excl1 = threading.Event() |
|
666 |
th_excl1 = self._addThread(target=_KeepExclusive, |
|
667 |
args=(ev_got_excl1, ev_downgrade_excl1, |
|
668 |
ev_release_excl1)) |
|
669 |
ev_got_excl1.wait() |
|
670 |
|
|
671 |
# Start a second exclusive acquire |
|
672 |
ev_started_excl2 = threading.Event() |
|
673 |
ev_release_excl2 = threading.Event() |
|
674 |
th_excl2 = self._addThread(target=_KeepExclusive2, |
|
675 |
args=(ev_started_excl2, ev_release_excl2)) |
|
676 |
ev_started_excl2.wait() |
|
677 |
|
|
678 |
# Start shared acquires, will jump ahead of second exclusive acquire when |
|
679 |
# first exclusive acquire downgrades |
|
680 |
ev_shared = [(threading.Event(), threading.Event()) for _ in range(5)] |
|
681 |
ev_release_shared = threading.Event() |
|
682 |
|
|
683 |
th_shared = [self._addThread(target=_KeepShared, |
|
684 |
args=(ev_started, ev_got, ev_release_shared)) |
|
685 |
for (ev_started, ev_got) in ev_shared] |
|
686 |
|
|
687 |
# Wait for all shared acquires to start |
|
688 |
for (ev, _) in ev_shared: |
|
689 |
ev.wait() |
|
690 |
|
|
691 |
# Check lock information |
|
692 |
self.assertEqual(self.sl.GetInfo(set([query.LQ_MODE, query.LQ_OWNER])), |
|
693 |
(self.sl.name, "exclusive", [th_excl1.getName()], None)) |
|
694 |
(_, _, _, pending) = self.sl.GetInfo(set([query.LQ_PENDING])) |
|
695 |
self.assertEqual([(pendmode, sorted(waiting)) |
|
696 |
for (pendmode, waiting) in pending], |
|
697 |
[("exclusive", [th_excl2.getName()]), |
|
698 |
("shared", sorted(th.getName() for th in th_shared))]) |
|
699 |
|
|
700 |
# Shared acquires won't start until the exclusive lock is downgraded |
|
701 |
ev_downgrade_excl1.set() |
|
702 |
|
|
703 |
# Wait for all shared acquires to be successful |
|
704 |
for (_, ev) in ev_shared: |
|
705 |
ev.wait() |
|
706 |
|
|
707 |
# Check lock information again |
|
708 |
self.assertEqual(self.sl.GetInfo(set([query.LQ_MODE, query.LQ_PENDING])), |
|
709 |
(self.sl.name, "shared", None, |
|
710 |
[("exclusive", [th_excl2.getName()])])) |
|
711 |
(_, _, owner, _) = self.sl.GetInfo(set([query.LQ_OWNER])) |
|
712 |
self.assertEqual(set(owner), set([th_excl1.getName()] + |
|
713 |
[th.getName() for th in th_shared])) |
|
714 |
|
|
715 |
ev_release_excl1.set() |
|
716 |
ev_release_excl2.set() |
|
717 |
ev_release_shared.set() |
|
718 |
|
|
719 |
self._waitThreads() |
|
720 |
|
|
721 |
self.assertEqual(self.sl.GetInfo(set([query.LQ_MODE, query.LQ_OWNER, |
|
722 |
query.LQ_PENDING])), |
|
723 |
(self.sl.name, None, None, [])) |
|
724 |
|
|
615 | 725 |
@_Repeat |
616 | 726 |
def testMixedAcquireTimeout(self): |
617 | 727 |
sync = threading.Event() |
... | ... | |
1374 | 1484 |
self.assertEqual(self.done.get_nowait(), 'DONE') |
1375 | 1485 |
self._setUpLS() |
1376 | 1486 |
|
1487 |
def testAcquireWithNamesDowngrade(self): |
|
1488 |
self.assertEquals(self.ls.acquire("two", shared=0), set(["two"])) |
|
1489 |
self.assertTrue(self.ls._is_owned()) |
|
1490 |
self.assertFalse(self.ls._get_lock()._is_owned()) |
|
1491 |
self.ls.release() |
|
1492 |
self.assertFalse(self.ls._is_owned()) |
|
1493 |
self.assertFalse(self.ls._get_lock()._is_owned()) |
|
1494 |
# Can't downgrade after releasing |
|
1495 |
self.assertRaises(AssertionError, self.ls.downgrade, "two") |
|
1496 |
|
|
1497 |
def testDowngrade(self): |
|
1498 |
# Not owning anything, must raise an exception |
|
1499 |
self.assertFalse(self.ls._is_owned()) |
|
1500 |
self.assertRaises(AssertionError, self.ls.downgrade) |
|
1501 |
|
|
1502 |
self.assertFalse(compat.any(i._is_owned() |
|
1503 |
for i in self.ls._get_lockdict().values())) |
|
1504 |
|
|
1505 |
self.assertEquals(self.ls.acquire(None, shared=0), |
|
1506 |
set(["one", "two", "three"])) |
|
1507 |
self.assertRaises(AssertionError, self.ls.downgrade, "unknown lock") |
|
1508 |
|
|
1509 |
self.assertTrue(self.ls._get_lock()._is_owned(shared=0)) |
|
1510 |
self.assertTrue(compat.all(i._is_owned(shared=0) |
|
1511 |
for i in self.ls._get_lockdict().values())) |
|
1512 |
|
|
1513 |
# Start downgrading locks |
|
1514 |
self.assertTrue(self.ls.downgrade(names=["one"])) |
|
1515 |
self.assertTrue(self.ls._get_lock()._is_owned(shared=0)) |
|
1516 |
self.assertTrue(compat.all(lock._is_owned(shared=[0, 1][int(name == "one")]) |
|
1517 |
for name, lock in |
|
1518 |
self.ls._get_lockdict().items())) |
|
1519 |
|
|
1520 |
self.assertTrue(self.ls.downgrade(names="two")) |
|
1521 |
self.assertTrue(self.ls._get_lock()._is_owned(shared=0)) |
|
1522 |
should_share = lambda name: [0, 1][int(name in ("one", "two"))] |
|
1523 |
self.assertTrue(compat.all(lock._is_owned(shared=should_share(name)) |
|
1524 |
for name, lock in |
|
1525 |
self.ls._get_lockdict().items())) |
|
1526 |
|
|
1527 |
# Downgrading the last exclusive lock to shared must downgrade the |
|
1528 |
# lockset-internal lock too |
|
1529 |
self.assertTrue(self.ls.downgrade(names="three")) |
|
1530 |
self.assertTrue(self.ls._get_lock()._is_owned(shared=1)) |
|
1531 |
self.assertTrue(compat.all(i._is_owned(shared=1) |
|
1532 |
for i in self.ls._get_lockdict().values())) |
|
1533 |
|
|
1534 |
# Downgrading a shared lock must be a no-op |
|
1535 |
self.assertTrue(self.ls.downgrade(names=["one", "three"])) |
|
1536 |
self.assertTrue(self.ls._get_lock()._is_owned(shared=1)) |
|
1537 |
self.assertTrue(compat.all(i._is_owned(shared=1) |
|
1538 |
for i in self.ls._get_lockdict().values())) |
|
1539 |
|
|
1540 |
self.ls.release() |
|
1541 |
|
|
1377 | 1542 |
def testPriority(self): |
1378 | 1543 |
def _Acquire(prev, next, name, priority, success_fn): |
1379 | 1544 |
prev.wait() |
Also available in: Unified diff