Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package crmsh for openSUSE:Factory checked 
in at 2021-12-16 02:00:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/crmsh (Old)
 and      /work/SRC/openSUSE:Factory/.crmsh.new.2520 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "crmsh"

Thu Dec 16 02:00:55 2021 rev:231 rq:940756 version:4.3.1+20211215.85834218

Changes:
--------
--- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes      2021-12-10 
21:52:55.050906693 +0100
+++ /work/SRC/openSUSE:Factory/.crmsh.new.2520/crmsh.changes    2021-12-16 
02:01:28.083652347 +0100
@@ -1,0 +2,7 @@
+Wed Dec 15 15:09:05 UTC 2021 - xli...@suse.com
+
+- Update to version 4.3.1+20211215.85834218:
+  * Dev: unittest: Adjust unit test based on previous changes
+  * Dev: xmlutil: Add class CrmMonXmlParser to parse xml output of crm_mon
+
+-------------------------------------------------------------------

Old:
----
  crmsh-4.3.1+20211210.a149de51.tar.bz2

New:
----
  crmsh-4.3.1+20211215.85834218.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ crmsh.spec ++++++
--- /var/tmp/diff_new_pack.aF3jY1/_old  2021-12-16 02:01:28.815652791 +0100
+++ /var/tmp/diff_new_pack.aF3jY1/_new  2021-12-16 02:01:28.831652801 +0100
@@ -36,7 +36,7 @@
 Summary:        High Availability cluster command-line interface
 License:        GPL-2.0-or-later
 Group:          %{pkg_group}
-Version:        4.3.1+20211210.a149de51
+Version:        4.3.1+20211215.85834218
 Release:        0
 URL:            http://crmsh.github.io
 Source0:        %{name}-%{version}.tar.bz2

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.aF3jY1/_old  2021-12-16 02:01:28.903652844 +0100
+++ /var/tmp/diff_new_pack.aF3jY1/_new  2021-12-16 02:01:28.903652844 +0100
@@ -9,7 +9,7 @@
 </service>
 <service name="tar_scm">
   <param name="url">https://github.com/ClusterLabs/crmsh.git</param>
-  <param 
name="changesrevision">9cdc6cb5447970fa20263d9edcc1234567a55303</param>
+  <param 
name="changesrevision">99c28d735cde5888794c4ef218a527c3e65ff118</param>
 </service>
 </servicedata>
 (No newline at EOF)

