Statistics
| Branch: | Tag: | Revision:

root / qa / qa_group.py @ cbaf1652

History | View | Annotate | Download (9.2 kB)

1 30131294 Adeodato Simo
#
2 30131294 Adeodato Simo
#
3 30131294 Adeodato Simo
4 52bebbdf Iustin Pop
# Copyright (C) 2010, 2011, 2012 Google Inc.
5 30131294 Adeodato Simo
#
6 30131294 Adeodato Simo
# This program is free software; you can redistribute it and/or modify
7 30131294 Adeodato Simo
# it under the terms of the GNU General Public License as published by
8 30131294 Adeodato Simo
# the Free Software Foundation; either version 2 of the License, or
9 30131294 Adeodato Simo
# (at your option) any later version.
10 30131294 Adeodato Simo
#
11 30131294 Adeodato Simo
# This program is distributed in the hope that it will be useful, but
12 30131294 Adeodato Simo
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 30131294 Adeodato Simo
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 30131294 Adeodato Simo
# General Public License for more details.
15 30131294 Adeodato Simo
#
16 30131294 Adeodato Simo
# You should have received a copy of the GNU General Public License
17 30131294 Adeodato Simo
# along with this program; if not, write to the Free Software
18 30131294 Adeodato Simo
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 30131294 Adeodato Simo
# 02110-1301, USA.
20 30131294 Adeodato Simo
21 30131294 Adeodato Simo
22 3582eef6 Iustin Pop
"""QA tests for node groups.
23 3582eef6 Iustin Pop

24 3582eef6 Iustin Pop
"""
25 3582eef6 Iustin Pop
26 75cf411a Adeodato Simo
from ganeti import constants
27 7ab8b7d7 Adeodato Simo
from ganeti import query
28 f3fd2c9d Adeodato Simo
from ganeti import utils
29 75cf411a Adeodato Simo
30 66787da5 Adeodato Simo
import qa_config
31 7ab8b7d7 Adeodato Simo
import qa_utils
32 7ab8b7d7 Adeodato Simo
33 f3fd2c9d Adeodato Simo
from qa_utils import AssertCommand, AssertEqual, GetCommandOutput
34 30131294 Adeodato Simo
35 30131294 Adeodato Simo
36 fe508a9d Michael Hanselmann
def GetDefaultGroup():
37 fe508a9d Michael Hanselmann
  """Returns the default node group.
38 fe508a9d Michael Hanselmann

39 fe508a9d Michael Hanselmann
  """
40 fe508a9d Michael Hanselmann
  groups = qa_config.get("groups", {})
41 fe508a9d Michael Hanselmann
  return groups.get("group-with-nodes", constants.INITIAL_NODE_GROUP_NAME)
42 fe508a9d Michael Hanselmann
43 fe508a9d Michael Hanselmann
44 66787da5 Adeodato Simo
def TestGroupAddRemoveRename():
45 66787da5 Adeodato Simo
  """gnt-group add/remove/rename"""
46 fe508a9d Michael Hanselmann
  existing_group_with_nodes = GetDefaultGroup()
47 fe508a9d Michael Hanselmann
48 b4d2d2cb Michael Hanselmann
  (group1, group2, group3) = qa_utils.GetNonexistentGroups(3)
49 66787da5 Adeodato Simo
50 66787da5 Adeodato Simo
  AssertCommand(["gnt-group", "add", group1])
51 66787da5 Adeodato Simo
  AssertCommand(["gnt-group", "add", group2])
52 66787da5 Adeodato Simo
  AssertCommand(["gnt-group", "add", group2], fail=True)
53 66787da5 Adeodato Simo
  AssertCommand(["gnt-group", "add", existing_group_with_nodes], fail=True)
54 66787da5 Adeodato Simo
55 66787da5 Adeodato Simo
  AssertCommand(["gnt-group", "rename", group1, group2], fail=True)
56 66787da5 Adeodato Simo
  AssertCommand(["gnt-group", "rename", group1, group3])
57 66787da5 Adeodato Simo
58 66787da5 Adeodato Simo
  try:
59 66787da5 Adeodato Simo
    AssertCommand(["gnt-group", "rename", existing_group_with_nodes, group1])
60 66787da5 Adeodato Simo
61 66787da5 Adeodato Simo
    AssertCommand(["gnt-group", "remove", group2])
62 66787da5 Adeodato Simo
    AssertCommand(["gnt-group", "remove", group3])
63 66787da5 Adeodato Simo
    AssertCommand(["gnt-group", "remove", group1], fail=True)
64 66787da5 Adeodato Simo
  finally:
