Hello community, here is the log from the commit of package crmsh for openSUSE:Factory checked in at 2019-12-16 15:20:21 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/crmsh (Old) and /work/SRC/openSUSE:Factory/.crmsh.new.4691 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "crmsh" Mon Dec 16 15:20:21 2019 rev:169 rq:757217 version:4.1.0+git.1576228931.ae559358 Changes: -------- --- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes 2019-12-10 22:42:33.409806142 +0100 +++ /work/SRC/openSUSE:Factory/.crmsh.new.4691/crmsh.changes 2019-12-16 15:20:28.531136492 +0100 @@ -1,0 +2,14 @@ +Fri Dec 13 09:33:44 UTC 2019 - xli...@suse.com + +- Update to version 4.1.0+git.1576228931.ae559358: + * Dev: bootstrap: support multi disk sbd configure + +------------------------------------------------------------------- +Wed Dec 11 07:05:30 UTC 2019 - xli...@suse.com + +- Update to version 4.1.0+git.1576047267.d87652bb: + * Dev: behave: functional test for resource failcount set subcommand + * Low: unittest: add ut for utils.get_nodeid_from_name + * Fix: ui_resource: set resource failcount correctly(bsc#1144241) + +------------------------------------------------------------------- Old: ---- crmsh-4.1.0+git.1575875711.41d65be4.tar.bz2 New: ---- crmsh-4.1.0+git.1576228931.ae559358.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ crmsh.spec ++++++ --- /var/tmp/diff_new_pack.e2UqJ2/_old 2019-12-16 15:20:29.819135955 +0100 +++ /var/tmp/diff_new_pack.e2UqJ2/_new 2019-12-16 15:20:29.827135952 +0100 @@ -36,7 +36,7 @@ Summary: High Availability cluster command-line interface License: GPL-2.0-or-later Group: %{pkg_group} -Version: 4.1.0+git.1575875711.41d65be4 +Version: 4.1.0+git.1576228931.ae559358 Release: 0 Url: http://crmsh.github.io Source0: %{name}-%{version}.tar.bz2 ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.e2UqJ2/_old 2019-12-16 15:20:29.887135926 +0100 +++ /var/tmp/diff_new_pack.e2UqJ2/_new 2019-12-16 15:20:29.887135926 +0100 @@ -5,4 +5,4 @@ <param name="url">https://github.com/liangxin1300/crmsh.git</param> <param name="changesrevision">d8dc51b4cb34964aa72e918999ebc7f03b48f3c9</param></service><service name="tar_scm"> <param name="url">https://github.com/ClusterLabs/crmsh.git</param> - <param name="changesrevision">000f2a79d35ac8d8642f7c93cf75b6d002f3c6e9</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">ae559358d1933de123c43a2f86d2d588810d8045</param></service></servicedata> \ No newline at end of file ++++++ crmsh-4.1.0+git.1575875711.41d65be4.tar.bz2 -> crmsh-4.1.0+git.1576228931.ae559358.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/.travis.yml new/crmsh-4.1.0+git.1576228931.ae559358/.travis.yml --- old/crmsh-4.1.0+git.1575875711.41d65be4/.travis.yml 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/.travis.yml 2019-12-13 10:22:11.000000000 +0100 @@ -65,6 +65,12 @@ script: - $FUNCTIONAL_TEST qdevice run validate + - name: "functional test for resource subcommand" + before_install: + - $FUNCTIONAL_TEST resource before_install + script: + - $FUNCTIONAL_TEST resource run + - stage: delivery if: type != pull_request AND branch = master env: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/crmsh/bootstrap.py new/crmsh-4.1.0+git.1576228931.ae559358/crmsh/bootstrap.py --- old/crmsh-4.1.0+git.1575875711.41d65be4/crmsh/bootstrap.py 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/crmsh/bootstrap.py 2019-12-13 10:22:11.000000000 +0100 @@ -1362,38 +1362,44 @@ if not confirm("SBD is already configured to use %s - overwrite?" % (configured_dev)): return - dev = "" dev_looks_sane = False while not dev_looks_sane: - dev = prompt_for_string('Path to storage device (e.g. /dev/disk/by-id/...), or "none"', r'none|\/.*', dev) + dev = prompt_for_string('Path to storage device (e.g. /dev/disk/by-id/...), or "none", use ";" as separator for multi path', r'none|\/.*') if dev == "none": _context.diskless_sbd = True init_sbd_diskless() return - if not is_block_device(dev): - print(" That doesn't look like a block device", file=sys.stderr) - dev = "" - else: - warn("All data on {} will be destroyed!".format(dev)) - if confirm('Are you sure you wish to use this device?'): - dev_looks_sane = True + dev_list = dev.strip(';').split(';') + for dev_item in dev_list: + if not is_block_device(dev_item): + print(" {} doesn't look like a block device".format(dev_item), file=sys.stderr) + dev_looks_sane = False + break else: - dev = "" - _context.sbd_device = dev + warn("All data on {} will be destroyed!".format(dev_item)) + if confirm('Are you sure you wish to use this device?'): + dev_looks_sane = True + else: + dev_looks_sane = False + break - if not is_block_device(_context.sbd_device): - error("SBD device %s doesn't seem to exist" % (_context.sbd_device)) + _context.sbd_device = dev_list + + for dev in _context.sbd_device: + if not is_block_device(dev): + error("SBD device %s doesn't seem to exist" % (dev)) # TODO: need to ensure watchdog is available # (actually, should work if watchdog unavailable, it'll just whine in the logs...) # TODO: what about timeouts for multipath devices? status_long('Initializing SBD...') - if not invoke("sbd -d %s create" % (_context.sbd_device)): - error("Failed to initialize SBD device %s" % (_context.sbd_device)) + for dev in _context.sbd_device: + if not invoke("sbd -d %s create" % (dev)): + error("Failed to initialize SBD device %s" % (dev)) status_done() utils.sysconfig_set(SYSCONFIG_SBD, - SBD_DEVICE=_context.sbd_device, + SBD_DEVICE=';'.join(_context.sbd_device), SBD_PACEMAKER="yes", SBD_STARTMODE="always", SBD_DELAY_START="no", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/crmsh/completers.py new/crmsh-4.1.0+git.1576228931.ae559358/crmsh/completers.py --- old/crmsh-4.1.0+git.1575875711.41d65be4/crmsh/completers.py 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/crmsh/completers.py 2019-12-13 10:22:11.000000000 +0100 @@ -44,7 +44,7 @@ booleans = choice(['yes', 'no', 'true', 'false', 'on', 'off']) -def resources(args): +def resources(args=None): cib_el = xmlutil.resources_xml() if cib_el is None: return [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/crmsh/ui_cluster.py new/crmsh-4.1.0+git.1576228931.ae559358/crmsh/ui_cluster.py --- old/crmsh-4.1.0+git.1575875711.41d65be4/crmsh/ui_cluster.py 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/crmsh/ui_cluster.py 2019-12-13 10:22:11.000000000 +0100 @@ -243,8 +243,8 @@ storage_group = optparse.OptionGroup(parser, "Storage configuration", "Options for configuring shared storage.") storage_group.add_option("-p", "--partition-device", dest="shared_device", metavar="DEVICE", help='Partition this shared storage device (only used in "storage" stage)') - storage_group.add_option("-s", "--sbd-device", dest="sbd_device", metavar="DEVICE", - help="Block device to use for SBD fencing") + storage_group.add_option("-s", "--sbd-device", dest="sbd_device", metavar="DEVICE", action="append", + help="Block device to use for SBD fencing, use \";\" as separator for multi path") storage_group.add_option("-o", "--ocfs2-device", dest="ocfs2_device", metavar="DEVICE", help='Block device to use for OCFS2 (only used in "vgfs" stage)') parser.add_option_group(storage_group) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/crmsh/ui_resource.py new/crmsh-4.1.0+git.1576228931.ae559358/crmsh/ui_resource.py --- old/crmsh-4.1.0+git.1575875711.41d65be4/crmsh/ui_resource.py 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/crmsh/ui_resource.py 2019-12-13 10:22:11.000000000 +0100 @@ -203,7 +203,8 @@ 'get': "crm_resource --meta --resource '%s' --get-parameter '%s'", } rsc_failcount = { - 'set': "crm_attribute -t status -n 'fail-count-%s' -N '%s' -v '%s' -d 0", + 'set': "crm_attribute -t status -n 'fail-count-%s' -N '%s' -v '%s'", + 'set_p': "crm_attribute -t status -P 'fail-count-%s' -N '%s' -v '%s'", 'delete': "crm_failcount -D -r %s -N %s", 'show': "crm_failcount -G -r %s -N %s", 'get': "crm_failcount -G -r %s -N %s", @@ -483,11 +484,75 @@ @command.wait @command.completers(compl.resources, _attrcmds, compl.nodes) - def do_failcount(self, context, rsc, cmd, node, value=None): + def do_failcount(self, context, rsc, cmd, node, value=None, operation=None, interval=None): """usage: - failcount <rsc> set <node> <value> + failcount <rsc> set <node> <value> [operation] [interval] failcount <rsc> delete <node> failcount <rsc> show <node>""" + def sec_to_ms(s): + return s + '000' + + def ms_to_sec(m): + return m[:len(m)-3] + + if rsc not in compl.resources(): + context.fatal_error("Resource {} not exists in this cluster".format(rsc)) + valid_cmd_list = ["set", "delete", "show"] + if cmd not in valid_cmd_list: + context.fatal_error("{} is not valid command(should be one of {})".format(cmd, valid_cmd_list)) + nodeid = utils.get_nodeid_from_name(node) + if nodeid is None: + context.fatal_error("Node {} not in this cluster".format(node)) + + if cmd == "set": + # query the current failcount status + query_cmd = "cibadmin -Ql --xpath '/cib/status/node_state[@id='{}']'".format(nodeid) + rc, out, err = utils.get_stdout_stderr(query_cmd) + if rc != 0: + context.fatal_error(err) + + # try to get failcount dict {operation:interval} + import re + failcount_res = re.findall(r'fail-count-{}#(.*)_([0-9]+)'.format(rsc), out) + if not failcount_res: + context.fatal_error("No failcount on node {} for resource {}".format(node, rsc)) + failcount_dict = dict(failcount_res) + + # validate for operation and interval + if operation and operation not in failcount_dict.keys(): + context.fatal_error("Usage: failcount <rsc> set <node> <value> [operation] [interval]\n\ + Should specify operation between \"{}\"".format(' '.join(failcount_dict.keys()))) + if (operation and interval) and (operation, sec_to_ms(interval)) not in failcount_res: + context.fatal_error("Usage: failcount <rsc> set <node> <value> [operation] [interval]\n\ + Should specify (operation, interval) between {}".\ + format([(op, ms_to_sec(inter)) for op, inter in failcount_res])) + + # just one failcount entry + if len(failcount_res) == 1: + operation = failcount_res[0][0] + interval = failcount_dict[operation] + rsc = '{}#{}_{}'.format(rsc, operation, interval) + + # multiple failcount entries for this resource and node + if len(failcount_res) > 1: + if operation and interval: + rsc = '{}#{}_{}'.format(rsc, operation, sec_to_ms(interval)) + elif int(value) == 0: + # using '-P' option of 'crm_attribute' command + cmd = "set_p" + if operation: + op_interval_str = '|'.join(['{}_{}'.format(operation, inter) for op, inter in failcount_res if op==operation]) + else: + op_interval_str = '|'.join(['{}_{}'.format(op, inter) for op, inter in failcount_res]) + rsc = '{}#({})'.format(rsc, op_interval_str) + else: + # value != 0 + if operation and len([op for op, _ in failcount_res if op == operation]) == 1: + rsc = '{}#{}_{}'.format(rsc, operation, failcount_dict[operation]) + else: + context.fatal_error("Should specify (operation, interval) between {}". + format([(op, ms_to_sec(inter)) for op, inter in failcount_res])) + return ui_utils.manage_attr(context.get_command_name(), self.rsc_failcount, rsc, cmd, node, value) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/crmsh/ui_utils.py new/crmsh-4.1.0+git.1576228931.ae559358/crmsh/ui_utils.py --- old/crmsh-4.1.0+git.1575875711.41d65be4/crmsh/ui_utils.py 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/crmsh/ui_utils.py 2019-12-13 10:22:11.000000000 +0100 @@ -22,7 +22,7 @@ def sanity_check(arg): if not utils.is_name_sane(arg): raise ValueError("Expected valid name, got '%s'" % (arg)) - if subcmd == 'set': + if subcmd in ['set', 'set_p']: if value is None: raise ValueError("Missing value argument to set") sanity_check(rsc) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/crmsh/utils.py new/crmsh-4.1.0+git.1576228931.ae559358/crmsh/utils.py --- old/crmsh-4.1.0+git.1575875711.41d65be4/crmsh/utils.py 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/crmsh/utils.py 2019-12-13 10:22:11.000000000 +0100 @@ -2253,4 +2253,15 @@ def is_unicast(): from . import corosync return corosync.get_value("totem.transport") == "udpu" + + +def get_nodeid_from_name(name): + rc, out = get_stdout('crm_node -l') + if rc != 0: + return None + res = re.search(r'^([0-9]+) {} '.format(name), out, re.M) + if res: + return res.group(1) + else: + return None # vim:ts=4:sw=4:et: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/data-manifest new/crmsh-4.1.0+git.1576228931.ae559358/data-manifest --- old/crmsh-4.1.0+git.1575875711.41d65be4/data-manifest 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/data-manifest 2019-12-13 10:22:11.000000000 +0100 @@ -71,6 +71,7 @@ test/features/qdevice_options.feature test/features/qdevice_setup_remove.feature test/features/qdevice_validate.feature +test/features/resource_failcount.feature test/features/steps/__init__.py test/features/steps/step_implenment.py test/features/steps/utils.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/doc/crm.8.adoc new/crmsh-4.1.0+git.1576228931.ae559358/doc/crm.8.adoc --- old/crmsh-4.1.0+git.1575875711.41d65be4/doc/crm.8.adoc 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/doc/crm.8.adoc 2019-12-13 10:22:11.000000000 +0100 @@ -2011,10 +2011,13 @@ ==== `failcount` Show/edit/delete the failcount of a resource. +When `set` a non-zero value, `operation` and `interval` should be +provided when multiple operation failcount entries exist. +`interval` is a value in seconds. Usage: ............... -failcount <rsc> set <node> <value> +failcount <rsc> set <node> <value> [operation] [interval] failcount <rsc> delete <node> failcount <rsc> show <node> ............... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/test/features/environment.py new/crmsh-4.1.0+git.1576228931.ae559358/test/features/environment.py --- old/crmsh-4.1.0+git.1575875711.41d65be4/test/features/environment.py 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/test/features/environment.py 2019-12-13 10:22:11.000000000 +0100 @@ -11,6 +11,10 @@ return None +def resource_cleanup(): + utils.get_stdout_stderr('crm resource cleanup') + + def before_step(context, step): context.logger = logging.getLogger("Step:{}".format(step.name)) @@ -20,6 +24,7 @@ if tag == "clean": online_nodes = get_online_nodes() if online_nodes: + resource_cleanup() try: parallax.parallax_call(online_nodes, 'crm cluster stop') except ValueError as err: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/test/features/resource_failcount.feature new/crmsh-4.1.0+git.1576228931.ae559358/test/features/resource_failcount.feature --- old/crmsh-4.1.0+git.1575875711.41d65be4/test/features/resource_failcount.feature 1970-01-01 01:00:00.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/test/features/resource_failcount.feature 2019-12-13 10:22:11.000000000 +0100 @@ -0,0 +1,64 @@ +@resource +Feature: Use "crm resource failcount" to manage failcounts + + Tag @clean means need to stop cluster service if the service is available + + Background: Setup one node cluster and configure a Dummy resource + Given Cluster service is "stopped" on "hanode1" + When Run "crm cluster init -y --no-overwrite-sshkey" on "hanode1" + Then Cluster service is "started" on "hanode1" + When Run "crm configure primitive d Dummy op monitor interval=3s" on "hanode1" + Then Resource "d" type "Dummy" is "Started" + + @clean + Scenario: Validation, input the wrong parameters + When Try "crm resource failcount ddd show hanode1" + Then Except "ERROR: resource.failcount: Resource ddd not exists in this cluster" + When Try "crm resource failcount d showss hanode1" + Then Except "ERROR: resource.failcount: showss is not valid command(should be one of ['set', 'delete', 'show'])" + When Try "crm resource failcount d set hanode11 0" + Then Except "ERROR: resource.failcount: Node hanode11 not in this cluster" + When Try "crm resource failcount d set hanode1 0" + Then Except "ERROR: resource.failcount: No failcount on node hanode1 for resource d" + + @clean + Scenario: Set the failcount to 0 + When Run "rm -f /run/resource-agents/Dummy-d.state" on "hanode1" + And Wait "5" seconds + Then Resource "d" failcount on "hanode1" is "1" + When Run "crm resource failcount d set hanode1 0" on "hanode1" + Then Resource "d" failcount on "hanode1" is "0" + + @clean + Scenario: Set multiple failcounts to 0 + When Run "sed -i -e '/rm \${OCF_RESKEY_state}/a\' -e "else\nreturn \$OCF_ERR_GENERIC" /usr/lib/ocf/resource.d/heartbeat/Dummy" on "hanode1" + And Run "rm -f /run/resource-agents/Dummy-d.state" on "hanode1" + And Wait "5" seconds + Then Resource "d" failcount on "hanode1" is "INFINITY" + """ + now have two failcount entries, one is monitor, another is stop + """ + When Run "crm resource failcount d set hanode1 0" on "hanode1" + """ + set all failcounts to 0 + """ + Then Resource "d" failcount on "hanode1" is "0" + When Run "crm resource cleanup" on "hanode1" + And Wait "5" seconds + And Run "rm -f /run/resource-agents/Dummy-d.state" on "hanode1" + And Wait "5" seconds + Then Resource "d" failcount on "hanode1" is "INFINITY" + """ + now have two failcount entries, one is monitor, another is stop + """ + When Run "crm resource failcount d set hanode1 0 stop" on "hanode1" + """ + set stop failcounts to 0 + """ + Then Resource "d" failcount on "hanode1" is "1" + When Run "crm resource failcount d set hanode1 0 monitor" on "hanode1" + """ + set monitor failcounts to 0 + """ + Then Resource "d" failcount on "hanode1" is "0" + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/test/features/steps/step_implenment.py new/crmsh-4.1.0+git.1576228931.ae559358/test/features/steps/step_implenment.py --- old/crmsh-4.1.0+git.1575875711.41d65be4/test/features/steps/step_implenment.py 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/test/features/steps/step_implenment.py 2019-12-13 10:22:11.000000000 +0100 @@ -1,4 +1,5 @@ import re +import time from behave import given, when, then from crmsh import corosync, parallax from utils import check_cluster_state, check_service_state, online, run_command, me, \ @@ -37,6 +38,11 @@ run_command(context, cmd, err_record=True) +@when('Wait "{second}" seconds') +def step_impl(context, second): + time.sleep(int(second)) + + @then('Except "{msg}"') def step_impl(context, msg): assert context.command_error_output == msg @@ -109,3 +115,28 @@ out = run_command(context, "sed -n -e '/quorum/,/^}/ p' /etc/corosync/corosync.conf") if out: context.logger.info("\n{}".format(out)) + + +@then('Resource "{res}" type "{res_type}" is "{state}"') +def step_impl(context, res, res_type, state): + try_count = 0 + result = None + while try_count < 5: + time.sleep(1) + out = run_command(context, "crm_mon -1") + if out: + result = re.search(r'\s{}\s+.*:{}\):\s+{} '.format(res, res_type, state), out) + if not result: + try_count += 1 + else: + break + assert result is not None + + +@then('Resource "{res}" failcount on "{node}" is "{number}"') +def step_impl(context, res, node, number): + cmd = "crm resource failcount {} show {}".format(res, node) + out = run_command(context, cmd) + if out: + result = re.search(r'name=fail-count-{} value={}'.format(res, number), out) + assert result is not None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/test/run-in-travis.sh new/crmsh-4.1.0+git.1576228931.ae559358/test/run-in-travis.sh --- old/crmsh-4.1.0+git.1575875711.41d65be4/test/run-in-travis.sh 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/test/run-in-travis.sh 2019-12-13 10:22:11.000000000 +0100 @@ -32,7 +32,7 @@ configure make_install exit $?;; - bootstrap|qdevice|hb_report) + bootstrap|qdevice|hb_report|resource) functional_tests $1 $2 exit $?;; *) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1575875711.41d65be4/test/unittests/test_utils.py new/crmsh-4.1.0+git.1576228931.ae559358/test/unittests/test_utils.py --- old/crmsh-4.1.0+git.1575875711.41d65be4/test/unittests/test_utils.py 2019-12-09 08:15:11.000000000 +0100 +++ new/crmsh-4.1.0+git.1576228931.ae559358/test/unittests/test_utils.py 2019-12-13 10:22:11.000000000 +0100 @@ -6,13 +6,52 @@ import os import socket +import re from unittest import mock +from nose.tools import eq_ from itertools import chain from crmsh import utils from crmsh import config from crmsh import tmpfiles +@mock.patch('re.search') +@mock.patch('crmsh.utils.get_stdout') +def test_get_nodeid_from_name_run_None1(mock_get_stdout, mock_re_search): + mock_get_stdout.return_value = (1, None) + mock_re_search_inst = mock.Mock() + mock_re_search.return_value = mock_re_search_inst + res = utils.get_nodeid_from_name("node1") + eq_(res, None) + mock_get_stdout.assert_called_once_with('crm_node -l') + mock_re_search.assert_not_called() + + +@mock.patch('re.search') +@mock.patch('crmsh.utils.get_stdout') +def test_get_nodeid_from_name_run_None2(mock_get_stdout, mock_re_search): + mock_get_stdout.return_value = (0, "172167901 node1 member\n172168231 node2 member") + mock_re_search.return_value = None + res = utils.get_nodeid_from_name("node111") + eq_(res, None) + mock_get_stdout.assert_called_once_with('crm_node -l') + mock_re_search.assert_called_once_with(r'^([0-9]+) node111 ', mock_get_stdout.return_value[1], re.M) + + +@mock.patch('re.search') +@mock.patch('crmsh.utils.get_stdout') +def test_get_nodeid_from_name(mock_get_stdout, mock_re_search): + mock_get_stdout.return_value = (0, "172167901 node1 member\n172168231 node2 member") + mock_re_search_inst = mock.Mock() + mock_re_search.return_value = mock_re_search_inst + mock_re_search_inst.group.return_value = '172168231' + res = utils.get_nodeid_from_name("node2") + eq_(res, '172168231') + mock_get_stdout.assert_called_once_with('crm_node -l') + mock_re_search.assert_called_once_with(r'^([0-9]+) node2 ', mock_get_stdout.return_value[1], re.M) + mock_re_search_inst.group.assert_called_once_with(1) + + def test_check_ssh_passwd_need_True(): with mock.patch('crmsh.utils.get_stdout_stderr') as mock_get_stdout_stderr: mock_get_stdout_stderr.side_effect = [(0, None, None), (1, None, None)]