Revision ec996117 qa/qa_utils.py
b/qa/qa_utils.py | ||
---|---|---|
23 | 23 |
|
24 | 24 |
""" |
25 | 25 |
|
26 |
import copy |
|
26 | 27 |
import operator |
27 | 28 |
import os |
28 | 29 |
import random |
... | ... | |
779 | 780 |
return path |
780 | 781 |
|
781 | 782 |
|
782 |
def _GetParameterOptions(key, specs, old_specs):
|
|
783 |
def _GetParameterOptions(specs): |
|
783 | 784 |
"""Helper to build policy options.""" |
784 |
values = ["%s=%s" % (par, keyvals[key]) |
|
785 |
for (par, keyvals) in specs.items() |
|
786 |
if key in keyvals] |
|
787 |
if old_specs: |
|
788 |
present_pars = frozenset(par |
|
789 |
for (par, keyvals) in specs.items() |
|
790 |
if key in keyvals) |
|
791 |
values.extend("%s=%s" % (par, keyvals[key]) |
|
792 |
for (par, keyvals) in old_specs.items() |
|
793 |
if key in keyvals and par not in present_pars) |
|
785 |
values = ["%s=%s" % (par, val) |
|
786 |
for (par, val) in specs.items()] |
|
794 | 787 |
return ",".join(values) |
795 | 788 |
|
796 | 789 |
|
797 |
def TestSetISpecs(new_specs, get_policy_fn=None, build_cmd_fn=None,
|
|
798 |
fail=False, old_values=None): |
|
790 |
def TestSetISpecs(new_specs=None, diff_specs=None, get_policy_fn=None,
|
|
791 |
build_cmd_fn=None, fail=False, old_values=None):
|
|
799 | 792 |
"""Change instance specs for an object. |
800 | 793 |
|
801 |
@type new_specs: dict of dict |
|
802 |
@param new_specs: new_specs[par][key], where key is "min", "max", "std". It |
|
803 |
can be an empty dictionary. |
|
794 |
At most one of new_specs or diff_specs can be specified. |
|
795 |
|
|
796 |
@type new_specs: dict |
|
797 |
@param new_specs: new complete specs, in the same format returned by |
|
798 |
L{ParseIPolicy}. |
|
799 |
@type diff_specs: dict |
|
800 |
@param diff_specs: diff_specs[key][par], where key is "min", "max", "std". It |
|
801 |
can be an incomplete specifications or an empty dictionary. |
|
804 | 802 |
@type get_policy_fn: function |
805 | 803 |
@param get_policy_fn: function that returns the current policy as in |
806 |
L{qa_cluster._GetClusterIPolicy}
|
|
804 |
L{ParseIPolicy}
|
|
807 | 805 |
@type build_cmd_fn: function |
808 | 806 |
@param build_cmd_fn: function that return the full command line from the |
809 | 807 |
options alone |
... | ... | |
811 | 809 |
@param fail: if the change is expected to fail |
812 | 810 |
@type old_values: tuple |
813 | 811 |
@param old_values: (old_policy, old_specs), as returned by |
814 |
L{qa_cluster._GetClusterIPolicy}
|
|
815 |
@return: same as L{qa_cluster._GetClusterIPolicy}
|
|
812 |
L{ParseIPolicy}
|
|
813 |
@return: same as L{ParseIPolicy}
|
|
816 | 814 |
|
817 | 815 |
""" |
818 | 816 |
assert get_policy_fn is not None |
819 | 817 |
assert build_cmd_fn is not None |
818 |
assert new_specs is None or diff_specs is None |
|
820 | 819 |
|
821 | 820 |
if old_values: |
822 | 821 |
(old_policy, old_specs) = old_values |
823 | 822 |
else: |
824 | 823 |
(old_policy, old_specs) = get_policy_fn() |
824 |
|
|
825 |
if diff_specs: |
|
826 |
new_specs = copy.deepcopy(old_specs) |
|
827 |
for (key, parvals) in diff_specs.items(): |
|
828 |
for (par, val) in parvals.items(): |
|
829 |
new_specs[key][par] = val |
|
830 |
|
|
825 | 831 |
if new_specs: |
826 | 832 |
cmd = [] |
827 |
if any(("min" in val or "max" in val) for val in new_specs.values()): |
|
833 |
if (diff_specs is None or |
|
834 |
("min" in diff_specs or "max" in diff_specs)): |
|
828 | 835 |
minmax_opt_items = [] |
829 | 836 |
for key in ["min", "max"]: |
830 |
keyopt = _GetParameterOptions(key, new_specs, old_specs)
|
|
837 |
keyopt = _GetParameterOptions(new_specs[key])
|
|
831 | 838 |
minmax_opt_items.append("%s:%s" % (key, keyopt)) |
832 | 839 |
cmd.extend([ |
833 | 840 |
"--ipolicy-bounds-specs", |
834 | 841 |
"/".join(minmax_opt_items) |
835 | 842 |
]) |
836 |
std_opt = _GetParameterOptions("std", new_specs, {}) |
|
843 |
if diff_specs: |
|
844 |
std_source = diff_specs |
|
845 |
else: |
|
846 |
std_source = new_specs |
|
847 |
std_opt = _GetParameterOptions(std_source.get("std", {})) |
|
837 | 848 |
if std_opt: |
838 | 849 |
cmd.extend(["--ipolicy-std-specs", std_opt]) |
839 | 850 |
AssertCommand(build_cmd_fn(cmd), fail=fail) |
840 | 851 |
|
841 |
# Check the new state |
|
842 |
(eff_policy, eff_specs) = get_policy_fn() |
|
843 |
AssertEqual(eff_policy, old_policy) |
|
844 |
if fail: |
|
845 |
AssertEqual(eff_specs, old_specs) |
|
852 |
# Check the new state |
|
853 |
(eff_policy, eff_specs) = get_policy_fn() |
|
854 |
AssertEqual(eff_policy, old_policy) |
|
855 |
if fail: |
|
856 |
AssertEqual(eff_specs, old_specs) |
|
857 |
else: |
|
858 |
AssertEqual(eff_specs, new_specs) |
|
859 |
|
|
846 | 860 |
else: |
847 |
for par in eff_specs: |
|
848 |
for key in eff_specs[par]: |
|
849 |
if par in new_specs and key in new_specs[par]: |
|
850 |
AssertEqual(int(eff_specs[par][key]), int(new_specs[par][key])) |
|
851 |
else: |
|
852 |
AssertEqual(int(eff_specs[par][key]), int(old_specs[par][key])) |
|
861 |
(eff_policy, eff_specs) = (old_policy, old_specs) |
|
862 |
|
|
853 | 863 |
return (eff_policy, eff_specs) |
854 | 864 |
|
855 | 865 |
|
... | ... | |
861 | 871 |
@rtype: tuple |
862 | 872 |
@return: (policy, specs), where: |
863 | 873 |
- policy is a dictionary of the policy values, instance specs excluded |
864 |
- specs is dict of dict, specs[par][key] is a spec value, where key is
|
|
874 |
- specs is dict of dict, specs[key][par] is a spec value, where key is
|
|
865 | 875 |
"min", "max", or "std" |
866 | 876 |
|
867 | 877 |
""" |
... | ... | |
870 | 880 |
ispec_keys = constants.ISPECS_MINMAX_KEYS | frozenset([constants.ISPECS_STD]) |
871 | 881 |
for (key, val) in policy.items(): |
872 | 882 |
if key in ispec_keys: |
873 |
for (par, pval) in val.items(): |
|
874 |
d = ret_specs.setdefault(par, {}) |
|
875 |
d[key] = pval |
|
883 |
ret_specs[key] = val |
|
876 | 884 |
else: |
877 | 885 |
ret_policy[key] = val |
878 | 886 |
return (ret_policy, ret_specs) |
Also available in: Unified diff