Hello community,

here is the log from the commit of package python-shaptools for 
openSUSE:Factory checked in at 2019-07-21 11:33:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-shaptools (Old)
 and      /work/SRC/openSUSE:Factory/.python-shaptools.new.4126 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-shaptools"

Sun Jul 21 11:33:39 2019 rev:4 rq:716587 version:0.3.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-shaptools/python-shaptools.changes        
2019-06-17 21:34:04.671014358 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-shaptools.new.4126/python-shaptools.changes  
    2019-07-21 11:33:40.348784109 +0200
@@ -1,0 +2,6 @@
+Wed Jul 17 09:34:22 UTC 2019 - Xabier Arbulu Insausti <[email protected]>
+
+- Create package version 0.3.0
+- shapcli is provided to expose shaptools api methods as command line tool 
+
+-------------------------------------------------------------------

Old:
----
  shaptools-0.2.1.tar.gz

New:
----
  shaptools-0.3.0.tar.gz

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

Other differences:
------------------
++++++ python-shaptools.spec ++++++
--- /var/tmp/diff_new_pack.xpgQtE/_old  2019-07-21 11:33:41.008783997 +0200
+++ /var/tmp/diff_new_pack.xpgQtE/_new  2019-07-21 11:33:41.008783997 +0200
@@ -22,7 +22,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-shaptools
-Version:        0.2.1
+Version:        0.3.0
 Release:        0
 Summary:        Python tools to interact with SAP HANA utilities
 License:        Apache-2.0
