QA: Split function to set and parse instance policies
authorBernardo Dal Seno <bdalseno@google.com>
Fri, 12 Apr 2013 08:22:35 +0000 (10:22 +0200)
committerBernardo Dal Seno <bdalseno@google.com>
Wed, 24 Apr 2013 10:05:15 +0000 (12:05 +0200)
The main parts, moved to qa_util, will be used for node groups too.

Signed-off-by: Bernardo Dal Seno <bdalseno@google.com>
Reviewed-by: Helga Velroyen <helgav@google.com>

qa/qa_cluster.py
qa/qa_utils.py

index 7bfc7a0..f532826 100644 (file)
@@ -538,16 +538,7 @@ def _GetClusterIPolicy():
   """
   info = qa_utils.GetObjectInfo(["gnt-cluster", "info"])
   policy = info["Instance policy - limits for instances"]
-  ret_specs = {}
-  ret_policy = {}
-  ispec_keys = constants.ISPECS_MINMAX_KEYS | frozenset([constants.ISPECS_STD])
-  for (key, val) in policy.items():
-    if key in ispec_keys:
-      for (par, pval) in val.items():
-        d = ret_specs.setdefault(par, {})
-        d[key] = pval
-    else:
-      ret_policy[key] = val
+  (ret_policy, ret_specs) = qa_utils.ParseIPolicy(policy)
 
   # Sanity checks
   assert len(ret_specs) > 0
@@ -615,20 +606,6 @@ def TestClusterModifyIPolicy():
       AssertEqual(eff_policy[p], old_policy[p])
 
 
-def _GetParameterOptions(key, specs, old_specs):
-  values = ["%s=%s" % (par, keyvals[key])
-            for (par, keyvals) in specs.items()
-            if key in keyvals]
-  if old_specs:
-    present_pars = frozenset(par
-                             for (par, keyvals) in specs.items()
-                             if key in keyvals)
-    values.extend("%s=%s" % (par, keyvals[key])
-                  for (par, keyvals) in old_specs.items()
-                  if key in keyvals and par not in present_pars)
-  return ",".join(values)
-
-
 def TestClusterSetISpecs(new_specs, fail=False, old_values=None):
   """Change instance specs.
 
