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')


Reply via email to