예제 #1
0
def after_scenario(_, scenario):
    if "clear_for_bad_messages" not in scenario.tags:
        response = requests.get(f'{Config.EXCEPTION_MANAGER_URL}/badmessages')
        response.raise_for_status()
        if response.json():
            logger.error(
                'Unexpected exception(s) -- these could be due to an underpowered environment',
                exception_manager_response=response.json())

            requests.get(f'{Config.EXCEPTION_MANAGER_URL}/reset')
            time.sleep(
                25
            )  # 25 seconds should be long enough for error to happen again if it hasn't cleared itself

            response = requests.get(
                f'{Config.EXCEPTION_MANAGER_URL}/badmessages')
            response.raise_for_status()
            if response.json():
                bad_message_details = []

                list_of_bad_message_hashes = response.json()
                for bad_message_hash in list_of_bad_message_hashes:
                    response = requests.get(
                        f'{Config.EXCEPTION_MANAGER_URL}/badmessage/{bad_message_hash}'
                    )
                    bad_message_details.append(response.json())

                _clear_queues_for_bad_messages_and_reset_exception_manager()
                logger.error(
                    'Unexpected exception(s) which were not due to eventual consistency timing',
                    exception_manager_response=bad_message_details)

                test_helper.fail(
                    f'Unexpected exception(s) thrown by RM. Details: {bad_message_details}'
                )
예제 #2
0
def check_case_events(context):
    response = requests.get(f"{Config.CASE_API_CASE_URL}{context.first_case['id']}", params={'caseEvents': True})
    response_json = response.json()
    for case_event in response_json['caseEvents']:
        if case_event['description'] == 'Invalid address':
            return
    test_helper.fail('Did not find expected invalid address event')
def check_for_event(context, event_type):
    events = get_logged_events_for_case_by_id(context.case_created_events[0]['payload']['collectionCase']['id'])

    for event in events:
        if event['eventType'] == event_type:
            return

    test_helper.fail(f"Case {context.first_case['id']} event_type {event_type} not logged")
 def success_callback(db_result, timeout_deadline):
     if db_result[0][0] == context.sample_count:
         return True
     elif time.time() > timeout_deadline:
         test_helper.fail(
             f"For Action-plan {context.action_plan_id}, DB didn't have the expected number of sample units. "
             f"Expected: {context.sample_count}, actual: {db_result[0][0]}")
     return False
예제 #5
0
def check_question_linked_event_is_logged(case_id):
    response = requests.get(f'{Config.CASE_API_CASE_URL}{case_id}',
                            params={'caseEvents': True})
    response_json = response.json()
    for case_event in response_json['caseEvents']:
        if case_event['description'] == 'Questionnaire Linked':
            return
    test_helper.fail('Did not find questionnaire linked event')
 def success_callback(db_result, timeout_deadline):
     results = {row[0]: row[1] for row in db_result}
     if all(results.values()) and len(results) == len(case_ids):
         return True
     elif time.time() > timeout_deadline:
         test_helper.fail(
             f"The expected cases did not all show as survey_launched=True within the time limit, "
             f"found values: {results}")
     return False
예제 #7
0
def check_case_events(context):
    response = requests.get(
        f'{Config.CASE_API_CASE_URL}{context.refused_case_id}',
        params={'caseEvents': True})
    response_json = response.json()
    for case_event in response_json['caseEvents']:
        if case_event['description'] == 'Refusal Received':
            return
    test_helper.fail('Did not find "Refusal Received" event')
def check_case_events_logged(context):
    response = requests.get(
        f"{Config.CASE_API_CASE_URL}{context.fulfilment_requested_case_id}",
        params={'caseEvents': True})
    response_json = response.json()
    for case_event in response_json['caseEvents']:
        if case_event['description'] == 'Fulfilment Request Received':
            return
    test_helper.fail('Did not find fulfilment request event')
예제 #9
0
def check_question_unlinked_event_is_logged(context):
    case_id = context.linked_case_id
    response = requests.get(f'{Config.CASE_API_CASE_URL}{case_id}',
                            params={'caseEvents': True})
    response_json = response.json()
    for case_event in response_json['caseEvents']:
        expected_desc = f'Questionnaire unlinked from case with QID {context.expected_questionnaire_id}'
        if case_event['description'] == expected_desc:
            return
    test_helper.fail('Questionnaire unlinked event has not occurred')