@@ -67,5 +67,6 @@
 %license LICENSE
 %endif
 %{python_sitelib}/*
+%python3_only %{_bindir}/shapcli
 
 %changelog

++++++ shaptools-0.2.1.tar.gz -> shaptools-0.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/shaptools-0.2.1/bin/shapcli 
new/shaptools-0.3.0/bin/shapcli
--- old/shaptools-0.2.1/bin/shapcli     1970-01-01 01:00:00.000000000 +0100
+++ new/shaptools-0.3.0/bin/shapcli     2019-07-18 11:03:12.820176367 +0200
@@ -0,0 +1,9 @@
+#!/usr/bin/env python3
+"""
+Shaptools command line tool
+"""
+
+from shaptools import shapcli
+
+if __name__ == "__main__":
+    shapcli.run()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/shaptools-0.2.1/docs/SHAPCLI.md 
new/shaptools-0.3.0/docs/SHAPCLI.md
--- old/shaptools-0.2.1/docs/SHAPCLI.md 1970-01-01 01:00:00.000000000 +0100
+++ new/shaptools-0.3.0/docs/SHAPCLI.md 2019-07-18 11:03:12.820176367 +0200
@@ -0,0 +1,51 @@
+# SHAPCLI
+
+shapcli is an executable tool to use the api provided by shaptools. It wraps 
most of the commands and
+exposes them as a command line tool.
+
+In order to use the utility the `shaptools` library must be installed (either 
using `pip` or `rpm` package).
+
+## Disclaimer
+
+This tool will only work if `shaptools` is installed for `python 3` version.
+
+## Motivation
+
+The major motivation behind this tools is to provide an easy way to run all of 
the tools provided by
+SAP regarding HANA. It wraps the next commands: `HDB`, `hdbnsutil`, 
`hdbuserstore`,
+`HDBSettings.sh`, `hdbsql`.
+
+Using this tool be avoid the need to change to SAP users every time we need to 
run any of these
+commands. This is really helpful when we are running other commands in the 
same time (as `crmsh`
+commands for example). Besides, having all of them gathered in the same place 
makes the usage
+easier.
+
+## How to use
+
+`shapcli` can be used providing the SAP HANA database information through 
command line or using a
+json configuration file (the options are mutually exclusive).
+Here an example of how to create the configuration file: 
[config.json](shapcli.config.example)
+
+Here some examples:
+
+```
+shapcli -s sid -i 00 -p HANAPASSWORD hana version
+shapcli -c config.json hana version
+```
+
+Check how it works and help output running:
+
+```
+shapcli -h
+```
+
+The main options are: `hana` and `sr`;
+
+* `hana`: Commands to manage SAP HANA database general functionalities.
+* `sr`: Commands to manage SAP HANA system replication.
+
+Using the `-h` flag in each option will output a new help output. For example:
+
+```
+shapcli hana -h
+```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/shaptools-0.2.1/docs/shapcli.config.example 
new/shaptools-0.3.0/docs/shapcli.config.example
--- old/shaptools-0.2.1/docs/shapcli.config.example     1970-01-01 
01:00:00.000000000 +0100
+++ new/shaptools-0.3.0/docs/shapcli.config.example     2019-07-18 
11:03:12.820176367 +0200
@@ -0,0 +1,5 @@
+{
+  "sid": "prd",
+  "instance": "00",
+  "password": "HANAPASSWORD"
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/shaptools-0.2.1/python-shaptools.changes 
new/shaptools-0.3.0/python-shaptools.changes
--- old/shaptools-0.2.1/python-shaptools.changes        2019-06-12 
15:57:43.139230730 +0200
+++ new/shaptools-0.3.0/python-shaptools.changes        2019-07-18 
11:03:12.820176367 +0200
@@ -1,4 +1,10 @@
 -------------------------------------------------------------------
+Wed Jul 17 09:34:22 UTC 2019 - Xabier Arbulu Insausti <[email protected]>
+
+- Create package version 0.3.0
+- shapcli is provided to expose shaptools api methods as command line tool 
+
+-------------------------------------------------------------------
 Tue Jun 11 11:29:44 UTC 2019 - Xabier Arbulu Insausti <[email protected]>
 
 - Create package version 0.2.1 with fixed spec files. Now the package
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/shaptools-0.2.1/python-shaptools.spec 
new/shaptools-0.3.0/python-shaptools.spec
--- old/shaptools-0.2.1/python-shaptools.spec   2019-06-12 15:57:43.139230730 
+0200
+++ new/shaptools-0.3.0/python-shaptools.spec   2019-07-18 11:03:12.820176367 
+0200
@@ -22,7 +22,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-shaptools
-Version:        0.2.1
+Version:        0.3.0
 Release:        0
 Summary:        Python tools to interact with SAP HANA utilities
 License:        Apache-2.0
@@ -67,5 +67,6 @@
 %license LICENSE
 %endif
 %{python_sitelib}/*
+%python3_only %{_bindir}/shapcli
 
 %changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/shaptools-0.2.1/setup.py new/shaptools-0.3.0/setup.py
--- old/shaptools-0.2.1/setup.py        2019-06-12 15:57:43.139230730 +0200
+++ new/shaptools-0.3.0/setup.py        2019-07-18 11:03:12.820176367 +0200
@@ -40,7 +40,7 @@
 
 ]
 
-SCRIPTS = []
+SCRIPTS = ['bin/shapcli']
 
 DEPENDENCIES = read('requirements.txt').split()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/shaptools-0.2.1/shaptools/__init__.py 
new/shaptools-0.3.0/shaptools/__init__.py
--- old/shaptools-0.2.1/shaptools/__init__.py   2019-06-12 15:57:43.139230730 
+0200
+++ new/shaptools-0.3.0/shaptools/__init__.py   2019-07-18 11:03:12.820176367 
+0200
@@ -6,4 +6,4 @@
 :since: 2018-11-15
 """
 
-__version__ = "0.2.1"
+__version__ = "0.3.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/shaptools-0.2.1/shaptools/shapcli.py 
new/shaptools-0.3.0/shaptools/shapcli.py
--- old/shaptools-0.2.1/shaptools/shapcli.py    1970-01-01 01:00:00.000000000 
+0100
+++ new/shaptools-0.3.0/shaptools/shapcli.py    2019-07-18 11:03:12.820176367 
+0200
@@ -0,0 +1,353 @@
+"""
+Code to expose some useful methods using the command line
+
+:author: xarbulu
+:organization: SUSE LLC
+:contact: [email protected]
+
+:since: 2019-07-11
+"""
+
+import logging
+import argparse
+import json
+
+from shaptools import hana
+
+PROG = 'shapcli'
+LOGGING_FORMAT = '%(message)s'
+
+
+class DecodedFormatter(logging.Formatter):
+    """
+    Custom formatter to remove the b'' from the logged text
+    """
+
+    def format(self, record):
+        message = super(DecodedFormatter, self).format(record)
+        if message.startswith('b\''):
+            message = message.split('\'')[1]
+        return message
+
+
+def setup_logger(level):
+    """
+    Setup logging
+    """
+    logger = logging.getLogger()
+    handler = logging.StreamHandler()
+    formatter = DecodedFormatter(LOGGING_FORMAT)
+    handler.setFormatter(formatter)
+    logger.addHandler(handler)
+    logger.setLevel(level=level)
+    return logger
+
+
+def parse_arguments():
+    """
+    Parse command line arguments
+    """
+    parser = argparse.ArgumentParser(PROG)
+
+    parser.add_argument(
+        '-v', '--verbosity',
+        help='Python logging level. Options: DEBUG, INFO, WARN, ERROR (INFO by 
default)')
+    parser.add_argument(
+        '-r', '--remotely',
+        help='Run the command in other machine using ssh')
+    parser.add_argument(
+        '-c', '--config',
+        help='JSON configuration file with SAP HANA instance data (sid, 
instance and password)')
+    parser.add_argument(
+        '-s', '--sid', help='SAP HANA sid')
+    parser.add_argument(
+        '-i', '--instance', help='SAP HANA instance')
+    parser.add_argument(
+        '-p', '--password', help='SAP HANA password')
+
+    subcommands = parser.add_subparsers(
+        title='subcommands', description='valid subcommands', help='additional 
help')
+    hana_subparser = subcommands.add_parser(
+        'hana', help='Commands to interact with SAP HANA databse')
+    sr_subparser = subcommands.add_parser(
+        'sr', help='Commands to interact with SAP HANA system replication')
+
+    parse_hana_arguments(hana_subparser)
+    parse_sr_arguments(sr_subparser)
+
+    args = parser.parse_args()
+    return parser, args
+
+
+def parse_hana_arguments(hana_subparser):
+    """
+    Parse hana subcommand arguements
+    """
+    subcommands = hana_subparser.add_subparsers(
+        title='hana', dest='hana', help='Commands to interact with SAP HANA 
databse')
+    subcommands.add_parser(
+        'is_running', help='Check if SAP HANA database is running')
+    subcommands.add_parser(
+        'version', help='Show SAP HANA database version')
+    subcommands.add_parser(
+        'start', help='Start SAP HANA database')
+    subcommands.add_parser(
+        'stop', help='Stop SAP HANA database')
+    subcommands.add_parser(
+        'info', help='Show SAP HANA database information')
+    subcommands.add_parser(
+        'kill', help='Kill all SAP HANA database processes')
+    subcommands.add_parser(
+        'overview', help='Show SAP HANA database overview')
+    subcommands.add_parser(
+        'landscape', help='Show SAP HANA database landscape')
+    subcommands.add_parser(
+        'uninstall', help='Uninstall SAP HANA database instance')
+    dummy = subcommands.add_parser(
+        'dummy', help='Get data from DUMMY table')
+    dummy.add_argument(
+        '--key_name',
+        help='Keystore to connect to sap hana db '\
+        '(if this value is set user, password and database are omitted')
+    dummy.add_argument(
+        '--user_name', help='User to connect to sap hana db')
+    dummy.add_argument(
+        '--user_password', help='Password to connect to sap hana db')
+    dummy.add_argument(
+        '--database', help='Database name to connect')
+
+    hdbsql = subcommands.add_parser(
+        'hdbsql', help='Run a sql command with hdbsql')
+    hdbsql.add_argument(
+        '--key_name',
+        help='Keystore to connect to sap hana db '\
+        '(if this value is set user, password and database are omitted')
+    hdbsql.add_argument(
+        '--user_name', help='User to connect to sap hana db')
+    hdbsql.add_argument(
+        '--user_password', help='Password to connect to sap hana db')
+    hdbsql.add_argument(
+        '--database', help='Database name to connect')
+    hdbsql.add_argument(
+        '--query', help='Query to execute')
+
+    user_key = subcommands.add_parser(
+        'user', help='Create a new user key')
+    user_key.add_argument(
+        '--key_name', help='Key name', required=True)
+    user_key.add_argument(
+        '--environment', help='Database location (host:port)', required=True)
+    user_key.add_argument(
+        '--user_name', help='User to connect to sap hana db', required=True)
+    user_key.add_argument(
+        '--user_password', help='Password to connect to sap hana db', 
required=True)
+    user_key.add_argument(
+        '--database', help='Database name to connect', required=True)
+
+    backup = subcommands.add_parser(
+        'backup', help='Create node backup')
+    backup.add_argument(
+        '--name', help='Backup file name', required=True)
+    backup.add_argument(
+        '--database', help='Database name to connect', required=True)
+    backup.add_argument(
+        '--key_name', help='Key name')
+    backup.add_argument(
+        '--user_name', help='User to connect to sap hana db')
+    backup.add_argument(
+        '--user_password', help='Password to connect to sap hana db')
+
+
+def parse_sr_arguments(sr_subparser):
+    """
+    Parse hana sr subcommand arguements
+    """
+    subcommands = sr_subparser.add_subparsers(
+        title='sr', dest='sr', help='Commands to interact with SAP HANA system 
replication')
+    state = subcommands.add_parser(
+        'state', help='Show SAP HANA system replication state')
+    state.add_argument('--sapcontrol', help='Run with sapcontrol', 
action='store_true')
+    status = subcommands.add_parser(
+        'status', help='Show SAP HANAsystem replication status')
+    status.add_argument('--sapcontrol', help='Run with sapcontrol', 
action='store_true')
+    subcommands.add_parser(
+        'disable', help='Disable SAP HANA system replication (to be executed 
in Primary node)')
+    cleanup = subcommands.add_parser(
+        'cleanup', help='Cleanup SAP HANA system replication')
+    cleanup.add_argument('--force', help='Force the cleanup', 
action='store_true')
+    subcommands.add_parser(
+        'takeover', help='Perform a takeover operation (to be executed in 
Secondary node)')
+    enable = subcommands.add_parser(
+        'enable', help='Enable SAP HANA system replication primary site')
+    enable.add_argument('--name', help='Primary site name', required=True)
+    register = subcommands.add_parser(
+        'register', help='Register SAP HANA system replication secondary site')
+    register.add_argument('--name', help='Secondary site name', required=True)
+    register.add_argument('--remote_host', help='Primary site hostname', 
required=True)
+    register.add_argument(
+        '--remote_instance', help='Primary site SAP HANA instance number', 
required=True)
+    register.add_argument(
+        '--replication_mode', help='System replication replication mode', 
default='sync')
+    register.add_argument(
+        '--operation_mode', help='System replication operation mode', 
default='logreplay')
+    unregister = subcommands.add_parser(
+        'unregister', help='Unegister SAP HANA system replication secondary 
site')
+    unregister.add_argument('--name', help='Primary site name', required=True)
+    copy_ssfs = subcommands.add_parser(
+        'copy_ssfs', help='Copy current node ssfs files to other host')
+    copy_ssfs.add_argument('--remote_host', help='Other host name', 
required=True)
+    copy_ssfs.add_argument(
+        '--remote_password',
+        help='Other host SAP HANA instance password (sid and instance must 
match '\
+        'with the current host)', required=True)
+
+
+# pylint:disable=W0212
+def uninstall(hana_instance, logger):
+    """
+    Uninstall SAP HANA database instance
+    """
+    logger.info(
+        'This command will uninstall SAP HANA instance '\
+        'with sid %s and instance number %s (y/n): ',
+        hana_instance.sid, hana_instance.inst)
+    response = input()
+    if response == 'y':
+        user = hana.HanaInstance.HANAUSER.format(sid=hana_instance.sid)
+        hana_instance.uninstall(user, hana_instance._password)
+    else:
+        logger.info('Command execution canceled')
+
+
+def run_hdbsql(hana_instance, hana_args, cmd):
+    """
+    Run hdbsql command
+    """
+    hdbsql_cmd = hana_instance._hdbsql_connect(
+        key_name=hana_args.key_name,
+        user_name=hana_args.user_name,
+        user_password=hana_args.user_password)
+    cmd = '{hdbsql_cmd} {database}\\"{cmd}\\"'.format(
+        hdbsql_cmd=hdbsql_cmd,
+        database='-d {} '.format(hana_args.database) if hana_args.database 
else '',
+        cmd=cmd)
+    hana_instance._run_hana_command(cmd)
+
+def run_hana_subcommands(hana_instance, hana_args, logger):
+    """
+    Run hana subcommands
+    """
+    str_args = hana_args.hana
+    if str_args == 'is_running':
+        result = hana_instance.is_running()
+        logger.info('SAP HANA database running state: %s', result)
+    elif str_args == 'version':
+        hana_instance.get_version()
+    elif str_args == 'start':
+        hana_instance.start()
+    elif str_args == 'stop':
+        hana_instance.stop()
+    elif str_args == 'info':
+        hana_instance._run_hana_command('HDB info')
+    elif str_args == 'kill':
+        hana_instance._run_hana_command('HDB kill-9')
+    elif str_args == 'overview':
+        hana_instance._run_hana_command('HDBSettings.sh systemOverview.py')
+    elif str_args == 'landscape':
+        hana_instance._run_hana_command('HDBSettings.sh 
landscapeHostConfiguration.py')
+    elif str_args == 'uninstall':
+        uninstall(hana_instance, logger)
+    elif str_args == 'dummy':
+        run_hdbsql(hana_instance, hana_args, 'SELECT * FROM DUMMY')
+    elif str_args == 'hdbsql':
+        run_hdbsql(hana_instance, hana_args, hana_args.query)
+    elif str_args == 'user':
+        hana_instance.create_user_key(
+            hana_args.key_name, hana_args.environment, hana_args.user_name,
+            hana_args.user_password, hana_args.database)
+    elif str_args == 'backup':
+        hana_instance.create_backup(
+            hana_args.database, hana_args.name, hana_args.key_name,
+            hana_args.user_name, hana_args.user_password)
+
+
+def run_sr_subcommands(hana_instance, sr_args, logger):
+    """
+    Run hana subcommands
+    """
+    str_args = sr_args.sr
+    if str_args == 'state':
+        # hana_instance.get_sr_state()
+        cmd = 'hdbnsutil -sr_state{}'.format(' --sapcontrol=1' if 
sr_args.sapcontrol else '')
+        hana_instance._run_hana_command(cmd)
+    elif str_args == 'status':
+        # hana_instance.get_sr_status()
+        cmd = 'HDBSettings.sh systemReplicationStatus.py{}'.format(
+            ' --sapcontrol=1' if sr_args.sapcontrol else '')
+        hana_instance._run_hana_command(cmd)
+    elif str_args == 'disable':
+        hana_instance.sr_disable_primary()
+    elif str_args == 'cleanup':
+        hana_instance.sr_cleanup(sr_args.force)
+    elif str_args == 'takeover':
+        hana_instance._run_hana_command('hdbnsutil -sr_takeover')
+    elif str_args == 'enable':
+        hana_instance.sr_enable_primary(sr_args.name)
+    elif str_args == 'register':
+        hana_instance.sr_register_secondary(
+            sr_args.name, sr_args.remote_host, sr_args.remote_instance,
+            sr_args.replication_mode, sr_args.operation_mode)
+    elif str_args == 'unregister':
+        hana_instance.sr_unregister_secondary(sr_args.name)
+    elif str_args == 'copy_ssfs':
+        hana_instance.copy_ssfs_files(sr_args.remote_host, 
sr_args.remote_password)
+
+
+def load_config_file(config_file, logger):
+    """
+    Load configuration file data
+    """
+    with open(config_file, 'r') as f_ptr:
+        json_data = json.load(f_ptr)
+    try:
+        return (json_data['sid'], json_data['instance'], json_data['password'])
+    except KeyError as err:
+        logger.error(err)
+        logger.error('Configuration file must have the sid, instance and 
password entries')
+        raise
+
+
+# pylint:disable=W0212
+def run():
+    """
+    Main execution
+    """
+    parser, args = parse_arguments()
+    logger = setup_logger(args.verbosity or logging.DEBUG)
+
+    if args.config:
+        sid, instance, password = load_config_file(args.config, logger)
+    elif args.sid and args.instance and args.password:
+        sid = args.sid
+        instance = args.instance
+        password = args.password
+    else:
+        logger.info(
+            'Configuration file or sid,instance and passwords parameters must 
be provided\n')
+        parser.print_help()
+        exit(1)
+    try:
+        hana_instance = hana.HanaInstance(sid, instance, password)
+        if vars(args).get('hana'):
+            run_hana_subcommands(hana_instance, args, logger)
+        elif vars(args).get('sr'):
+            run_sr_subcommands(hana_instance, args, logger)
+        else:
+            parser.print_help()
+    except Exception as err:
+        logger.error(err)
+        exit(1)
+
+
+if __name__ == "__main__": # pragma: no cover
+    run()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/shaptools-0.2.1/tests/shapcli_test.py 
new/shaptools-0.3.0/tests/shapcli_test.py
--- old/shaptools-0.2.1/tests/shapcli_test.py   1970-01-01 01:00:00.000000000 
+0100
+++ new/shaptools-0.3.0/tests/shapcli_test.py   2019-07-18 11:03:12.824176437 
+0200
@@ -0,0 +1,613 @@
+"""
+Unitary tests for shaptools/shapcli.py.
+
+:author: xarbulu
+:organization: SUSE LLC
+:contact: [email protected]
+
+:since: 2019-07-16
+"""
+
+# pylint:disable=C0103,C0111,W0212,W0611
+
+import os
+import sys
+sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 
'..')))
+
+import logging
+
+try:
+    from unittest import mock
+except ImportError:
+    import mock
+
+import pytest
+
+from shaptools import shapcli
+
+
+class TestShapCli(object):
+    """
+    Unitary tests for shaptools/shapcli.py.
+    """
+
+    def test_format(self):
+        mock_record = mock.Mock(
+            name='test',
+            level=1,
+            pathname='path',
+            lineno=1,
+            msg='msg',
+            args=(),
+            exc_info=None,
+            exc_text=None,
+            stack_info=None
+        )
+        mock_record.getMessage.return_value = 'msg'
+        formatter = shapcli.DecodedFormatter()
+        message = formatter.format(mock_record)
+        assert message == 'msg'
+
+        mock_record.getMessage.return_value = "b'msg'"
+        formatter = shapcli.DecodedFormatter()
+        message = formatter.format(mock_record)
+        assert message == 'msg'
+
+    @mock.patch('logging.getLogger')
+    @mock.patch('logging.StreamHandler')
+    @mock.patch('shaptools.shapcli.DecodedFormatter')
+    def test_setup_logger(self, mock_formatter, mock_stream_handler, 
mock_get_logger):
+
+        mock_logger_instance = mock.Mock()
+        mock_get_logger.return_value = mock_logger_instance
+
+        mock_stream_instance = mock.Mock()
+        mock_stream_handler.return_value = mock_stream_instance
+
+        mock_formatter_instance = mock.Mock()
+        mock_formatter.return_value = mock_formatter_instance
+
+        logger = shapcli.setup_logger('INFO')
+
+        mock_formatter.assert_called_once_with(shapcli.LOGGING_FORMAT)
+        mock_stream_handler.assert_called_once_with()
+        mock_get_logger.assert_called_once_with()
+        
mock_stream_instance.setFormatter.assert_called_once_with(mock_formatter_instance)
+
+        
mock_logger_instance.addHandler.assert_called_once_with(mock_stream_instance)
+        mock_logger_instance.setLevel.assert_called_once_with(level='INFO')
+
+        assert logger == mock_logger_instance
+
+    @mock.patch('argparse.ArgumentParser')
+    @mock.patch('shaptools.shapcli.parse_hana_arguments')
+    @mock.patch('shaptools.shapcli.parse_sr_arguments')
+    def test_parse_arguments(
+        self, mock_parse_sr_arguments, mock_parse_hana_arguments, 
mock_argument_parser):
+
+        mock_argument_parser_instance = mock.Mock()
+        mock_argument_parser.return_value = mock_argument_parser_instance
+        mock_argument_parser_instance.parse_args.return_value = 'args'
+
+        mock_subcommands = mock.Mock()
+        mock_argument_parser_instance.add_subparsers.return_value = 
mock_subcommands
+
+        mock_hana = mock.Mock()
+        mock_sr = mock.Mock()
+        mock_subcommands.add_parser.side_effect = [mock_hana, mock_sr]
+
+        my_parser, my_args = shapcli.parse_arguments()
+
+        mock_argument_parser.assert_called_once_with(shapcli.PROG)
+
+        mock_argument_parser_instance.add_argument.assert_has_calls([
+            mock.call('-v', '--verbosity',
+                help='Python logging level. Options: DEBUG, INFO, WARN, ERROR 
(INFO by default)'),
+            mock.call('-r', '--remotely',
+                help='Run the command in other machine using ssh'),
+            mock.call('-c', '--config',
+                help='JSON configuration file with SAP HANA instance data 
(sid, instance and password)'),
+            mock.call('-s', '--sid',
+                help='SAP HANA sid'),
+            mock.call('-i', '--instance',
+                help='SAP HANA instance'),
+            mock.call('-p', '--password',
+                help='SAP HANA password')
+        ])
+
+        assert mock_argument_parser_instance.add_argument.call_count == 6
+
+        mock_argument_parser_instance.add_subparsers.assert_called_once_with(
+            title='subcommands', description='valid subcommands', 
help='additional help')
+
+        mock_subcommands.add_parser.assert_has_calls([
+            mock.call('hana', help='Commands to interact with SAP HANA 
databse'),
+            mock.call('sr', help='Commands to interact with SAP HANA system 
replication')
+        ])
+
+        mock_parse_sr_arguments.assert_called_once_with(mock_sr)
+        mock_parse_hana_arguments.assert_called_once_with(mock_hana)
+
+        mock_argument_parser_instance.parse_args.assert_called_once_with()
+
+        assert my_parser == mock_argument_parser_instance
+        assert my_args == 'args'
+
+    def test_parse_hana_arguments(self):
+
+        mock_subparser = mock.Mock()
+        mock_subcommands = mock.Mock()
+        mock_subparser.add_subparsers.return_value = mock_subcommands
+
+        mock_dummy = mock.Mock()
+        mock_hdbsql = mock.Mock()
+        mock_user_key = mock.Mock()
+        mock_backup = mock.Mock()
+
+        mock_subcommands.add_parser.side_effect = [
+            None, None, None, None, None, None, None, None, None,
+            mock_dummy, mock_hdbsql, mock_user_key, mock_backup
+        ]
+
+        shapcli.parse_hana_arguments(mock_subparser)
+
+        mock_subparser.add_subparsers.assert_called_once_with(
+            title='hana', dest='hana', help='Commands to interact with SAP 
HANA databse')
+
+        mock_subcommands.add_parser.assert_has_calls([
+            mock.call('is_running', help='Check if SAP HANA database is 
running'),
+            mock.call('version', help='Show SAP HANA database version'),
+            mock.call('start', help='Start SAP HANA database'),
+            mock.call('stop', help='Stop SAP HANA database'),
+            mock.call('info', help='Show SAP HANA database information'),
+            mock.call('kill', help='Kill all SAP HANA database processes'),
+            mock.call('overview', help='Show SAP HANA database overview'),
+            mock.call('landscape', help='Show SAP HANA database landscape'),
+            mock.call('uninstall', help='Uninstall SAP HANA database 
instance'),
+            mock.call('dummy', help='Get data from DUMMY table'),
+            mock.call('hdbsql', help='Run a sql command with hdbsql'),
+            mock.call('user', help='Create a new user key'),
+            mock.call('backup', help='Create node backup')
+        ])
+
+        mock_dummy.add_argument.assert_has_calls([
+            mock.call('--key_name',
+                help='Keystore to connect to sap hana db '\
+                '(if this value is set user, password and database are 
omitted'),
+            mock.call('--user_name', help='User to connect to sap hana db'),
+            mock.call('--user_password', help='Password to connect to sap hana 
db'),
+            mock.call('--database', help='Database name to connect')
+        ])
+
+        mock_hdbsql.add_argument.assert_has_calls([
+            mock.call('--key_name',
+                help='Keystore to connect to sap hana db '\
+                '(if this value is set user, password and database are 
omitted'),
+            mock.call('--user_name', help='User to connect to sap hana db'),
+            mock.call('--user_password', help='Password to connect to sap hana 
db'),
+            mock.call('--database', help='Database name to connect'),
+            mock.call('--query', help='Query to execute')
+        ])
+
+        mock_user_key.add_argument.assert_has_calls([
+            mock.call('--key_name', help='Key name', required=True),
+            mock.call('--environment', help='Database location (host:port)', 
required=True),
+            mock.call('--user_name', help='User to connect to sap hana db', 
required=True),
+            mock.call('--user_password', help='Password to connect to sap hana 
db', required=True),
+            mock.call('--database', help='Database name to connect', 
required=True)
+        ])
+
+        mock_backup.add_argument.assert_has_calls([
+            mock.call('--name', help='Backup file name', required=True),
+            mock.call('--database', help='Database name to connect', 
required=True),
+            mock.call('--key_name', help='Key name'),
+            mock.call('--user_name', help='User to connect to sap hana db'),
+            mock.call('--user_password', help='Password to connect to sap hana 
db')
+        ])
+
+    def test_parse_sr_arguments(self):
+
+        mock_subparser = mock.Mock()
+        mock_subcommands = mock.Mock()
+        mock_subparser.add_subparsers.return_value = mock_subcommands
+
+        mock_state = mock.Mock()
+        mock_status = mock.Mock()
+        mock_cleanup = mock.Mock()
+        mock_enable= mock.Mock()
+        mock_register = mock.Mock()
+        mock_unregister= mock.Mock()
+        mock_copy_ssfs= mock.Mock()
+
+        mock_subcommands.add_parser.side_effect = [
+            mock_state, mock_status, None, mock_cleanup, None, mock_enable,
+            mock_register, mock_unregister, mock_copy_ssfs
+        ]
+
+        shapcli.parse_sr_arguments(mock_subparser)
+
+        mock_subparser.add_subparsers.assert_called_once_with(
+            title='sr', dest='sr', help='Commands to interact with SAP HANA 
system replication')
+
+        mock_subcommands.add_parser.assert_has_calls([
+            mock.call('state', help='Show SAP HANA system replication state'),
+            mock.call('status', help='Show SAP HANAsystem replication status'),
+            mock.call('disable', help='Disable SAP HANA system replication (to 
be executed in Primary node)'),
+            mock.call('cleanup', help='Cleanup SAP HANA system replication'),
+            mock.call('takeover', help='Perform a takeover operation (to be 
executed in Secondary node)'),
+            mock.call('enable', help='Enable SAP HANA system replication 
primary site'),
+            mock.call('register', help='Register SAP HANA system replication 
secondary site'),
+            mock.call('unregister', help='Unegister SAP HANA system 
replication secondary site'),
+            mock.call('copy_ssfs', help='Copy current node ssfs files to other 
host')
+        ])
+
+        mock_state.add_argument.assert_called_once_with(
+            '--sapcontrol', help='Run with sapcontrol', action='store_true')
+
+        mock_status.add_argument.assert_called_once_with(
+            '--sapcontrol', help='Run with sapcontrol', action='store_true')
+
+        mock_cleanup.add_argument.assert_called_once_with(
+            '--force', help='Force the cleanup', action='store_true'),
+
+        mock_enable.add_argument.assert_called_once_with(
+            '--name', help='Primary site name', required=True)
+
+        mock_register.add_argument.assert_has_calls([
+            mock.call('--name', help='Secondary site name', required=True),
+            mock.call('--remote_host', help='Primary site hostname', 
required=True),
+            mock.call('--remote_instance', help='Primary site SAP HANA 
instance number', required=True),
+            mock.call('--replication_mode', help='System replication 
replication mode', default='sync'),
+            mock.call('--operation_mode', help='System replication operation 
mode', default='logreplay')
+        ])
+
+        mock_unregister.add_argument.assert_called_once_with(
+            '--name', help='Primary site name', required=True)
+
+        mock_copy_ssfs.add_argument.assert_has_calls([
+            mock.call('--remote_host', help='Other host name', required=True),
+            mock.call('--remote_password',
+                help='Other host SAP HANA instance password (sid and instance 
must match '\
+                'with the current host)', required=True)
+        ])
+
+    @mock.patch('shaptools.shapcli.input')
+    def test_uninstall(self, mock_input):
+
+        mock_hana_instance = mock.Mock(sid='prd', inst='00', _password='pass')
+        mock_logger = mock.Mock()
+        mock_input.return_value = 'y'
+
+        shapcli.uninstall(mock_hana_instance, mock_logger)
+
+        mock_input.assert_called_once_with()
+        mock_logger.info.assert_called_once_with(
+            'This command will uninstall SAP HANA instance '\
+            'with sid %s and instance number %s (y/n): ', 'prd', '00')
+        mock_hana_instance.uninstall.assert_called_once_with('prdadm', 'pass')
+
+    @mock.patch('shaptools.shapcli.input')
+    def test_uninstall_cancel(self, mock_input):
+
+        mock_hana_instance = mock.Mock(sid='prd', inst='00', _password='pass')
+        mock_logger = mock.Mock()
+        mock_input.return_value = 'n'
+
+        shapcli.uninstall(mock_hana_instance, mock_logger)
+
+        mock_input.assert_called_once_with()
+        mock_logger.info.assert_has_calls([
+            mock.call(
+                'This command will uninstall SAP HANA instance '\
+                'with sid %s and instance number %s (y/n): ', 'prd', '00'),
+            mock.call('Command execution canceled')
+        ])
+
+    def test_run_hdbsql(self):
+        mock_hana_instance = mock.Mock(sid='prd', inst='00', _password='pass')
+        args = mock.Mock(key_name='key', user_name='user', 
user_password='pass', database='db')
+
+        mock_hana_instance._hdbsql_connect.return_value = 'hdbsql'
+
+        shapcli.run_hdbsql(mock_hana_instance, args, 'cmd')
+
+        mock_hana_instance._hdbsql_connect.assert_called_once_with(
+            key_name='key', user_name='user', user_password='pass')
+
+        mock_hana_instance._run_hana_command.assert_called_once_with(
+            'hdbsql -d db \\"cmd\\"'
+        )
+
+    @mock.patch('shaptools.shapcli.run_hdbsql')
+    @mock.patch('shaptools.shapcli.uninstall')
+    def test_run_hana_subcommands(self, mock_uninstall, mock_run_hdbsql):
+
+        mock_hana_instance = mock.Mock()
+        mock_logger = mock.Mock()
+
+        mock_hana_instance.is_running.return_value = 1
+        mock_hana_args = mock.Mock(hana='is_running')
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance.is_running.assert_called_once_with()
+        mock_logger.info.assert_called_once_with('SAP HANA database running 
state: %s', 1)
+
+        mock_hana_args = mock.Mock(hana='version')
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance.get_version.assert_called_once_with()
+
+        mock_hana_args = mock.Mock(hana='start')
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance.start.assert_called_once_with()
+
+        mock_hana_args = mock.Mock(hana='stop')
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance.stop.assert_called_once_with()
+
+        mock_hana_args = mock.Mock(hana='info')
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance._run_hana_command.assert_called_once_with('HDB 
info')
+        mock_hana_instance.reset_mock()
+
+        mock_hana_args = mock.Mock(hana='kill')
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance._run_hana_command.assert_called_once_with('HDB 
kill-9')
+        mock_hana_instance.reset_mock()
+
+        mock_hana_args = mock.Mock(hana='overview')
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        
mock_hana_instance._run_hana_command.assert_called_once_with('HDBSettings.sh 
systemOverview.py')
+        mock_hana_instance.reset_mock()
+
+        mock_hana_args = mock.Mock(hana='landscape')
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        
mock_hana_instance._run_hana_command.assert_called_once_with('HDBSettings.sh 
landscapeHostConfiguration.py')
+        mock_hana_instance.reset_mock()
+
+        mock_hana_args = mock.Mock(hana='uninstall')
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_uninstall.assert_called_once_with(mock_hana_instance, mock_logger)
+
+        mock_hana_args = mock.Mock(hana='dummy')
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_run_hdbsql.assert_called_once_with(mock_hana_instance, 
mock_hana_args, 'SELECT * FROM DUMMY')
+        mock_run_hdbsql.reset_mock()
+
+        mock_hana_args = mock.Mock(hana='hdbsql', query='query')
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_run_hdbsql.assert_called_once_with(mock_hana_instance, 
mock_hana_args, 'query')
+        mock_run_hdbsql.reset_mock()
+
+        mock_hana_args = mock.Mock(
+            hana='user', key_name='key', environment='env',
+            user_name='user', user_password='pass', database='db')
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance.create_user_key.assert_called_once_with('key', 
'env', 'user', 'pass', 'db')
+
+        mock_hana_args = mock.Mock(
+            hana='backup', database='db', key_name='key',
+            user_name='user', user_password='pass')
+        mock_hana_args.name = 'name'
+        shapcli.run_hana_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance.create_backup.assert_called_once_with('db', 'name', 
'key', 'user', 'pass')
+
+    def test_run_sr_subcommands(self):
+
+        mock_hana_instance = mock.Mock()
+        mock_logger = mock.Mock()
+
+        mock_hana_args = mock.Mock(sr='state', sapcontrol=True)
+        shapcli.run_sr_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        cmd = 'hdbnsutil -sr_state --sapcontrol=1'
+        mock_hana_instance._run_hana_command.assert_called_once_with(cmd)
+        mock_hana_instance.reset_mock()
+
+        mock_hana_args = mock.Mock(sr='state', sapcontrol=False)
+        shapcli.run_sr_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        cmd = 'hdbnsutil -sr_state'
+        mock_hana_instance._run_hana_command.assert_called_once_with(cmd)
+        mock_hana_instance.reset_mock()
+
+        mock_hana_args = mock.Mock(sr='status', sapcontrol=True)
+        shapcli.run_sr_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        cmd = 'HDBSettings.sh systemReplicationStatus.py --sapcontrol=1'
+        mock_hana_instance._run_hana_command.assert_called_once_with(cmd)
+        mock_hana_instance.reset_mock()
+
+        mock_hana_args = mock.Mock(sr='status', sapcontrol=False)
+        shapcli.run_sr_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        cmd = 'HDBSettings.sh systemReplicationStatus.py'
+        mock_hana_instance._run_hana_command.assert_called_once_with(cmd)
+        mock_hana_instance.reset_mock()
+
+        mock_hana_args = mock.Mock(sr='disable')
+        shapcli.run_sr_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance.sr_disable_primary.assert_called_once_with()
+
+        mock_hana_args = mock.Mock(sr='cleanup', force=True)
+        shapcli.run_sr_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance.sr_cleanup.assert_called_once_with(True)
+
+        mock_hana_args = mock.Mock(sr='takeover')
+        shapcli.run_sr_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        
mock_hana_instance._run_hana_command.assert_called_once_with('hdbnsutil 
-sr_takeover')
+        mock_hana_instance.reset_mock()
+        mock_hana_instance.reset_mock()
+
+        mock_hana_args = mock.Mock(sr='enable')
+        mock_hana_args.name = 'primary'
+        shapcli.run_sr_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance.sr_enable_primary.assert_called_once_with('primary')
+        mock_hana_instance.reset_mock()
+
+        mock_hana_args = mock.Mock(
+            sr='register', remote_host='remote', remote_instance='00',
+            replication_mode='repl', operation_mode='oper')
+        mock_hana_args.name = 'secondary'
+        shapcli.run_sr_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance.sr_register_secondary.assert_called_once_with(
+            'secondary', 'remote', '00', 'repl', 'oper')
+        mock_hana_instance.reset_mock()
+
+        mock_hana_args = mock.Mock(sr='unregister')
+        mock_hana_args.name = 'secondary'
+        shapcli.run_sr_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        
mock_hana_instance.sr_unregister_secondary.assert_called_once_with('secondary')
+        mock_hana_instance.reset_mock()
+
+        mock_hana_args = mock.Mock(sr='copy_ssfs', remote_host='remote', 
remote_password='pass')
+        shapcli.run_sr_subcommands(mock_hana_instance, mock_hana_args, 
mock_logger)
+        mock_hana_instance.copy_ssfs_files.assert_called_once_with('remote', 
'pass')
+        mock_hana_instance.reset_mock()
+
+    @mock.patch('shaptools.shapcli.json.load')
+    @mock.patch('shaptools.shapcli.open')
+    def test_load_config_file(self, mock_open, mock_json_load):
+
+        mock_logger = mock.Mock()
+        mock_json_load.return_value = {'sid': 'prd', 'instance': '00', 
'password': 'pass'}
+
+        data = shapcli.load_config_file('config.json', mock_logger)
+        assert data[0] == 'prd'
+        assert data[1] == '00'
+        assert data[2] == 'pass'
+
+    @mock.patch('shaptools.shapcli.json.load')
+    @mock.patch('shaptools.shapcli.open')
+    def test_load_config_file_error(self, mock_open, mock_json_load):
+
+        mock_logger = mock.Mock()
+        mock_json_load.return_value = {'sid': 'prd', 'instance': '00'}
+
+        with pytest.raises(KeyError) as err:
+            shapcli.load_config_file('config.json', mock_logger)
+
+        mock_logger.error.assert_has_calls([
+            mock.call('Configuration file must have the sid, instance and 
password entries')
+        ])
+
+    @mock.patch('shaptools.shapcli.run_hana_subcommands')
+    @mock.patch('shaptools.shapcli.hana.HanaInstance')
+    @mock.patch('shaptools.shapcli.load_config_file')
+    @mock.patch('shaptools.shapcli.setup_logger')
+    @mock.patch('shaptools.shapcli.parse_arguments')
+    def test_run_hana(
+            self, mock_parse_arguments, mock_setup_logger,
+            mock_load_config_file, mock_hana,
+            mock_run_hana_subcommands):
+
+        mock_parser = mock.Mock()
+        mock_args = mock.Mock(verbosity='INFO', config='config.json', 
hana=True)
+        mock_logger = mock.Mock()
+        mock_hana_instance = mock.Mock()
+        mock_parse_arguments.return_value = [mock_parser, mock_args]
+        mock_setup_logger.return_value = mock_logger
+        mock_load_config_file.return_value = ['prd', '00', 'pass']
+        mock_hana.return_value = mock_hana_instance
+
+        shapcli.run()
+
+        mock_parse_arguments.assert_called_once_with()
+        mock_setup_logger.assert_called_once_with('INFO')
+        mock_load_config_file.assert_called_once_with('config.json', 
mock_logger)
+        mock_hana.assert_called_once_with('prd', '00', 'pass')
+        mock_run_hana_subcommands.assert_called_once_with(mock_hana_instance, 
mock_args, mock_logger)
+
+    @mock.patch('shaptools.shapcli.run_sr_subcommands')
+    @mock.patch('shaptools.shapcli.hana.HanaInstance')
+    @mock.patch('shaptools.shapcli.setup_logger')
+    @mock.patch('shaptools.shapcli.parse_arguments')
+    def test_run_sr(
+            self, mock_parse_arguments, mock_setup_logger,
+            mock_hana, mock_run_sr_subcommands):
+
+        mock_parser = mock.Mock()
+        mock_args = mock.Mock(
+            verbosity='INFO', config=False, sid='qas', instance='01', 
password='mypass', sr=True)
+        mock_logger = mock.Mock()
+        mock_hana_instance = mock.Mock()
+        mock_parse_arguments.return_value = [mock_parser, mock_args]
+        mock_setup_logger.return_value = mock_logger
+        mock_hana.return_value = mock_hana_instance
+
+        shapcli.run()
+
+        mock_parse_arguments.assert_called_once_with()
+        mock_setup_logger.assert_called_once_with('INFO')
+        mock_hana.assert_called_once_with('qas', '01', 'mypass')
+        mock_run_sr_subcommands.assert_called_once_with(mock_hana_instance, 
mock_args, mock_logger)
+
+    @mock.patch('shaptools.shapcli.hana.HanaInstance')
+    @mock.patch('shaptools.shapcli.setup_logger')
+    @mock.patch('shaptools.shapcli.parse_arguments')
+    def test_run_help(
+            self, mock_parse_arguments, mock_setup_logger, mock_hana):
+
+        mock_parser = mock.Mock()
+        mock_args = mock.Mock(
+            verbosity='INFO', config=False, sid='qas', instance='01', 
password='mypass')
+        mock_logger = mock.Mock()
+        mock_hana_instance = mock.Mock()
+        mock_parse_arguments.return_value = [mock_parser, mock_args]
+        mock_setup_logger.return_value = mock_logger
+        mock_hana.return_value = mock_hana_instance
+
+        shapcli.run()
+
+        mock_parse_arguments.assert_called_once_with()
+        mock_setup_logger.assert_called_once_with('INFO')
+        mock_hana.assert_called_once_with('qas', '01', 'mypass')
+        mock_parser.print_help.assert_called_once_with()
+
+
+    @mock.patch('shaptools.shapcli.setup_logger')
+    @mock.patch('shaptools.shapcli.parse_arguments')
+    def test_run_sr_invalid_params(self, mock_parse_arguments, 
mock_setup_logger):
+
+        mock_parser = mock.Mock()
+        mock_args = mock.Mock(
+            verbosity=False, config=False, sid='qas', instance='01', 
password=False, sr=True)
+        mock_logger = mock.Mock()
+        mock_hana_instance = mock.Mock()
+        mock_parse_arguments.return_value = [mock_parser, mock_args]
+        mock_setup_logger.return_value = mock_logger
+
+        with pytest.raises(SystemExit) as my_exit:
+            shapcli.run()
+
+        assert my_exit.type == SystemExit
+        assert my_exit.value.code == 1
+
+        mock_parse_arguments.assert_called_once_with()
+        mock_setup_logger.assert_called_once_with(logging.DEBUG)
+        mock_logger.info.assert_called_once_with(
+            'Configuration file or sid,instance and passwords parameters must 
be provided\n')
+        mock_parser.print_help.assert_called_once_with()
+
+    @mock.patch('shaptools.shapcli.run_sr_subcommands')
+    @mock.patch('shaptools.shapcli.hana.HanaInstance')
+    @mock.patch('shaptools.shapcli.setup_logger')
+    @mock.patch('shaptools.shapcli.parse_arguments')
+    def test_run_error(
+            self, mock_parse_arguments, mock_setup_logger,
+            mock_hana, mock_run_sr_subcommands):
+
+        mock_parser = mock.Mock()
+        mock_args = mock.Mock(
+            verbosity='INFO', config=False, sid='qas', instance='01', 
password='mypass', sr=True)
+        mock_logger = mock.Mock()
+        mock_hana_instance = mock.Mock()
+        mock_parse_arguments.return_value = [mock_parser, mock_args]
+        mock_setup_logger.return_value = mock_logger
+        mock_hana.return_value = mock_hana_instance
+        mock_run_sr_subcommands.side_effect = ValueError('my error')
+
+        with pytest.raises(SystemExit) as my_exit:
+            shapcli.run()
+
+        assert my_exit.type == SystemExit
+        assert my_exit.value.code == 1
+
+        mock_parse_arguments.assert_called_once_with()
+        mock_setup_logger.assert_called_once_with('INFO')
+        mock_hana.assert_called_once_with('qas', '01', 'mypass')
+        mock_run_sr_subcommands.assert_called_once_with(mock_hana_instance, 
mock_args, mock_logger)


Reply via email to