# pylint: disable=unused-argument import json import uuid from datetime import datetime, timezone from unittest.mock import MagicMock as Mock import pytest from db_schema.schemas.apps import UnitOfWorkPriorityEnum as AppsUnitOfWorkPriorityEnum from db_schema.schemas.slz import UnitOfWorkPriorityEnum as SlzUnitOfWorkPriorityEnum from delphi_slz_admin.services.reprocessing import ( ReprocessingLambdaInvalidResponse, ReprocessingService, ) FREEZED_DT = datetime(2015, 10, 15, 12, 23, 45, tzinfo=timezone.utc) @pytest.mark.freeze_time(FREEZED_DT) def test_reprocess_slz_uows_ok(db, clean_db, content_status, mocker): mocker.patch('uuid.uuid4', return_value=uuid.UUID('96c7cb9b-778b-4ef2-8b54-840daf6f4c8c')) api_response = {'StatusCode': 202} mocked_call: Mock = mocker.patch( 'botocore.client.BaseClient._make_api_call', return_value=api_response ) service = ReprocessingService(db) priority = SlzUnitOfWorkPriorityEnum.PRIORITY_4 env = 'test' expected_payload = { 'account': '{{account-id}}', 'detail': {}, 'detail-type': 'Scheduled Event', 'id': '96c7cb9b-778b-4ef2-8b54-840daf6f4c8c', 'region': 'us-east-1', 'reprocessing': [{ 'uow_id': content_status.unit_of_work.unit_of_work_code, 'unit_of_work_id': content_status.unit_of_work.unit_of_work_id, 'priority': priority.value, }], 'resources': ['arn:aws:events:us-east-1:123456789012:rule/ExampleRule'], 'source': 'aws.events', 'time': FREEZED_DT.replace(microsecond=0).isoformat(), } count = len(service.reprocess_slz_uows([content_status.content_status_id], priority, env)) assert count == 1 mocked_call.assert_called_once_with( 'Invoke', { 'FunctionName': 'test-delphi-slz-job-manager-test', 'Payload': json.dumps(expected_payload).encode(), 'InvocationType': 'Event', }, ) @pytest.mark.freeze_time(FREEZED_DT) def test_reprocess_slz_uows_no_priority(db, clean_db, content_status, mocker): mocker.patch('uuid.uuid4', return_value=uuid.UUID('96c7cb9b-778b-4ef2-8b54-840daf6f4c8c')) api_response = {'StatusCode': 202} mocked_call: Mock = mocker.patch( 'botocore.client.BaseClient._make_api_call', return_value=api_response ) service = ReprocessingService(db) priority = None env = 'test' expected_payload = { 'account': '{{account-id}}', 'detail': {}, 'detail-type': 'Scheduled Event', 'id': '96c7cb9b-778b-4ef2-8b54-840daf6f4c8c', 'region': 'us-east-1', 'reprocessing': [{ 'uow_id': content_status.unit_of_work.unit_of_work_code, 'unit_of_work_id': content_status.unit_of_work.unit_of_work_id, 'priority': 5, }], 'resources': ['arn:aws:events:us-east-1:123456789012:rule/ExampleRule'], 'source': 'aws.events', 'time': FREEZED_DT.replace(microsecond=0).isoformat(), } count = len(service.reprocess_slz_uows([content_status.content_status_id], priority, env)) assert count == 1 mocked_call.assert_called_once_with( 'Invoke', { 'FunctionName': 'test-delphi-slz-job-manager-test', 'Payload': json.dumps(expected_payload).encode(), 'InvocationType': 'Event', }, ) def test_reprocess_slz_uows_no_items(db, clean_db, content_status, mocker): mocked_call: Mock = mocker.patch('botocore.client.BaseClient._make_api_call') service = ReprocessingService(db) priority = SlzUnitOfWorkPriorityEnum.PRIORITY_4 env = 'test' count = len(service.reprocess_slz_uows([content_status.content_status_id + 100], priority, env)) assert count == 0 assert not mocked_call.called def test_reprocess_slz_uows_invalid_lambda_response(db, clean_db, content_status, mocker): api_response = {'StatusCode': 500} mocker.patch('botocore.client.BaseClient._make_api_call', return_value=api_response) service = ReprocessingService(db) priority = SlzUnitOfWorkPriorityEnum.PRIORITY_4 env = 'test' with pytest.raises(ReprocessingLambdaInvalidResponse): service.reprocess_slz_uows([content_status.content_status_id], priority, env) @pytest.mark.freeze_time(FREEZED_DT) def test_reprocess_apps_uows_ok(db, clean_db, apps_unit_of_work, mocker): api_response = {'StatusCode': 202} mocked_call: Mock = mocker.patch( 'botocore.client.BaseClient._make_api_call', return_value=api_response ) service = ReprocessingService(db) priority = AppsUnitOfWorkPriorityEnum.PRIORITY_4 env = 'test' driver_options = ['foo', 'bar', 'baz'] expected_payload = { 'initialize': False, 'time': FREEZED_DT.replace(microsecond=0).isoformat(), 'data_sources': ['slz', 'chartmetric'], 'reprocessing': [{ 'unit_of_work_id': apps_unit_of_work.unit_of_work_id, 'priority': priority.value }], 'add_driver_java_options': driver_options, } count = service.reprocess_apps_uows([apps_unit_of_work.unit_of_work_id], priority, driver_options, env) assert count == 1 mocked_call.assert_called_once_with( 'Invoke', { 'FunctionName': 'test-delphi-apps-etl-manager-test', 'Payload': json.dumps(expected_payload).encode(), 'InvocationType': 'Event', }, ) @pytest.mark.freeze_time(FREEZED_DT) def test_reprocess_apps_uows_no_priority(db, clean_db, apps_unit_of_work, mocker): api_response = {'StatusCode': 202} mocked_call: Mock = mocker.patch( 'botocore.client.BaseClient._make_api_call', return_value=api_response ) service = ReprocessingService(db) priority = None env = 'test' driver_options = ['foo', 'bar', 'baz'] expected_payload = { 'initialize': False, 'time': FREEZED_DT.replace(microsecond=0).isoformat(), 'data_sources': ['slz', 'chartmetric'], 'reprocessing': [{ 'unit_of_work_id': apps_unit_of_work.unit_of_work_id, }], 'add_driver_java_options': driver_options, } count = service.reprocess_apps_uows([apps_unit_of_work.unit_of_work_id], priority, driver_options, env) assert count == 1 mocked_call.assert_called_once_with( 'Invoke', { 'FunctionName': 'test-delphi-apps-etl-manager-test', 'Payload': json.dumps(expected_payload).encode(), 'InvocationType': 'Event', }, ) @pytest.mark.freeze_time(FREEZED_DT) def test_reprocess_apps_uows_ok_without_driver_options(db, clean_db, apps_unit_of_work, mocker): api_response = {'StatusCode': 202} mocked_call: Mock = mocker.patch( 'botocore.client.BaseClient._make_api_call', return_value=api_response ) service = ReprocessingService(db) priority = AppsUnitOfWorkPriorityEnum.PRIORITY_4 env = 'test' driver_options = None expected_payload = { 'initialize': False, 'time': FREEZED_DT.replace(microsecond=0).isoformat(), 'data_sources': ['slz', 'chartmetric'], 'reprocessing': [{ 'unit_of_work_id': apps_unit_of_work.unit_of_work_id, 'priority': priority.value }], } count = service.reprocess_apps_uows([apps_unit_of_work.unit_of_work_id], priority, driver_options, env) assert count == 1 mocked_call.assert_called_once_with( 'Invoke', { 'FunctionName': 'test-delphi-apps-etl-manager-test', 'Payload': json.dumps(expected_payload).encode(), 'InvocationType': 'Event', }, ) def test_reprocess_apps_uows_invalid_lambda_response(db, clean_db, apps_unit_of_work, mocker): api_response = {'StatusCode': 500} mocker.patch('botocore.client.BaseClient._make_api_call', return_value=api_response) service = ReprocessingService(db) priority = SlzUnitOfWorkPriorityEnum.PRIORITY_4 env = 'test' with pytest.raises(ReprocessingLambdaInvalidResponse): service.reprocess_apps_uows([apps_unit_of_work.unit_of_work_id], priority, None, env)