32 |
32 |
from ganeti import errors
|
33 |
33 |
from ganeti import utils
|
34 |
34 |
from ganeti import objects
|
|
35 |
from ganeti import qlang
|
35 |
36 |
from ganeti.errors import OpPrereqError, ParameterError
|
36 |
37 |
|
37 |
38 |
|
... | ... | |
753 |
754 |
self.assertTrue(result.endswith(")"))
|
754 |
755 |
|
755 |
756 |
|
|
757 |
class TestGetOnlineNodes(unittest.TestCase):
|
|
758 |
class _FakeClient:
|
|
759 |
def __init__(self):
|
|
760 |
self._query = []
|
|
761 |
|
|
762 |
def AddQueryResult(self, *args):
|
|
763 |
self._query.append(args)
|
|
764 |
|
|
765 |
def CountPending(self):
|
|
766 |
return len(self._query)
|
|
767 |
|
|
768 |
def Query(self, res, fields, filter_):
|
|
769 |
if res != constants.QR_NODE:
|
|
770 |
raise Exception("Querying wrong resource")
|
|
771 |
|
|
772 |
(exp_fields, check_filter, result) = self._query.pop(0)
|
|
773 |
|
|
774 |
if exp_fields != fields:
|
|
775 |
raise Exception("Expected fields %s, got %s" % (exp_fields, fields))
|
|
776 |
|
|
777 |
if not (filter_ is None or check_filter(filter_)):
|
|
778 |
raise Exception("Filter doesn't match expectations")
|
|
779 |
|
|
780 |
return objects.QueryResponse(fields=None, data=result)
|
|
781 |
|
|
782 |
def testEmpty(self):
|
|
783 |
cl = self._FakeClient()
|
|
784 |
|
|
785 |
cl.AddQueryResult(["name", "offline", "sip"], None, [])
|
|
786 |
self.assertEqual(cli.GetOnlineNodes(None, cl=cl), [])
|
|
787 |
self.assertEqual(cl.CountPending(), 0)
|
|
788 |
|
|
789 |
def testNoSpecialFilter(self):
|
|
790 |
cl = self._FakeClient()
|
|
791 |
|
|
792 |
cl.AddQueryResult(["name", "offline", "sip"], None, [
|
|
793 |
[(constants.RS_NORMAL, "master.example.com"),
|
|
794 |
(constants.RS_NORMAL, False),
|
|
795 |
(constants.RS_NORMAL, "192.0.2.1")],
|
|
796 |
[(constants.RS_NORMAL, "node2.example.com"),
|
|
797 |
(constants.RS_NORMAL, False),
|
|
798 |
(constants.RS_NORMAL, "192.0.2.2")],
|
|
799 |
])
|
|
800 |
self.assertEqual(cli.GetOnlineNodes(None, cl=cl),
|
|
801 |
["master.example.com", "node2.example.com"])
|
|
802 |
self.assertEqual(cl.CountPending(), 0)
|
|
803 |
|
|
804 |
def testNoMaster(self):
|
|
805 |
cl = self._FakeClient()
|
|
806 |
|
|
807 |
def _CheckFilter(filter_):
|
|
808 |
self.assertEqual(filter_, [qlang.OP_NOT, [qlang.OP_TRUE, "master"]])
|
|
809 |
return True
|
|
810 |
|
|
811 |
cl.AddQueryResult(["name", "offline", "sip"], _CheckFilter, [
|
|
812 |
[(constants.RS_NORMAL, "node2.example.com"),
|
|
813 |
(constants.RS_NORMAL, False),
|
|
814 |
(constants.RS_NORMAL, "192.0.2.2")],
|
|
815 |
])
|
|
816 |
self.assertEqual(cli.GetOnlineNodes(None, cl=cl, filter_master=True),
|
|
817 |
["node2.example.com"])
|
|
818 |
self.assertEqual(cl.CountPending(), 0)
|
|
819 |
|
|
820 |
def testSecondaryIpAddress(self):
|
|
821 |
cl = self._FakeClient()
|
|
822 |
|
|
823 |
cl.AddQueryResult(["name", "offline", "sip"], None, [
|
|
824 |
[(constants.RS_NORMAL, "master.example.com"),
|
|
825 |
(constants.RS_NORMAL, False),
|
|
826 |
(constants.RS_NORMAL, "192.0.2.1")],
|
|
827 |
[(constants.RS_NORMAL, "node2.example.com"),
|
|
828 |
(constants.RS_NORMAL, False),
|
|
829 |
(constants.RS_NORMAL, "192.0.2.2")],
|
|
830 |
])
|
|
831 |
self.assertEqual(cli.GetOnlineNodes(None, cl=cl, secondary_ips=True),
|
|
832 |
["192.0.2.1", "192.0.2.2"])
|
|
833 |
self.assertEqual(cl.CountPending(), 0)
|
|
834 |
|
|
835 |
def testNoMasterFilterNodeName(self):
|
|
836 |
cl = self._FakeClient()
|
|
837 |
|
|
838 |
def _CheckFilter(filter_):
|
|
839 |
self.assertEqual(filter_,
|
|
840 |
[qlang.OP_AND,
|
|
841 |
[qlang.OP_OR] + [[qlang.OP_EQUAL, "name", name]
|
|
842 |
for name in ["node2", "node3"]],
|
|
843 |
[qlang.OP_NOT, [qlang.OP_TRUE, "master"]]])
|
|
844 |
return True
|
|
845 |
|
|
846 |
cl.AddQueryResult(["name", "offline", "sip"], _CheckFilter, [
|
|
847 |
[(constants.RS_NORMAL, "node2.example.com"),
|
|
848 |
(constants.RS_NORMAL, False),
|
|
849 |
(constants.RS_NORMAL, "192.0.2.12")],
|
|
850 |
[(constants.RS_NORMAL, "node3.example.com"),
|
|
851 |
(constants.RS_NORMAL, False),
|
|
852 |
(constants.RS_NORMAL, "192.0.2.13")],
|
|
853 |
])
|
|
854 |
self.assertEqual(cli.GetOnlineNodes(["node2", "node3"], cl=cl,
|
|
855 |
secondary_ips=True, filter_master=True),
|
|
856 |
["192.0.2.12", "192.0.2.13"])
|
|
857 |
self.assertEqual(cl.CountPending(), 0)
|
|
858 |
|
|
859 |
def testOfflineNodes(self):
|
|
860 |
cl = self._FakeClient()
|
|
861 |
|
|
862 |
cl.AddQueryResult(["name", "offline", "sip"], None, [
|
|
863 |
[(constants.RS_NORMAL, "master.example.com"),
|
|
864 |
(constants.RS_NORMAL, False),
|
|
865 |
(constants.RS_NORMAL, "192.0.2.1")],
|
|
866 |
[(constants.RS_NORMAL, "node2.example.com"),
|
|
867 |
(constants.RS_NORMAL, True),
|
|
868 |
(constants.RS_NORMAL, "192.0.2.2")],
|
|
869 |
[(constants.RS_NORMAL, "node3.example.com"),
|
|
870 |
(constants.RS_NORMAL, True),
|
|
871 |
(constants.RS_NORMAL, "192.0.2.3")],
|
|
872 |
])
|
|
873 |
self.assertEqual(cli.GetOnlineNodes(None, cl=cl, nowarn=True),
|
|
874 |
["master.example.com"])
|
|
875 |
self.assertEqual(cl.CountPending(), 0)
|
|
876 |
|
|
877 |
def testNodeGroup(self):
|
|
878 |
cl = self._FakeClient()
|
|
879 |
|
|
880 |
def _CheckFilter(filter_):
|
|
881 |
self.assertEqual(filter_,
|
|
882 |
[qlang.OP_OR, [qlang.OP_EQUAL, "group", "foobar"],
|
|
883 |
[qlang.OP_EQUAL, "group.uuid", "foobar"]])
|
|
884 |
return True
|
|
885 |
|
|
886 |
cl.AddQueryResult(["name", "offline", "sip"], _CheckFilter, [
|
|
887 |
[(constants.RS_NORMAL, "master.example.com"),
|
|
888 |
(constants.RS_NORMAL, False),
|
|
889 |
(constants.RS_NORMAL, "192.0.2.1")],
|
|
890 |
[(constants.RS_NORMAL, "node3.example.com"),
|
|
891 |
(constants.RS_NORMAL, False),
|
|
892 |
(constants.RS_NORMAL, "192.0.2.3")],
|
|
893 |
])
|
|
894 |
self.assertEqual(cli.GetOnlineNodes(None, cl=cl, nodegroup="foobar"),
|
|
895 |
["master.example.com", "node3.example.com"])
|
|
896 |
self.assertEqual(cl.CountPending(), 0)
|
|
897 |
|
|
898 |
|
756 |
899 |
if __name__ == '__main__':
|
757 |
900 |
testutils.GanetiTestProgram()
|