From f5ee1f437487081b662b07dd73b816aadff63cff Mon Sep 17 00:00:00 2001 From: Xabier Arbulu Insausti Date: Wed, 29 May 2019 13:36:13 +0100 Subject: [PATCH] Update UT with the last changes --- python-shaptools.changes | 6 +++ .../connectors/base_connector.py | 6 +-- .../connectors/pyhdb_connector.py | 4 +- tests/hdb_connector/base_connect_test.py | 44 ++++++++++++++++++- tests/hdb_connector/dbapi_connector_test.py | 20 +++++---- tests/hdb_connector/pyhdb_connector_test.py | 41 ++++++++++++----- 6 files changed, 97 insertions(+), 24 deletions(-) diff --git a/python-shaptools.changes b/python-shaptools.changes index 357fb26..a7707fb 100644 --- a/python-shaptools.changes +++ b/python-shaptools.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Wed May 29 12:26:08 UTC 2019 - Ayoub Belarbi (abelarbi@suse.com) + +- Update hdb connector to return metadata besides the query + records. + ------------------------------------------------------------------- Thu May 16 09:35:41 UTC 2019 - Xabier Arbulu Insausti diff --git a/shaptools/hdb_connector/connectors/base_connector.py b/shaptools/hdb_connector/connectors/base_connector.py index 83baeee..4b14da6 100644 --- a/shaptools/hdb_connector/connectors/base_connector.py +++ b/shaptools/hdb_connector/connectors/base_connector.py @@ -56,9 +56,9 @@ def load_cursor(cls, cursor): Args: cursor (obj): Cursor object created by the connector (dbapi or pydhb) """ - instance = cls() - instance.records = cursor.fetchall() # TODO catch any exceptions raised by fetchall() - instance.metadata = cursor.description + records = cursor.fetchall() # TODO: catch any exceptions raised by fetchall() + metadata = cursor.description + instance = cls(records, metadata) instance._logger.info('query records: %s', instance.records) return instance diff --git a/shaptools/hdb_connector/connectors/pyhdb_connector.py b/shaptools/hdb_connector/connectors/pyhdb_connector.py index 97914a6..da886bf 100644 --- a/shaptools/hdb_connector/connectors/pyhdb_connector.py +++ b/shaptools/hdb_connector/connectors/pyhdb_connector.py @@ -57,13 +57,15 @@ def query(self, sql_statement): """ self._logger.info('executing sql query: %s', sql_statement) try: + cursor = None cursor = self._connection.cursor() cursor.execute(sql_statement) result = base_connector.QueryResult.load_cursor(cursor) except pyhdb.exceptions.DatabaseError as err: raise base_connector.QueryError('query failed: {}'.format(err)) finally: - cursor.close() + if cursor: + cursor.close() return result def disconnect(self): diff --git a/tests/hdb_connector/base_connect_test.py b/tests/hdb_connector/base_connect_test.py index c082a59..da2eabf 100644 --- a/tests/hdb_connector/base_connect_test.py +++ b/tests/hdb_connector/base_connect_test.py @@ -23,9 +23,51 @@ import mock +class TestQueryResul(unittest.TestCase): + """ + Unitary tests for base_connector.py QueryResult class + """ + + @classmethod + def setUpClass(cls): + """ + Global setUp. + """ + + logging.basicConfig(level=logging.INFO) + from shaptools.hdb_connector.connectors import base_connector + cls._base_connector = base_connector + + def setUp(self): + """ + Test setUp. + """ + + def tearDown(self): + """ + Test tearDown. + """ + + @classmethod + def tearDownClass(cls): + """ + Global tearDown. + """ + + @mock.patch('logging.Logger.info') + def test_load_cursor(self, logger): + mock_cursor = mock.Mock() + mock_cursor.description = 'metadata' + mock_cursor.fetchall.return_value = ['data1', 'data2'] + result = self._base_connector.QueryResult.load_cursor(mock_cursor) + logger.assert_called_once_with('query records: %s', ['data1', 'data2']) + self.assertEqual(result.records, ['data1', 'data2']) + self.assertEqual(result.metadata, 'metadata') + + class TestHana(unittest.TestCase): """ - Unitary tests for hana.py. + Unitary tests for base_connector.py BaseConnector class """ @classmethod diff --git a/tests/hdb_connector/dbapi_connector_test.py b/tests/hdb_connector/dbapi_connector_test.py index 193faa8..7ecd36b 100644 --- a/tests/hdb_connector/dbapi_connector_test.py +++ b/tests/hdb_connector/dbapi_connector_test.py @@ -89,11 +89,15 @@ def test_connect_error(self, mock_logger, mock_dbapi): mock_logger.assert_called_once_with( 'connecting to SAP HANA database at %s:%s', 'host', 1234) + @mock.patch('shaptools.hdb_connector.connectors.base_connector.QueryResult') @mock.patch('logging.Logger.info') - def test_query(self, mock_logger): + def test_query(self, mock_logger, mock_result): cursor_mock_instance = mock.Mock() cursor_mock = mock.Mock(return_value=cursor_mock_instance) - cursor_mock_instance.fetchall.return_value = 'result' + mock_result_inst = mock.Mock() + mock_result_inst.records = ['data1', 'data2'] + mock_result_inst.metadata = 'metadata' + mock_result.load_cursor.return_value = mock_result_inst context_manager_mock = mock.Mock( __enter__ = cursor_mock, __exit__ = mock.Mock() @@ -101,16 +105,14 @@ def test_query(self, mock_logger): self._conn._connection = mock.Mock() self._conn._connection.cursor.return_value = context_manager_mock - response = self._conn.query('query') + result = self._conn.query('query') cursor_mock_instance.execute.assert_called_once_with('query') - cursor_mock_instance.fetchall.assert_called_once_with() + mock_result.load_cursor.assert_called_once_with(cursor_mock_instance) - self.assertEqual(response.data, 'result') - mock_logger.assert_has_calls([ - mock.call('executing sql query: %s', 'query'), - mock.call('query result: %s', 'result') - ]) + self.assertEqual(result.records, ['data1', 'data2']) + self.assertEqual(result.metadata, 'metadata') + mock_logger.assert_called_once_with('executing sql query: %s', 'query') @mock.patch('shaptools.hdb_connector.connectors.dbapi_connector.dbapi') @mock.patch('logging.Logger.info') diff --git a/tests/hdb_connector/pyhdb_connector_test.py b/tests/hdb_connector/pyhdb_connector_test.py index a0c948d..5d5e633 100644 --- a/tests/hdb_connector/pyhdb_connector_test.py +++ b/tests/hdb_connector/pyhdb_connector_test.py @@ -90,37 +90,58 @@ def test_connect_error(self, mock_logger, mock_pyhdb, mock_socket): mock_logger.assert_called_once_with( 'connecting to SAP HANA database at %s:%s', 'host', 1234) + @mock.patch('shaptools.hdb_connector.connectors.base_connector.QueryResult') @mock.patch('logging.Logger.info') - def test_query(self, mock_logger): + def test_query(self, mock_logger, mock_result): mock_cursor = mock.Mock() - mock_cursor.fetchall.return_value = 'result' self._conn._connection = mock.Mock() self._conn._connection.cursor.return_value = mock_cursor - response = self._conn.query('query') + mock_result_inst = mock.Mock() + mock_result_inst.records = ['data1', 'data2'] + mock_result_inst.metadata = 'metadata' + mock_result.load_cursor.return_value = mock_result_inst + + result = self._conn.query('query') mock_cursor.execute.assert_called_once_with('query') - mock_cursor.fetchall.assert_called_once_with() + mock_result.load_cursor.assert_called_once_with(mock_cursor) - self.assertEqual(response.data, 'result') - mock_logger.assert_has_calls([ - mock.call('executing sql query: %s', 'query'), - mock.call('query result: %s', 'result') - ]) + self.assertEqual(result.records, ['data1', 'data2']) + self.assertEqual(result.metadata, 'metadata') + mock_logger.assert_called_once_with('executing sql query: %s', 'query') + mock_cursor.close.assert_called_once_with() @mock.patch('shaptools.hdb_connector.connectors.pyhdb_connector.pyhdb') @mock.patch('logging.Logger.info') def test_query_error(self, mock_logger, mock_pyhdb): mock_pyhdb.exceptions.DatabaseError = PyhdbException self._conn._connection = mock.Mock() - self._conn._connection.cursor.side_effect = mock_pyhdb.exceptions.DatabaseError('error') + self._conn._connection.cursor.side_effect = PyhdbException('error') + with self.assertRaises(self._pyhdb_connector.base_connector.QueryError) as err: + self._conn.query('query') + + self.assertTrue('query failed: {}'.format('error') in str(err.exception)) + self._conn._connection.cursor.assert_called_once_with() + mock_logger.assert_called_once_with('executing sql query: %s', 'query') + + @mock.patch('shaptools.hdb_connector.connectors.pyhdb_connector.pyhdb') + @mock.patch('logging.Logger.info') + def test_query_error_execute(self, mock_logger, mock_pyhdb): + mock_pyhdb.exceptions.DatabaseError = PyhdbException + self._conn._connection = mock.Mock() + cursor_mock = mock.Mock() + self._conn._connection.cursor.return_value = cursor_mock + cursor_mock.execute = mock.Mock() + cursor_mock.execute.side_effect = PyhdbException('error') with self.assertRaises(self._pyhdb_connector.base_connector.QueryError) as err: self._conn.query('query') self.assertTrue('query failed: {}'.format('error') in str(err.exception)) self._conn._connection.cursor.assert_called_once_with() mock_logger.assert_called_once_with('executing sql query: %s', 'query') + cursor_mock.close.assert_called_once_with() @mock.patch('logging.Logger.info') def test_disconnect(self, mock_logger):