Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.client.gnt_cluster_unittest.py @ d01e51a5

History | View | Annotate | Download (9.3 kB)

1 66d1f035 René Nussbaumer
#!/usr/bin/python
2 66d1f035 René Nussbaumer
#
3 66d1f035 René Nussbaumer
4 66d1f035 René Nussbaumer
# Copyright (C) 2011 Google Inc.
5 66d1f035 René Nussbaumer
#
6 66d1f035 René Nussbaumer
# This program is free software; you can redistribute it and/or modify
7 66d1f035 René Nussbaumer
# it under the terms of the GNU General Public License as published by
8 66d1f035 René Nussbaumer
# the Free Software Foundation; either version 2 of the License, or
9 66d1f035 René Nussbaumer
# (at your option) any later version.
10 66d1f035 René Nussbaumer
#
11 66d1f035 René Nussbaumer
# This program is distributed in the hope that it will be useful, but
12 66d1f035 René Nussbaumer
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 66d1f035 René Nussbaumer
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 66d1f035 René Nussbaumer
# General Public License for more details.
15 66d1f035 René Nussbaumer
#
16 66d1f035 René Nussbaumer
# You should have received a copy of the GNU General Public License
17 66d1f035 René Nussbaumer
# along with this program; if not, write to the Free Software
18 66d1f035 René Nussbaumer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 66d1f035 René Nussbaumer
# 02110-1301, USA.
20 66d1f035 René Nussbaumer
21 66d1f035 René Nussbaumer
22 66d1f035 René Nussbaumer
"""Script for testing ganeti.client.gnt_cluster"""
23 66d1f035 René Nussbaumer
24 66d1f035 René Nussbaumer
import unittest
25 1ca7b773 Michael Hanselmann
import optparse
26 66d1f035 René Nussbaumer
27 66d1f035 René Nussbaumer
from ganeti.client import gnt_cluster
28 66d1f035 René Nussbaumer
from ganeti import utils
29 66d1f035 René Nussbaumer
from ganeti import compat
30 1ca7b773 Michael Hanselmann
from ganeti import constants
31 66d1f035 René Nussbaumer
32 66d1f035 René Nussbaumer
import testutils
33 66d1f035 René Nussbaumer
34 66d1f035 René Nussbaumer
35 1ca7b773 Michael Hanselmann
class TestEpoUtilities(unittest.TestCase):
36 66d1f035 René Nussbaumer
  def setUp(self):
37 66d1f035 René Nussbaumer
    self.nodes2ip = dict(("node%s" % i, "192.0.2.%s" % i) for i in range(1, 10))
38 66d1f035 René Nussbaumer
    self.nodes = set(self.nodes2ip.keys())
39 66d1f035 René Nussbaumer
    self.ips2node = dict((v, k) for (k, v) in self.nodes2ip.items())
40 66d1f035 René Nussbaumer
41 66d1f035 René Nussbaumer
  def _FakeAction(*args):
42 66d1f035 René Nussbaumer
    return True
43 66d1f035 René Nussbaumer
44 66d1f035 René Nussbaumer
  def _FakePing(ip, port, live_port_needed=False):
45 66d1f035 René Nussbaumer
    self.assert_(live_port_needed)
46 66d1f035 René Nussbaumer
    self.assertEqual(port, 0)
47 66d1f035 René Nussbaumer
    return True
48 66d1f035 René Nussbaumer
49 66d1f035 René Nussbaumer
  def _FakeSleep(secs):
50 66d1f035 René Nussbaumer
    self.assert_(secs >= 0 and secs <= 5)
51 66d1f035 René Nussbaumer
    return
52 66d1f035 René Nussbaumer
53 8e74adce René Nussbaumer
  def _NoopFeedback(self, text):
54 8e74adce René Nussbaumer
    return
55 8e74adce René Nussbaumer
56 66d1f035 René Nussbaumer
  def testPingFnRemoveHostsUp(self):
57 66d1f035 René Nussbaumer
    seen = set()
58 66d1f035 René Nussbaumer
    def _FakeSeenPing(ip, *args, **kwargs):
59 66d1f035 René Nussbaumer
      node = self.ips2node[ip]
60 66d1f035 René Nussbaumer
      self.assertFalse(node in seen)
