"""Fixtures for lambda testing.""" import os from dotenv import load_dotenv import httpx import mysql.connector from owsclient import M2MTokenManager from owsclient import OwsClient from py.xml import html import pytest from pytest_html.extras import url from secrets_manager.lambda_ext import LambdaSecretsManager from utils.dockerized_lambda_client import DockerizedLambdaAPIClient from utils.ows_abacus_schedule_client import AbacusScheduleAPIClient load_dotenv() import config # noqa: E402 from schedule_auto_add.constants import graphql as graphql_constants # noqa: E402 QA_BASE_URL = os.environ.get('QA_BASE_URL', 'http://schedule-auto-add-lambda:8080') ABACUS_SCHEDULE_QA_BASE_URL = os.environ.get( 'ABACUS_SCHEDULE_QA_BASE_URL', 'https://qa-ows-abacus-schedule.theorchard.io' ) CONTRIBUTOR_ID = os.environ.get( 'CONTRIBUTOR_ID', '2078df88-b9ed-416b-93a5-27f2c6caf858' ) CONTRIBUTION_ID = os.environ.get( 'CONTRIBUTION_ID', '8f3fa11c-3003-477a-849e-1ee00b52b5f5' ) # reporting JIRA_PREFIX_URL = 'https://theorchard.atlassian.net/browse/' PYTEST_REPORT_PREFIX = 'schedule_auto_add lambda integration tests results' PYTEST_REPORT_SUMMARY = 'Lambda for adding newly created ' \ 'contributions to the schedule marked ' \ '"auto_add" for the related contributor (if it exists.)' def dockerized_lambda_api_client(headers): """Create schedule_auto_add dockerized lambda object.""" return DockerizedLambdaAPIClient(QA_BASE_URL, headers) def abacus_schedule_api_client(headers): """Create ows_abacus_schedule object.""" return AbacusScheduleAPIClient( ABACUS_SCHEDULE_QA_BASE_URL, headers ) @pytest.fixture(scope='session') def basic_headers(): """Return basic headers.""" return {'Content-Type': 'application/json'} def mysql_client(): """Mysql client for integration tests.""" return mysql.connector.connect( host=os.environ.get('MYSQL_HOST'), port=os.environ.get('MYSQL_PORT'), database=os.environ.get('MYSQL_DB'), user=os.environ.get('MYSQL_USER'), password=os.environ.get('MYSQL_PASS') ) def db_select(schedule_name): """Query the DB.""" cnx = mysql_client() cursor = cnx.cursor(buffered=True, dictionary=True) query = """SELECT schedule_id FROM schedule where schedule_name=%(name)s""" params = {'name': schedule_name} cursor.execute(query, params) result = cursor.fetchall() cnx.commit() cnx.close() return result def query_the_db(query): """Query the DB.""" cnx = mysql_client() cursor = cnx.cursor() cursor.execute(query) cnx.commit() cnx.close() def query_the_db_with_values(query, values): """Query the DB.""" cnx = mysql_client() cursor = cnx.cursor() cursor.execute(query, values) cnx.commit() cnx.close() secrets_manager = LambdaSecretsManager( environment=config.QA_ENVIRONMENT, service_name=config.APPLICATION_NAME, ) m2m_token_manager = M2MTokenManager( secrets_manager=secrets_manager, environment=config.QA_ENVIRONMENT, service_name=config.APPLICATION_NAME, ) def gql_client_execute(graphql_query, graphql_parms): """Graphql client for integration testing.""" ows_client = OwsClient( service_name=config.APPLICATION_NAME, environment=config.QA_ENVIRONMENT, m2m_token_manager=m2m_token_manager ) response = ows_client.graphql_query( service_name='graphql-router', query=graphql_query, variables=graphql_parms, # m2m_identity_uuid of lambda-abacus-schedule-auto-add machine identity_id='b04a668c-53f9-47a4-a85d-90c6881ad242', profile_id=os.environ.get('ORCHARD_PROFILE_ID'), profile_type='AbacusProfile', correlation_id='integration-test-correlation-id', headers={ 'Orchard-Profile-Id': os.environ.get('ORCHARD_PROFILE_ID'), 'Orchard-Profile-UUID': os.environ.get('ORCHARD_PROFILE_UUID'), # m2m_identity_uuid of lambda-abacus-schedule-auto-add machine 'Orchard-Identity-Id': 'b04a668c-53f9-47a4-a85d-90c6881ad242', 'Orchard-Roles': 'administrator', 'Orchard-Profile-Type': 'AbacusProfile' }, timeout=httpx.Timeout(60) ) response_data = response.json() errors = response_data.get('errors') if errors: raise RuntimeError(f'GraphQL query failed: {errors}') return response_data def gql_get_contribution_info(contribution_id): """Get contribution info from graphql.""" contribution_info = gql_client_execute( graphql_constants.INEGR_TESTS_CONTRIBUTION_INFO_QUERY, {'id': contribution_id} ) return contribution_info def gql_unlink_contribution_from_schedule( contribution_id, schedule_id ): """Mutation to untie contribution from schedule.""" gql_client_execute( graphql_constants.INTEGR_TESTS_UNLINK_CONTRIBUTION_FROM_SCHEDULE_MUTATION, { 'contributionId': contribution_id, 'abacusScheduleId': schedule_id } ) @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 = []