def test_node_missing_and_gets_created(self): assert_xml_equal( etree_to_str( node._ensure_node_exists(self.nodes, "name-test2", self.state) ), etree_to_str(self.node2) )
def test_new_not_append(self): subelement = lib.get_sub_element( self.root, "new_element", "new_id", append_if_missing=False ) assert_xml_equal( """ <root> <sub_element/> </root> """, etree_to_str(self.root) ) assert_xml_equal( """<new_element id="new_id" />""", etree_to_str(subelement) )
def test_new_with_id(self): assert_xml_equal( '<new_element id="new_id"/>', etree_to_str( lib.get_sub_element(self.root, "new_element", "new_id") ) ) assert_xml_equal( """ <root> <sub_element/> <new_element id="new_id"/> </root> """, etree_to_str(self.root) )
def test_not_useful(self): element = etree.Element("new") lib.append_when_useful(self.parent, element) assert_xml_equal( self.tree_str, etree_to_str(self.tree) )
def test_not_useful_with_attributes(self): element = etree.Element("new", attr="test") lib.append_when_useful(self.parent, element, attribs_important=False) assert_xml_equal( self.tree_str, etree_to_str(self.tree) )
def test_different_parent_not_useful(self): element = self.tree.find(".//element-B2") lib.append_when_useful(self.parent, element) assert_xml_equal( self.tree_str, etree_to_str(self.tree) )
def test_already_appended(self): element = self.tree.find(".//element-A2") lib.append_when_useful(self.parent, element) assert_xml_equal( self.tree_str, etree_to_str(self.tree) )
def _assert_move_last_from_cloned_group(self, clone_type): # pylint: disable=no-self-use cib_before = f""" <resources> <group id="G"> <primitive id="RG1" /> <primitive id="RG2" /> <primitive id="RG3" /> </group> <{clone_type} id="X-{clone_type}"> <group id="X"> <primitive id="R1" /> </group> </{clone_type}> <primitive id="R3" /> </resources> """ cib_after = """ <resources> <group id="G"> <primitive id="RG1" /> <primitive id="RG2" /> <primitive id="RG3" /> <primitive id="R1" /> </group> <primitive id="R3" /> </resources> """ cib = etree.fromstring(cib_before) relation.move_resources_to_group( _resource(cib, "G"), _resources(cib, "R1"), ) assert_xml_equal(cib_after, etree_to_str(cib))
def test_group_running(self): resources_state = fixture.complete_state_resources( etree.fromstring(""" <resources> <group id="G" number_resources="2"> <resource id="R1" role="Started" nodes_running_on="1"> <node name="node1" id="1" cached="false" /> </resource> <resource id="R2" role="Started" nodes_running_on="1"> <node name="node1" id="1" cached="false" /> </resource> </group> </resources> """)) self.config.runner.pcmk.load_state( resources=etree_to_str(resources_state)) resource.group_add( self.env_assist.get_env(), "G", ["R1", "R2"], wait=self.timeout, ) self.env_assist.assert_reports([ fixture.report_resource_running("G", {"Started": ["node1"]}), ])
def state_complete(resource_status_xml): status = etree.parse(rc("crm_mon.minimal.xml")).getroot() resource_status = etree.fromstring(resource_status_xml) for resource in resource_status.xpath(".//resource"): _default_element_attributes( resource, { "active": "true", "managed": "true", "failed": "false", "failure_ignored": "false", "nodes_running_on": "1", "orphaned": "false", "resource_agent": "ocf::heartbeat:Dummy", "role": "Started", }) for clone in resource_status.xpath(".//clone"): _default_element_attributes(clone, { "failed": "false", "failure_ignored": "false", }) for bundle in resource_status.xpath(".//bundle"): _default_element_attributes( bundle, { "type": "docker", "image": "image:name", "unique": "false", "failed": "false", }) status.append(resource_status) return etree_to_str(status)
def _cannot_multireplace(tag, parent_xpath, cib_tree): return AssertionError( ( "Cannot replace '{element}' in '{parent}' because '{parent}'" " contains more than one '{element}' in given cib:\n{cib}" ).format( element=tag, parent=parent_xpath, cib=etree_to_str(cib_tree)) )
def push_cib(lib_env, custom_cib=None, wait=False): i, expected_call = call_queue.take(CALL_TYPE_PUSH_CIB) if custom_cib is None and expected_call.custom_cib: raise AssertionError( ("Trying to call env.push_cib (call no. {0}) without " "a custom cib but a custom cib was expected").format(i)) if custom_cib is not None and not expected_call.custom_cib: raise AssertionError( ("Trying to call env.push_cib (call no. {0}) with a custom " "cib but no custom cib was expected").format(i)) assert_xml_equal( expected_call.cib_xml, etree_to_str(lib_env.cib), ("Trying to call env.push_cib (call no. {0}) but cib in env does" " not match\n\n").format(i)) if wait != expected_call.wait: raise AssertionError( ("Trying to call env.push_cib (call no. {0}) with 'wait' == " "{1} but it was expected 'wait' == {2}").format( i, wait, expected_call.wait)) if expected_call.exception: raise expected_call.exception
def setUp(self): self.node1 = etree.fromstring(""" <node id="1" uname="rh73-node1"/> """) self.node2 = etree.fromstring(""" <node id="2" uname="rh73-node2"> <instance_attributes id="nodes-2"> <nvpair name="a" value="A" /> <nvpair name="b" value="B" /> <nvpair name="c" value="C" /> </instance_attributes> </node> """) self.node3 = etree.fromstring(""" <node id="3" uname="rh73-node3" > <instance_attributes id="nodes-3-a"> <nvpair name="a" value="A" /> </instance_attributes> <instance_attributes id="nodes-3-b"> <nvpair name="b" value="B" /> </instance_attributes> </node> """) self.cib = etree.fromstring(""" <cib> <configuration> <nodes>{0}{1}{2}</nodes> </configuration> </cib> """.format( *[etree_to_str(el) for el in [self.node1, self.node2, self.node3]])) self.state = "node state list"
def _find_in(cib_tree, element_xpath): element_list = _find_all_in(cib_tree, element_xpath) if len(element_list) > 1: raise AssertionError( "Found more than one '{0}' in given cib:\n{1}".format( element_xpath, etree_to_str(cib_tree))) return element_list[0]
def test_success(self): lib.remove_device_from_all_levels(self.tree, "d3") assert_xml_equal( """ <fencing-topology> <fencing-level id="fl1" index="1" devices="d1,d2" target="nodeA" /> <fencing-level id="fl3" index="1" devices="d2,d1" target="nodeB" /> <fencing-level id="fl5" index="1" devices="d4" target-pattern="node\d+" /> <fencing-level id="fl6" index="2" devices="d1" target-pattern="node\d+" /> <fencing-level id="fl7" index="3" devices="d4" target-attribute="fencing" target-value="improved" /> <fencing-level id="fl8" index="4" devices="d5" target-attribute="fencing" target-value="improved" /> <fencing-level id="fl9" index="3" devices="dR" target-pattern="node-R.*" /> <fencing-level id="fl10" index="4" devices="dR-special" target-attribute="fencing" target-value="remote-special" /> </fencing-topology> """, etree_to_str(self.tree))
def wrap_element_by_master(cib_file, resource_id, master_id=None): cib_tree = etree.parse(cib_file, etree.XMLParser(huge_tree=True)).getroot() element = cib_tree.find(f'.//*[@id="{resource_id}"]') final_master_id = (master_id if master_id is not None else f"{resource_id}-master") master_element = _xml_to_element(f""" <master id="{final_master_id}"> </master> """) element.getparent().append(master_element) master_element.append(element) final_xml = etree_to_str(cib_tree) environ = dict(os.environ) environ["CIB_file"] = cib_file runner = CommandRunner(mock.MagicMock(logging.Logger), MockLibraryReportProcessor(), environ) stdout, stderr, retval = runner.run([ "cibadmin", "--replace", "--scope", "resources", "--xml-pipe", ], stdin_string=final_xml) assert retval == 0, ("Error running wrap_element_by_master:\n" + stderr + "\n" + stdout)
def load_state(self, name="runner.pcmk.load_state", filename="crm_mon.minimal.xml", resources=None, raw_resources=None): """ Create call for loading pacemaker state. string name -- key of the call string filename -- points to file with the status in the content string resources -- xml - resources section, will be put to state """ if resources and raw_resources is not None: raise AssertionError( "Cannot use 'resources' and 'raw_resources' together") state = etree.fromstring(open(rc(filename)).read()) if raw_resources is not None: resources = fixture_state_resources_xml(**raw_resources) if resources: state.append(complete_state_resources(etree.fromstring(resources))) self.__calls.place( name, RunnerCall( "crm_mon --one-shot --as-xml --inactive", stdout=etree_to_str(state), ))
def setUp(self): self.node1 = etree.fromstring(""" <node id="1" uname="rh73-node1"/> """) self.node2 = etree.fromstring(""" <node id="2" uname="rh73-node2"> <instance_attributes id="nodes-2"> <nvpair name="a" value="A" /> <nvpair name="b" value="B" /> <nvpair name="c" value="C" /> </instance_attributes> </node> """) self.node3 = etree.fromstring(""" <node id="3" uname="rh73-node3" > <instance_attributes id="nodes-3-a"> <nvpair name="a" value="A" /> </instance_attributes> <instance_attributes id="nodes-3-b"> <nvpair name="b" value="B" /> </instance_attributes> </node> """) self.cib = etree.fromstring(""" <cib> <configuration> <nodes>{0}{1}{2}</nodes> </configuration> </cib> """.format(*[ etree_to_str(el) for el in [self.node1, self.node2, self.node3] ])) self.state = "node state list"
def test_returns_cib_from_cib_data(self): cib_filename = "cib-empty.xml" (self.config #Value of cib_data is unimportant here. See details in sibling test. .env.set_cib_data("whatever").runner.cib.load(filename=cib_filename)) assert_xml_equal(etree_to_str(self.env_assist.get_env().get_cib()), open(rc(cib_filename)).read())
def cib_resources(cib_resources_xml, cib_base_file=None): cib_xml = open(rc(cib_base_file or "cib-empty.xml")).read() cib = etree.fromstring(cib_xml) resources_section = cib.find(".//resources") for child in etree.fromstring(cib_resources_xml): resources_section.append(child) return etree_to_str(cib)
def test_with_type(self): node._create_node(self.nodes, "id-test", "name-test", "type-test") assert_xml_equal( """ <nodes> <node id="id-test" uname="name-test" type="type-test" /> </nodes> """, etree_to_str(self.nodes))
def test_append_new_nvpair_to_given_element(self): nvset_element = etree.fromstring('<nvset id="a"/>') nvpair._append_new_nvpair(nvset_element, "b", "c") assert_xml_equal( etree_to_str(nvset_element), """ <nvset id="a"> <nvpair id="a-b" name="b" value="c"></nvpair> </nvset> """)
def test_remove(self): nvpair.set_nvpair_in_nvset(self.nvset, "attr2", "") assert_xml_equal( """ <nvset id="nvset"> <nvpair id="nvset-attr" name="attr" value="1"/> <notnvpair id="nvset-test" name="test" value="0"/> </nvset> """, etree_to_str(self.nvset))
def test_with_type(self): node._create_node(self.nodes, "id-test", "name-test", "type-test") assert_xml_equal( """ <nodes> <node id="id-test" uname="name-test" type="type-test" /> </nodes> """, etree_to_str(self.nodes) )
def test_remove_not_existing(self): nvpair.set_nvpair_in_nvset(self.nvset, "attr3", "", self.id_provider) assert_xml_equal( """ <nvset id="nvset"> <nvpair id="nvset-attr" name="attr" value="1"/> <nvpair id="nvset-attr2" name="attr2" value="2"/> <notnvpair id="nvset-test" name="test" value="0"/> </nvset> """, etree_to_str(self.nvset))
def _find_in(cib_tree, element_xpath): element = cib_tree.find(element_xpath) if element is None: raise AssertionError( "Cannot find '{0}' in given cib:\n{1}".format( element_xpath, etree_to_str(cib_tree) ) ) return element
def test_empty_value_has_no_effect(self): nvpair.arrange_first_nvset("nvset", self.root, {}) assert_xml_equal( """ <nvset id="nvset"> <nvpair id="nvset-attr" name="attr" value="1"/> <nvpair id="nvset-attr2" name="attr2" value="2"/> <notnvpair id="nvset-test" name="test" value="0"/> </nvset> """, etree_to_str(self.nvset))
def test_new_last(self): lib.get_sub_element(self.root, "new_element", "new_id", None) assert_xml_equal( """ <root> <sub_element/> <new_element id="new_id"/> </root> """, etree_to_str(self.root) )
def fixture_wait_and_get_state_calls(state_resource_xml): crm_mon = etree.fromstring(open(rc("crm_mon.minimal.xml")).read()) crm_mon.append(etree.fromstring(state_resource_xml)) return [ Call("crm_resource --wait --timeout=10"), Call( "crm_mon --one-shot --as-xml --inactive", etree_to_str(crm_mon), ), ]
def test_with_id_provider(self): nvset_element = etree.fromstring('<nvset id="a"/>') provider = IdProvider(nvset_element) provider.book_ids("a-b") nvpair._append_new_nvpair(nvset_element, "b", "c", provider) assert_xml_equal( etree_to_str(nvset_element), """ <nvset id="a"> <nvpair id="a-b-1" name="b" value="c"></nvpair> </nvset> """)
def test_empty_value_has_no_effect(self): xml = """ <instance_attributes id="iattrs"> <nvpair id="1" name="a" value="b"/> <nvpair id="2" name="c" value="d"/> <nvpair id="3" name="e" value="f"/> </instance_attributes> """ nvset_element = etree.fromstring(xml) nvpair.update_nvset(nvset_element, {}) assert_xml_equal(xml, etree_to_str(nvset_element))
def test_node_pattern(self): lib._append_level_element(self.tree, "2", TARGET_TYPE_REGEXP, "node-\d+", ["d1", "d2"]) assert_xml_equal( """ <fencing-topology> <fencing-level id="fl-node-d-2" devices="d1,d2" index="2" target-pattern="node-\d+" /> </fencing-topology> """, etree_to_str(self.tree))
def test_node_name(self): lib._append_level_element(self.tree, 1, TARGET_TYPE_NODE, "node1", ["d1"]) assert_xml_equal( """ <fencing-topology> <fencing-level id="fl-node1-1" devices="d1" index="1" target="node1" /> </fencing-topology> """, etree_to_str(self.tree))
def test_node_name(self): lib._append_level_element( self.tree, 1, TARGET_TYPE_NODE, "node1", ["d1"] ) assert_xml_equal( """ <fencing-topology> <fencing-level id="fl-node1-1" devices="d1" index="1" target="node1" /> </fencing-topology> """, etree_to_str(self.tree) )
def test_node_pattern(self): lib._append_level_element( self.tree, "2", TARGET_TYPE_REGEXP, "node-\d+", ["d1", "d2"] ) assert_xml_equal( """ <fencing-topology> <fencing-level id="fl-node-d-2" devices="d1,d2" index="2" target-pattern="node-\d+" /> </fencing-topology> """, etree_to_str(self.tree) )
def test_empty_node(self, mock_get_node): mock_get_node.return_value = self.node1 node.update_node_instance_attrs( self.cib, "rh73-node1", {"x": "X"}, self.state ) assert_xml_equal( etree_to_str(self.node1), """ <node id="1" uname="rh73-node1"> <instance_attributes id="nodes-1"> <nvpair id="nodes-1-x" name="x" value="X" /> </instance_attributes> </node> """ )
def test_node_attribute(self): lib._append_level_element( self.tree, 3, TARGET_TYPE_ATTRIBUTE, ("name%@x", "val%@x"), ["d1"], ) assert_xml_equal( """ <fencing-topology> <fencing-level id="fl-namex-3" devices="d1" index="3" target-attribute="name%@x" target-value="val%@x" /> </fencing-topology> """, etree_to_str(self.tree) )
def test_exisitng_attrs(self, mock_get_node): mock_get_node.return_value = self.node2 node.update_node_instance_attrs( self.cib, "rh73-node2", {"a": "", "b": "b", "x": "X"}, self.state ) assert_xml_equal( etree_to_str(self.node2), """ <node id="2" uname="rh73-node2"> <instance_attributes id="nodes-2"> <nvpair name="b" value="b" /> <nvpair name="c" value="C" /> <nvpair id="nodes-2-x" name="x" value="X" /> </instance_attributes> </node> """ )
def test_multiple_attrs_sets(self, mock_get_node): mock_get_node.return_value = self.node3 node.update_node_instance_attrs( self.cib, "rh73-node3", {"x": "X"}, self.state ) assert_xml_equal( etree_to_str(self.node3), """ <node id="3" uname="rh73-node3" > <instance_attributes id="nodes-3-a"> <nvpair name="a" value="A" /> <nvpair id="nodes-3-a-x" name="x" value="X" /> </instance_attributes> <instance_attributes id="nodes-3-b"> <nvpair name="b" value="B" /> </instance_attributes> </node> """ )
def test_success(self): lib.remove_device_from_all_levels(self.tree, "d3") assert_xml_equal( """ <fencing-topology> <fencing-level id="fl1" index="1" devices="d1,d2" target="nodeA" /> <fencing-level id="fl3" index="1" devices="d2,d1" target="nodeB" /> <fencing-level id="fl5" index="1" devices="d4" target-pattern="node\d+" /> <fencing-level id="fl6" index="2" devices="d1" target-pattern="node\d+" /> <fencing-level id="fl7" index="3" devices="d4" target-attribute="fencing" target-value="improved" /> <fencing-level id="fl8" index="4" devices="d5" target-attribute="fencing" target-value="improved" /> <fencing-level id="fl9" index="3" devices="dR" target-pattern="node-R.*" /> <fencing-level id="fl10" index="4" devices="dR-special" target-attribute="fencing" target-value="remote-special" /> </fencing-topology> """, etree_to_str(self.tree) )
def test_success(self): lib.remove_all_levels(self.tree) assert_xml_equal( "<fencing-topology />", etree_to_str(self.tree) )
def test_no_such_device(self): original_xml = etree_to_str(self.tree) lib.remove_device_from_all_levels(self.tree, "dX") assert_xml_equal(original_xml, etree_to_str(self.tree))
def test_node_already_exists(self): assert_xml_equal( etree_to_str(node._ensure_node_exists(self.nodes, "name-test1")), etree_to_str(self.node1) )
def test_found(self): assert_xml_equal( etree_to_str(node._get_node_by_uname(self.nodes, "name-test1")), """<node id="id-test1" uname="name-test1" />""" )