65 66787da5 Adeodato Simo
    # Try to ensure idempotency re groups that already existed.
66 66787da5 Adeodato Simo
    AssertCommand(["gnt-group", "rename", group1, existing_group_with_nodes])
67 66787da5 Adeodato Simo
68 66787da5 Adeodato Simo
69 4b10fb65 Adeodato Simo
def TestGroupAddWithOptions():
70 4b10fb65 Adeodato Simo
  """gnt-group add with options"""
71 b4d2d2cb Michael Hanselmann
  (group1, ) = qa_utils.GetNonexistentGroups(1)
72 4b10fb65 Adeodato Simo
73 4b10fb65 Adeodato Simo
  AssertCommand(["gnt-group", "add", "--alloc-policy", "notvalid", group1],
74 4b10fb65 Adeodato Simo
                fail=True)
75 4b10fb65 Adeodato Simo
76 4b10fb65 Adeodato Simo
  AssertCommand(["gnt-group", "add", "--alloc-policy", "last_resort",
77 4b10fb65 Adeodato Simo
                 "--node-parameters", "oob_program=/bin/true", group1])
78 4b10fb65 Adeodato Simo
79 4b10fb65 Adeodato Simo
  AssertCommand(["gnt-group", "remove", group1])
80 4b10fb65 Adeodato Simo
81 4b10fb65 Adeodato Simo
82 cbaf1652 Bernardo Dal Seno
def _GetGroupIPolicy(groupname):
83 cbaf1652 Bernardo Dal Seno
  """Return the run-time values of the cluster-level instance policy.
84 cbaf1652 Bernardo Dal Seno

85 cbaf1652 Bernardo Dal Seno
  @type groupname: string
86 cbaf1652 Bernardo Dal Seno
  @param groupname: node group name
87 cbaf1652 Bernardo Dal Seno
  @rtype: tuple
88 cbaf1652 Bernardo Dal Seno
  @return: (policy, specs), where:
89 cbaf1652 Bernardo Dal Seno
      - policy is a dictionary of the policy values, instance specs excluded
90 cbaf1652 Bernardo Dal Seno
      - specs is dict of dict, specs[par][key] is a spec value, where key is
91 cbaf1652 Bernardo Dal Seno
        "min" or "max"
92 cbaf1652 Bernardo Dal Seno

93 cbaf1652 Bernardo Dal Seno
  """
94 cbaf1652 Bernardo Dal Seno
  info = qa_utils.GetObjectInfo(["gnt-group", "info", groupname])
95 cbaf1652 Bernardo Dal Seno
  assert len(info) == 1
96 cbaf1652 Bernardo Dal Seno
  policy = info[0]["Instance policy"]
97 cbaf1652 Bernardo Dal Seno
98 cbaf1652 Bernardo Dal Seno
  (ret_policy, ret_specs) = qa_utils.ParseIPolicy(policy)
99 cbaf1652 Bernardo Dal Seno
100 cbaf1652 Bernardo Dal Seno
  # Sanity checks
101 cbaf1652 Bernardo Dal Seno
  assert len(ret_specs) > 0
102 cbaf1652 Bernardo Dal Seno
  good = all("min" in d and "max" in d
103 cbaf1652 Bernardo Dal Seno
             for d in ret_specs.values())
104 cbaf1652 Bernardo Dal Seno
  assert good, "Missing item in specs: %s" % ret_specs
105 cbaf1652 Bernardo Dal Seno
  assert len(ret_policy) > 0
106 cbaf1652 Bernardo Dal Seno
  return (ret_policy, ret_specs)
107 cbaf1652 Bernardo Dal Seno
108 cbaf1652 Bernardo Dal Seno
109 cbaf1652 Bernardo Dal Seno
def _TestGroupSetISpecs(groupname, new_specs, fail=False, old_values=None):
110 cbaf1652 Bernardo Dal Seno
  """Change instance specs on a group.
111 cbaf1652 Bernardo Dal Seno

112 cbaf1652 Bernardo Dal Seno
  @type groupname: string
113 cbaf1652 Bernardo Dal Seno
  @param groupname: group name
114 cbaf1652 Bernardo Dal Seno
  @type new_specs: dict of dict
115 cbaf1652 Bernardo Dal Seno
  @param new_specs: new_specs[par][key], where key is "min", "max", "std". It
116 cbaf1652 Bernardo Dal Seno
      can be an empty dictionary.
117 cbaf1652 Bernardo Dal Seno
  @type fail: bool
118 cbaf1652 Bernardo Dal Seno
  @param fail: if the change is expected to fail
119 cbaf1652 Bernardo Dal Seno
  @type old_values: tuple
120 cbaf1652 Bernardo Dal Seno
  @param old_values: (old_policy, old_specs), as returned by
121 cbaf1652 Bernardo Dal Seno
     L{_GetGroupIPolicy}
122 cbaf1652 Bernardo Dal Seno
  @return: same as L{_GetGroupIPolicy}
123 cbaf1652 Bernardo Dal Seno

124 cbaf1652 Bernardo Dal Seno
  """