def receipt_msg_published_to_gcp_pubsub(context):
    context.first_case = context.case_created_events[0]['payload']['collectionCase']
    for uac in context.uac_created_events:
        if uac['payload']['uac']['caseId'] == context.first_case['id']:
            questionnaire_id = uac['payload']['uac']['questionnaireId']
            break
    else:
        test_helper.fail('Could not find UAC_UPDATED event for receipted case')

    _publish_object_finalize(context, questionnaire_id=questionnaire_id)
    test_helper.assertTrue(context.sent_to_gcp)
def _field_callback(ch, method, _properties, body, context):
    context.emitted_action_instruction = json.loads(body)

    if not context.emitted_action_instruction['actionInstruction'] == 'CREATE':
        ch.basic_nack(delivery_tag=method.delivery_tag)
        test_helper.fail(
            f'Unexpected message on {Config.RABBITMQ_OUTBOUND_FIELD_QUEUE} case queue. '
            f'Got "{context.emitted_action_instruction["actionInstruction"]}", wanted "CREATE"'
        )

    ch.basic_ack(delivery_tag=method.delivery_tag)
    ch.stop_consuming()
예제 #12
0
def _field_work_create_callback(ch, method, _properties, body, context):
    action_create = json.loads(body)

    if not action_create['actionInstruction'] == 'CREATE':
        ch.basic_nack(delivery_tag=method.delivery_tag)
        test_helper.fail(f'Unexpected message on {Config.RABBITMQ_OUTBOUND_FIELD_QUEUE} case queue. '
                         f'Got "{action_create["actionInstruction"]}", wanted "CREATE"')

    context.addressType = action_create['addressType']
    context.fwmt_emitted_case_id = action_create['caseId']
    context.field_action_create_message = action_create
    ch.basic_ack(delivery_tag=method.delivery_tag)
    ch.stop_consuming()
예제 #13
0
def _add_expected_uac_data(message, expected_data):
    case_id = message['payload']['uac']['caseId']
    uac_payload = message['payload']['uac']

    if uac_payload['questionnaireId'][:2] in ('01', '02', '04', '21', '22',
                                              '24'):
        expected_data[case_id]['uac'] = uac_payload['uac']
        expected_data[case_id]['qid'] = uac_payload['questionnaireId']
    elif uac_payload['questionnaireId'][:2] == '03':
        expected_data[case_id]['uac_wales'] = uac_payload['uac']
        expected_data[case_id]['qid_wales'] = uac_payload['questionnaireId']
    else:
        test_helper.fail('Unexpected questionnaire type')

    return expected_data
def field_work_update_callback(ch, method, _properties, body, context):
    action_instruction = json.loads(body)

    if not action_instruction['actionInstruction'] == 'UPDATE':
        ch.basic_nack(delivery_tag=method.delivery_tag)
        test_helper.fail(
            f'Unexpected message on {Config.RABBITMQ_OUTBOUND_FIELD_QUEUE} case queue. '
            f'Got "{action_instruction["actionInstruction"]}", wanted "UPDATE"'
        )

    for index, case in enumerate(context.expected_cases_for_action):
        if _message_matches(case, action_instruction):
            del context.expected_cases_for_action[index]
            ch.basic_ack(delivery_tag=method.delivery_tag)

            break
예제 #15
0
def test_uacs_correct(context):
    test_helper.assertEqual(len(context.messages_received),
                            len(context.expected_uacs_cases))

    for msg in context.uac_created_events:
        _validate_uac_message(msg)

        for index, case_created_event in enumerate(
                context.expected_uacs_cases):
            if (uac_message_matches_rh_message(case_created_event, msg) and
                (msg['payload']['uac']['questionnaireId'][:2]
                 == case_created_event['expected_questionnaire_type'])):
                del context.expected_uacs_cases[index]
                break
        else:
            test_helper.fail('Could not find UAC Updated event')
예제 #16
0
def check_no_msgs_sent_to_queue(context, queue, on_message_callback, timeout=5):
    context.messages_received = []
    rabbit = RabbitContext(queue_name=queue)
    connection = rabbit.open_connection()

    connection.call_later(
        delay=timeout,
        callback=functools.partial(_timeout_callback_expected, rabbit))

    rabbit.channel.basic_consume(
        queue=queue,
        on_message_callback=on_message_callback)
    rabbit.channel.start_consuming()
    if len(context.messages_received) > 0:
        test_helper.fail(f'Expected no messages on the queue {queue}, found {len(context.messages_received)}'
                         f', message(s): {context.messages_received}')