61 66d1f035 René Nussbaumer
      seen.add(node)
62 66d1f035 René Nussbaumer
      return True
63 66d1f035 René Nussbaumer
64 66d1f035 René Nussbaumer
    helper = gnt_cluster._RunWhenNodesReachableHelper(self.nodes,
65 66d1f035 René Nussbaumer
                                                      self._FakeAction,
66 8e74adce René Nussbaumer
                                                      self.nodes2ip, 0,
67 8e74adce René Nussbaumer
                                                      self._NoopFeedback,
68 66d1f035 René Nussbaumer
                                                      _ping_fn=_FakeSeenPing,
69 66d1f035 René Nussbaumer
                                                      _sleep_fn=self._FakeSleep)
70 66d1f035 René Nussbaumer
71 66d1f035 René Nussbaumer
    nodes_len = len(self.nodes)
72 66d1f035 René Nussbaumer
    for (num, _) in enumerate(self.nodes):
73 66d1f035 René Nussbaumer
      helper.Wait(5)
74 66d1f035 René Nussbaumer
      if num < nodes_len - 1:
75 66d1f035 René Nussbaumer
        self.assertRaises(utils.RetryAgain, helper)
76 66d1f035 René Nussbaumer
      else:
77 66d1f035 René Nussbaumer
        helper()
78 66d1f035 René Nussbaumer
79 66d1f035 René Nussbaumer
    self.assertEqual(seen, self.nodes)
80 66d1f035 René Nussbaumer
    self.assertFalse(helper.down)
81 66d1f035 René Nussbaumer
    self.assertEqual(helper.up, self.nodes)
82 66d1f035 René Nussbaumer
83 66d1f035 René Nussbaumer
  def testActionReturnFalseSetsHelperFalse(self):
84 66d1f035 René Nussbaumer
    called = False
85 66d1f035 René Nussbaumer
    def _FalseAction(*args):
86 66d1f035 René Nussbaumer
      return called
87 66d1f035 René Nussbaumer
88 66d1f035 René Nussbaumer
    helper = gnt_cluster._RunWhenNodesReachableHelper(self.nodes, _FalseAction,
89 8e74adce René Nussbaumer
                                                      self.nodes2ip, 0,
90 8e74adce René Nussbaumer
                                                      self._NoopFeedback,
91 66d1f035 René Nussbaumer
                                                      _ping_fn=self._FakePing,
92 66d1f035 René Nussbaumer
                                                      _sleep_fn=self._FakeSleep)
93 66d1f035 René Nussbaumer
    for _ in self.nodes:
94 66d1f035 René Nussbaumer
      try:
95 66d1f035 René Nussbaumer
        helper()
96 66d1f035 René Nussbaumer
      except utils.RetryAgain:
97 66d1f035 René Nussbaumer
        called = True
98 66d1f035 René Nussbaumer
99 66d1f035 René Nussbaumer
    self.assertFalse(helper.success)
100 66d1f035 René Nussbaumer
101 66d1f035 René Nussbaumer
  def testMaybeInstanceStartup(self):
102 66d1f035 René Nussbaumer
    instances_arg = []
103 66d1f035 René Nussbaumer
    def _FakeInstanceStart(opts, instances, start):
104 66d1f035 René Nussbaumer
      instances_arg.append(set(instances))
105 66d1f035 René Nussbaumer
      return None
106 66d1f035 René Nussbaumer
107 66d1f035 René Nussbaumer
    inst_map = {
108 66d1f035 René Nussbaumer
      "inst1": set(["node1", "node2"]),
109 66d1f035 René Nussbaumer
      "inst2": set(["node1", "node3"]),
110 66d1f035 René Nussbaumer
      "inst3": set(["node2", "node1"]),
111 66d1f035 René Nussbaumer
      "inst4": set(["node2", "node1", "node3"]),
112 66d1f035 René Nussbaumer
      "inst5": set(["node4"]),
113 66d1f035 René Nussbaumer
      }
114 66d1f035 René Nussbaumer
115 66d1f035 René Nussbaumer
    fn = _FakeInstanceStart
