def setUp(self): self.order_entity = RelationEntityDto( "order1", ResourceRelationType.ORDER, [], { "id": "order1", "first-action": "start", "first": "d1", "then-action": "start", "then": "d2", }) self.order_set_entity = RelationEntityDto( "order_set_id", ResourceRelationType.ORDER_SET, [], { "id": "order_set_id", "sets": [ { "members": ["d1", "d2", "d3"], "metadata": {}, }, { "members": ["d4", "d5", "d0"], "metadata": { "sequential": "true", "require-all": "false", "score": "10", }, }, ], })
def test_simple_in_group(self): resources_members = ["outer:g1"] resources = { "d1": self.primitive_fixture("d1", resources_members), "d2": self.primitive_fixture("d2", resources_members), "g1": RelationEntityDto("g1", "group", ["inner:g1"], {"id": "g1"}), } relations = { "inner:g1": RelationEntityDto( "inner:g1", ResourceRelationType.INNER_RESOURCES, ["d1", "d2"], {"id": "g1"}, ), "outer:g1": RelationEntityDto( "outer:g1", ResourceRelationType.OUTER_RESOURCE, ["g1"], {"id": "g1"}, ), } expected = dict( relation_entity=dto.to_dict(resources["d1"]), is_leaf=False, members=[ dict( relation_entity=dto.to_dict(relations["outer:g1"]), is_leaf=False, members=[ dict( relation_entity=dto.to_dict(resources["g1"]), is_leaf=False, members=[ dict( relation_entity=dto.to_dict( relations["inner:g1"]), is_leaf=False, members=[ dict( relation_entity=dto.to_dict( resources["d2"]), is_leaf=False, members=[], ), ], ), ], ), ], ), ], ) self.assertEqual( expected, dto.to_dict( lib.ResourceRelationTreeBuilder( resources, relations).get_tree("d1").to_dto()), )
def test_from_dto(self): inner_ent = RelationEntityDto("inner:g1", ResourceRelationType.INNER_RESOURCES, [], {}) outer_ent = RelationEntityDto("outer:g1", ResourceRelationType.OUTER_RESOURCE, [], {}) order_ent1 = RelationEntityDto("order1", ResourceRelationType.ORDER, [], {}) order_ent2 = RelationEntityDto("order2", ResourceRelationType.ORDER, [], {}) order_set_ent = RelationEntityDto("order_set", ResourceRelationType.ORDER_SET, [], {}) dto = ResourceRelationDto( D1_PRIMITIVE, [ _fixture_res_rel_dto(order_set_ent), _fixture_res_rel_dto(order_ent2), _fixture_res_rel_dto(outer_ent), _fixture_res_rel_dto(inner_ent), _fixture_res_rel_dto(order_ent1), ], False, ) obj = relations.ResourcePrintableNode.from_dto(dto) self.assertEqual(D1_PRIMITIVE, obj.relation_entity) self.assertEqual(False, obj.is_leaf) expected_members = (inner_ent, outer_ent, order_ent1, order_ent2, order_set_ent) self.assertEqual(len(expected_members), len(obj.members)) for i, member in enumerate(obj.members): self.assert_member(member, expected_members[i])
def test_group(self): obj = lib.ResourceRelationsFetcher( fixture_cib( """ <group id="g1"> <primitive id="d1" class="c" provider="pcmk" type="Dummy"/> <primitive id="d2" class="c" provider="pcmk" type="Dummy"/> </group> """, "", )) expected = ( { "d1": RelationEntityDto( "d1", ResourceRelationType.RSC_PRIMITIVE, ["outer:g1"], fixture_dummy_metadata("d1"), ), "d2": RelationEntityDto( "d2", ResourceRelationType.RSC_PRIMITIVE, ["outer:g1"], fixture_dummy_metadata("d2"), ), "g1": RelationEntityDto( "g1", ResourceRelationType.RSC_GROUP, ["inner:g1"], {"id": "g1"}, ), }, { "inner:g1": RelationEntityDto( "inner:g1", ResourceRelationType.INNER_RESOURCES, ["d1", "d2"], {"id": "g1"}, ), "outer:g1": RelationEntityDto( "outer:g1", ResourceRelationType.OUTER_RESOURCE, ["g1"], {"id": "g1"}, ), }, ) for res in ("d1", "d2", "g1"): with self.subTest(resource=res): self.assertEqual(expected, obj.get_relations(res))
def test_success(self, mock_print): self.lib_call.return_value = ResourceRelationDto( RelationEntityDto("d1", "primitive", [], { "class": "ocf", "provider": "pacemaker", "type": "Dummy", }), [ ResourceRelationDto( RelationEntityDto( "order1", ResourceRelationType.ORDER, [], { "first-action": "start", "first": "d1", "then-action": "start", "then": "d2", "kind": "Mandatory", "symmetrical": "true", }), [ ResourceRelationDto( RelationEntityDto( "d2", "primitive", [], { "class": "ocf", "provider": "heartbeat", "type": "Dummy", }), [], False), ], False), ResourceRelationDto( RelationEntityDto( "inner:g1", ResourceRelationType.INNER_RESOURCES, [], {}), [ ResourceRelationDto( RelationEntityDto("g1", "group", [], {}), [], True, ), ], False) ], False, ).to_dict() relations.show_resource_relations_cmd(self.lib, ["d1"], dict_to_modifiers({})) self.lib_call.assert_called_once_with("d1") self.assertEqual([ mock.call("d1 (resource: ocf:pacemaker:Dummy)"), mock.call("|- inner resource(s) (None)"), mock.call("| `- g1 (resource: group) [displayed elsewhere]"), mock.call("`- order (None)"), mock.call(" | start d1 then start d2"), mock.call(" | kind=Mandatory symmetrical=true"), mock.call(" `- d2 (resource: ocf:heartbeat:Dummy)"), ], mock_print.call_args_list)
def test_ordering_constraint(self): obj = lib.ResourceRelationsFetcher( fixture_cib( """ <primitive id="d1" class="c" provider="pcmk" type="Dummy"/> <primitive id="d2" class="c" provider="pcmk" type="Dummy"/> """, """ <rsc_order first="d1" first-action="start" id="order-d1-d2-mandatory" then="d2" then-action="start" kind="Mandatory"/> """, )) expected = ( { "d1": RelationEntityDto( "d1", ResourceRelationType.RSC_PRIMITIVE, ["order-d1-d2-mandatory"], fixture_dummy_metadata("d1"), ), "d2": RelationEntityDto( "d2", ResourceRelationType.RSC_PRIMITIVE, ["order-d1-d2-mandatory"], fixture_dummy_metadata("d2"), ), }, { "order-d1-d2-mandatory": RelationEntityDto( "order-d1-d2-mandatory", ResourceRelationType.ORDER, members=["d1", "d2"], metadata={ "id": "order-d1-d2-mandatory", "first": "d1", "first-action": "start", "then": "d2", "then-action": "start", "kind": "Mandatory", }, ), }, ) for res in ("d1", "d2"): with self.subTest(resource=res): self.assertEqual(expected, obj.get_relations(res))
def primitive_fixture(_id, members): return RelationEntityDto( _id, ResourceRelationType.RSC_PRIMITIVE, members, fixture_dummy_metadata(_id), )
def get_relations( self, resource_id: str ) -> Tuple[IdRelationMap, IdRelationMap]: resources_to_process = {resource_id} relations = {} resources: MutableMapping[str, RelationEntityDto] = {} while resources_to_process: res_id = resources_to_process.pop() if res_id in resources: # already processed continue res_el = self._get_resource_el(res_id) res_relations = { rel.id: rel for rel in self._get_resource_relations(res_el) } resources[res_id] = RelationEntityDto( res_id, _get_resource_relation_type(res_el), list(res_relations.keys()), dict(cast(Mapping[str, str], res_el.attrib)), ) relations.update(res_relations) resources_to_process.update( self._get_all_members(res_relations.values()) ) return resources, relations
def test_other(self): obj = relations.ResourcePrintableNode( RelationEntityDto("an_id", "a_type", [], {}), [], False, ) self.assertEqual("an_id (resource: a_type)", obj.title) self.assertEqual([], obj.detail)
def test_other_not_verbose(self): obj = relations.ResourcePrintableNode( RelationEntityDto("an_id", "a_type", [], {}), [], False, ) self.assertEqual("an_id", obj.get_title(verbose=False)) self.assertEqual([], obj.detail)
def test_multiple_inner_resources(self): obj = relations.RelationPrintableNode( RelationEntityDto("inner:g1", ResourceRelationType.INNER_RESOURCES, ["m1", "m2", "m0"], {"id": "g1"}), [], False, ) self.assertEqual("inner resource(s) (g1)", obj.title) self.assertEqual(["members: m1 m2 m0"], obj.detail)
def _get_ordering_constraint_relation( ord_const_el: Element) -> RelationEntityDto: attrs = ord_const_el.attrib return RelationEntityDto( attrs["id"], ResourceRelationType.ORDER, [attrs["first"], attrs["then"]], dict(attrs), )
def _get_outer_resource_relation( parent_resource_el: Element) -> RelationEntityDto: attrs = parent_resource_el.attrib return RelationEntityDto( OUTER_RESOURCE_ID_TEMPLATE.format(attrs["id"]), ResourceRelationType.OUTER_RESOURCE, [attrs["id"]], dict(attrs), )
def setUp(self): self.maxDiff = None self.lib_call = mock.Mock() self.lib = mock.Mock(spec_set=["resource"]) self.lib.resource = mock.Mock(spec_set=["get_resource_relations_tree"]) self.lib.resource.get_resource_relations_tree = self.lib_call self.lib_call.return_value = ResourceRelationDto( RelationEntityDto("d1", "primitive", [], { "class": "ocf", "provider": "pacemaker", "type": "Dummy", }), [ ResourceRelationDto( RelationEntityDto( "order1", ResourceRelationType.ORDER, [], { "first-action": "start", "first": "d1", "then-action": "start", "then": "d2", "kind": "Mandatory", "symmetrical": "true", }), [ ResourceRelationDto( RelationEntityDto( "d2", "primitive", [], { "class": "ocf", "provider": "heartbeat", "type": "Dummy", }), [], False), ], False), ResourceRelationDto( RelationEntityDto( "inner:g1", ResourceRelationType.INNER_RESOURCES, [], {}), [ ResourceRelationDto( RelationEntityDto("g1", "group", [], {}), [], True, ), ], False) ], False, ).to_dict()
def test_unknown_not_verbose(self): obj = relations.RelationPrintableNode( RelationEntityDto("random", "undifined type", [], { "id": "random_id", }), [], False, ) self.assertEqual("<unknown>", obj.get_title(verbose=False)) self.assertEqual([], obj.detail)
def test_primitive_without_provider_class(self): obj = relations.ResourcePrintableNode( RelationEntityDto("d1", ResourceRelationType.RSC_PRIMITIVE, [], { "type": "Dummy", }), [], False, ) self.assertEqual("d1 (resource: Dummy)", obj.get_title(verbose=True)) self.assertEqual([], obj.detail)
def test_primitive_without_provider_class(self): obj = relations.ResourcePrintableNode( RelationEntityDto("d1", "primitive", [], { "type": "Dummy", }), [], False, ) self.assertEqual("d1 (resource: Dummy)", obj.title) self.assertEqual([], obj.detail)
def test_unknown(self): obj = relations.RelationPrintableNode( RelationEntityDto("random", "undifined type", [], { "id": "random_id", }), [], False, ) self.assertEqual("<unknown> (random_id)", obj.title) self.assertEqual([], obj.detail)
def _get_ordering_constraint_relation( ord_const_el: _Element, ) -> RelationEntityDto: attrs = cast(Mapping[str, str], ord_const_el.attrib) return RelationEntityDto( str(attrs["id"]), ResourceRelationType.ORDER, [str(attrs["first"]), str(attrs["then"])], dict(attrs), )
def _get_outer_resource_relation( parent_resource_el: _Element, ) -> RelationEntityDto: attrs = cast(Mapping[str, str], parent_resource_el.attrib) return RelationEntityDto( OUTER_RESOURCE_ID_TEMPLATE.format(attrs["id"]), ResourceRelationType.OUTER_RESOURCE, [str(attrs["id"])], dict(attrs), )
def _test_wrapper(self, wrapper_tag): obj = lib.ResourceRelationsFetcher( fixture_cib( f""" <{wrapper_tag} id="w1"> <primitive id="d1" class="c" provider="pcmk" type="Dummy"/> </{wrapper_tag}> """, "", )) expected = ( { "d1": RelationEntityDto( "d1", "primitive", ["outer:w1"], fixture_dummy_metadata("d1"), ), "w1": RelationEntityDto("w1", wrapper_tag, ["inner:w1"], {"id": "w1"}), }, { "inner:w1": RelationEntityDto( "inner:w1", ResourceRelationType.INNER_RESOURCES, ["d1"], {"id": "w1"}, ), "outer:w1": RelationEntityDto( "outer:w1", ResourceRelationType.OUTER_RESOURCE, ["w1"], {"id": "w1"}, ), }, ) for res in ("d1", "w1"): with self.subTest(resource=res): self.assertEqual(expected, obj.get_relations(res))
def entity_fixture(index): return RelationEntityDto.from_dict(dict( id=f"ent_id{index}", type="ent_type", members=[f"{index}m1", f"{index}m2", f"{index}m0"], metadata=dict( id=f"ent_id{index}", k0="val0", k1="val1", ) ))
def _fixture_dummy(_id): return RelationEntityDto( _id, ResourceRelationType.RSC_PRIMITIVE, [], { "class": "ocf", "provider": "pacemaker", "type": "Dummy", }, )
def test_inner_resources(self): obj = relations.RelationPrintableNode( RelationEntityDto("inner:g1", ResourceRelationType.INNER_RESOURCES, ["m0"], { "id": "g1", }), [], False, ) self.assertEqual("inner resource(s) (g1)", obj.get_title(verbose=True)) self.assertEqual([], obj.detail)
def test_outer_resource(self): obj = relations.RelationPrintableNode( RelationEntityDto("outer:g1", ResourceRelationType.OUTER_RESOURCE, [], { "id": "g1", }), [], False, ) self.assertEqual("outer resource (g1)", obj.title) self.assertEqual([], obj.detail)
def _fixture_dummy(_id): return RelationEntityDto( _id, "primitive", [], { "class": "ocf", "provider": "pacemaker", "type": "Dummy", }, )
def test_primitive_without_class(self): obj = relations.ResourcePrintableNode( RelationEntityDto("d1", "primitive", [], { "provider": "pacemaker", "type": "Dummy", }), [], False, ) self.assertEqual("d1 (resource: pacemaker:Dummy)", obj.get_title(verbose=True)) self.assertEqual([], obj.detail)
def _get_inner_resources_relation( parent_resource_el: Element) -> RelationEntityDto: attrs = parent_resource_el.attrib return RelationEntityDto( INNER_RESOURCE_ID_TEMPLATE.format(attrs["id"]), ResourceRelationType.INNER_RESOURCES, [ res.attrib["id"] for res in common.get_inner_resources(parent_resource_el) ], dict(attrs), )
def _get_inner_resources_relation( parent_resource_el: _Element, ) -> RelationEntityDto: attrs = cast(Mapping[str, str], parent_resource_el.attrib) return RelationEntityDto( INNER_RESOURCE_ID_TEMPLATE.format(attrs["id"]), ResourceRelationType.INNER_RESOURCES, [ str(res.attrib["id"]) for res in common.get_inner_resources(parent_resource_el) ], dict(attrs), )
def test_outer_resourcenot_verbose(self): obj = relations.RelationPrintableNode( RelationEntityDto( "outer:g1", ResourceRelationType.OUTER_RESOURCE, [], { "id": "g1", }, ), [], False, ) self.assertEqual("outer resource", obj.get_title(verbose=False)) self.assertEqual([], obj.detail)