++++++ crmsh-4.3.1+20211210.a149de51.tar.bz2 -> 
crmsh-4.3.1+20211215.85834218.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-4.3.1+20211210.a149de51/crmsh/bootstrap.py 
new/crmsh-4.3.1+20211215.85834218/crmsh/bootstrap.py
--- old/crmsh-4.3.1+20211210.a149de51/crmsh/bootstrap.py        2021-12-10 
03:35:17.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/crmsh/bootstrap.py        2021-12-15 
15:55:49.000000000 +0100
@@ -353,12 +353,7 @@
     """
     with logger_utils.status_long(message):
         while True:
-            # -r here to display inactive resources
-            # -R here to display individual clone instances
-            _rc, out, err = utils.get_stdout_stderr("crm_mon -1rR")
-            # Make sure clone instances also started(no Stopped instance)
-            if re.search(r"{}\s+.*:\s+Started\s".format(resource), out) and \
-                    not 
re.search(r"{}\s+.*:\s+(Stopped|Starting)".format(resource), out):
+            if xmlutil.CrmMonXmlParser.is_resource_started(resource):
                 break
             status_progress()
             sleep(1)
@@ -367,8 +362,7 @@
 def wait_for_cluster():
     with logger_utils.status_long("Waiting for cluster"):
         while True:
-            _rc, out, _err = utils.get_stdout_stderr("crm_mon -1")
-            if is_online(out):
+            if is_online():
                 break
             status_progress()
             sleep(2)
@@ -387,12 +381,12 @@
     return peer_node
 
 
-def is_online(crm_mon_txt):
+def is_online():
     """
     Check whether local node is online
     Besides that, in join process, check whether init node is online
     """
-    if not re.search("Online: .* {} ".format(utils.this_node()), crm_mon_txt):
+    if not xmlutil.CrmMonXmlParser.is_node_online(utils.this_node()):
         return False
 
     # if peer_node is None, this is in the init process
@@ -402,7 +396,7 @@
     # In join process
     # If the joining node is already online but can't find the init node
     # The communication IP maybe mis-configured
-    if not re.search("Online: .* {} ".format(peer_node), crm_mon_txt):
+    if not xmlutil.CrmMonXmlParser.is_node_online(peer_node):
         shutil.copy(COROSYNC_CONF_ORIG, corosync.conf())
         csync2_update(corosync.conf())
         utils.stop_service("corosync")
@@ -1270,7 +1264,7 @@
     if utils.calculate_quorate_status(expected_votes, actual_votes) and not 
diskless_sbd:
         # safe to use reload
         return QdevicePolicy.QDEVICE_RELOAD
-    elif utils.has_resource_running():
+    elif xmlutil.CrmMonXmlParser.is_any_resource_running():
         # will lose quorum, and with RA running
         # no reload, no restart cluster service
         # just leave a warning
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-4.3.1+20211210.a149de51/crmsh/cibconfig.py 
new/crmsh-4.3.1+20211215.85834218/crmsh/cibconfig.py
--- old/crmsh-4.3.1+20211210.a149de51/crmsh/cibconfig.py        2021-12-10 
03:35:17.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/crmsh/cibconfig.py        2021-12-15 
15:55:49.000000000 +0100
@@ -41,7 +41,7 @@
 from .xmlutil import merge_attributes, is_cib_element, sanity_check_meta
 from .xmlutil import is_simpleconstraint, is_template, rmnode, is_defaults, 
is_live_cib
 from .xmlutil import get_rsc_operations, delete_rscref, xml_equals, 
lookup_node, RscState
-from .xmlutil import cibtext2elem, is_related, check_id_ref, xml_tostring
+from .xmlutil import text2elem, is_related, check_id_ref, xml_tostring
 from .xmlutil import sanitize_cib_for_patching
 from .cliformat import get_score, nvpairs2list, abs_pos_score, 
cli_acl_roleref, nvpair_format
 from .cliformat import cli_nvpair, cli_acl_rule, rsc_set_constraint, get_kind, 
head_id_format
@@ -623,7 +623,7 @@
         try:
             cib_elem = etree.fromstring(s)
         except etree.ParseError as msg:
-            logger_utils.cib_parse_err(msg, s)
+            logger_utils.text_xml_parse_err(msg, s)
             return False
         sanitize_cib(cib_elem)
         if not show_unrecognized_elems(cib_elem):
@@ -2749,7 +2749,7 @@
         if cib is None:
             cib = read_cib(cibdump2elem)
         elif isinstance(cib, str):
-            cib = cibtext2elem(cib)
+            cib = text2elem(cib)
         if not self._import_cib(cib):
             return False
         if cibadmin_can_patch():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-4.3.1+20211210.a149de51/crmsh/constants.py 
new/crmsh-4.3.1+20211215.85834218/crmsh/constants.py
--- old/crmsh-4.3.1+20211210.a149de51/crmsh/constants.py        2021-12-10 
03:35:17.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/crmsh/constants.py        2021-12-15 
15:55:49.000000000 +0100
@@ -511,7 +511,9 @@
 XML_NODE_QUERY_STANDBY_PATH = 
"//nodes/node[@id='{node_id}']/instance_attributes/nvpair[@name='standby']"
 XML_STATUS_QUERY_STANDBY_PATH = 
"//status/node_state[@id='{node_id}']/transient_attributes/instance_attributes/nvpair[@name='standby']"
 CRM_MON_ONE_SHOT = "crm_mon -1"
+CRM_MON_XML_OUTPUT= "crm_mon --output-as=xml"
 STONITH_TIMEOUT_DEFAULT = 60
 PCMK_DELAY_MAX = 30
 DLM_CONTROLD_RA = "ocf::pacemaker:controld"
+LVMLOCKD_RA = "ocf::heartbeat:lvmlockd"
 # vim:ts=4:sw=4:et:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-4.3.1+20211210.a149de51/crmsh/log.py 
new/crmsh-4.3.1+20211215.85834218/crmsh/log.py
--- old/crmsh-4.3.1+20211210.a149de51/crmsh/log.py      2021-12-10 
03:35:17.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/crmsh/log.py      2021-12-15 
15:55:49.000000000 +0100
@@ -370,7 +370,7 @@
     def empty_cib_err(self):
         self.logger.error("No CIB!")
 
-    def cib_parse_err(self, msg, s):
+    def text_xml_parse_err(self, msg, s):
         self.logger.error(msg)
         self.logger.info("offending string: %s", s)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-4.3.1+20211210.a149de51/crmsh/ocfs2.py 
new/crmsh-4.3.1+20211215.85834218/crmsh/ocfs2.py
--- old/crmsh-4.3.1+20211210.a149de51/crmsh/ocfs2.py    2021-12-10 
03:35:17.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/crmsh/ocfs2.py    2021-12-15 
15:55:49.000000000 +0100
@@ -5,6 +5,8 @@
 from . import ra
 from . import corosync
 from . import log
+from . import xmlutil
+from . import constants
 
 
 logger = log.setup_logger(__name__)
@@ -330,7 +332,7 @@
         if not target:
             return
         with logger_utils.status_long("Verify OCFS2 environment"):
-            use_cluster_lvm2 = 
utils.has_resource_configured("ocf::heartbeat:lvmlockd", peer)
+            use_cluster_lvm2 = 
xmlutil.CrmMonXmlParser.is_resource_configured(constants.LVMLOCKD_RA, peer)
             self._verify_packages(use_cluster_lvm2)
             if utils.is_dev_a_plain_raw_disk_or_partition(target, peer):
                 utils.compare_uuid_with_peer_dev([target], peer)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-4.3.1+20211210.a149de51/crmsh/sbd.py 
new/crmsh-4.3.1+20211215.85834218/crmsh/sbd.py
--- old/crmsh-4.3.1+20211210.a149de51/crmsh/sbd.py      2021-12-10 
03:35:17.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/crmsh/sbd.py      2021-12-15 
15:55:49.000000000 +0100
@@ -7,6 +7,7 @@
 from . import log
 from . import constants
 from . import corosync
+from . import xmlutil
 
 
 logger = log.setup_logger(__name__)
@@ -220,7 +221,7 @@
         """
         # TODO this function should be outside of sbd.py, to adjust any fence 
