"""Fixtures for lambda testing.""" import os import mysql.connector import pytest import snowflake.connector from cryptography.hazmat.primitives import serialization from dotenv import load_dotenv from py.xml import html from pytest_html.extras import url from tests.integration.utils.dockerized_lambda_client import DockerizedLambdaAPIClient load_dotenv(override=True) os.environ['SNOWFLAKE_DATABASE'] = 'ROYALTY_ACCOUNTING' os.environ['SNOWFLAKE_SCHEMA'] = 'TEST' QA_BASE_URL = os.environ.get('QA_BASE_URL', 'http://snapshot-contracts-lambda:8080') JIRA_PREFIX_URL = 'https://theorchard.atlassian.net/browse/' PYTEST_REPORT_PREFIX = 'snapshot_contracts lambda integration tests results' PYTEST_REPORT_SUMMARY = ( 'This lambda inserts contract data ' 'into the Snowflake table ' 'BOOKED_ACCOUNT_CONTRACT_SNAPSHOT ' 'for the closed statement period' ) def dockerized_lambda_api_client(headers): """Create snapshot_contracts dockerized lambda object.""" return DockerizedLambdaAPIClient(QA_BASE_URL, headers) @pytest.fixture(scope='session') def basic_headers(): """Return basic headers.""" return {'Content-Type': 'application/json'} def check_db_empty(compare_func, table='ledger_adjustment_applied'): """Check whether table is empty.""" cnx = mysql.connector.connect( host='snapshot-contracts-mysql', port='3306', database='royalty_accounting', user='db_user', password='db_pass', ) cursor = cnx.cursor() cursor.execute('SELECT * FROM {}'.format(table)) cursor.fetchall() rc = cursor.rowcount assert compare_func(rc, 0) cursor.close() cnx.close() def get_table_row_count(table=''): """Return the number of rows in a table.""" cnx = mysql.connector.connect( host='snapshot-contracts-mysql', port='3306', database='royalty_accounting', user='db_user', password='db_pass', ) cursor = cnx.cursor() cursor.execute(f'SELECT COUNT(*) FROM {table}') count = cursor.fetchone()[0] cursor.close() cnx.close() return count @pytest.mark.optionalhook def pytest_html_results_summary(prefix, summary, postfix): """Populate report with info and summary.""" prefix.extend([html.p(PYTEST_REPORT_PREFIX)]) summary.extend([html.p(PYTEST_REPORT_SUMMARY)]) def pytest_html_results_table_header(cells): """Create results table header.""" cells.insert(1, html.th('Jira ID')) cells.insert(2, html.th('Description')) cells.pop() def pytest_html_results_table_row(report, cells): """Populate results table row.""" jira_ids = getattr(report, 'jira_ids', []) jira_links = [] for index, item in enumerate(jira_ids): link = url('{}{}'.format(JIRA_PREFIX_URL, item), item) if index == 0: jira_links.append(html.a(link['name'], href=link['content'])) else: jira_links.append(', ') jira_links.append(html.a(link['name'], href=link['content'])) jira_links_html = html.td(*jira_links) cells.insert(1, jira_links_html) cells.insert(2, html.td(report.description)) cells.pop() @pytest.hookimpl(hookwrapper=True) def pytest_runtest_makereport(item, call): """Populate results table.""" outcome = yield report = outcome.get_result() report.description = str(item.function.__doc__) if item.get_closest_marker('jira') is not None: to_populate = [] for item in item.get_closest_marker('jira').args: to_populate.append(item) report.jira_ids = to_populate else: report.jira_id = [] def _load_private_key(path: str, passphrase: str): path = os.path.expanduser(os.path.expandvars(path)) with open(path, 'rb') as key_file: return serialization.load_pem_private_key( key_file.read(), password=passphrase.encode() if passphrase else None, ) @pytest.fixture(scope='session') def snowflake_conn(): """Create snowflake connection.""" key_path = os.environ['SNOWFLAKE_PRIVATE_KEY_PATH'] passphrase = os.environ['SNOWFLAKE_KEY_PASSPHRASE'] private_key = _load_private_key(key_path, passphrase) conn = snowflake.connector.connect( user=os.environ['SNOWFLAKE_USER'], account=os.environ['SNOWFLAKE_ACCOUNT'], warehouse=os.environ['SNOWFLAKE_WAREHOUSE'], database=os.environ['SNOWFLAKE_DATABASE'], schema=os.environ['SNOWFLAKE_SCHEMA'], role=os.environ.get('SNOWFLAKE_ROLE'), private_key=private_key, ) try: yield conn finally: conn.close() def table_has_records(conn, db_name, db_schema) -> bool: """Check whether snowflake table has records.""" sql = ( f'SELECT 1 FROM {db_name}.{db_schema}.BOOKED_ACCOUNT_CONTRACT_SNAPSHOT LIMIT 1' # noqa: E501 ) with conn.cursor() as cur: cur.execute(sql) return cur.fetchone() is not None