def test_get_session_when_closed(self, mock_client): mock_client.return_value = mock_client mock_client.max_pool_connections = DEFAULT_POOL_LIMIT pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME) pooled_qldb_driver._is_closed = True self.assertRaises(DriverClosedError, pooled_qldb_driver.get_session)
def test_release_session(self, mock_client, mock_logger_debug, mock_qldb_session, mock_queue, mock_bounded_semaphore, mock_atomic_integer): mock_client.return_value = mock_client mock_client.max_pool_connections = DEFAULT_POOL_LIMIT pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME) pooled_qldb_driver._release_session(mock_qldb_session) mock_queue().put.assert_called_once_with(mock_qldb_session) mock_bounded_semaphore().release.assert_called_once_with() mock_atomic_integer().increment.assert_called_once_with() mock_logger_debug.assert_called_once()
def test_execute_lambda(self, mock_get_session, mock_client): mock_client.return_value = mock_client mock_lambda = Mock() mock_session = mock_get_session.return_value.__enter__.return_value mock_session.execute_lambda.return_value = MOCK_MESSAGE driver = PooledQldbDriver(MOCK_LEDGER_NAME) result = driver.execute_lambda(mock_lambda, mock_lambda) mock_get_session.assert_called_once_with() mock_session.execute_lambda.assert_called_once_with(mock_lambda, mock_lambda) self.assertEqual(result, MOCK_MESSAGE)
def test_create_new_session(self, mock_client, mock_session_start_session, mock_qldb_session): mock_session_start_session.return_value = mock_session_start_session mock_qldb_session.return_value = mock_qldb_session mock_client.return_value = mock_client mock_client.max_pool_connections = DEFAULT_POOL_LIMIT pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME) session = pooled_qldb_driver._create_new_session() mock_session_start_session.assert_called_once_with(MOCK_LEDGER_NAME, pooled_qldb_driver._client) mock_qldb_session.assert_called_once_with(mock_session_start_session, pooled_qldb_driver._read_ahead, pooled_qldb_driver._retry_limit, pooled_qldb_driver._executor) self.assertEqual(session, mock_qldb_session)
def test_close(self, mock_client, mock_qldb_session1, mock_qldb_session2, mock_close): mock_client.return_value = mock_client mock_client.max_pool_connections = DEFAULT_POOL_LIMIT pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME) pooled_qldb_driver._pool = Queue() pooled_qldb_driver._pool.put(mock_qldb_session1) pooled_qldb_driver._pool.put(mock_qldb_session2) pooled_qldb_driver.close() mock_close.assert_called_once_with() mock_qldb_session1.close.assert_called_once_with() mock_qldb_session2.close.assert_called_once_with()
def test_get_session_new_session(self, mock_client, mock_pooled_qldb_session, mock_create_new_session, mock_release_session, mock_bounded_semaphore, mock_atomic_integer): mock_pooled_qldb_session.return_value = mock_pooled_qldb_session mock_client.return_value = mock_client mock_client.max_pool_connections = DEFAULT_POOL_LIMIT pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME) session = pooled_qldb_driver.get_session() mock_bounded_semaphore().acquire.assert_called_once_with(timeout=DEFAULT_TIMEOUT_SECONDS) mock_atomic_integer().decrement.assert_called_once_with() mock_pooled_qldb_session.assert_called_once_with(mock_create_new_session(), mock_release_session) self.assertEqual(session, mock_pooled_qldb_session)
def test_execute_statement(self, mock_get_session, mock_client): mock_client.return_value = mock_client retry_indicator = Mock() mock_session = mock_get_session.return_value.__enter__.return_value mock_session.execute_statement.return_value = MOCK_MESSAGE driver = PooledQldbDriver(MOCK_LEDGER_NAME) result = driver.execute_statement(MOCK_STATEMENT, MOCK_PARAMETER_1, MOCK_PARAMETER_2, retry_indicator=retry_indicator) mock_get_session.assert_called_once_with() mock_session.execute_statement.assert_called_once_with(MOCK_STATEMENT, MOCK_PARAMETER_1, MOCK_PARAMETER_2, retry_indicator=retry_indicator) self.assertEqual(result, MOCK_MESSAGE)
def test_default_constructor_with_parameters(self, mock_config_merge, mock_client, mock_bounded_semaphore, mock_atomic_integer, mock_queue): mock_queue.return_value = mock_queue mock_atomic_integer.return_value = mock_atomic_integer mock_bounded_semaphore.return_value = mock_bounded_semaphore mock_client.return_value = mock_client mock_config_merge.return_value = mock_config_merge mock_config_merge.max_pool_connections = DEFAULT_POOL_LIMIT pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME, region_name=EMPTY_STRING, verify=EMPTY_STRING, endpoint_url=EMPTY_STRING, aws_access_key_id=EMPTY_STRING, aws_secret_access_key=EMPTY_STRING, aws_session_token=EMPTY_STRING, config=MOCK_CONFIG) mock_config_merge.assert_called_once() mock_client.assert_called_once_with(DEFAULT_SESSION_NAME, region_name=EMPTY_STRING, verify=EMPTY_STRING, endpoint_url=EMPTY_STRING, aws_access_key_id=EMPTY_STRING, aws_secret_access_key=EMPTY_STRING, aws_session_token=EMPTY_STRING, config=mock_config_merge) self.assertEqual(pooled_qldb_driver._ledger_name, MOCK_LEDGER_NAME) self.assertEqual(pooled_qldb_driver._retry_limit, DEFAULT_RETRY_LIMIT) self.assertEqual(pooled_qldb_driver._read_ahead, DEFAULT_READ_AHEAD) self.assertEqual(pooled_qldb_driver._pool_permits, mock_bounded_semaphore) self.assertEqual(pooled_qldb_driver._pool_permits_counter, mock_atomic_integer) self.assertEqual(pooled_qldb_driver._pool, mock_queue) mock_bounded_semaphore.assert_called_once_with(DEFAULT_POOL_LIMIT) mock_atomic_integer.assert_called_once_with(DEFAULT_POOL_LIMIT) mock_queue.assert_called_once_with()
def create_qldb_driver(ledger_name=Constants.LEDGER_NAME, region_name=None, endpoint_url=None, boto3_session=None): """ Create a QLDB driver for creating sessions. :type ledger_name: str :param ledger_name: The QLDB ledger name. :type region_name: str :param region_name: See [1]. :type endpoint_url: str :param endpoint_url: See [1]. :type boto3_session: :py:class:`boto3.session.Session` :param boto3_session: The boto3 session to create the client with (see [1]). :rtype: :py:class:`pyqldb.driver.pooled_qldb_driver.PooledQldbDriver` :return: A pooled QLDB driver object. [1]: `Boto3 Session.client Reference <https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/session.html#boto3.session.Session.client>`. """ qldb_driver = PooledQldbDriver(ledger_name=ledger_name, region_name=region_name, endpoint_url=endpoint_url, boto3_session=boto3_session) return qldb_driver
def test_get_session_existing_session(self, mock_client, mock_qldb_session, mock_pooled_qldb_session, mock_release_session, mock_bounded_semaphore, mock_atomic_integer, mock_logger_debug): mock_pooled_qldb_session.return_value = mock_pooled_qldb_session mock_client.return_value = mock_client mock_client.max_pool_connections = DEFAULT_POOL_LIMIT pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME) pooled_qldb_driver._pool = Queue() pooled_qldb_driver._pool.put(mock_qldb_session) session = pooled_qldb_driver.get_session() mock_qldb_session._abort_or_close.assert_called_once_with() mock_pooled_qldb_session.assert_called_once_with(mock_qldb_session, mock_release_session) self.assertEqual(session, mock_pooled_qldb_session) mock_bounded_semaphore().acquire.assert_called_once_with(timeout=DEFAULT_TIMEOUT_SECONDS) mock_atomic_integer().decrement.assert_called_once_with() self.assertEqual(mock_logger_debug.call_count, 2)
def __init__(self, ledger_name=LEDGER_NAME, region_name=REGION, endpoint_url=None, boto3_session=None, aws_access_key_id=ACCESSID, aws_secret_access_key=ACCESSSECRETKEY): self.bd = PooledQldbDriver(ledger_name=ledger_name, region_name=region_name, endpoint_url=endpoint_url, boto3_session=boto3_session, aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key) self.logger = getLogger() self.logger.info('Instanciando driver')
def test_context_manager(self, mock_client, mock_close): mock_client.return_value = mock_client mock_client.max_pool_connections = DEFAULT_POOL_LIMIT with PooledQldbDriver(MOCK_LEDGER_NAME): pass mock_close.assert_called_once_with()
def test_constructor_with_boto3_session(self, mock_config_merge): mock_session = Mock(spec=MOCK_BOTO3_SESSION) mock_config_merge.return_value = mock_config_merge mock_config_merge.max_pool_connections = DEFAULT_POOL_LIMIT pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME, boto3_session=mock_session, config=MOCK_CONFIG) mock_session.client.assert_called_once_with(DEFAULT_SESSION_NAME, config=mock_config_merge, endpoint_url=None, verify=None) self.assertEqual(pooled_qldb_driver._client, mock_session.client())
def create_qldb_driver(ledger_name=Constants.LEDGER_NAME, region_name=None, endpoint_url=None, boto3_session=None): qldb_driver = PooledQldbDriver(ledger_name=ledger_name, region_name=region_name, endpoint_url=endpoint_url, boto3_session=boto3_session) return qldb_driver
def test_get_session_session_pool_empty_error(self, mock_client, mock_bounded_semaphore, mock_session_pool_empty_error, mock_logger_debug): mock_client.return_value = mock_client mock_client.max_pool_connections = DEFAULT_POOL_LIMIT mock_bounded_semaphore().acquire.return_value = False mock_session_pool_empty_error.return_value = Exception pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME) self.assertRaises(Exception, pooled_qldb_driver.get_session) mock_session_pool_empty_error.assert_called_once_with(DEFAULT_TIMEOUT_SECONDS) mock_logger_debug.assert_called_once()
def __create_qldb_driver(self, ledger_name="testLedger", region_name=None, endpoint_url=None, boto3_session=None): #creates the authentication using IAM with application information qldb_driver = PooledQldbDriver(ledger_name=ledger_name, region_name=region_name, endpoint_url=endpoint_url, boto3_session=boto3_session) self.pooled_qldb_driver = qldb_driver
def test_constructor_with_boto3_session_and_parameters_that_may_overwrite(self, mock_config_merge, mock_logger_warning): mock_session = Mock(spec=MOCK_BOTO3_SESSION) mock_config_merge.return_value = mock_config_merge mock_config_merge.max_pool_connections = DEFAULT_POOL_LIMIT region_name = 'region_name' pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME, boto3_session=mock_session, config=MOCK_CONFIG, region_name=region_name) mock_session.client.assert_called_once_with(DEFAULT_SESSION_NAME, config=mock_config_merge, endpoint_url=None, verify=None) self.assertEqual(pooled_qldb_driver._client, mock_session.client()) mock_logger_warning.assert_called_once()
def test_get_session_exception(self, mock_client, mock_pooled_qldb_session, mock_bounded_semaphore, mock_atomic_integer): mock_client.return_value = mock_client mock_client.max_pool_connections = DEFAULT_POOL_LIMIT pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME) mock_pooled_qldb_session.side_effect = Exception self.assertRaises(Exception, pooled_qldb_driver.get_session) mock_bounded_semaphore().acquire.assert_called_once_with(timeout=DEFAULT_TIMEOUT_SECONDS) mock_atomic_integer().decrement.assert_called_once_with() mock_bounded_semaphore().release.assert_called_once_with() mock_atomic_integer().increment.assert_called_once_with()
def test_get_session_session_with_different_timeout(self, mock_client, mock_bounded_semaphore, mock_session_pool_empty_error, mock_logger_debug): mock_client.return_value = mock_client mock_client.max_pool_connections = DEFAULT_POOL_LIMIT mock_bounded_semaphore().acquire.return_value = False mock_session_pool_empty_error.return_value = Exception new_timeout = 20 pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME, timeout=new_timeout) self.assertRaises(Exception, pooled_qldb_driver.get_session) mock_bounded_semaphore().acquire.assert_called_once_with(timeout=new_timeout) mock_session_pool_empty_error.assert_called_once_with(new_timeout) mock_logger_debug.assert_called_once()
def test_context_manager_with_invalid_session_error(self, mock_client, mock_close, mock_session_client): mock_client.return_value = mock_client mock_client.max_pool_connections = DEFAULT_POOL_LIMIT mock_invalid_session_error_message = {'Error': {'Code': 'InvalidSessionException', 'Message': MOCK_MESSAGE}} mock_invalid_session_error = ClientError(mock_invalid_session_error_message, MOCK_MESSAGE) mock_session_client.start_session.side_effect = mock_invalid_session_error with self.assertRaises(ClientError): with PooledQldbDriver(MOCK_LEDGER_NAME) as pooled_qldb_driver: pooled_qldb_driver._create_new_session() mock_close.assert_called_once_with()
def driver(self, ledger_name=None): if not ledger_name: ledger_name = self._default_ledger_name if ledger_name in self._drivers: return self._drivers.get(ledger_name) credentials = self.get_aws_credentials() self._drivers[ledger_name] = PooledQldbDriver( ledger_name=ledger_name, region_name=credentials['region_name'], aws_access_key_id=credentials['aws_access_key_id'], aws_secret_access_key=credentials['aws_secret_access_key'], ) return self._drivers[ledger_name]
def test_constructor_with_pool_limit_0(self, mock_client, mock_bounded_semaphore, mock_atomic_integer, mock_queue): mock_queue.return_value = mock_queue mock_atomic_integer.return_value = mock_atomic_integer mock_bounded_semaphore.return_value = mock_bounded_semaphore mock_client.return_value = mock_client mock_client.max_pool_connections = DEFAULT_POOL_LIMIT pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME) self.assertEqual(pooled_qldb_driver._ledger_name, MOCK_LEDGER_NAME) self.assertEqual(pooled_qldb_driver._retry_limit, DEFAULT_RETRY_LIMIT) self.assertEqual(pooled_qldb_driver._read_ahead, DEFAULT_READ_AHEAD) self.assertEqual(pooled_qldb_driver._pool_permits, mock_bounded_semaphore) self.assertEqual(pooled_qldb_driver._pool_permits_counter, mock_atomic_integer) self.assertEqual(pooled_qldb_driver._pool, mock_queue) mock_bounded_semaphore.assert_called_once_with(DEFAULT_POOL_LIMIT) mock_atomic_integer.assert_called_once_with(DEFAULT_POOL_LIMIT) mock_queue.assert_called_once_with()
class QLDBDriver(): def __init__(self, ledger_name=LEDGER_NAME, region_name=REGION, endpoint_url=None, boto3_session=None, aws_access_key_id=ACCESSID, aws_secret_access_key=ACCESSSECRETKEY): self.bd = PooledQldbDriver(ledger_name=ledger_name, region_name=region_name, endpoint_url=endpoint_url, boto3_session=boto3_session, aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key) self.logger = getLogger() self.logger.info('Instanciando driver') def create_qldb_session(self): self.logger.info('Creando session') qldb_session = self.bd.get_session() return qldb_session def execute_query(self, executor, query): self.logger.info('Ejecutando query {}...'.format(query)) return executor.execute_statement(query) def execute_insert(self, executor, table, data): data_json = json.dumps(data).replace("\"", "'").replace("[", "").replace("]", "") query = "INSERT INTO {} << {} >>".format(table, data_json) self.logger.info('Ejecutando Insert {}...'.format(query)) return executor.execute_statement(query) def create_insert(self, table, data): try: with self.create_qldb_session() as session: query_lambda = lambda executor: self.execute_insert( executor, table, data) query_retry = lambda retry_attempt: self.logger.info( 'Existen conflictos con este insert, intento: {}'.format( retry_attempt)) return session.execute_lambda(query_lambda, query_retry) except Exception: self.logger.exception('Error en query, tabla: {}'.format(table)) return None def create_query(self, query): try: with self.create_qldb_session() as session: query_lambda = lambda executor: self.execute_query( executor, query) query_retry = lambda retry_attempt: self.logger.info( 'Existen conflictos con este query, intento: {}'.format( retry_attempt)) cursor = session.execute_lambda(query_lambda, query_retry) rows = [] for row in cursor: r = ion.dumps(row, binary=False, omit_version_marker=True) r = ion.loads(r) rows.append(dict(r)) return rows except Exception: self.logger.exception('Error en query: {}'.format(query)) return None
import boto3 import json import hashlib from pyqldb.driver.pooled_qldb_driver import PooledQldbDriver qldb_driver = PooledQldbDriver(ledger_name='EPollLedger') def validateHash(transaction_executor, voterId): voteIdHash = hashlib.md5(voterId.encode('utf-8')).hexdigest() query = "SELECT * FROM Hashes AS vh WHERE vh.hash = ?", voteIdHash cursor = transaction_executor.execute_statement( "SELECT * FROM Hashes AS vh WHERE vh.hash = ?", voteIdHash) first_record = next(cursor, None) if first_record: return False, '' else: arg = {'hash': voteIdHash} transaction_executor.execute_statement("INSERT INTO Hashes ?", arg) query_2 = "SELECT hid FROM Hashes AS h BY hid WHERE Hashes = ?", voteIdHash cursor_2 = transaction_executor.execute_statement( "SELECT * FROM Hashes AS vh WHERE vh.hash = ?", voteIdHash) hashId = next(cursor_2, None) return True, hashId def getOptionId(transaction_executor, option): query = "SELECT oid FROM Options as o BY oid WHERE c.Options = ?", option cursor = transaction_executor.execute_statement( "SELECT oid FROM Options as o BY oid WHERE o.OptionName = ?", option)
def get_driver(ledger_name): return PooledQldbDriver(ledger_name=ledger_name, endpoint_url=QLDB_ENDPOINT)
def test_constructor_with_default_timeout(self, mock_client): mock_client.return_value = mock_client pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME) self.assertEqual(pooled_qldb_driver._timeout, DEFAULT_TIMEOUT_SECONDS)
def test_constructor_with_new_timeout(self, mock_client): mock_client.return_value = mock_client new_timeout = 10 pooled_qldb_driver = PooledQldbDriver(MOCK_LEDGER_NAME, timeout=new_timeout) self.assertEqual(pooled_qldb_driver._timeout, new_timeout)
def test_constructor_with_read_ahead_2(self, mock_client): mock_client.return_value = mock_client driver = PooledQldbDriver(MOCK_LEDGER_NAME, read_ahead=2) self.assertEqual(driver._read_ahead, 2)
def test_get_retry_limit(self, mock_client): mock_client.return_value = mock_client driver = PooledQldbDriver(MOCK_LEDGER_NAME) self.assertEqual(driver.retry_limit, driver._retry_limit)
def test_constructor_with_retry_limit_positive_value(self, mock_client): mock_client.return_value = mock_client driver = PooledQldbDriver(MOCK_LEDGER_NAME, retry_limit=1) self.assertEqual(driver._retry_limit, 1)