device
 
-        if not utils.has_resource_configured(SBDManager.SBD_RA):
+        if not 
xmlutil.CrmMonXmlParser.is_resource_configured(SBDManager.SBD_RA):
             return
 
         if self.two_node_without_qdevice:
@@ -433,7 +434,7 @@
         """
         Try to configure sbd resource, restart cluster on needed
         """
-        if not utils.has_resource_running():
+        if not xmlutil.CrmMonXmlParser.is_any_resource_running():
             logger.info("Restarting cluster service")
             utils.cluster_run_cmd("crm cluster restart")
             bootstrap.wait_for_cluster()
@@ -500,7 +501,7 @@
         """
         if not utils.package_is_installed("sbd") or \
                 not utils.service_is_enabled("sbd.service") or \
-                utils.has_resource_configured(self.SBD_RA):
+                xmlutil.CrmMonXmlParser.is_resource_configured(self.SBD_RA):
             return
 
         # disk-based sbd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-4.3.1+20211210.a149de51/crmsh/utils.py 
new/crmsh-4.3.1+20211215.85834218/crmsh/utils.py
--- old/crmsh-4.3.1+20211210.a149de51/crmsh/utils.py    2021-12-10 
03:35:17.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/crmsh/utils.py    2021-12-15 
15:55:49.000000000 +0100
@@ -2676,14 +2676,14 @@
     return int(actual_votes)/int(expected_votes) > 0.5
 
 
-def get_stdout_or_raise_error(cmd, remote=None, success_val_list=[0]):
+def get_stdout_or_raise_error(cmd, remote=None, success_val_list=[0], 
no_raise=False):
     """
     Common function to get stdout from cmd or raise exception
     """
     if remote:
         cmd = "ssh {} root@{} \"{}\"".format(SSH_OPTION, remote, cmd)
     rc, out, err = get_stdout_stderr(cmd, no_reg=True)
-    if rc not in success_val_list:
+    if rc not in success_val_list and not no_raise:
         raise ValueError("Failed to run \"{}\": {}".format(cmd, err))
     return out
 
@@ -2696,28 +2696,6 @@
     return dict(re.findall("(Expected|Total) votes:\s+(\d+)", out))
 
 
-def has_resource_running(ra_type=None):
-    """
-    Check if any RA is running
-    """
-    cmd = "crm_mon -1"
-    if ra_type:
-        cmd = "crm_mon -1rR"
-    out = get_stdout_or_raise_error(cmd)
-    if ra_type:
-        return re.search("{}.*Started".format(ra_type), out) is not None
-    else:
-        return re.search("No active resources", out) is None
-
-
-def has_resource_configured(ra_type, peer=None):
-    """
-    Check if the RA configured
-    """
-    out = get_stdout_or_raise_error("crm_mon -1rR", remote=peer)
-    return re.search(ra_type, out) is not None
-
-
 def check_all_nodes_reachable():
     """
     Check if all cluster nodes are reachable
