Revision 63e08b25 qa/qa_utils.py

b/qa/qa_utils.py
777 777
    return "%s%s" % (vcluster.MakeNodeRoot(basedir, name), path)
778 778
  else:
779 779
    return path
780

  
781

  
782
def _GetParameterOptions(key, specs, old_specs):
783
  """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)
794
  return ",".join(values)
795

  
796

  
797
def TestSetISpecs(new_specs, get_policy_fn=None, build_cmd_fn=None,
798
                  fail=False, old_values=None):
799
  """Change instance specs for an object.
800

  
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.
804
  @type get_policy_fn: function
805
  @param get_policy_fn: function that returns the current policy as in
806
      L{qa_cluster._GetClusterIPolicy}
807
  @type build_cmd_fn: function
808
  @param build_cmd_fn: function that return the full command line from the
809
      options alone
810
  @type fail: bool
811
  @param fail: if the change is expected to fail
812
  @type old_values: tuple
813
  @param old_values: (old_policy, old_specs), as returned by
814
     L{qa_cluster._GetClusterIPolicy}
815
  @return: same as L{qa_cluster._GetClusterIPolicy}
816

  
817
  """
818
  assert get_policy_fn is not None
819
  assert build_cmd_fn is not None
820

  
821
  if old_values:
822
    (old_policy, old_specs) = old_values
823
  else:
824
    (old_policy, old_specs) = get_policy_fn()
825
  if new_specs:
826
    cmd = []
827
    if any(("min" in val or "max" in val) for val in new_specs.values()):
828
      minmax_opt_items = []
829
      for key in ["min", "max"]:
830
        keyopt = _GetParameterOptions(key, new_specs, old_specs)
831
        minmax_opt_items.append("%s:%s" % (key, keyopt))
832
      cmd.extend([
833
        "--ipolicy-bounds-specs",
834
        "/".join(minmax_opt_items)
835
        ])
836
    std_opt = _GetParameterOptions("std", new_specs, {})
837
    if std_opt:
838
      cmd.extend(["--ipolicy-std-specs", std_opt])
839
    AssertCommand(build_cmd_fn(cmd), fail=fail)
840

  
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)
846
  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]))
853
  return (eff_policy, eff_specs)
854

  
855

  
856
def ParseIPolicy(policy):
857
  """Parse and split instance an instance policy.
858

  
859
  @type policy: dict
860
  @param policy: policy, as returned by L{GetObjectInfo}
861
  @rtype: tuple
862
  @return: (policy, specs), where:
863
      - 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
865
        "min", "max", or "std"
866

  
867
  """
868
  ret_specs = {}
869
  ret_policy = {}
870
  ispec_keys = constants.ISPECS_MINMAX_KEYS | frozenset([constants.ISPECS_STD])
871
  for (key, val) in policy.items():
872
    if key in ispec_keys:
873
      for (par, pval) in val.items():
874
        d = ret_specs.setdefault(par, {})
875
        d[key] = pval
876
    else:
877
      ret_policy[key] = val
878
  return (ret_policy, ret_specs)

Also available in: Unified diff