116 66d1f035 René Nussbaumer
    self.assert_(gnt_cluster._MaybeInstanceStartup(None, inst_map, set(),
117 66d1f035 René Nussbaumer
                                                   _instance_start_fn=fn))
118 66d1f035 René Nussbaumer
    self.assertFalse(instances_arg)
119 66d1f035 René Nussbaumer
    result = gnt_cluster._MaybeInstanceStartup(None, inst_map, set(["node1"]),
120 66d1f035 René Nussbaumer
                                               _instance_start_fn=fn)
121 66d1f035 René Nussbaumer
    self.assert_(result)
122 66d1f035 René Nussbaumer
    self.assertFalse(instances_arg)
123 66d1f035 René Nussbaumer
    result = gnt_cluster._MaybeInstanceStartup(None, inst_map,
124 66d1f035 René Nussbaumer
                                               set(["node1", "node3"]),
125 66d1f035 René Nussbaumer
                                               _instance_start_fn=fn)
126 66d1f035 René Nussbaumer
    self.assert_(result is None)
127 66d1f035 René Nussbaumer
    self.assertEqual(instances_arg.pop(0), set(["inst2"]))
128 66d1f035 René Nussbaumer
    self.assertFalse("inst2" in inst_map)
129 66d1f035 René Nussbaumer
    result = gnt_cluster._MaybeInstanceStartup(None, inst_map,
130 66d1f035 René Nussbaumer
                                               set(["node1", "node3"]),
131 66d1f035 René Nussbaumer
                                               _instance_start_fn=fn)
132 66d1f035 René Nussbaumer
    self.assert_(result)
133 66d1f035 René Nussbaumer
    self.assertFalse(instances_arg)
134 66d1f035 René Nussbaumer
    result = gnt_cluster._MaybeInstanceStartup(None, inst_map,
135 66d1f035 René Nussbaumer
                                               set(["node1", "node3", "node2"]),
136 66d1f035 René Nussbaumer
                                               _instance_start_fn=fn)
137 66d1f035 René Nussbaumer
    self.assertEqual(instances_arg.pop(0), set(["inst1", "inst3", "inst4"]))
138 66d1f035 René Nussbaumer
    self.assert_(result is None)
139 66d1f035 René Nussbaumer
    result = gnt_cluster._MaybeInstanceStartup(None, inst_map,
140 66d1f035 René Nussbaumer
                                               set(["node1", "node3", "node2",
141 66d1f035 René Nussbaumer
                                                    "node4"]),
142 66d1f035 René Nussbaumer
                                               _instance_start_fn=fn)
143 66d1f035 René Nussbaumer
    self.assert_(result is None)
144 66d1f035 René Nussbaumer
    self.assertEqual(instances_arg.pop(0), set(["inst5"]))
145 66d1f035 René Nussbaumer
    self.assertFalse(inst_map)
146 66d1f035 René Nussbaumer
147 66d1f035 René Nussbaumer
148 1ca7b773 Michael Hanselmann
class _ClientForEpo:
149 1ca7b773 Michael Hanselmann
  def __init__(self, groups, nodes):
150 1ca7b773 Michael Hanselmann
    self._groups = groups
151 1ca7b773 Michael Hanselmann
    self._nodes = nodes
152 1ca7b773 Michael Hanselmann
153 1ca7b773 Michael Hanselmann
  def QueryGroups(self, names, fields, use_locking):
154 1ca7b773 Michael Hanselmann
    assert not use_locking
155 1ca7b773 Michael Hanselmann
    assert fields == ["node_list"]
156 1ca7b773 Michael Hanselmann
    return self._groups
157 1ca7b773 Michael Hanselmann
158 1ca7b773 Michael Hanselmann
  def QueryNodes(self, names, fields, use_locking):
159 1ca7b773 Michael Hanselmann
    assert not use_locking
160 1ca7b773 Michael Hanselmann
    assert fields == ["name", "master", "pinst_list", "sinst_list", "powered",
161 1ca7b773 Michael Hanselmann
                      "offline"]
162 1ca7b773 Michael Hanselmann
    return self._nodes
163 1ca7b773 Michael Hanselmann
164 1ca7b773 Michael Hanselmann
165 1ca7b773 Michael Hanselmann
class TestEpo(unittest.TestCase):
166 1ca7b773 Michael Hanselmann
  _ON_EXITCODE = 253