@@ -2965,14 +2943,16 @@
     """
     Check if dlm ra controld is running
     """
-    return has_resource_running(constants.DLM_CONTROLD_RA)
+    from . import xmlutil
+    return 
xmlutil.CrmMonXmlParser.is_resource_started(constants.DLM_CONTROLD_RA)
 
 
 def is_dlm_configured():
     """
     Check if dlm configured
     """
-    return has_resource_configured(constants.DLM_CONTROLD_RA)
+    from . import xmlutil
+    return 
xmlutil.CrmMonXmlParser.is_resource_configured(constants.DLM_CONTROLD_RA)
 
 
 def is_quorate():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-4.3.1+20211210.a149de51/crmsh/xmlutil.py 
new/crmsh-4.3.1+20211215.85834218/crmsh/xmlutil.py
--- old/crmsh-4.3.1+20211210.a149de51/crmsh/xmlutil.py  2021-12-10 
03:35:17.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/crmsh/xmlutil.py  2021-12-15 
15:55:49.000000000 +0100
@@ -15,7 +15,7 @@
 from . import constants
 from . import userdir
 from .utils import add_sudo, str2file, str2tmp, get_boolean
-from .utils import get_stdout, stdout2list, crm_msec, crm_time_cmp
+from .utils import get_stdout, get_stdout_or_raise_error, stdout2list, 
crm_msec, crm_time_cmp
 from .utils import olist, get_cib_in_use, get_tempdir, to_ascii
 from . import log
 
@@ -101,15 +101,15 @@
     return None
 
 
-def cibtext2elem(cibtext):
+def text2elem(text):
     """
     Convert a text format CIB to
     an XML tree.
     """
     try:
-        return etree.fromstring(cibtext)
+        return etree.fromstring(text)
     except Exception as err:
-        logger_utils.cib_parse_err(err, cibtext)
+        logger_utils.text_xml_parse_err(err, text)
         return None
 
 
@@ -120,7 +120,7 @@
         cmd = cib_dump
     rc, outp, errp = sudocall(cmd)
     if rc == 0:
-        return cibtext2elem(outp)
+        return text2elem(outp)
     elif rc != constants.cib_no_section_rc:
         logger.error("running %s: %s", cmd, errp)
     return None
@@ -1482,4 +1482,68 @@
     return e
 
 
+class CrmMonXmlParser(object):
+    """
+    Class to parse xml output of crm_mon
+    """
+    def __init__(self, peer=None):
+        """
+        Init function
+        when peer set, parse peer node's results
+        """
+        self.xml_elem = None
+        self.peer = peer
+
+    def _load(self):
+        """
+        Load xml output of crm_mon
+        """
+        output = get_stdout_or_raise_error(constants.CRM_MON_XML_OUTPUT, 
remote=self.peer, no_raise=True)
+        self.xml_elem = text2elem(output)
+
+    @classmethod
+    def is_node_online(cls, node):
+        """
+        Check if node online
+        """
+        cls_inst = cls()
+        cls_inst._load()
+        elem_list = cls_inst.xml_elem.xpath('//node[@name="{}" and 
@online="true"]'.format(node))
+        return len(elem_list) != 0
+
+    @classmethod
+    def is_resource_configured(cls, ra_type, peer=None):
+        """
+        Check if the RA configured
+        """
+        cls_inst = cls(peer=peer)
+        cls_inst._load()
+        elem_list = 
cls_inst.xml_elem.xpath('//resource[@resource_agent="{}"]'.format(ra_type))
+        return len(elem_list) != 0
+
+    @classmethod
+    def is_any_resource_running(cls, peer=None):
+        """
+        Check if any RA is running
+        """
+        cls_inst = cls(peer=peer)
+        cls_inst._load()
+        elem_list = cls_inst.xml_elem.xpath('//resource[@active="true"]')
+        return len(elem_list) != 0
+
+    @classmethod
+    def is_resource_started(cls, ra, peer=None):
+        """
+        Check if the RA started(in all clone instances if configured as clone)
+
+        @ra could be resource id or resource type
+        """
+        cls_inst = cls(peer=peer)
+        cls_inst._load()
+        elem_list = cls_inst.xml_elem.xpath('//resource[(@id="{ra}" or 
@resource_agent="{ra}") and @active="true"]'.format(ra=ra))
+        # Stopped or not exist
+        if not elem_list:
+            return False
+        # Starting will return False
+        return all([True if elem.get('role') == 'Started' else False for elem 
in elem_list])
 # vim:ts=4:sw=4:et:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-4.3.1+20211210.a149de51/test/unittests/test_bootstrap.py 
