Hello community, here is the log from the commit of package salt-shaptools for openSUSE:Factory checked in at 2020-05-28 09:19:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/salt-shaptools (Old) and /work/SRC/openSUSE:Factory/.salt-shaptools.new.3606 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "salt-shaptools" Thu May 28 09:19:24 2020 rev:14 rq:809597 version:0.3.6 Changes: -------- --- /work/SRC/openSUSE:Factory/salt-shaptools/salt-shaptools.changes 2020-05-15 23:52:44.657593591 +0200 +++ /work/SRC/openSUSE:Factory/.salt-shaptools.new.3606/salt-shaptools.changes 2020-05-28 09:19:24.785219121 +0200 @@ -1,0 +2,14 @@ +Thu May 21 10:14:22 UTC 2020 - Xabier Arbulu <[email protected]> + +- Version 0.3.6 + * Add the option to configure the cluster properties and defaults + * Update cluster_configured to add `force` flag + (bsc#1170702) + +------------------------------------------------------------------- +Fri May 8 23:37:02 UTC 2020 - Simranpal Singh <[email protected]> + +- Version 0.3.5 + * Add support to pass extra tar options + +------------------------------------------------------------------- Old: ---- salt-shaptools-0.3.4.tar.gz New: ---- salt-shaptools-0.3.6.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ salt-shaptools.spec ++++++ --- /var/tmp/diff_new_pack.P0uPaB/_old 2020-05-28 09:19:25.205219891 +0200 +++ /var/tmp/diff_new_pack.P0uPaB/_new 2020-05-28 09:19:25.209219898 +0200 @@ -19,7 +19,7 @@ # See also https://en.opensuse.org/openSUSE:Specfile_guidelines Name: salt-shaptools -Version: 0.3.4 +Version: 0.3.6 Release: 0 Summary: Salt modules and states for SAP Applications and SLE-HA components management ++++++ salt-shaptools-0.3.4.tar.gz -> salt-shaptools-0.3.6.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/salt-shaptools-0.3.4/salt/modules/crmshmod.py new/salt-shaptools-0.3.6/salt/modules/crmshmod.py --- old/salt-shaptools-0.3.4/salt/modules/crmshmod.py 2020-03-31 20:02:39.980481668 +0200 +++ new/salt-shaptools-0.3.6/salt/modules/crmshmod.py 2020-05-27 16:14:29.985993498 +0200 @@ -23,6 +23,7 @@ # Import Python libs from __future__ import absolute_import, unicode_literals, print_function import logging +import json from salt import exceptions import salt.utils.path @@ -564,7 +565,8 @@ def configure_load( method, url, - is_xml=None): + is_xml=None, + force=False): ''' Load a part of configuration (or all of it) from a local file or a network URL. The replace method replaces the current configuration with @@ -577,8 +579,10 @@ Used method (check in the description) url Used configuration file url (or path if it's a local file) - is_xml: + is_xml Set to true if the file is an xml file + force + Force commit in the configure load operation CLI Example: @@ -586,11 +590,84 @@ salt '*' crm.configure_load update file.conf ''' - cmd = '{crm_command} configure load {xml}{method} {url}'.format( + cmd = '{crm_command} {force} configure load {xml}{method} {url}'.format( crm_command=CRM_COMMAND, + force='-F' if force else '-n', xml='xml ' if is_xml else '', - method=method, url=url) + method=method, + url=url) + + return __salt__['cmd.retcode'](cmd) + + +def configure_get_property( + option): + ''' + Get a cluster property value + + option: + property name to get the value + + Raises: exceptions.CommandExecutionError if the property doesn't exist + ''' + + cmd = '{crm_command} configure get_property {property}'.format( + crm_command=CRM_COMMAND, property=option) + + value = __salt__['cmd.run'](cmd).strip() + if "ERROR: configure.get_property:" in value: + raise exceptions.CommandExecutionError(value) + return value + + +def configure_property( + option, + value): + ''' + Set a cluster property value + + option: + property name to set the value + value: + property new value + ''' + + cmd = '{crm_command} configure property {property}={value}'.format( + crm_command=CRM_COMMAND, property=option, value=json.dumps(value)) + return __salt__['cmd.retcode'](cmd) + + +def configure_rsc_defaults( + option, + value): + ''' + Set a cluster rsc default value + + option: + property name to set the value + value: + property new value + ''' + + cmd = '{crm_command} configure rsc_defaults {property}={value}'.format( + crm_command=CRM_COMMAND, property=option, value=json.dumps(value)) + return __salt__['cmd.retcode'](cmd) + + +def configure_op_defaults( + option, + value): + ''' + Set a cluster op default value + + option: + property name to set the value + value: + property new value + ''' + cmd = '{crm_command} configure op_defaults {property}={value}'.format( + crm_command=CRM_COMMAND, property=option, value=json.dumps(value)) return __salt__['cmd.retcode'](cmd) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/salt-shaptools-0.3.4/salt/modules/hanamod.py new/salt-shaptools-0.3.6/salt/modules/hanamod.py --- old/salt-shaptools-0.3.4/salt/modules/hanamod.py 2020-03-31 20:02:39.980481668 +0200 +++ new/salt-shaptools-0.3.6/salt/modules/hanamod.py 2020-05-27 16:14:29.985993498 +0200 @@ -970,7 +970,8 @@ name, software_folders, output_dir, - hana_version='20'): + hana_version='20', + additional_extract_options=None): ''' Extract HANA pydbapi python client from the provided software folders @@ -982,8 +983,16 @@ standard way in SAP landscape output_dir Folder where the package is extracted + additional_extract_options + Additional options to pass to the tar extraction command ''' + if not isinstance(software_folders, list): + raise TypeError( + "software_folders must be a list, not {} type".format(type(software_folders).__name__) + ) current_platform = hana.HanaInstance.get_platform() + tar_options_str = ('{} -xvf'.format(additional_extract_options) + if additional_extract_options else '-xvf') hana_client_pattern = re.compile('^HDB_CLIENT:{}.*:{}:.*'.format( hana_version, current_platform)) try: @@ -991,5 +1000,5 @@ except SapFolderNotFoundError: raise exceptions.CommandExecutionError('HANA client not found') pydbapi_file = '{}/client/{}'.format(hana_client_folder, name) - __salt__['archive.tar'](options='xvf', tarfile=pydbapi_file, dest=output_dir) + __salt__['archive.tar'](options=tar_options_str, tarfile=pydbapi_file, cwd=output_dir) return pydbapi_file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/salt-shaptools-0.3.4/salt/states/crmshmod.py new/salt-shaptools-0.3.6/salt/states/crmshmod.py --- old/salt-shaptools-0.3.4/salt/states/crmshmod.py 2020-03-31 20:02:39.980481668 +0200 +++ new/salt-shaptools-0.3.6/salt/states/crmshmod.py 2020-05-27 16:14:29.985993498 +0200 @@ -235,7 +235,8 @@ def cluster_configured( name, url, - is_xml=None): + is_xml=None, + force=False): """ Machine is congifured with the provided configuration file @@ -245,6 +246,8 @@ Configuration file path or url is_xml: True if the configuration file is xml type, False otherwise + force + Force commit in the configure load operation """ method = name @@ -271,7 +274,8 @@ result = __salt__['crm.configure_load']( method=method, url=url, - is_xml=is_xml) + is_xml=is_xml, + force=force) if result: ret['comment'] = 'Error configuring the cluster with method {} and file {}'.format( @@ -386,6 +390,12 @@ ret['result'] = True return ret + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Corosync configuration would be update' + ret['changes'] = changes + return ret + new_conf_file_content = _convert2corosync(new_conf_dict) if backup: __salt__['file.copy'](name, '{}.backup'.format(name)) @@ -395,3 +405,146 @@ ret['comment'] = 'Corosync configuration file updated' ret['result'] = True return ret + + +def cluster_properties_present( + name, + properties): + """ + Configure the cluster properties after the cluster creation + + name: + This parameter is ignored + properties: + Dictionary with properties and their values to be configured + """ + + changes = {} + ret = {'name': name, + 'changes': changes, + 'result': False, + 'comment': ''} + + if __salt__['crm.status'](): + ret['result'] = False + ret['comment'] = 'Cluster is not created yet. Run cluster_initialized before' + return ret + + # We could check if the properties have already the provided values, but setting already + # configured values is not harmful + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Cluster properties would be configured' + ret['changes'] = properties + return ret + + errors = [] + for option, value in properties.items(): + try: + __salt__['crm.configure_get_property'](option=option) + __salt__['crm.configure_property'](option=option, value=value) + changes[option] = value + except exceptions.CommandExecutionError: + errors.append(str(option)) + + if errors: + ret['comment'] = 'Error configuring the properties {}'.format(", ".join(errors)) + ret['changes'] = changes + ret['result'] = False + return ret + + ret['changes'] = changes + ret['comment'] = 'Cluster properties configured' + ret['result'] = True + return ret + + +def cluster_rsc_defaults_present( + name, + rsc_defaults): + """ + Configure the cluster rsc_defaults after the cluster creation + + name: + This parameter is ignored + properties: + Dictionary with rsc_defaults and their values to be configured + + Warning: The state doesn't do any validation, so it will add any provided option/value entry + to the cluster configuration + """ + + changes = {} + ret = {'name': name, + 'changes': changes, + 'result': False, + 'comment': ''} + + if __salt__['crm.status'](): + ret['result'] = False + ret['comment'] = 'Cluster is not created yet. Run cluster_initialized before' + return ret + + # We could check if the rsc_defaults have already the provided values, but setting already + # configured values is not harmful + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Cluster rsc_defaults would be configured' + ret['changes'] = rsc_defaults + return ret + + for option, value in rsc_defaults.items(): + __salt__['crm.configure_rsc_defaults'](option=option, value=value) + changes[option] = value + + ret['changes'] = changes + ret['comment'] = 'Cluster rsc_defaults configured' + ret['result'] = True + return ret + + +def cluster_op_defaults_present( + name, + op_defaults): + """ + Configure the cluster op_defaults after the cluster creation + + name: + This parameter is ignored + properties: + Dictionary with op_defaults and their values to be configured + + Warning: The state doesn't do any validation, so it will add any provided option/value entry + to the cluster configuration + """ + + changes = {} + ret = {'name': name, + 'changes': changes, + 'result': False, + 'comment': ''} + + if __salt__['crm.status'](): + ret['result'] = False + ret['comment'] = 'Cluster is not created yet. Run cluster_initialized before' + return ret + + # We could check if the op_defaults have already the provided values, but setting already + # configured values is not harmful + + if __opts__['test']: + ret['result'] = None + ret['comment'] = 'Cluster op_defaults would be configured' + ret['changes'] = op_defaults + return ret + + for option, value in op_defaults.items(): + __salt__['crm.configure_op_defaults'](option=option, value=value) + changes[option] = value + + ret['changes'] = changes + ret['comment'] = 'Cluster op_defaults configured' + ret['result'] = True + return ret diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/salt-shaptools-0.3.4/salt/states/hanamod.py new/salt-shaptools-0.3.6/salt/states/hanamod.py --- old/salt-shaptools-0.3.4/salt/states/hanamod.py 2020-03-31 20:02:39.980481668 +0200 +++ new/salt-shaptools-0.3.6/salt/states/hanamod.py 2020-05-27 16:14:29.985993498 +0200 @@ -762,7 +762,8 @@ software_folders, output_dir, hana_version='20', - force=False): + force=False, + additional_extract_options=None): ''' Extract HANA pydbapi python client from the provided software folders @@ -776,6 +777,8 @@ Folder where the package is extracted force Force new extraction if the file already is extracted + additional_extract_options + Additional options to pass to the tar extraction command ''' ret = {'name': name, @@ -799,7 +802,12 @@ __salt__['file.mkdir'](output_dir) try: - client = __salt__['hana.extract_pydbapi'](name, software_folders, output_dir, hana_version) + client = __salt__['hana.extract_pydbapi']( + name, + software_folders, + output_dir, + hana_version, + additional_extract_options) except exceptions.CommandExecutionError as err: ret['comment'] = six.text_type(err) return ret diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/salt-shaptools-0.3.4/salt-shaptools.changes new/salt-shaptools-0.3.6/salt-shaptools.changes --- old/salt-shaptools-0.3.4/salt-shaptools.changes 2020-03-31 20:02:39.980481668 +0200 +++ new/salt-shaptools-0.3.6/salt-shaptools.changes 2020-05-27 16:14:29.985993498 +0200 @@ -1,14 +1,28 @@ ------------------------------------------------------------------- +Thu May 21 10:14:22 UTC 2020 - Xabier Arbulu <[email protected]> + +- Version 0.3.6 + * Add the option to configure the cluster properties and defaults + * Update cluster_configured to add `force` flag + (bsc#1170702) + +------------------------------------------------------------------- +Fri May 8 23:37:02 UTC 2020 - Simranpal Singh <[email protected]> + +- Version 0.3.5 + * Add support to pass extra tar options + +------------------------------------------------------------------- Fri Mar 27 18:06:32 UTC 2020 - Simranpal Singh <[email protected]> - Version 0.3.4 - * Add new salt module and state to extract the sar files using SAPCAR + * Add new salt module and state to extract the sar files using SAPCAR ------------------------------------------------------------------- Fri Mar 20 14:49:04 UTC 2020 - Xabier Arbulu <[email protected]> - Version 0.3.3 - * Add new salt state to extract the HANA python dbapi client + * Add new salt state to extract the HANA python dbapi client ------------------------------------------------------------------- Thu Mar 5 10:03:39 UTC 2020 - Xabier Arbulu <[email protected]> @@ -16,7 +30,7 @@ - Version 0.3.2 * Add a new salt state method to update corosync configuration file - * Fix travis file to install the py packages in develop mode + * Fix travis file to install the py packages in develop mode ------------------------------------------------------------------- Fri Jan 24 10:40:26 UTC 2020 - Xabier Arbulu <[email protected]> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/salt-shaptools-0.3.4/salt-shaptools.spec new/salt-shaptools-0.3.6/salt-shaptools.spec --- old/salt-shaptools-0.3.4/salt-shaptools.spec 2020-03-31 20:02:39.980481668 +0200 +++ new/salt-shaptools-0.3.6/salt-shaptools.spec 2020-05-27 16:14:29.985993498 +0200 @@ -19,7 +19,7 @@ # See also https://en.opensuse.org/openSUSE:Specfile_guidelines Name: salt-shaptools -Version: 0.3.4 +Version: 0.3.6 Release: 0 Summary: Salt modules and states for SAP Applications and SLE-HA components management diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/salt-shaptools-0.3.4/tests/unit/modules/test_crmshmod.py new/salt-shaptools-0.3.6/tests/unit/modules/test_crmshmod.py --- old/salt-shaptools-0.3.4/tests/unit/modules/test_crmshmod.py 2020-03-31 20:02:39.980481668 +0200 +++ new/salt-shaptools-0.3.6/tests/unit/modules/test_crmshmod.py 2020-05-27 16:14:29.985993498 +0200 @@ -646,7 +646,7 @@ result = crmshmod.configure_load('update', 'file.conf') assert result mock_cmd_run.assert_called_once_with( - '{crm_command} configure load {method} {url}'.format( + '{crm_command} -n configure load {method} {url}'.format( crm_command=crmshmod.CRM_COMMAND, method='update', url='file.conf')) @@ -658,14 +658,124 @@ mock_cmd_run = MagicMock(return_value=True) with patch.dict(crmshmod.__salt__, {'cmd.retcode': mock_cmd_run}): - result = crmshmod.configure_load('update', 'file.conf', True) + result = crmshmod.configure_load('update', 'file.conf', True, True) assert result mock_cmd_run.assert_called_once_with( - '{crm_command} configure load xml {method} {url}'.format( + '{crm_command} -F configure load xml {method} {url}'.format( crm_command=crmshmod.CRM_COMMAND, method='update', url='file.conf')) + def test_configure_get_property(self): + ''' + Test configure_get_property + ''' + + mock_cmd_run = MagicMock(return_value=' value ') + + with patch.dict(crmshmod.__salt__, {'cmd.run': mock_cmd_run}): + result = crmshmod.configure_get_property('item') + assert result == 'value' + mock_cmd_run.assert_called_once_with( + '{crm_command} configure get_property {property}'.format( + crm_command=crmshmod.CRM_COMMAND, + property='item')) + + def test_configure_get_property_error(self): + ''' + Test configure_get_property when it raises an error + ''' + + mock_cmd_run = MagicMock(return_value='ERROR: configure.get_property: item') + + with patch.dict(crmshmod.__salt__, {'cmd.run': mock_cmd_run}): + with pytest.raises(exceptions.CommandExecutionError) as err: + crmshmod.configure_get_property('item') + mock_cmd_run.assert_called_once_with( + '{crm_command} configure get_property {property}'.format( + crm_command=crmshmod.CRM_COMMAND, + property='item')) + + assert 'ERROR: configure.get_property: item' in str(err.value) + + def test_configure_property(self): + ''' + Test configure_property method + ''' + mock_cmd_run = MagicMock(return_value=True) + + with patch.dict(crmshmod.__salt__, {'cmd.retcode': mock_cmd_run}): + result = crmshmod.configure_property('item', 'value') + assert result + mock_cmd_run.assert_called_once_with( + '{crm_command} configure property {item}="{value}"'.format( + crm_command=crmshmod.CRM_COMMAND, + item='item', + value='value')) + + mock_cmd_run.reset_mock() + + with patch.dict(crmshmod.__salt__, {'cmd.retcode': mock_cmd_run}): + result = crmshmod.configure_property('item', False) + assert result + mock_cmd_run.assert_called_once_with( + '{crm_command} configure property {item}={value}'.format( + crm_command=crmshmod.CRM_COMMAND, + item='item', + value='false')) + + def test_configure_rsc_defaults(self): + ''' + Test configure_rsc_defaults method + ''' + mock_cmd_run = MagicMock(return_value=True) + + with patch.dict(crmshmod.__salt__, {'cmd.retcode': mock_cmd_run}): + result = crmshmod.configure_rsc_defaults('item', 'value') + assert result + mock_cmd_run.assert_called_once_with( + '{crm_command} configure rsc_defaults {item}="{value}"'.format( + crm_command=crmshmod.CRM_COMMAND, + item='item', + value='value')) + + mock_cmd_run.reset_mock() + + with patch.dict(crmshmod.__salt__, {'cmd.retcode': mock_cmd_run}): + result = crmshmod.configure_rsc_defaults('item', False) + assert result + mock_cmd_run.assert_called_once_with( + '{crm_command} configure rsc_defaults {item}={value}'.format( + crm_command=crmshmod.CRM_COMMAND, + item='item', + value='false')) + + def test_configure_op_defaults(self): + ''' + Test configure_op_defaults method + ''' + mock_cmd_run = MagicMock(return_value=True) + + with patch.dict(crmshmod.__salt__, {'cmd.retcode': mock_cmd_run}): + result = crmshmod.configure_op_defaults('item', 'value') + assert result + mock_cmd_run.assert_called_once_with( + '{crm_command} configure op_defaults {item}="{value}"'.format( + crm_command=crmshmod.CRM_COMMAND, + item='item', + value='value')) + + mock_cmd_run.reset_mock() + + with patch.dict(crmshmod.__salt__, {'cmd.retcode': mock_cmd_run}): + result = crmshmod.configure_op_defaults('item', False) + assert result + mock_cmd_run.assert_called_once_with( + '{crm_command} configure op_defaults {item}={value}'.format( + crm_command=crmshmod.CRM_COMMAND, + item='item', + value='false')) + def test_detect_cloud_py2(self): ''' Test detect_cloud diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/salt-shaptools-0.3.4/tests/unit/modules/test_hanamod.py new/salt-shaptools-0.3.6/tests/unit/modules/test_hanamod.py --- old/salt-shaptools-0.3.4/tests/unit/modules/test_hanamod.py 2020-03-31 20:02:39.980481668 +0200 +++ new/salt-shaptools-0.3.6/tests/unit/modules/test_hanamod.py 2020-05-27 16:14:29.985993498 +0200 @@ -892,13 +892,13 @@ mock_tar = MagicMock() with patch.dict(hanamod.__salt__, {'archive.tar': mock_tar}): pydbapi_file = hanamod.extract_pydbapi( - 'PYDBAPI.tar.gz', ['1234', '5678'], '/tmp/output') + 'PYDBAPI.tar.gz', ['1234', '5678'], '/tmp/output', additional_extract_options='-l') mock_compile.assert_called_once_with('^HDB_CLIENT:20.*:LINUX_X86_64:.*') mock_find_sap_folders.assert_called_once_with( ['1234', '5678'], compile_mocked) mock_tar.assert_called_once_with( - options='xvf', tarfile='my_folder/client/PYDBAPI.tar.gz', dest='/tmp/output') + options='-l -xvf', tarfile='my_folder/client/PYDBAPI.tar.gz', cwd='/tmp/output') assert pydbapi_file == 'my_folder/client/PYDBAPI.tar.gz' @mock.patch('re.compile') @@ -911,9 +911,17 @@ mock_find_sap_folders.side_effect = hanamod.SapFolderNotFoundError with pytest.raises(exceptions.CommandExecutionError) as err: pydbapi_file = hanamod.extract_pydbapi( - 'PYDBAPI.tar.gz', ['1234', '5678'], '/tmp/output') + 'PYDBAPI.tar.gz', ['1234', '5678'], '/tmp/output', additional_extract_options='-l') mock_compile.assert_called_once_with('^HDB_CLIENT:20.*:LINUX_X86_64:.*') mock_find_sap_folders.assert_called_once_with( ['1234', '5678'], compile_mocked) assert 'HANA client not found' in str(err.value) + + def test_extract_pydbapi_software_folders_type_error(self): + software_folders = '1234' + with pytest.raises(TypeError) as err: + pydbapi_file = hanamod.extract_pydbapi( + 'PYDBAPI.tar.gz', software_folders, '/tmp/output', additional_extract_options='-l') + assert 'software_folders must be a list, not {} type'.format( + type(software_folders).__name__) in str(err.value) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/salt-shaptools-0.3.4/tests/unit/states/test_crmshmod.py new/salt-shaptools-0.3.6/tests/unit/states/test_crmshmod.py --- old/salt-shaptools-0.3.4/tests/unit/states/test_crmshmod.py 2020-03-31 20:02:39.980481668 +0200 +++ new/salt-shaptools-0.3.6/tests/unit/states/test_crmshmod.py 2020-05-27 16:14:29.985993498 +0200 @@ -7,6 +7,7 @@ from __future__ import absolute_import, unicode_literals, print_function import sys +import collections from salt import exceptions # Import Salt Testing Libs @@ -431,7 +432,8 @@ mock_configured.assert_called_once_with( method='update', url='file.config', - is_xml=False) + is_xml=False, + force=False) def test_configured_error(self): ''' @@ -451,12 +453,14 @@ assert crmshmod.cluster_configured( name='update', url='file.config', - is_xml=False) == ret + is_xml=False, + force=True) == ret mock_status.assert_called_once_with() mock_configured.assert_called_once_with( method='update', url='file.config', - is_xml=False) + is_xml=False, + force=True) def test_configured_command_error(self): ''' @@ -481,7 +485,8 @@ mock_configured.assert_called_once_with( method='update', url='file.config', - is_xml=False) + is_xml=False, + force=False) def test_convert2dict(self): corofile = """ @@ -682,6 +687,34 @@ mock_mergedicts.assert_called_once_with( {'data': 1}, {'my_data': 1}, {}) + @mock.patch('salt.states.crmshmod._convert2dict') + @mock.patch('salt.states.crmshmod._mergedicts') + def test_corosync_updated_test(self, mock_mergedicts, mock_convert2dict): + ''' + Test to check corosync_updated in test mode + ''' + + ret = {'name': '/etc/corosync/corosync.conf', + 'changes': {'data': 1}, + 'result': None, + 'comment': 'Corosync configuration would be update'} + + mock_convert2dict.return_value = ({}, {}) + mock_mergedicts.return_value = ({}, {'data': 1}) + + file_content = "my corosync file content\nmy corosync file 2nd line content" + with patch.dict(crmshmod.__opts__, {'test': True}): + with patch("salt.utils.files.fopen", mock_open(read_data=file_content)): + assert crmshmod.corosync_updated( + name='/etc/corosync/corosync.conf', + data={'my_data': 1}) == ret + + mock_convert2dict.assert_called_once_with( + ['my corosync file content', 'my corosync file 2nd line content'] + ) + mock_mergedicts.assert_called_once_with( + {}, {'my_data': 1}, {}) + @mock.patch('salt.states.crmshmod._convert2corosync') @mock.patch('salt.states.crmshmod._convert2dict') @mock.patch('salt.states.crmshmod._mergedicts') @@ -723,3 +756,215 @@ mock_write.assert_called_once_with( '/etc/corosync/corosync.conf', 'new content') + + # 'cluster_properties_present' function tests + + def test_properties_present_no_cluster(self): + ''' + Test to check properties_present when the cluster is not created + ''' + + ret = {'name': 'name', + 'changes': {}, + 'result': False, + 'comment': 'Cluster is not created yet. Run cluster_initialized before'} + + mock_status = MagicMock(return_value=1) + with patch.dict(crmshmod.__salt__, {'crm.status': mock_status}): + assert crmshmod.cluster_properties_present('name', {'data': 'value'}) == ret + mock_status.assert_called_once_with() + + def test_properties_present_test(self): + ''' + Test to check properties_present in test mode + ''' + + ret = {'name': 'name', + 'changes': {'data': 'value'}, + 'result': None, + 'comment': 'Cluster properties would be configured'} + + mock_status = MagicMock(return_value=0) + with patch.dict(crmshmod.__salt__, {'crm.status': mock_status}): + with patch.dict(crmshmod.__opts__, {'test': True}): + assert crmshmod.cluster_properties_present('name', {'data': 'value'}) == ret + mock_status.assert_called_once_with() + + def test_properties_present(self): + ''' + Test to check properties_present + ''' + + ret = {'name': 'name', + 'changes': {'data1': 'value1', 'data2': 'value2'}, + 'result': True, + 'comment': 'Cluster properties configured'} + + mock_status = MagicMock(return_value=0) + mock_configure_get_property = MagicMock() + mock_configure_property = MagicMock() + with patch.dict(crmshmod.__salt__, {'crm.status': mock_status, + 'crm.configure_get_property': mock_configure_get_property, + 'crm.configure_property': mock_configure_property}): + assert crmshmod.cluster_properties_present( + name='name', + properties={'data1': 'value1', 'data2': 'value2'}) == ret + mock_status.assert_called_once_with() + mock_configure_get_property.assert_has_calls([ + mock.call(option='data1'), + mock.call(option='data2') + ]) + mock_configure_property.assert_has_calls([ + mock.call(option='data1', value='value1'), + mock.call(option='data2', value='value2') + ]) + + def test_properties_present_error(self): + ''' + Test to check properties_present with an error + ''' + + ret = {'name': 'name', + 'changes': {'data3': 'value3'}, + 'result': False, + 'comment': 'Error configuring the properties data1, data2'} + + mock_status = MagicMock(return_value=0) + mock_configure_get_property = MagicMock(side_effect=[ + exceptions.CommandExecutionError('err1'), + exceptions.CommandExecutionError('err2'), + "value3" + ]) + mock_configure_property = MagicMock() + # We need to create the dictionary this way, otherwise the items output is different in py2 and py3 + data = collections.OrderedDict() + data['data1'] = 'value1' + data['data2'] = 'value2' + data['data3'] = 'value3' + with patch.dict(crmshmod.__salt__, {'crm.status': mock_status, + 'crm.configure_get_property': mock_configure_get_property, + 'crm.configure_property': mock_configure_property}): + assert crmshmod.cluster_properties_present( + name='name', + properties=data) == ret + mock_status.assert_called_once_with() + mock_configure_get_property.assert_has_calls([ + mock.call(option='data1'), + mock.call(option='data2'), + mock.call(option='data3') + ]) + mock_configure_property.assert_has_calls([ + mock.call(option='data3', value='value3') + ]) + + # 'cluster_rsc_defaults_present' function tests + + def test_rsc_defaults_present_no_cluster(self): + ''' + Test to check rsc_defaults_present when the cluster is not created + ''' + + ret = {'name': 'name', + 'changes': {}, + 'result': False, + 'comment': 'Cluster is not created yet. Run cluster_initialized before'} + + mock_status = MagicMock(return_value=1) + with patch.dict(crmshmod.__salt__, {'crm.status': mock_status}): + assert crmshmod.cluster_rsc_defaults_present('name', {'data': 'value'}) == ret + mock_status.assert_called_once_with() + + def test_rsc_defaults_present_test(self): + ''' + Test to check rsc_defaults_present in test mode + ''' + + ret = {'name': 'name', + 'changes': {'data': 'value'}, + 'result': None, + 'comment': 'Cluster rsc_defaults would be configured'} + + mock_status = MagicMock(return_value=0) + with patch.dict(crmshmod.__salt__, {'crm.status': mock_status}): + with patch.dict(crmshmod.__opts__, {'test': True}): + assert crmshmod.cluster_rsc_defaults_present('name', {'data': 'value'}) == ret + mock_status.assert_called_once_with() + + def test_rsc_defaults_present(self): + ''' + Test to check rsc_defaults_present + ''' + + ret = {'name': 'name', + 'changes': {'data1': 'value1', 'data2': 'value2'}, + 'result': True, + 'comment': 'Cluster rsc_defaults configured'} + + mock_status = MagicMock(return_value=0) + mock_configure_rsc_defaults = MagicMock() + with patch.dict(crmshmod.__salt__, {'crm.status': mock_status, + 'crm.configure_rsc_defaults': mock_configure_rsc_defaults}): + assert crmshmod.cluster_rsc_defaults_present( + name='name', + rsc_defaults={'data1': 'value1', 'data2': 'value2'}) == ret + mock_status.assert_called_once_with() + mock_configure_rsc_defaults.assert_has_calls([ + mock.call(option='data1', value='value1'), + mock.call(option='data2', value='value2') + ]) + + # 'cluster_op_defaults_present' function tests + + def test_op_defaults_present_no_cluster(self): + ''' + Test to check op_defaults_present when the cluster is not created + ''' + + ret = {'name': 'name', + 'changes': {}, + 'result': False, + 'comment': 'Cluster is not created yet. Run cluster_initialized before'} + + mock_status = MagicMock(return_value=1) + with patch.dict(crmshmod.__salt__, {'crm.status': mock_status}): + assert crmshmod.cluster_op_defaults_present('name', {'data': 'value'}) == ret + mock_status.assert_called_once_with() + + def test_op_defaults_present_test(self): + ''' + Test to check op_defaults_present in test mode + ''' + + ret = {'name': 'name', + 'changes': {'data': 'value'}, + 'result': None, + 'comment': 'Cluster op_defaults would be configured'} + + mock_status = MagicMock(return_value=0) + with patch.dict(crmshmod.__salt__, {'crm.status': mock_status}): + with patch.dict(crmshmod.__opts__, {'test': True}): + assert crmshmod.cluster_op_defaults_present('name', {'data': 'value'}) == ret + mock_status.assert_called_once_with() + + def test_op_defaults_present(self): + ''' + Test to check op_defaults_present + ''' + + ret = {'name': 'name', + 'changes': {'data1': 'value1', 'data2': 'value2'}, + 'result': True, + 'comment': 'Cluster op_defaults configured'} + + mock_status = MagicMock(return_value=0) + mock_configure_op_defaults = MagicMock() + with patch.dict(crmshmod.__salt__, {'crm.status': mock_status, + 'crm.configure_op_defaults': mock_configure_op_defaults}): + assert crmshmod.cluster_op_defaults_present( + name='name', + op_defaults={'data1': 'value1', 'data2': 'value2'}) == ret + mock_status.assert_called_once_with() + mock_configure_op_defaults.assert_has_calls([ + mock.call(option='data1', value='value1'), + mock.call(option='data2', value='value2') + ]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/salt-shaptools-0.3.4/tests/unit/states/test_hanamod.py new/salt-shaptools-0.3.6/tests/unit/states/test_hanamod.py --- old/salt-shaptools-0.3.4/tests/unit/states/test_hanamod.py 2020-03-31 20:02:39.980481668 +0200 +++ new/salt-shaptools-0.3.6/tests/unit/states/test_hanamod.py 2020-05-27 16:14:29.985993498 +0200 @@ -150,7 +150,7 @@ 'cp.get_file': mock_cp, 'file.move': mock_mv, 'hana.create_conf_file': mock_create_xml, - 'hana.update_hdb_pwd_file':mock_update_xml, + 'hana.update_hdb_pwd_file': mock_update_xml, 'hana.update_conf_file': mock_update, 'hana.install': mock_install, 'file.remove': mock_remove}): @@ -1079,11 +1079,12 @@ with patch.dict(hanamod.__salt__, {'file.mkdir': mock_mkdir, 'hana.extract_pydbapi': mock_extract_pydbapi}): assert hanamod.pydbapi_extracted( - 'PYDBAPI.tar', ['1234', '5678'], '/tmp/output', force=True) == ret + 'PYDBAPI.tar', ['1234', '5678'], '/tmp/output', + additional_extract_options='-l', force=True) == ret mock_mkdir.assert_called_once_with('/tmp/output') mock_extract_pydbapi.assert_called_once_with( - 'PYDBAPI.tar', ['1234', '5678'], '/tmp/output', '20') + 'PYDBAPI.tar', ['1234', '5678'], '/tmp/output', '20', '-l') def test_pydbapi_extracted_correct(self): ret = {'name': 'PYDBAPI.tar', @@ -1097,8 +1098,9 @@ with patch.dict(hanamod.__salt__, {'file.mkdir': mock_mkdir, 'hana.extract_pydbapi': mock_extract_pydbapi}): assert hanamod.pydbapi_extracted( - 'PYDBAPI.tar', ['1234', '5678'], '/tmp/output', force=True) == ret + 'PYDBAPI.tar', ['1234', '5678'], '/tmp/output', + force=True, additional_extract_options='-l') == ret mock_mkdir.assert_called_once_with('/tmp/output') mock_extract_pydbapi.assert_called_once_with( - 'PYDBAPI.tar', ['1234', '5678'], '/tmp/output', '20') + 'PYDBAPI.tar', ['1234', '5678'], '/tmp/output', '20', '-l')