예제 #17
0
 def new_address_load_success_callback(db_result, timeout_deadline):
     # Check we have the right number of cases and all the expected case ID's are present
     if len(db_result) == len(context.bulk_new_addresses):
         new_address_case_ids = {
             case_created['payload']['collectionCase']['id']
             for case_created in context.case_created_events
         }
         for case_id in (result[0] for result in db_result):
             test_helper.assertIn(
                 case_id, new_address_case_ids,
                 f'Found case ID {case_id} in action plan {context.action_plan_id} '
                 f'with no matching created event from the new address bulk load'
             )
         return True
     if time.time() > timeout_deadline:
         test_helper.fail(
             "Didn't find all new address cases in action database before the time out"
         )
     return False
예제 #18
0
def get_ccs_case_by_postcode(context, case_type):
    response = requests.get(
        f'{Config.CASE_API_CASE_URL}ccs/postcode/{context.ccs_case["postcode"]}'
    )
    response.raise_for_status()
    found_cases = response.json()

    for case in found_cases:
        if case['id'] == context.ccs_case['id']:
            matched_case = case
            break
    else:
        test_helper.fail('Failed to find the new CCS case by postcode search')

    test_helper.assertEqual(context.ccs_case['postcode'],
                            matched_case['postcode'])
    test_helper.assertEqual(context.ccs_case['caseRef'],
                            matched_case['caseRef'])
    test_helper.assertEqual(context.ccs_case['caseType'], case_type)
예제 #19
0
def _fieldwork_message_callback(ch, method, _properties, body, context, expected_value):
    action_instruction = json.loads(body)

    if not action_instruction['actionInstruction'] == 'CREATE':
        ch.basic_nack(delivery_tag=method.delivery_tag)
        test_helper.fail(f'Unexpected message on {Config.RABBITMQ_OUTBOUND_FIELD_QUEUE} case queue. '
                         f'Got "{action_instruction["actionInstruction"]}", wanted "CREATE"')

    for index, _ in enumerate(context.expected_cases_for_action):
        _check_expected_secure_establishment_value(action_instruction, expected_value)
        ch.basic_ack(delivery_tag=method.delivery_tag)
        del context.expected_cases_for_action[index]
        break

    else:
        test_helper.fail(
            f'Found message on {Config.RABBITMQ_OUTBOUND_FIELD_QUEUE} case queue which did not '
            f'match any expected sample units')

    if not context.expected_cases_for_action:
        ch.stop_consuming()
예제 #20
0
def _test_cases_correct(context):
    context.expected_sample_units = context.sample_units.copy()
    test_helper.assertEqual(
        len(context.expected_sample_units), len(context.case_created_events),
        'Number of cases loaded and case created events do not match')

    for event in context.case_created_events:
        _validate_case(event)

        for index, sample_unit in enumerate(context.expected_sample_units):
            if _sample_unit_matches_case_event(sample_unit, event):
                context.expected_sample_units.pop(index)
                break
        else:
            logger.error(
                'To match case created event to any of the expected sample units',
                unmatched_sample_units=context.expected_sample_units,
                case_created_event=event)
            test_helper.fail(
                'Could not find correct case updated messages for all loaded sample units'
            )
예제 #21
0
def _field_work_receipt_callback(ch, method, _properties, body, context):
    action_instruction = json.loads(body)

    if not action_instruction['actionInstruction'] == 'UPDATE':
        ch.basic_nack(delivery_tag=method.delivery_tag)
        test_helper.fail(
            f'Unexpected message on {Config.RABBITMQ_OUTBOUND_FIELD_QUEUE} case queue. '
            f'Got "{action_instruction["actionInstruction"]}", wanted "UPDATE"'
        )

    context.addressType = action_instruction['addressType']
    context.fwmt_emitted_case_id = action_instruction['caseId']
    context.fwmt_emitted_undelivered_flag = action_instruction[
        'undeliveredAsAddress']

    test_helper.assertEquals(context.first_case['address']['uprn'],
                             action_instruction['uprn'], "uprn")
    test_helper.assertEquals(context.first_case['address']['estabUprn'],
                             action_instruction['estabUprn'], "estab Uprn")

    ch.basic_ack(delivery_tag=method.delivery_tag)
    ch.stop_consuming()