125 cbaf1652 Bernardo Dal Seno
  build_cmd = lambda opts: ["gnt-group", "modify"] + opts + [groupname]
126 cbaf1652 Bernardo Dal Seno
  get_policy = lambda: _GetGroupIPolicy(groupname)
127 cbaf1652 Bernardo Dal Seno
  return qa_utils.TestSetISpecs(new_specs, get_policy_fn=get_policy,
128 cbaf1652 Bernardo Dal Seno
                                build_cmd_fn=build_cmd, fail=fail,
129 cbaf1652 Bernardo Dal Seno
                                old_values=old_values)
130 cbaf1652 Bernardo Dal Seno
131 cbaf1652 Bernardo Dal Seno
132 b5a93c73 Bernardo Dal Seno
def _TestGroupModifyISpecs(groupname):
133 cbaf1652 Bernardo Dal Seno
  # This test is built on the assumption that the default ipolicy holds for
134 cbaf1652 Bernardo Dal Seno
  # the node group under test
135 cbaf1652 Bernardo Dal Seno
  old_values = _GetGroupIPolicy(groupname)
136 cbaf1652 Bernardo Dal Seno
  mod_values = _TestGroupSetISpecs(groupname,
137 cbaf1652 Bernardo Dal Seno
                                   dict((p, {"min": 4, "max": 4})
138 cbaf1652 Bernardo Dal Seno
                                        for p in constants.ISPECS_PARAMETERS),
139 cbaf1652 Bernardo Dal Seno
                                   old_values=old_values)
140 cbaf1652 Bernardo Dal Seno
  for par in constants.ISPECS_PARAMETERS:
141 cbaf1652 Bernardo Dal Seno
    # First make sure that the test works with good values
142 cbaf1652 Bernardo Dal Seno
    mod_values = _TestGroupSetISpecs(groupname, {par: {"min": 8, "max": 8}},
143 cbaf1652 Bernardo Dal Seno
                                     old_values=mod_values)
144 cbaf1652 Bernardo Dal Seno
    _TestGroupSetISpecs(groupname, {par: {"min": 8, "max": 4}},
145 cbaf1652 Bernardo Dal Seno
                        fail=True, old_values=mod_values)
146 cbaf1652 Bernardo Dal Seno
  AssertCommand(["gnt-group", "modify", "--ipolicy-bounds-specs", "default",
147 cbaf1652 Bernardo Dal Seno
                 groupname])
148 cbaf1652 Bernardo Dal Seno
  AssertEqual(_GetGroupIPolicy(groupname), old_values)
149 cbaf1652 Bernardo Dal Seno
150 b5a93c73 Bernardo Dal Seno
  # Get the ipolicy command (from the cluster config)
151 b5a93c73 Bernardo Dal Seno
  mnode = qa_config.GetMasterNode()
152 b5a93c73 Bernardo Dal Seno
  addcmd = GetCommandOutput(mnode.primary, utils.ShellQuoteArgs([
153 b5a93c73 Bernardo Dal Seno
    "gnt-group", "show-ispecs-cmd", "--include-defaults", groupname,
154 b5a93c73 Bernardo Dal Seno
    ]))
155 b5a93c73 Bernardo Dal Seno
  modcmd = ["gnt-group", "modify"]
156 b5a93c73 Bernardo Dal Seno
  opts = addcmd.split()
157 b5a93c73 Bernardo Dal Seno
  assert opts[0:2] == ["gnt-group", "add"]
158 b5a93c73 Bernardo Dal Seno
  for k in range(2, len(opts) - 1):
159 b5a93c73 Bernardo Dal Seno
    if opts[k].startswith("--ipolicy-"):
160 b5a93c73 Bernardo Dal Seno
      assert k + 2 <= len(opts)
161 b5a93c73 Bernardo Dal Seno
      modcmd.extend(opts[k:k + 2])
162 b5a93c73 Bernardo Dal Seno
  modcmd.append(groupname)
163 b5a93c73 Bernardo Dal Seno
  # Apply the ipolicy to the group and verify the result
164 b5a93c73 Bernardo Dal Seno
  AssertCommand(modcmd)
