Hi!
On Wed, Apr 24, 2013 at 2:00 PM, Bernardo Dal Seno <bdals...@google.com>wrote: > Existing tests are updated to cope with the new instance specs format. > > Signed-off-by: Bernardo Dal Seno <bdals...@google.com> > --- > qa/ganeti-qa.py | 10 +++++++--- > qa/qa_cluster.py | 26 +++++++++++++++++--------- > qa/qa_group.py | 34 ++++++++++++++++++++++++++-------- > qa/qa_utils.py | 54 > ++++++++++++++++++++++++++++++++++++------------------ > 4 files changed, 86 insertions(+), 38 deletions(-) > > diff --git a/qa/ganeti-qa.py b/qa/ganeti-qa.py > index b4d8d2a..ca698d0 100755 > --- a/qa/ganeti-qa.py > +++ b/qa/ganeti-qa.py > @@ -524,9 +524,11 @@ def RunExclusiveStorageTests(): > > def _BuildSpecDict(par, mn, st, mx): > return { > - "min": {par: mn}, > - "max": {par: mx}, > - "std": {par: st}, > + constants.ISPECS_MINMAX: [{ > + constants.ISPECS_MIN: {par: mn}, > + constants.ISPECS_MAX: {par: mx}, > + }], > + constants.ISPECS_STD: {par: st}, > } > > > @@ -539,6 +541,8 @@ def TestIPolicyPlainInstance(): > > # This test assumes that the group policy is empty > (_, old_specs) = qa_cluster.TestClusterSetISpecs() > + # We also assume to have only one min/max bound > + assert len(old_specs[constants.ISPECS_MINMAX]) == 1 > node = qa_config.AcquireNode() > try: > # Log of policy changes, list of tuples: > diff --git a/qa/qa_cluster.py b/qa/qa_cluster.py > index a139e5f..e281178 100644 > --- a/qa/qa_cluster.py > +++ b/qa/qa_cluster.py > @@ -532,8 +532,8 @@ def _GetClusterIPolicy(): > @rtype: tuple > @return: (policy, specs), where: > - policy is a dictionary of the policy values, instance specs > excluded > - - specs is dict of dict, specs[key][par] is a spec value, where key > is > - "min", "max", or "std" > + - specs is a dictionary containing only the specs, using the > internal > + format (see L{constants.IPOLICY_DEFAULTS} for an example) > > """ > info = qa_utils.GetObjectInfo(["gnt-cluster", "info"]) > @@ -541,7 +541,8 @@ def _GetClusterIPolicy(): > (ret_policy, ret_specs) = qa_utils.ParseIPolicy(policy) > > # Sanity checks > - assert "min" in ret_specs and "std" in ret_specs and "max" in ret_specs > + assert "minmax" in ret_specs and "std" in ret_specs > + assert len(ret_specs["minmax"]) > 0 > assert len(ret_policy) > 0 > return (ret_policy, ret_specs) > > @@ -613,8 +614,9 @@ def TestClusterSetISpecs(new_specs=None, > diff_specs=None, fail=False, > @param new_specs: new complete specs, in the same format returned by > L{_GetClusterIPolicy} > @type diff_specs: dict > - @param diff_specs: diff_specs[key][par], where key is "min", "max", > "std". It > - can be an incomplete specifications or an empty dictionary. > + @param diff_specs: partial specs, it can be an incomplete > specifications, but > + if min/max specs are specified, their number must match the number > of the > + existing specs > @type fail: bool > @param fail: if the change is expected to fail > @type old_values: tuple > @@ -634,6 +636,8 @@ def TestClusterModifyISpecs(): > """gnt-cluster modify --specs-*""" > params = ["memory-size", "disk-size", "disk-count", "cpu-count", > "nic-count"] > (cur_policy, cur_specs) = _GetClusterIPolicy() > + # This test assumes that there is only one min/max bound > + assert len(cur_specs[constants.ISPECS_MINMAX]) == 1 > for par in params: > test_values = [ > (True, 0, 4, 12), > @@ -650,13 +654,17 @@ def TestClusterModifyISpecs(): > (False, 0, 4, "a"), > # This is to restore the old values > (True, > - cur_specs["min"][par], cur_specs["std"][par], > cur_specs["max"][par]) > + cur_specs[constants.ISPECS_MINMAX][0][constants.ISPECS_MIN][par], > + cur_specs[constants.ISPECS_STD][par], > + cur_specs[constants.ISPECS_MINMAX][0][constants.ISPECS_MAX][par]) > ] > for (good, mn, st, mx) in test_values: > new_vals = { > - "min": {par: mn}, > - "std": {par: st}, > - "max": {par: mx} > + constants.ISPECS_MINMAX: [{ > + constants.ISPECS_MIN: {par: mn}, > + constants.ISPECS_MAX: {par: mx} > + }], > + constants.ISPECS_STD: {par: st} > } > cur_state = (cur_policy, cur_specs) > # We update cur_specs, as we've copied the values to restore already > diff --git a/qa/qa_group.py b/qa/qa_group.py > index 202bde8..e71451a 100644 > --- a/qa/qa_group.py > +++ b/qa/qa_group.py > @@ -87,8 +87,9 @@ def _GetGroupIPolicy(groupname): > @rtype: tuple > @return: (policy, specs), where: > - policy is a dictionary of the policy values, instance specs > excluded > - - specs is dict of dict, specs[key][par] is a spec value, where key > is > - "min" or "max" > + - specs is a dictionary containing only the specs, using the > internal > + format (see L{constants.IPOLICY_DEFAULTS} for an example), but > without > + the standard values > > """ > info = qa_utils.GetObjectInfo(["gnt-group", "info", groupname]) > @@ -98,7 +99,8 @@ def _GetGroupIPolicy(groupname): > (ret_policy, ret_specs) = qa_utils.ParseIPolicy(policy) > > # Sanity checks > - assert "min" in ret_specs and "max" in ret_specs > + assert "minmax" in ret_specs > + assert len(ret_specs["minmax"]) > 0 > assert len(ret_policy) > 0 > return (ret_policy, ret_specs) > > @@ -115,8 +117,9 @@ def _TestGroupSetISpecs(groupname, new_specs=None, > diff_specs=None, > @param new_specs: new complete specs, in the same format returned by > L{_GetGroupIPolicy} > @type diff_specs: dict > - @param diff_specs: diff_specs[key][par], where key is "min", "max". It > - can be an incomplete specifications or an empty dictionary. > + @param diff_specs: partial specs, it can be an incomplete > specifications, but > + if min/max specs are specified, their number must match the number > of the > + existing specs > @type fail: bool > @param fail: if the change is expected to fail > @type old_values: tuple > @@ -138,15 +141,30 @@ def _TestGroupModifyISpecs(groupname): > # the node group under test > old_values = _GetGroupIPolicy(groupname) > samevals = dict((p, 4) for p in constants.ISPECS_PARAMETERS) > - base_specs = {"min": samevals, "max": samevals} > + base_specs = { > + constants.ISPECS_MINMAX: [{ > + constants.ISPECS_MIN: samevals, > + constants.ISPECS_MAX: samevals, > + }], > + } > mod_values = _TestGroupSetISpecs(groupname, new_specs=base_specs, > old_values=old_values) > for par in constants.ISPECS_PARAMETERS: > # First make sure that the test works with good values > - good_specs = {"min": {par: 8}, "max": {par: 8}} > + good_specs = { > + constants.ISPECS_MINMAX: [{ > + constants.ISPECS_MIN: {par: 8}, > + constants.ISPECS_MAX: {par: 8}, > + }], > + } > mod_values = _TestGroupSetISpecs(groupname, diff_specs=good_specs, > old_values=mod_values) > - bad_specs = {"min": {par: 8}, "max": {par: 4}} > + bad_specs = { > + constants.ISPECS_MINMAX: [{ > + constants.ISPECS_MIN: {par: 8}, > + constants.ISPECS_MAX: {par: 4}, > + }], > + } > _TestGroupSetISpecs(groupname, diff_specs=bad_specs, fail=True, > old_values=mod_values) > AssertCommand(["gnt-group", "modify", "--ipolicy-bounds-specs", > "default", > diff --git a/qa/qa_utils.py b/qa/qa_utils.py > index 412f913..7ec0d49 100644 > --- a/qa/qa_utils.py > +++ b/qa/qa_utils.py > @@ -797,8 +797,9 @@ def TestSetISpecs(new_specs=None, diff_specs=None, > get_policy_fn=None, > @param new_specs: new complete specs, in the same format returned by > L{ParseIPolicy}. > @type diff_specs: dict > - @param diff_specs: diff_specs[key][par], where key is "min", "max", > "std". It > - can be an incomplete specifications or an empty dictionary. > + @param diff_specs: partial specs, it can be an incomplete > specifications, but > + if min/max specs are specified, their number must match the number > of the > + existing specs > @type get_policy_fn: function > @param get_policy_fn: function that returns the current policy as in > L{ParseIPolicy} > @@ -824,26 +825,35 @@ def TestSetISpecs(new_specs=None, diff_specs=None, > get_policy_fn=None, > > if diff_specs: > new_specs = copy.deepcopy(old_specs) > - for (key, parvals) in diff_specs.items(): > - for (par, val) in parvals.items(): > - new_specs[key][par] = val > + if constants.ISPECS_MINMAX in diff_specs: > + AssertEqual(len(new_specs[constants.ISPECS_MINMAX]), > + len(diff_specs[constants.ISPECS_MINMAX])) > + for (new_minmax, diff_minmax) in > zip(new_specs[constants.ISPECS_MINMAX], > + > diff_specs[constants.ISPECS_MINMAX]): > + for (key, parvals) in diff_minmax.items(): > + for (par, val) in parvals.items(): > + new_minmax[key][par] = val > + for (par, val) in diff_specs.get(constants.ISPECS_STD, {}).items(): > + new_specs[constants.ISPECS_STD][par] = val > > if new_specs: > cmd = [] > - if (diff_specs is None or > - ("min" in diff_specs or "max" in diff_specs)): > + if (diff_specs is None or constants.ISPECS_MINMAX in diff_specs): > minmax_opt_items = [] > - for key in ["min", "max"]: > - keyopt = _GetParameterOptions(new_specs[key]) > - minmax_opt_items.append("%s:%s" % (key, keyopt)) > + for minmax in new_specs[constants.ISPECS_MINMAX]: > + minmax_opts = [] > + for key in ["min", "max"]: > + keyopt = _GetParameterOptions(minmax[key]) > + minmax_opts.append("%s:%s" % (key, keyopt)) > + minmax_opt_items.append("/".join(minmax_opts)) > cmd.extend([ > "--ipolicy-bounds-specs", > - "/".join(minmax_opt_items) > + "//".join(minmax_opt_items) > ]) > - if diff_specs: > - std_source = diff_specs > - else: > + if diff_specs is None: > std_source = new_specs > + else: > + std_source = diff_specs > std_opt = _GetParameterOptions(std_source.get("std", {})) > if std_opt: > cmd.extend(["--ipolicy-std-specs", std_opt]) > @@ -871,15 +881,23 @@ def ParseIPolicy(policy): > @rtype: tuple > @return: (policy, specs), where: > - policy is a dictionary of the policy values, instance specs > excluded > - - specs is dict of dict, specs[key][par] is a spec value, where key > is > - "min", "max", or "std" > + - specs is a dictionary containing only the specs, using the > internal > + format (see L{constants.IPOLICY_DEFAULTS} for an example) > > """ > 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: > + if key == "bounds specs": > + ret_specs[constants.ISPECS_MINMAX] = [] > + for minmax in val: > + ret_minmax = {} > + for key in minmax: > + keyparts = key.split("/", 1) > + assert len(keyparts) > 1 > + ret_minmax[keyparts[0]] = minmax[key] > + ret_specs[constants.ISPECS_MINMAX].append(ret_minmax) > + elif key == constants.ISPECS_STD: > ret_specs[key] = val > else: > ret_policy[key] = val > -- > 1.8.2.1 > > LGTM, thanks