"""Help functions for Projections integration test.""" from datetime import datetime from datetime import timedelta import json import subprocess from subprocess import Popen import time from boto.exception import SWFResponseError from boto.s3.connection import Bucket from boto.s3.connection import Key from boto.s3.connection import S3Connection import boto.swf.layer1 as swf import boto3 from flows import config as flows_config from flows import datastore from flows.projections import config as flow_config from integration_tests.flows.projections import config as test_config from integration_tests.flows.projections import queries def _prepare_s3(): """Upload test CSV file to S3.""" file_bucket = Bucket(S3Connection(), test_config.test_bucket_name) key_object = Key(file_bucket) key_object.key = test_config.source_file_data['s3_path'] with open( test_config.source_file_data['local_path'], mode='r') as csv_file: key_object.set_contents_from_string(csv_file.read()) def clean_database(): """Drop all test tables.""" datastore.execute('DROP TABLE IF EXISTS test_projections_revenue_etl_log;') datastore.execute('DROP TABLE IF EXISTS test_projections_revenue;') temp_table = '{table_name}_{correlation_id}'.format( table_name=flow_config.PROJECTIONS_REVENUE, correlation_id=test_config.correlation_id) datastore.execute('DROP TABLE IF EXISTS {temp_table};'.format( temp_table=temp_table)) datastore.execute('DROP TABLE IF EXISTS test_digital_revenue;') datastore.execute('DROP TABLE IF EXISTS test_cable_revenue;') datastore.execute('DROP TABLE IF EXISTS test_theatrical_revenue;') def _create_test_tables(): """Create tables for integration test.""" # create main flow tables datastore.execute( 'CREATE TABLE test_projections_revenue_etl_log ' 'LIKE projections_revenue_etl_log;') datastore.execute( 'CREATE TABLE test_projections_revenue ' 'LIKE projections_revenue;') # create revenue tables datastore.execute( 'CREATE TABLE test_digital_revenue ' 'LIKE digital_revenue;') datastore.execute( 'CREATE TABLE test_cable_revenue ' 'LIKE cable_revenue;') datastore.execute( 'CREATE TABLE test_theatrical_revenue ' 'LIKE theatrical_revenue;') def _prepare_mysql(): """Clear required db tables.""" clean_database() _create_test_tables() # insert test revenu data datastore.execute(queries.insert_revenue, test_config.test_revenue_data) def prepare_data(): """Prepare test data.""" _prepare_s3() _prepare_mysql() def _run_flow(): """Run flow.""" params = { 'domain': flows_config.SWF_DOMAIN, 'executionStartToCloseTimeout': str(flow_config.SWF_WORKFLOW_TIMEOUT), 'taskList': {'name': flow_config.SWF_WORKFLOW_NAME}, 'workflowId': test_config.SWF_WORKFLOW_ID, 'workflowType': { 'name': flow_config.SWF_WORKFLOW_NAME, 'version': flow_config.SWF_WORKFLOW_VERSION} } context = { 'correlation_id': test_config.correlation_id, 's3_bucket': test_config.test_bucket_name, 's3_key': test_config.source_file_data['s3_path'] } swf_client = boto3.client('swf', region_name=flows_config.SWF_REGION_NAME) return swf_client.start_workflow_execution( input=json.dumps(context), **params) def execute_flow(): """Execute Projections workflow.""" try: try: swf.Layer1().terminate_workflow_execution( test_config.domain, test_config.SWF_WORKFLOW_ID) except SWFResponseError: # if no flow with the same id running pass # start worker process worker_process = Popen( [test_config.python_path, test_config.application_path, 'worker', 'projections'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) time.sleep(5) # start decider process decider_process = Popen( [test_config.python_path, test_config.application_path, 'decider', 'projections'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # waiting for activities initialization time.sleep(20) # run flow execution run_response = _run_flow() # get workflow run id run_id = run_response['runId'] # wait for workflow execution end max_time = datetime.now() + timedelta( seconds=test_config.flow_execution_timeout) while datetime.now() < max_time: execution = swf.Layer1().describe_workflow_execution( domain=test_config.domain, workflow_id=test_config.SWF_WORKFLOW_ID, run_id=run_id) print(execution) time.sleep(1) if execution['executionInfo'].get('executionStatus') != 'CLOSED': time.sleep(10) if datetime.now() > max_time: raise TimeoutError('Projections flow execution timeout') else: break except Exception as e: print(e) raise finally: worker_process.kill() decider_process.kill()