165 b5a93c73 Bernardo Dal Seno
  new_addcmd = GetCommandOutput(mnode.primary, utils.ShellQuoteArgs([
166 b5a93c73 Bernardo Dal Seno
    "gnt-group", "show-ispecs-cmd", groupname,
167 b5a93c73 Bernardo Dal Seno
    ]))
168 b5a93c73 Bernardo Dal Seno
  AssertEqual(addcmd, new_addcmd)
169 b5a93c73 Bernardo Dal Seno
170 b5a93c73 Bernardo Dal Seno
171 b5a93c73 Bernardo Dal Seno
def _TestGroupModifyIPolicy(groupname):
172 b5a93c73 Bernardo Dal Seno
  _TestGroupModifyISpecs(groupname)
173 cbaf1652 Bernardo Dal Seno
174 cbaf1652 Bernardo Dal Seno
  # We assume that the default ipolicy holds
175 cbaf1652 Bernardo Dal Seno
  (old_policy, old_specs) = _GetGroupIPolicy(groupname)
176 cbaf1652 Bernardo Dal Seno
  for (par, setval, iname, expval) in [
177 cbaf1652 Bernardo Dal Seno
    ("vcpu-ratio", 1.5, None, 1.5),
178 cbaf1652 Bernardo Dal Seno
    ("spindle-ratio", 1.5, None, 1.5),
179 cbaf1652 Bernardo Dal Seno
    ("disk-templates", constants.DT_PLAIN,
180 cbaf1652 Bernardo Dal Seno
     "enabled disk templates", constants.DT_PLAIN)
181 cbaf1652 Bernardo Dal Seno
    ]:
182 cbaf1652 Bernardo Dal Seno
    if not iname:
183 cbaf1652 Bernardo Dal Seno
      iname = par
184 cbaf1652 Bernardo Dal Seno
    build_cmdline = lambda val: ["gnt-group", "modify", "--ipolicy-" + par,
185 cbaf1652 Bernardo Dal Seno
                                 str(val), groupname]
186 cbaf1652 Bernardo Dal Seno
187 cbaf1652 Bernardo Dal Seno
    AssertCommand(build_cmdline(setval))
188 cbaf1652 Bernardo Dal Seno
    (new_policy, new_specs) = _GetGroupIPolicy(groupname)
189 cbaf1652 Bernardo Dal Seno
    AssertEqual(new_specs, old_specs)
190 cbaf1652 Bernardo Dal Seno
    for (p, val) in new_policy.items():
191 cbaf1652 Bernardo Dal Seno
      if p == iname:
192 cbaf1652 Bernardo Dal Seno
        AssertEqual(val, expval)
193 cbaf1652 Bernardo Dal Seno
      else:
194 cbaf1652 Bernardo Dal Seno
        AssertEqual(val, old_policy[p])
195 cbaf1652 Bernardo Dal Seno
196 cbaf1652 Bernardo Dal Seno
    AssertCommand(build_cmdline("default"))
197 cbaf1652 Bernardo Dal Seno
    (new_policy, new_specs) = _GetGroupIPolicy(groupname)
198 cbaf1652 Bernardo Dal Seno
    AssertEqual(new_specs, old_specs)
199 cbaf1652 Bernardo Dal Seno
    AssertEqual(new_policy, old_policy)
200 b5a93c73 Bernardo Dal Seno
201 b5a93c73 Bernardo Dal Seno
202 4b10fb65 Adeodato Simo
def TestGroupModify():
203 4b10fb65 Adeodato Simo
  """gnt-group modify"""
204 b4d2d2cb Michael Hanselmann
  (group1, ) = qa_utils.GetNonexistentGroups(1)
205 4b10fb65 Adeodato Simo
206 4b10fb65 Adeodato Simo
  AssertCommand(["gnt-group", "add", group1])
207 4b10fb65 Adeodato Simo
208 4b10fb65 Adeodato Simo
  try:
209 b5a93c73 Bernardo Dal Seno
    _TestGroupModifyIPolicy(group1)
210 4b10fb65 Adeodato Simo
    AssertCommand(["gnt-group", "modify", "--alloc-policy", "unallocable",
211 4b10fb65 Adeodato Simo
                   "--node-parameters", "oob_program=/bin/false", group1])
212 4b10fb65 Adeodato Simo
    AssertCommand(["gnt-group", "modify",
213 4b10fb65 Adeodato Simo
                   "--alloc-policy", "notvalid", group1], fail=True)
214 52bebbdf Iustin Pop
    AssertCommand(["gnt-group", "modify",
215 52bebbdf Iustin Pop
                   "--node-parameters", "spindle_count=10", group1])
216 52bebbdf Iustin Pop
    if qa_config.TestEnabled("htools"):
