Statistics
| Branch: | Tag: | Revision:

root / qa / qa_group.py @ b780c231

History | View | Annotate | Download (9.8 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 7c8ae421 Bernardo Dal Seno
      - specs is a dictionary containing only the specs, using the internal
91 7c8ae421 Bernardo Dal Seno
        format (see L{constants.IPOLICY_DEFAULTS} for an example), but without
92 7c8ae421 Bernardo Dal Seno
        the standard values
93 cbaf1652 Bernardo Dal Seno

94 cbaf1652 Bernardo Dal Seno
  """
95 cbaf1652 Bernardo Dal Seno
  info = qa_utils.GetObjectInfo(["gnt-group", "info", groupname])
96 cbaf1652 Bernardo Dal Seno
  assert len(info) == 1
97 cbaf1652 Bernardo Dal Seno
  policy = info[0]["Instance policy"]
98 cbaf1652 Bernardo Dal Seno
99 cbaf1652 Bernardo Dal Seno
  (ret_policy, ret_specs) = qa_utils.ParseIPolicy(policy)
100 cbaf1652 Bernardo Dal Seno
101 cbaf1652 Bernardo Dal Seno
  # Sanity checks
102 7c8ae421 Bernardo Dal Seno
  assert "minmax" in ret_specs
103 7c8ae421 Bernardo Dal Seno
  assert len(ret_specs["minmax"]) > 0
104 cbaf1652 Bernardo Dal Seno
  assert len(ret_policy) > 0
105 cbaf1652 Bernardo Dal Seno
  return (ret_policy, ret_specs)
106 cbaf1652 Bernardo Dal Seno
107 cbaf1652 Bernardo Dal Seno
108 ec996117 Bernardo Dal Seno
def _TestGroupSetISpecs(groupname, new_specs=None, diff_specs=None,
109 ec996117 Bernardo Dal Seno
                        fail=False, old_values=None):
110 cbaf1652 Bernardo Dal Seno
  """Change instance specs on a group.
111 cbaf1652 Bernardo Dal Seno

112 ec996117 Bernardo Dal Seno
  At most one of new_specs or diff_specs can be specified.
113 ec996117 Bernardo Dal Seno

114 cbaf1652 Bernardo Dal Seno
  @type groupname: string
115 cbaf1652 Bernardo Dal Seno
  @param groupname: group name
116 ec996117 Bernardo Dal Seno
  @type new_specs: dict
117 ec996117 Bernardo Dal Seno
  @param new_specs: new complete specs, in the same format returned by
118 ec996117 Bernardo Dal Seno
      L{_GetGroupIPolicy}
119 ec996117 Bernardo Dal Seno
  @type diff_specs: dict
120 7c8ae421 Bernardo Dal Seno
  @param diff_specs: partial specs, it can be an incomplete specifications, but
121 7c8ae421 Bernardo Dal Seno
      if min/max specs are specified, their number must match the number of the
122 7c8ae421 Bernardo Dal Seno
      existing specs
123 cbaf1652 Bernardo Dal Seno
  @type fail: bool
124 cbaf1652 Bernardo Dal Seno
  @param fail: if the change is expected to fail
125 cbaf1652 Bernardo Dal Seno
  @type old_values: tuple
126 cbaf1652 Bernardo Dal Seno
  @param old_values: (old_policy, old_specs), as returned by
127 ec996117 Bernardo Dal Seno
      L{_GetGroupIPolicy}
128 cbaf1652 Bernardo Dal Seno
  @return: same as L{_GetGroupIPolicy}
129 cbaf1652 Bernardo Dal Seno

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

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

263 f3fd2c9d Adeodato Simo
  """
264 f3fd2c9d Adeodato Simo
  assert node1 != node2
265 b4d2d2cb Michael Hanselmann
266 b4d2d2cb Michael Hanselmann
  (other_group, ) = qa_utils.GetNonexistentGroups(1)
267 f3fd2c9d Adeodato Simo
268 aecba21e Michael Hanselmann
  master_node = qa_config.GetMasterNode().primary
269 f3fd2c9d Adeodato Simo
270 f3fd2c9d Adeodato Simo
  def AssertInGroup(group, nodes):
271 f3fd2c9d Adeodato Simo
    real_output = GetCommandOutput(master_node,
272 f3fd2c9d Adeodato Simo
                                   "gnt-node list --no-headers -o group " +
273 f3fd2c9d Adeodato Simo
                                   utils.ShellQuoteArgs(nodes))
274 f3fd2c9d Adeodato Simo
    AssertEqual(real_output.splitlines(), [group] * len(nodes))
275 f3fd2c9d Adeodato Simo
276 f3fd2c9d Adeodato Simo
  AssertInGroup(orig_group, [node1, node2])
277 f3fd2c9d Adeodato Simo
  AssertCommand(["gnt-group", "add", other_group])
278 f3fd2c9d Adeodato Simo
279 f3fd2c9d Adeodato Simo
  try:
280 f3fd2c9d Adeodato Simo
    AssertCommand(["gnt-group", "assign-nodes", other_group, node1, node2])
281 f3fd2c9d Adeodato Simo
    AssertInGroup(other_group, [node1, node2])
282 f3fd2c9d Adeodato Simo
283 f3fd2c9d Adeodato Simo
    # This should fail because moving node1 to orig_group would leave their
284 f3fd2c9d Adeodato Simo
    # common instance split between orig_group and other_group.
285 f3fd2c9d Adeodato Simo
    AssertCommand(["gnt-group", "assign-nodes", orig_group, node1], fail=True)
286 f3fd2c9d Adeodato Simo
    AssertInGroup(other_group, [node1, node2])
287 f3fd2c9d Adeodato Simo
288 f3fd2c9d Adeodato Simo
    AssertCommand(["gnt-group", "assign-nodes", "--force", orig_group, node1])
289 f3fd2c9d Adeodato Simo
    AssertInGroup(orig_group, [node1])
290 f3fd2c9d Adeodato Simo
    AssertInGroup(other_group, [node2])
291 f3fd2c9d Adeodato Simo
292 f3fd2c9d Adeodato Simo
    AssertCommand(["gnt-group", "assign-nodes", orig_group, node2])
293 f3fd2c9d Adeodato Simo
    AssertInGroup(orig_group, [node1, node2])
294 f3fd2c9d Adeodato Simo
  finally:
295 f3fd2c9d Adeodato Simo
    AssertCommand(["gnt-group", "remove", other_group])