예제 #22
0
    def success_callback(db_result, timeout_deadline):
        actual_event_types = [row[0] for row in db_result]

        if len(actual_event_types) > len(expected_event_types):
            # Fail fast if we find too many events
            test_helper.fail(
                f'Actual events logged against QID do not match expected, '
                f'actual events: {actual_event_types}, expected: {expected_event_types}'
            )

        if Counter(list(actual_event_types)) == Counter(
                list(expected_event_types)):
            # Counter returns a dict of list elements and their frequency in the given list so
            # comparing counters of lists will return true if they contain the same elements, ignoring order
            return True

        elif time.time() > timeout_deadline:
            test_helper.fail(
                f'Did not find expected QID events within the time limit, '
                f'actual events: {actual_event_types}, expected: {expected_event_types}'
            )
        return False
예제 #23
0
def validate_unaddressed_print_file(context):
    try:
        subprocess.run(
            ['docker', 'run',
             '--env', 'DB_HOST=postgres',
             '--env', 'DB_PORT=5432',
             '--env', 'OUR_PUBLIC_KEY_PATH=dummy_keys/our_dummy_public.asc',
             '--env', 'QM_PUBLIC_KEY_PATH=dummy_keys/supplier_QM_dummy_public_key.asc',
             '--env', 'PPO_PUBLIC_KEY_PATH=dummy_keys/supplier_PPO_dummy_public_key.asc',
             '--env', 'RABBITMQ_SERVICE_HOST=rabbitmq',
             '--env', 'RABBITMQ_SERVICE_PORT=5672',
             '--env', f'SFTP_QM_DIRECTORY={Config.SFTP_QM_DIRECTORY}',
             '--env', f'SFTP_PPO_DIRECTORY={Config.SFTP_PPO_DIRECTORY}',
             '--env', 'SFTP_HOST=sftp',
             '--env', 'SFTP_KEY_FILENAME=dummy_keys/dummy_rsa',
             '--env', 'SFTP_PASSPHRASE=secret',
             '--env', 'SFTP_USERNAME=centos',
             '--link', 'rabbitmq', '--link', 'postgres', '--network', 'censusrmdockerdev_default', '-t',
             'eu.gcr.io/census-rm-ci/rm/census-rm-qid-batch-runner', '/home/qidbatchrunner/run_acceptance_tests.sh'],
            check=True)
    except subprocess.CalledProcessError:
        test_helper.fail('Unaddressed print file test failed')
예제 #24
0
def check_manifest_files_created(context, pack_code):
    with SftpUtility() as sftp_utility:
        files = sftp_utility.get_all_files_after_time(
            context.test_start_local_datetime, pack_code)

        for _file in files:
            if _file.filename.endswith(".csv.gpg"):
                csv_file = _file
                manifest_file = _get_matching_manifest_file(
                    csv_file.filename, files)

                if manifest_file is None:
                    test_helper.fail(
                        f'Failed to find manifest file for {csv_file.filename}'
                    )

                actual_manifest = _get_actual_manifest(sftp_utility,
                                                       manifest_file,
                                                       pack_code)
                creation_datetime = actual_manifest['manifestCreated']
                expected_manifest = _create_expected_manifest(
                    sftp_utility, csv_file, creation_datetime, pack_code)
                test_helper.assertDictEqual(actual_manifest, expected_manifest)
        ch.basic_nack(delivery_tag=method.delivery_tag)
        test_helper.fail(
            f'Unexpected message on {Config.RABBITMQ_OUTBOUND_FIELD_QUEUE} case queue. '
            f'Got "{action_instruction["actionInstruction"]}", wanted "CREATE"'
        )

    for index, case in enumerate(context.expected_cases_for_action):
        if _message_matches(case, action_instruction):
            _message_valid(case, action_instruction)
            del context.expected_cases_for_action[index]
            ch.basic_ack(delivery_tag=method.delivery_tag)

            break
    else:
        test_helper.fail(
            f'Found message on {Config.RABBITMQ_OUTBOUND_FIELD_QUEUE} case queue which did not '
            f'match any expected sample units')

    if not context.expected_cases_for_action:
        ch.stop_consuming()


def _message_matches(case, action_instruction):
    return action_instruction['caseId'] == case['id']


def _message_valid(case, action_instruction):
    test_helper.assertEqual(float(case['address']['latitude']),
                            action_instruction['latitude'])
    test_helper.assertEqual(float(case['address']['longitude']),
                            action_instruction['longitude'])
