From: Bernardo Dal Seno Date: Fri, 12 Apr 2013 08:22:35 +0000 (+0200) Subject: QA: Split function to set and parse instance policies X-Git-Tag: v2.8.0beta1~126 X-Git-Url: https://code.grnet.gr/git/ganeti-local/commitdiff_plain/63e08b2511c88d8c5f23a33e188477b640615a65 QA: Split function to set and parse instance policies The main parts, moved to qa_util, will be used for node groups too. Signed-off-by: Bernardo Dal Seno Reviewed-by: Helga Velroyen --- diff --git a/qa/qa_cluster.py b/qa/qa_cluster.py index 7bfc7a0..f532826 100644 --- a/qa/qa_cluster.py +++ b/qa/qa_cluster.py @@ -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(): diff --git a/qa/qa_utils.py b/qa/qa_utils.py index e8b49bd..9cea4b2 100644 --- a/qa/qa_utils.py +++ b/qa/qa_utils.py @@ -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)