new/crmsh-4.3.1+20211215.85834218/test/unittests/test_bootstrap.py
--- old/crmsh-4.3.1+20211210.a149de51/test/unittests/test_bootstrap.py  
2021-12-10 03:35:17.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/test/unittests/test_bootstrap.py  
2021-12-15 15:55:49.000000000 +0100
@@ -608,31 +608,31 @@
         mock_error.assert_called_once_with("error")
 
     @mock.patch('crmsh.utils.this_node')
-    @mock.patch('re.search')
     @mock.patch('crmsh.bootstrap.get_cluster_node_hostname')
-    def test_is_online_local_offline(self, mock_get_peer, mock_search, 
mock_this_node):
+    @mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_node_online')
+    def test_is_online_local_offline(self, mock_is_online, mock_get_peer, 
mock_this_node):
         mock_this_node.return_value = "node1"
-        mock_search.return_value = None
+        mock_is_online.return_value = False
 
-        assert bootstrap.is_online("text") is False
+        assert bootstrap.is_online() is False
 
         mock_this_node.assert_called_once_with()
         mock_get_peer.assert_not_called()
-        mock_search.assert_called_once_with("Online: .* node1 ", "text")
+        mock_is_online.assert_called_once_with("node1")
 
     @mock.patch('crmsh.utils.this_node')
-    @mock.patch('re.search')
     @mock.patch('crmsh.bootstrap.get_cluster_node_hostname')
-    def test_is_online_on_init_node(self, mock_get_peer, mock_search, 
mock_this_node):
-        mock_search.return_value = mock.Mock()
+    @mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_node_online')
+    def test_is_online_on_init_node(self, mock_is_online, mock_get_peer, 
mock_this_node):
         mock_this_node.return_value = "node1"
         mock_get_peer.return_value = None
+        mock_is_online.return_value = True
 
-        assert bootstrap.is_online("text") is True
+        assert bootstrap.is_online() is True
 
         mock_this_node.assert_called_once_with()
         mock_get_peer.assert_called_once_with()
-        mock_search.assert_called_once_with("Online: .* node1 ", "text")
+        mock_is_online.assert_called_once_with("node1")
 
     @mock.patch('crmsh.utils.fatal')
     @mock.patch('crmsh.utils.stop_service')
@@ -640,25 +640,21 @@
     @mock.patch('crmsh.corosync.conf')
     @mock.patch('shutil.copy')
     @mock.patch('crmsh.utils.this_node')
-    @mock.patch('re.search')
     @mock.patch('crmsh.bootstrap.get_cluster_node_hostname')