167 1ca7b773 Michael Hanselmann
  _OFF_EXITCODE = 254
168 1ca7b773 Michael Hanselmann
169 1ca7b773 Michael Hanselmann
  def _ConfirmForce(self, *args):
170 1ca7b773 Michael Hanselmann
    self.fail("Shouldn't need confirmation")
171 1ca7b773 Michael Hanselmann
172 1ca7b773 Michael Hanselmann
  def _Confirm(self, exp_names, result, names, ltype, text):
173 1ca7b773 Michael Hanselmann
    self.assertEqual(names, exp_names)
174 1ca7b773 Michael Hanselmann
    self.assertFalse(result is NotImplemented)
175 1ca7b773 Michael Hanselmann
    return result
176 1ca7b773 Michael Hanselmann
177 1ca7b773 Michael Hanselmann
  def _Off(self, exp_node_list, opts, node_list, inst_map):
178 1ca7b773 Michael Hanselmann
    self.assertEqual(node_list, exp_node_list)
179 1ca7b773 Michael Hanselmann
    self.assertFalse(inst_map)
180 1ca7b773 Michael Hanselmann
    return self._OFF_EXITCODE
181 1ca7b773 Michael Hanselmann
182 1ca7b773 Michael Hanselmann
  def _Test(self, *args, **kwargs):
183 1ca7b773 Michael Hanselmann
    defaults = dict(cl=NotImplemented, _on_fn=NotImplemented,
184 1ca7b773 Michael Hanselmann
                    _off_fn=NotImplemented,
185 1ca7b773 Michael Hanselmann
                    _stdout_fn=lambda *args: None,
186 1ca7b773 Michael Hanselmann
                    _stderr_fn=lambda *args: None)
187 1ca7b773 Michael Hanselmann
    defaults.update(kwargs)
188 1ca7b773 Michael Hanselmann
    return gnt_cluster.Epo(*args, **defaults)
189 1ca7b773 Michael Hanselmann
190 1ca7b773 Michael Hanselmann
  def testShowAllWithGroups(self):
191 1ca7b773 Michael Hanselmann
    opts = optparse.Values(dict(groups=True, show_all=True))
192 1ca7b773 Michael Hanselmann
    result = self._Test(opts, NotImplemented)
193 1ca7b773 Michael Hanselmann
    self.assertEqual(result, constants.EXIT_FAILURE)
194 1ca7b773 Michael Hanselmann
195 1ca7b773 Michael Hanselmann
  def testShowAllWithArgs(self):
196 1ca7b773 Michael Hanselmann
    opts = optparse.Values(dict(groups=False, show_all=True))
197 1ca7b773 Michael Hanselmann
    result = self._Test(opts, ["a", "b", "c"])
198 1ca7b773 Michael Hanselmann
    self.assertEqual(result, constants.EXIT_FAILURE)
199 1ca7b773 Michael Hanselmann
200 1ca7b773 Michael Hanselmann
  def testNoArgumentsNoParameters(self):
201 1ca7b773 Michael Hanselmann
    for (force, confirm_result) in [(True, NotImplemented), (False, False),
202 1ca7b773 Michael Hanselmann
                                    (False, True)]:
203 1ca7b773 Michael Hanselmann
      opts = optparse.Values(dict(groups=False, show_all=False, force=force,
204 1ca7b773 Michael Hanselmann
                                  on=False))
205 1ca7b773 Michael Hanselmann
      client = _ClientForEpo(NotImplemented, [
206 1ca7b773 Michael Hanselmann
        ("node1.example.com", False, [], [], True, False),
207 1ca7b773 Michael Hanselmann
        ])
208 1ca7b773 Michael Hanselmann
209 1ca7b773 Michael Hanselmann
      if force:
210 1ca7b773 Michael Hanselmann
        confirm_fn = self._ConfirmForce
211 1ca7b773 Michael Hanselmann
      else:
212 1ca7b773 Michael Hanselmann
        confirm_fn = compat.partial(self._Confirm, ["node1.example.com"],
213 1ca7b773 Michael Hanselmann
                                    confirm_result)