@@ -643,39 +620,10 @@ def TestClusterSetISpecs(new_specs, fail=False, old_values=None):
   @return: same as L{_GetClusterIPolicy}
 
   """
-  if old_values:
-    (old_policy, old_specs) = old_values
-  else:
-    (old_policy, old_specs) = _GetClusterIPolicy()
-  if new_specs:
-    cmd = ["gnt-cluster", "modify"]
-    if any(("min" in val or "max" in val) for val in new_specs.values()):
-      minmax_opt_items = []
-      for key in ["min", "max"]:
-        keyopt = _GetParameterOptions(key, new_specs, old_specs)
-        minmax_opt_items.append("%s:%s" % (key, keyopt))
-      cmd.extend([
-        "--ipolicy-bounds-specs",
-        "/".join(minmax_opt_items)
-        ])
-    std_opt = _GetParameterOptions("std", new_specs, {})
-    if std_opt:
-      cmd.extend(["--ipolicy-std-specs", std_opt])
-    AssertCommand(cmd, fail=fail)
-
-  # Check the new state
-  (eff_policy, eff_specs) = _GetClusterIPolicy()
-  AssertEqual(eff_policy, old_policy)
-  if fail:
-    AssertEqual(eff_specs, old_specs)
-  else:
-    for par in eff_specs:
-      for key in eff_specs[par]:
-        if par in new_specs and key in new_specs[par]:
-          AssertEqual(int(eff_specs[par][key]), int(new_specs[par][key]))
-        else:
-          AssertEqual(int(eff_specs[par][key]), int(old_specs[par][key]))
-  return (eff_policy, eff_specs)
+  build_cmd = lambda opts: ["gnt-cluster", "modify"] + opts
+  return qa_utils.TestSetISpecs(new_specs, get_policy_fn=_GetClusterIPolicy,
+                                build_cmd_fn=build_cmd, fail=fail,
+                                old_values=old_values)
 
 
 def TestClusterModifyISpecs():
index e8b49bd..9cea4b2 100644 (file)
@@ -777,3 +777,102 @@ def MakeNodePath(node, path):
     return "%s%s" % (vcluster.MakeNodeRoot(basedir, name), path)
   else:
     return path
+
+
+def _GetParameterOptions(key, specs, old_specs):
+  """Helper to build policy options."""
+  values = ["%s=%s" % (par, keyvals[key])
+            for (par, keyvals) in specs.items()
+            if key in keyvals]
+  if old_specs:
+    present_pars = frozenset(par
+                             for (par, keyvals) in specs.items()
+                             if key in keyvals)
+    values.extend("%s=%s" % (par, keyvals[key])
+                  for (par, keyvals) in old_specs.items()
+                  if key in keyvals and par not in present_pars)
+  return ",".join(values)
+
+
+def TestSetISpecs(new_specs, get_policy_fn=None, build_cmd_fn=None,
+                  fail=False, old_values=None):
+  """Change instance specs for an object.
+
+  @type new_specs: dict of dict
+  @param new_specs: new_specs[par][key], where key is "min", "max", "std". It
+      can be an empty dictionary.
+  @type get_policy_fn: function
+  @param get_policy_fn: function that returns the current policy as in
+      L{qa_cluster._GetClusterIPolicy}
+  @type build_cmd_fn: function
+  @param build_cmd_fn: function that return the full command line from the
+      options alone
+  @type fail: bool
+  @param fail: if the change is expected to fail
+  @type old_values: tuple
+  @param old_values: (old_policy, old_specs), as returned by
+     L{qa_cluster._GetClusterIPolicy}
+  @return: same as L{qa_cluster._GetClusterIPolicy}
+
+  """
+  assert get_policy_fn is not None
+  assert build_cmd_fn is not None
+
+  if old_values:
+    (old_policy, old_specs) = old_values
+  else:
+    (old_policy, old_specs) = get_policy_fn()
+  if new_specs:
+    cmd = []
+    if any(("min" in val or "max" in val) for val in new_specs.values()):
+      minmax_opt_items = []
+      for key in ["min", "max"]:
+        keyopt = _GetParameterOptions(key, new_specs, old_specs)
+        minmax_opt_items.append("%s:%s" % (key, keyopt))
+      cmd.extend([
+        "--ipolicy-bounds-specs",
+        "/".join(minmax_opt_items)
+        ])
+    std_opt = _GetParameterOptions("std", new_specs, {})
+    if std_opt:
+      cmd.extend(["--ipolicy-std-specs", std_opt])
+    AssertCommand(build_cmd_fn(cmd), fail=fail)
+
+  # Check the new state
+  (eff_policy, eff_specs) = get_policy_fn()
+  AssertEqual(eff_policy, old_policy)
+  if fail:
+    AssertEqual(eff_specs, old_specs)
+  else:
+    for par in eff_specs:
+      for key in eff_specs[par]:
+        if par in new_specs and key in new_specs[par]:
+          AssertEqual(int(eff_specs[par][key]), int(new_specs[par][key]))
+        else:
+          AssertEqual(int(eff_specs[par][key]), int(old_specs[par][key]))
+  return (eff_policy, eff_specs)
+
+
+def ParseIPolicy(policy):
+  """Parse and split instance an instance policy.
+
+  @type policy: dict
+  @param policy: policy, as returned by L{GetObjectInfo}
+  @rtype: tuple
+  @return: (policy, specs), where:
+      - policy is a dictionary of the policy values, instance specs excluded
+      - specs is dict of dict, specs[par][key] is a spec value, where key is
+        "min", "max", or "std"
+
+  """
+  ret_specs = {}
+  ret_policy = {}
+  ispec_keys = constants.ISPECS_MINMAX_KEYS | frozenset([constants.ISPECS_STD])
+  for (key, val) in policy.items():
+    if key in ispec_keys:
+      for (par, pval) in val.items():
+        d = ret_specs.setdefault(par, {})
+        d[key] = pval
+    else:
+      ret_policy[key] = val
+  return (ret_policy, ret_specs)