예제 #26
0
def create_expected_reminder_questionnaire_csv_lines(context, pack_code):
    expected_data = defaultdict(dict)

    expected_reminder_case_created_events = (
        case for case in context.case_created_events
        if case['payload']['collectionCase']['id'] in context.reminder_case_ids
    )

    for uac in context.reminder_uac_updated_events:
        if not uac['payload']['uac']['questionnaireId'].startswith('03'):
            expected_data[uac['payload']['uac']
                          ['caseId']]['uac'] = uac['payload']['uac']['uac']
            expected_data[uac['payload']['uac']['caseId']]['qid'] = uac[
                'payload']['uac']['questionnaireId']
        elif not expected_data[uac['payload']['uac']['caseId']].get(
                'uac_wales'):
            expected_data[uac['payload']['uac']['caseId']]['uac_wales'] = uac[
                'payload']['uac']['uac']
            expected_data[uac['payload']['uac']['caseId']]['qid_wales'] = uac[
                'payload']['uac']['questionnaireId']
        else:
            test_helper.fail('Too many reminder UAC Updated events for case')

    for case in expected_reminder_case_created_events:
        expected_data = _add_expected_questionnaire_case_data(
            case, expected_data)

    return [
        _create_expected_questionnaire_csv_line(case, pack_code)
        for case in expected_data.values()
    ]


def _add_expected_uac_data(message, expected_data):
    case_id = message['payload']['uac']['caseId']
    uac_payload = message['payload']['uac']

    if uac_payload['questionnaireId'][:2] in ('01', '02', '04', '21', '22',
                                              '24'):
        expected_data[case_id]['uac'] = uac_payload['uac']
        expected_data[case_id]['qid'] = uac_payload['questionnaireId']
    elif uac_payload['questionnaireId'][:2] == '03':
        expected_data[case_id]['uac_wales'] = uac_payload['uac']
        expected_data[case_id]['qid_wales'] = uac_payload['questionnaireId']
    else:
        test_helper.fail('Unexpected questionnaire type')

    return expected_data


def _add_expected_case_data(message, expected_data):
    case_id = message['payload']['collectionCase']['id']

    collection_case = message['payload']['collectionCase']
    expected_data[case_id]['case_ref'] = collection_case['caseRef']
    expected_data[case_id]['coordinator_id'] = collection_case[
        'fieldCoordinatorId']
    expected_data[case_id]['officer_id'] = collection_case['fieldOfficerId']

    _populate_expected_address(case_id, expected_data, message)

    return expected_data


def _add_expected_questionnaire_case_data(message, expected_data):
    case_id = message['payload']['collectionCase']['id']

    expected_data[case_id]['coordinator_id'] = message['payload'][
        'collectionCase']['fieldCoordinatorId']
    expected_data[case_id]['officer_id'] = message['payload'][
        'collectionCase']['fieldOfficerId']

    _populate_expected_address(case_id, expected_data, message)

    return expected_data


def _add_expected_individual_case_data(message, expected_data):
    case_id = message['payload']['collectionCase']['id']

    collection_case = message['payload']['collectionCase']
    expected_data[case_id]['case_ref'] = collection_case['caseRef']

    _populate_expected_address(case_id, expected_data, message)

    return expected_data


def _populate_expected_address(case_id, expected_data, message):
    address = message['payload']['collectionCase']['address']
    expected_data[case_id]['address_line_1'] = address['addressLine1']
    expected_data[case_id]['address_line_2'] = address['addressLine2']
    expected_data[case_id]['address_line_3'] = address['addressLine3']
    expected_data[case_id]['town_name'] = address['townName']
    expected_data[case_id]['postcode'] = address['postcode']
    expected_data[case_id]['organization_name'] = address['organisationName']


def _create_expected_csv_line(case, prefix):
    return (f'{case["uac"]}|'
            f'{case["case_ref"]}|'
            f'|||'
            f'{case["address_line_1"]}|'
            f'{case["address_line_2"]}|'
            f'{case["address_line_3"]}|'
            f'{case["town_name"]}|'
            f'{case["postcode"]}|'
            f'{prefix}|'
            f'{case["questionnaire_id"]}|'
            f'{case["organization_name"]}|'
            f'{case["coordinator_id"]}|'
            f'{case["officer_id"]}')
예제 #27
0
def _timeout_callback(rabbit):
    logger.error('Timed out waiting for messages')
    rabbit.close_connection()
    test_helper.fail("Didn't find the expected number of messages")