def conflicting_variants(self, actions, pkg_vars): """Given a set of actions, determine that none of the actions have matching variant values for any variant. We return a list of variants that conflict, and a list of the actions involved. """ conflict_vars = set() conflict_actions = set() action_list = list(actions) # compare every action in the list with every other, # determining what actions have conflicting variants # The comparison is commutative. for i in range(0, len(action_list)): action = action_list[i] var = action.get_variant_template() vc = variant.VariantCombinations(var, True) for j in range(i + 1, len(action_list)): cmp_action = action_list[j] cmp_var = variant.VariantCombinations( cmp_action.get_variant_template(), True) if vc.intersects(cmp_var): intersection = vc.intersection(cmp_var) intersection.simplify(pkg_vars, assert_on_different_domains=False) conflict_actions.add(action) conflict_actions.add(cmp_action) for k in intersection.sat_set: if len(k) != 0: conflict_vars.add(k) return conflict_vars, list(conflict_actions)
def conflicting_dep_actions(self, actions, pkg_vars, compared): """Given a set of depend actions, determine that if any of the two actions are conflicting. We return a list of variants that conflict, and a list of the actions involved.""" def get_fmri_set(action): fmris = set() for dep in action.attrs["fmri"]: fmris.add(fmri.extract_pkg_name(dep)) return fmris conflict_vars = set() conflict_actions = set() action_list = list(actions) # Record the fmri set of action we have generated. fmris_dict = [None] * len(actions) multidep_type = frozenset(["require-any", "group-any"]) # compare every action in the list with every other, # determining what actions have conflicting variants # The comparison is commutative. for i in range(0, len(action_list)): action = action_list[i] var = action.get_variant_template() vc = variant.VariantCombinations(var, True) if action.attrs["type"] in multidep_type: if fmris_dict[i] == None: fmris_dict[i] = get_fmri_set(action) fmris = fmris_dict[i] for j in range(i + 1, len(action_list)): cmp_action = action_list[j] # If we have compared this pair of actions, # don't bother to compare again. if ((action, cmp_action) in compared or (cmp_action, action) in compared): continue compared.add((action, cmp_action)) if (cmp_action.attrs["type"] in multidep_type and action.attrs["type"] in multidep_type): fmris_dict[j] = get_fmri_set(cmp_action) cmp_fmris = fmris_dict[j] if fmris != cmp_fmris: continue cmp_var = variant.VariantCombinations( cmp_action.get_variant_template(), True) if vc.intersects(cmp_var): intersection = vc.intersection(cmp_var) intersection.simplify(pkg_vars, assert_on_different_domains=False) conflict_actions.add(action) conflict_actions.add(cmp_action) for k in intersection.sat_set: if len(k) != 0: conflict_vars.add(k) return conflict_vars, list(conflict_actions)
def get_variant_combinations(self, satisfied=False): """Create the combinations of variants that this action satisfies or needs satisfied. 'satisfied' determines whether the combination produced is satisfied or unsatisfied.""" variants = self.action.get_variant_template() variants.merge_unknown(self.pkg_vars) return variant.VariantCombinations(variants, satisfied=satisfied)
def test_variant_combinations(self): """Test functionality of VariantCombinations.""" vct_1 = variant.VariantCombinationTemplate( dict([(1, ["a", "b", "c"]), (2, ["z", "y", "x"])])) vct_2 = variant.VariantCombinationTemplate( dict([(10, ["l", "m", "n"]), (20, ["p", "q", "r"])])) vct_3 = variant.VariantCombinationTemplate( dict([(1, ["a"]), (2, ["z"])])) vct_4 = variant.VariantCombinationTemplate( dict([(1, ["a", "b", "d"]), (2, ["z", "y", "x"])])) set_combo = set([ frozenset([(1, "a"), (2, "z")]), frozenset([(1, "a"), (2, "y")]), frozenset([(1, "a"), (2, "x")]), frozenset([(1, "b"), (2, "z")]), frozenset([(1, "b"), (2, "y")]), frozenset([(1, "b"), (2, "x")]), frozenset([(1, "c"), (2, "z")]), frozenset([(1, "c"), (2, "y")]), frozenset([(1, "c"), (2, "x")]) ]) vc1_s = variant.VariantCombinations(vct_1, True) self.assertEqual(vc1_s.sat_set, set_combo) self.assertEqual(vc1_s.not_sat_set, set()) self.assertTrue(not vc1_s.is_empty()) vc1_ns = variant.VariantCombinations(vct_1, False) self.assertEqual(vc1_ns.not_sat_set, set_combo) self.assertEqual(vc1_ns.sat_set, set()) self.assertTrue(not vc1_ns.is_empty()) self.assertRaises(AssertionError, vc1_ns.simplify, vct_2) self.assertEqual(vc1_ns.not_sat_set, set_combo) self.assertEqual(vc1_ns.sat_set, set()) self.assertTrue(not vc1_ns.is_empty()) self.assertRaises(AssertionError, vc1_ns.simplify, vct_4) self.assertEqual(vc1_ns.not_sat_set, set_combo) self.assertEqual(vc1_ns.sat_set, set()) self.assertTrue(not vc1_ns.is_empty()) vc1_tmp = copy.copy(vc1_ns) self.assertTrue(not vc1_tmp.is_satisfied()) vc1_tmp.mark_all_as_satisfied() self.assertTrue(vc1_tmp.is_satisfied()) self.assertEqual(vc1_tmp.sat_set, set_combo) vct3_set_combo = set([frozenset([(1, "a"), (2, "z")])]) vc3_ns = variant.VariantCombinations(vct_3, False) self.assertEqual(vc3_ns.not_sat_set, vct3_set_combo) self.assertTrue(vc3_ns.issubset(vc1_ns, False)) self.assertTrue(not vc1_ns.issubset(vc3_ns, False)) self.assertTrue(vc1_ns.issubset(vc3_ns, True)) self.assertTrue(not vc1_s.issubset(vc3_ns, True)) vc3_s = variant.VariantCombinations(vct_3, True) vc2_s = variant.VariantCombinations(vct_2, True) self.assertTrue(vc3_s.intersects(vc1_s)) self.assertTrue(vc3_ns.intersects(vc1_s)) self.assertTrue(not vc3_ns.intersects(vc2_s)) self.assertTrue(not vc3_s.intersects(vc2_s)) self.assertTrue(vc1_s.intersects(vc3_s)) intersect = vc3_s.intersection(vc1_s) self.assertEqual(intersect.sat_set, vct3_set_combo) self.assertEqual(intersect.not_sat_set, set()) # Test that modifing the original does not modify the copy. vc3_ns_copy = copy.copy(vc3_ns) vc3_ns.mark_all_as_satisfied() self.assertEqual(vc3_ns_copy.not_sat_set, vct3_set_combo) self.assertEqual(vc3_ns.not_sat_set, set()) self.assertEqual(vc3_ns.sat_set, vct3_set_combo) vct_empty = variant.VariantCombinationTemplate(dict([])) vc_empty = variant.VariantCombinations(vct_empty, True) self.assertTrue(vc_empty.is_empty()) self.assertTrue(vc_empty.intersects(vc1_ns)) self.assertTrue(vc1_ns.intersects(vc_empty)) vc1_ns.mark_as_satisfied(vc3_s) self.assertEqual(vc1_ns.sat_set, vct3_set_combo) self.assertEqual(vc1_ns.not_sat_set, set_combo - vct3_set_combo) vc1_s.simplify(vct_1) self.assertEqual(vc1_s.sat_set, set()) self.assertEqual(vc1_s.not_sat_set, set()) vc1_ns_simp = variant.VariantCombinations(vct_1, False) vc1_ns_simp.simplify(vct_1) self.assertEqual(vc1_ns_simp.sat_set, set()) self.assertEqual(vc1_ns_simp.not_sat_set, set())