217 52bebbdf Iustin Pop
      AssertCommand(["hbal", "-L", "-G", group1])
218 52bebbdf Iustin Pop
    AssertCommand(["gnt-group", "modify",
219 52bebbdf Iustin Pop
                   "--node-parameters", "spindle_count=default", group1])
220 4b10fb65 Adeodato Simo
  finally:
221 4b10fb65 Adeodato Simo
    AssertCommand(["gnt-group", "remove", group1])
222 4b10fb65 Adeodato Simo
223 4b10fb65 Adeodato Simo
224 7ab8b7d7 Adeodato Simo
def TestGroupList():
225 30131294 Adeodato Simo
  """gnt-group list"""
226 7ab8b7d7 Adeodato Simo
  qa_utils.GenericQueryTest("gnt-group", query.GROUP_FIELDS.keys())
227 30131294 Adeodato Simo
228 30131294 Adeodato Simo
229 7ab8b7d7 Adeodato Simo
def TestGroupListFields():
230 7ab8b7d7 Adeodato Simo
  """gnt-group list-fields"""
231 7ab8b7d7 Adeodato Simo
  qa_utils.GenericQueryFieldsTest("gnt-group", query.GROUP_FIELDS.keys())
232 f3fd2c9d Adeodato Simo
233 f3fd2c9d Adeodato Simo
234 f3fd2c9d Adeodato Simo
def TestAssignNodesIncludingSplit(orig_group, node1, node2):
235 f3fd2c9d Adeodato Simo
  """gnt-group assign-nodes --force
236 f3fd2c9d Adeodato Simo

237 f3fd2c9d Adeodato Simo
  Expects node1 and node2 to be primary and secondary for a common instance.
238 f3fd2c9d Adeodato Simo

239 f3fd2c9d Adeodato Simo
  """
240 f3fd2c9d Adeodato Simo
  assert node1 != node2
241 b4d2d2cb Michael Hanselmann
242 b4d2d2cb Michael Hanselmann
  (other_group, ) = qa_utils.GetNonexistentGroups(1)
243 f3fd2c9d Adeodato Simo
244 aecba21e Michael Hanselmann
  master_node = qa_config.GetMasterNode().primary
245 f3fd2c9d Adeodato Simo
246 f3fd2c9d Adeodato Simo
  def AssertInGroup(group, nodes):
247 f3fd2c9d Adeodato Simo
    real_output = GetCommandOutput(master_node,
248 f3fd2c9d Adeodato Simo
                                   "gnt-node list --no-headers -o group " +
249 f3fd2c9d Adeodato Simo
                                   utils.ShellQuoteArgs(nodes))
250 f3fd2c9d Adeodato Simo
    AssertEqual(real_output.splitlines(), [group] * len(nodes))
251 f3fd2c9d Adeodato Simo
252 f3fd2c9d Adeodato Simo
  AssertInGroup(orig_group, [node1, node2])
253 f3fd2c9d Adeodato Simo
  AssertCommand(["gnt-group", "add", other_group])
254 f3fd2c9d Adeodato Simo
255 f3fd2c9d Adeodato Simo
  try:
256 f3fd2c9d Adeodato Simo
    AssertCommand(["gnt-group", "assign-nodes", other_group, node1, node2])
257 f3fd2c9d Adeodato Simo
    AssertInGroup(other_group, [node1, node2])
258 f3fd2c9d Adeodato Simo
259 f3fd2c9d Adeodato Simo
    # This should fail because moving node1 to orig_group would leave their
260 f3fd2c9d Adeodato Simo
    # common instance split between orig_group and other_group.
261 f3fd2c9d Adeodato Simo
    AssertCommand(["gnt-group", "assign-nodes", orig_group, node1], fail=True)
262 f3fd2c9d Adeodato Simo
    AssertInGroup(other_group, [node1, node2])
263 f3fd2c9d Adeodato Simo
264 f3fd2c9d Adeodato Simo
    AssertCommand(["gnt-group", "assign-nodes", "--force", orig_group, node1])
265 f3fd2c9d Adeodato Simo
    AssertInGroup(orig_group, [node1])
266 f3fd2c9d Adeodato Simo
    AssertInGroup(other_group, [node2])
267 f3fd2c9d Adeodato Simo
268 f3fd2c9d Adeodato Simo
    AssertCommand(["gnt-group", "assign-nodes", orig_group, node2])
269 f3fd2c9d Adeodato Simo
    AssertInGroup(orig_group, [node1, node2])
270 f3fd2c9d Adeodato Simo
  finally:
271 f3fd2c9d Adeodato Simo
    AssertCommand(["gnt-group", "remove", other_group])