-    def test_is_online_peer_offline(self, mock_get_peer, mock_search, 
mock_this_node,
+    @mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_node_online')
+    def test_is_online_peer_offline(self, mock_is_online, mock_get_peer, 
mock_this_node,
             mock_copy, mock_corosync_conf, mock_csync2, mock_stop_service, 
mock_error):
+        mock_is_online.side_effect = [True, False]
         bootstrap.COROSYNC_CONF_ORIG = "/tmp/crmsh_tmpfile"
-        mock_search.side_effect = [ mock.Mock(), None ]
         mock_this_node.return_value = "node2"
         mock_get_peer.return_value = "node1"
         mock_corosync_conf.side_effect = [ "/etc/corosync/corosync.conf",
                 "/etc/corosync/corosync.conf"]
 
-        bootstrap.is_online("text")
+        bootstrap.is_online()
 
         mock_this_node.assert_called_once_with()
         mock_get_peer.assert_called_once_with()
-        mock_search.assert_has_calls([
-            mock.call("Online: .* node2 ", "text"),
-            mock.call("Online: .* node1 ", "text")
-            ])
         mock_corosync_conf.assert_has_calls([
             mock.call(),
             mock.call()
@@ -674,22 +670,18 @@
     @mock.patch('crmsh.corosync.conf')
     @mock.patch('shutil.copy')
     @mock.patch('crmsh.utils.this_node')
-    @mock.patch('re.search')
     @mock.patch('crmsh.bootstrap.get_cluster_node_hostname')
-    def test_is_online_both_online(self, mock_get_peer, mock_search, 
mock_this_node,
+    @mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_node_online')
+    def test_is_online_both_online(self, mock_is_online, mock_get_peer, 
mock_this_node,
             mock_copy, mock_corosync_conf, mock_csync2, mock_stop_service, 
mock_error):
-        mock_search.side_effect = [ mock.Mock(), mock.Mock() ]
+        mock_is_online.side_effect = [True, True]
         mock_this_node.return_value = "node2"
         mock_get_peer.return_value = "node1"
 
-        assert bootstrap.is_online("text") is True
+        assert bootstrap.is_online() is True
 
         mock_this_node.assert_called_once_with()
         mock_get_peer.assert_called_once_with()
-        mock_search.assert_has_calls([
-            mock.call("Online: .* node2 ", "text"),
-            mock.call("Online: .* node1 ", "text")
-            ])
         mock_corosync_conf.assert_not_called()
         mock_copy.assert_not_called()
         mock_csync2.assert_not_called()
@@ -1075,7 +1067,7 @@
         mock_get_dict.assert_called_once_with()
         mock_quorate.assert_called_once_with(3, 2)
 
-    @mock.patch('crmsh.utils.has_resource_running')
+    @mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_any_resource_running')
     @mock.patch('crmsh.utils.calculate_quorate_status')
     @mock.patch('crmsh.utils.get_quorum_votes_dict')
     def test_evaluate_qdevice_quorum_effect_reload(self, mock_get_dict, 
mock_quorate, mock_ra_running):
@@ -1088,7 +1080,7 @@
         mock_quorate.assert_called_once_with(2, 1)
         mock_ra_running.assert_called_once_with()
 
-    @mock.patch('crmsh.utils.has_resource_running')
+    @mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_any_resource_running')
     @mock.patch('crmsh.utils.calculate_quorate_status')
     @mock.patch('crmsh.utils.get_quorum_votes_dict')
     def test_evaluate_qdevice_quorum_effect(self, mock_get_dict, mock_quorate, 
mock_ra_running):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-4.3.1+20211210.a149de51/test/unittests/test_ocfs2.py 
new/crmsh-4.3.1+20211215.85834218/test/unittests/test_ocfs2.py
--- old/crmsh-4.3.1+20211210.a149de51/test/unittests/test_ocfs2.py      
2021-12-10 03:35:17.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/test/unittests/test_ocfs2.py      
2021-12-15 15:55:49.000000000 +0100
@@ -4,7 +4,7 @@
     from unittest import mock
 except ImportError:
     import mock
-from crmsh import ocfs2, utils, ra
+from crmsh import ocfs2, utils, ra, constants
 
 logging.basicConfig(level=logging.INFO)
 
@@ -450,7 +450,7 @@
     @mock.patch('crmsh.utils.compare_uuid_with_peer_dev')
     @mock.patch('crmsh.utils.is_dev_a_plain_raw_disk_or_partition')
     @mock.patch('crmsh.ocfs2.OCFS2Manager._verify_packages')
-    @mock.patch('crmsh.utils.has_resource_configured')
+    @mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_resource_configured')
     @mock.patch('crmsh.log.LoggerUtils.status_long')
     @mock.patch('crmsh.ocfs2.OCFS2Manager._find_target_on_join')
     def test_join_ocfs2(self, mock_find, mock_long, mock_configured, 
mock_verify_packages, mock_is_mapper, mock_compare):
@@ -459,7 +459,7 @@
         mock_is_mapper.return_value = True
         self.ocfs2_inst3.join_ocfs2("node1")
         mock_find.assert_called_once_with("node1")
-        mock_configured.assert_called_once_with("ocf::heartbeat:lvmlockd", 
"node1")
+        mock_configured.assert_called_once_with(constants.LVMLOCKD_RA, "node1")
         mock_verify_packages.assert_called_once_with(False)
         mock_is_mapper.assert_called_once_with("/dev/sda2", "node1")
         mock_compare.assert_called_once_with(["/dev/sda2"], "node1")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-4.3.1+20211210.a149de51/test/unittests/test_sbd.py 
new/crmsh-4.3.1+20211215.85834218/test/unittests/test_sbd.py
--- old/crmsh-4.3.1+20211210.a149de51/test/unittests/test_sbd.py        
2021-12-10 03:35:17.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/test/unittests/test_sbd.py        
2021-12-15 15:55:49.000000000 +0100
@@ -608,7 +608,7 @@
     @mock.patch('crmsh.bootstrap.wait_for_cluster')
     @mock.patch('crmsh.utils.cluster_run_cmd')
     @mock.patch('logging.Logger.info')
-    @mock.patch('crmsh.utils.has_resource_running')
+    @mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_any_resource_running')
     def test_restart_cluster_on_needed_no_ra_running(self, mock_ra_running, 
mock_status, mock_cluster_run, mock_wait, mock_config_sbd_ra):
         mock_ra_running.return_value = False
         self.sbd_inst._restart_cluster_and_configure_sbd_ra()
@@ -619,7 +619,7 @@
 
     @mock.patch('crmsh.sbd.SBDTimeout.get_stonith_timeout')
     @mock.patch('logging.Logger.warning')
-    @mock.patch('crmsh.utils.has_resource_running')
+    @mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_any_resource_running')
     def test_restart_cluster_on_needed_diskless(self, mock_ra_running, 
mock_warn, mock_get_timeout):
         mock_ra_running.return_value = True
         mock_get_timeout.return_value = 60
@@ -632,7 +632,7 @@
 
     @mock.patch('crmsh.sbd.SBDManager.configure_sbd_resource_and_properties')
     @mock.patch('logging.Logger.warning')
-    @mock.patch('crmsh.utils.has_resource_running')
+    @mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_any_resource_running')
     def test_restart_cluster_on_needed(self, mock_ra_running, mock_warn, 
mock_config_sbd_ra):
         mock_ra_running.return_value = True
         self.sbd_inst._restart_cluster_and_configure_sbd_ra()
@@ -666,7 +666,7 @@
     
@mock.patch('crmsh.sbd.SBDTimeout.adjust_sbd_timeout_related_cluster_configuration')
     @mock.patch('crmsh.utils.set_property')
     @mock.patch('crmsh.utils.get_stdout_or_raise_error')
-    @mock.patch('crmsh.utils.has_resource_configured')
+    @mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_resource_configured')
     @mock.patch('crmsh.utils.service_is_enabled')
     @mock.patch('crmsh.utils.package_is_installed')
     def test_configure_sbd_resource_and_properties(self, mock_package, 
mock_enabled, mock_configured, mock_run, mock_set_property, sbd_adjust):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-4.3.1+20211210.a149de51/test/unittests/test_utils.py 
new/crmsh-4.3.1+20211215.85834218/test/unittests/test_utils.py
--- old/crmsh-4.3.1+20211210.a149de51/test/unittests/test_utils.py      
2021-12-10 03:35:17.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/test/unittests/test_utils.py      
2021-12-15 15:55:49.000000000 +0100
@@ -1223,35 +1223,11 @@
     mock_run.assert_called_once_with("corosync-quorumtool -s", remote=None, 
success_val_list=[0, 2])
 
 
-@mock.patch("crmsh.utils.get_stdout_or_raise_error")
-def test_has_resource_running(mock_run):
-    mock_run.return_value = """
-Node List:
-  * Online: [ 15sp2-1 ]
-
-Active Resources:
-  * No active resources
-    """
-    res = utils.has_resource_running()
-    assert res is False
-    mock_run.assert_called_once_with("crm_mon -1")
-
-
 def test_re_split_string():
     assert utils.re_split_string('[; ]', "/dev/sda1; /dev/sdb1 ; ") == 
["/dev/sda1", "/dev/sdb1"]
     assert utils.re_split_string('[; ]', "/dev/sda1 ") == ["/dev/sda1"]
 
 
-@mock.patch("crmsh.utils.get_stdout_or_raise_error")
-def test_has_resource_configured(mock_run):
-    mock_run.return_value = """
-primitive stonith-sbd stonith:external/sbd \
-        params pcmk_delay_max=30s
-    """
-    res = utils.has_resource_configured("stonith:external/sbd")
-    assert res is True
-
-
 @mock.patch('crmsh.utils.get_dev_info')
 def test_has_dev_partitioned(mock_get_dev_info):
     mock_get_dev_info.return_value = """
@@ -1525,11 +1501,11 @@
     mock_run.assert_called_once_with('dlm_tool set_config "key2=test"')
 
 
-@mock.patch('crmsh.utils.has_resource_configured')
+@mock.patch('crmsh.xmlutil.CrmMonXmlParser.is_resource_configured')
 def test_is_dlm_configured(mock_configured):
     mock_configured.return_value = True
     assert utils.is_dlm_configured() is True
-    mock_configured.assert_called_once_with("ocf::pacemaker:controld")
+    mock_configured.assert_called_once_with(constants.DLM_CONTROLD_RA)
 
 
 @mock.patch('crmsh.utils.get_stdout_or_raise_error')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-4.3.1+20211210.a149de51/test/unittests/test_xmlutil.py 
new/crmsh-4.3.1+20211215.85834218/test/unittests/test_xmlutil.py
--- old/crmsh-4.3.1+20211210.a149de51/test/unittests/test_xmlutil.py    
1970-01-01 01:00:00.000000000 +0100
+++ new/crmsh-4.3.1+20211215.85834218/test/unittests/test_xmlutil.py    
2021-12-15 15:55:49.000000000 +0100
@@ -0,0 +1,86 @@
+import unittest
+
+try:
+    from unittest import mock
+except ImportError:
+    import mock
+
+from crmsh import xmlutil, constants
+
+
+class TestCrmMonXmlParser(unittest.TestCase):
+    """
+    Unitary tests for crmsh.xmlutil.CrmMonXmlParser
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        """
+        Global setUp.
+        """
+
+    def setUp(self):
+        """
+        Test setUp.
+        """
+        self.parser_inst = xmlutil.CrmMonXmlParser()
+        self.nodes_xml = """
+  <nodes>
+    <node name="tbw-1" id="1084783148" online="true" standby="false" 
standby_onfail="false" maintenance="false" pending="false" unclean="false" 
shutdown="false" expected_up="true" is_dc="true" resources_running="3" 
type="member"/>
+    <node name="tbw-2" id="1084783312" online="true" standby="false" 
standby_onfail="false" maintenance="false" pending="false" unclean="false" 
shutdown="false" expected_up="true" is_dc="false" resources_running="2" 
type="member"/>
+  </nodes>
+        """
+        self.resources_xml = """
+      <resources>
+        <resource id="ocfs2-dlm" resource_agent="ocf::pacemaker:controld" 
role="Started" active="true" orphaned="false" blocked="false" managed="true" 
failed="false" failure_ignored="false" nodes_running_on="1">
+          <node name="tbw-2" id="1084783312" cached="true"/>
+        </resource>
+        <resource id="ocfs2-clusterfs" 
resource_agent="ocf::heartbeat:Filesystem" role="Started" active="true" 
orphaned="false" blocked="false" managed="true" failed="false" 
failure_ignored="false" nodes_running_on="1">
+          <node name="tbw-2" id="1084783312" cached="true"/>
+        </resource>
+      </resources>
+        """
+
+    def tearDown(self):
+        """
+        Test tearDown.
+        """
+
+    @classmethod
+    def tearDownClass(cls):
+        """
+        Global tearDown.
+        """
+
+    @mock.patch('crmsh.xmlutil.text2elem')
+    @mock.patch('crmsh.xmlutil.get_stdout_or_raise_error')
+    def test_load(self, mock_run, mock_text2elem):
+        mock_run.return_value = "data"
+        mock_text2elem.return_value = mock.Mock()
+        self.parser_inst._load()
+        mock_run.assert_called_once_with(constants.CRM_MON_XML_OUTPUT, 
remote=None, no_raise=True)
+        mock_text2elem.assert_called_once_with("data")
+
+    @mock.patch('crmsh.xmlutil.get_stdout_or_raise_error')
+    def test_is_node_online(self, mock_run):
+        mock_run.return_value = self.nodes_xml
+        assert xmlutil.CrmMonXmlParser.is_node_online("node1") is False
+        assert xmlutil.CrmMonXmlParser.is_node_online("tbw-2") is True
+
+    @mock.patch('crmsh.xmlutil.get_stdout_or_raise_error')
+    def test_is_resource_configured(self, mock_run):
+        mock_run.return_value = self.resources_xml
+        assert xmlutil.CrmMonXmlParser.is_resource_configured("test") is False
+        assert 
xmlutil.CrmMonXmlParser.is_resource_configured("ocf::heartbeat:Filesystem") is 
True
+
+    @mock.patch('crmsh.xmlutil.get_stdout_or_raise_error')
+    def test_is_any_resource_running(self, mock_run):
+        mock_run.return_value = self.resources_xml
+        assert xmlutil.CrmMonXmlParser.is_any_resource_running() is True
+
+    @mock.patch('crmsh.xmlutil.get_stdout_or_raise_error')
+    def test_is_resource_started(self, mock_run):
+        mock_run.return_value = self.resources_xml
+        assert xmlutil.CrmMonXmlParser.is_resource_started("test") is False
+        assert xmlutil.CrmMonXmlParser.is_resource_started("ocfs2-clusterfs") 
is True
+        assert 
xmlutil.CrmMonXmlParser.is_resource_started("ocf::pacemaker:controld") is True

Reply via email to