214 1ca7b773 Michael Hanselmann
215 1ca7b773 Michael Hanselmann
      off_fn = compat.partial(self._Off, ["node1.example.com"])
216 1ca7b773 Michael Hanselmann
217 1ca7b773 Michael Hanselmann
      result = self._Test(opts, [], cl=client, _off_fn=off_fn,
218 1ca7b773 Michael Hanselmann
                          _confirm_fn=confirm_fn)
219 1ca7b773 Michael Hanselmann
      if force or confirm_result:
220 1ca7b773 Michael Hanselmann
        self.assertEqual(result, self._OFF_EXITCODE)
221 1ca7b773 Michael Hanselmann
      else:
222 1ca7b773 Michael Hanselmann
        self.assertEqual(result, constants.EXIT_FAILURE)
223 1ca7b773 Michael Hanselmann
224 1ca7b773 Michael Hanselmann
  def testPowerOn(self):
225 1ca7b773 Michael Hanselmann
    for master in [False, True]:
226 1ca7b773 Michael Hanselmann
      opts = optparse.Values(dict(groups=False, show_all=True,
227 1ca7b773 Michael Hanselmann
                                  force=True, on=True))
228 1ca7b773 Michael Hanselmann
      client = _ClientForEpo(NotImplemented, [
229 1ca7b773 Michael Hanselmann
        ("node1.example.com", False, [], [], True, False),
230 1ca7b773 Michael Hanselmann
        ("node2.example.com", False, [], [], False, False),
231 1ca7b773 Michael Hanselmann
        ("node3.example.com", False, [], [], True, True),
232 1ca7b773 Michael Hanselmann
        ("node4.example.com", False, [], [], None, True),
233 1ca7b773 Michael Hanselmann
        ("node5.example.com", master, [], [], False, False),
234 1ca7b773 Michael Hanselmann
        ])
235 1ca7b773 Michael Hanselmann
236 1ca7b773 Michael Hanselmann
      def _On(_, all_nodes, node_list, inst_map):
237 1ca7b773 Michael Hanselmann
        self.assertEqual(all_nodes,
238 1ca7b773 Michael Hanselmann
                         ["node%s.example.com" % i for i in range(1, 6)])
239 1ca7b773 Michael Hanselmann
        if master:
240 1ca7b773 Michael Hanselmann
          self.assertEqual(node_list, ["node2.example.com"])
241 1ca7b773 Michael Hanselmann
        else:
242 1ca7b773 Michael Hanselmann
          self.assertEqual(node_list, ["node2.example.com",
243 1ca7b773 Michael Hanselmann
                                       "node5.example.com"])
244 1ca7b773 Michael Hanselmann
        self.assertFalse(inst_map)
245 1ca7b773 Michael Hanselmann
        return self._ON_EXITCODE
246 1ca7b773 Michael Hanselmann
247 1ca7b773 Michael Hanselmann
      result = self._Test(opts, [], cl=client, _on_fn=_On,
248 1ca7b773 Michael Hanselmann
                          _confirm_fn=self._ConfirmForce)
249 1ca7b773 Michael Hanselmann
      self.assertEqual(result, self._ON_EXITCODE)
250 1ca7b773 Michael Hanselmann
251 1ca7b773 Michael Hanselmann
  def testMasterWithoutShowAll(self):
252 1ca7b773 Michael Hanselmann
    opts = optparse.Values(dict(groups=False, show_all=False,
253 1ca7b773 Michael Hanselmann
                                force=True, on=False))
254 1ca7b773 Michael Hanselmann
    client = _ClientForEpo(NotImplemented, [
255 1ca7b773 Michael Hanselmann
      ("node1.example.com", True, [], [], True, False),
256 1ca7b773 Michael Hanselmann
      ])
257 1ca7b773 Michael Hanselmann
    result = self._Test(opts, [], cl=client, _confirm_fn=self._ConfirmForce)
258 1ca7b773 Michael Hanselmann
    self.assertEqual(result, constants.EXIT_FAILURE)
259 1ca7b773 Michael Hanselmann
260 1ca7b773 Michael Hanselmann
261 66d1f035 René Nussbaumer
if __name__ == "__main__":
262 66d1f035 René Nussbaumer
  testutils.GanetiTestProgram()