예제 #1
0
def test_migrate_app_with_uninitialised_app(monkeypatch, mock_es_client, sample_search_app):
    """
    Test that migrate_app() creates an index and schedules an initial sync for an
    uninitialised search app.
    """
    sync_model_task_mock = Mock()
    monkeypatch.setattr('datahub.search.migrate.sync_model', sync_model_task_mock)
    mock_client = mock_es_client.return_value
    mock_client.indices.exists_alias.side_effect = [
        # No alias at first attempt
        False,
        # Return True once alias created
        True,
    ]

    migrate_app(sample_search_app)

    expected_index_name = (
        f'{settings.ES_INDEX_PREFIX}-{SAMPLE_APP_NAME}-7c4194a0f6eaa2cee1dda9df1dfc2856'
    )
    assert mock_client.indices.create.call_args_list == [
        call(index=expected_index_name, body=ANY),
    ]
    assert sync_model_task_mock.apply_async.call_args_list == [
        call(args=(sample_search_app.name,)),
    ]
예제 #2
0
def test_migrate_app_with_app_in_invalid_state(monkeypatch, mock_es_client):
    """
    Test that migrate_app() raises an exception for apps in an invalid state.

    This refers to an app that needs migrating, but the current write index is not one of
    the read indices. This should never happen.
    """
    migrate_model_task_mock = Mock()
    monkeypatch.setattr('datahub.search.migrate.complete_model_migration', migrate_model_task_mock)

    read_indices = ('read-index',)
    write_index = 'write-index'
    current_hash = 'current-hash'
    target_hash = 'target-hash'
    mock_app = create_mock_search_app(
        current_mapping_hash=current_hash,
        target_mapping_hash=target_hash,
        read_indices=read_indices,
        write_index=write_index,
    )

    with pytest.raises(DataHubException):
        migrate_app(mock_app)

    migrate_model_task_mock.apply_async.assert_not_called()
예제 #3
0
def test_migrate_app_with_app_in_inconsistent_state(monkeypatch, mock_es_client):
    """
    Test that migrate_app() resyncs an app in an inconsistent state.

    This refers to an app with multiple read indices (i.e. an app with an interrupted migration).

    In this case, a resync should be scheduled to attempt to complete the migration.
    """
    migrate_model_task_mock = Mock()
    monkeypatch.setattr('datahub.search.migrate.complete_model_migration', migrate_model_task_mock)

    mock_client = mock_es_client.return_value
    old_index = 'test-index-current-hash'
    read_indices = ('test-index-current-hash', 'another-index')
    current_hash = 'current-hash'
    target_hash = 'current-hash'
    mock_app = create_mock_search_app(
        current_mapping_hash=current_hash,
        target_mapping_hash=target_hash,
        read_indices=read_indices,
        write_index=old_index,
    )

    migrate_app(mock_app)

    mock_app.es_model.create_index.assert_not_called()
    mock_client.indices.update_aliases.assert_not_called()

    migrate_model_task_mock.apply_async.assert_called_once_with(
        args=(mock_app.name, target_hash),
    )
예제 #4
0
def test_migrate_app_with_uninitialised_app(
    monkeypatch,
    mock_connection_for_create_index,
    sample_search_app,
):
    """
    Test that migrate_app() creates an index and schedules an initial sync for an
    uninitialised search app.
    """
    sync_model_task_mock = Mock()
    monkeypatch.setattr('datahub.search.migrate.sync_model',
                        sync_model_task_mock)
    mock_client = mock_connection_for_create_index.return_value
    mock_client.indices.exists_alias.side_effect = [
        # No alias at first attempt
        False,
        # Return True once alias created
        True,
    ]

    migrate_app(sample_search_app)

    expected_index_name = (
        f'{settings.OPENSEARCH_INDEX_PREFIX}-{SAMPLE_APP_NAME}-e8f30732b3051b52d19a699b069110d6'
    )
    assert mock_client.indices.create.call_args_list == [
        call(index=expected_index_name, body=ANY),
    ]
    assert sync_model_task_mock.apply_async.call_args_list == [
        call(args=(sample_search_app.name, )),
    ]
예제 #5
0
def test_migrate_app_with_app_needing_migration(monkeypatch,
                                                mock_opensearch_client):
    """Test that migrate_app() migrates an app needing migration."""
    migrate_model_task_mock = Mock()
    monkeypatch.setattr('datahub.search.migrate.complete_model_migration',
                        migrate_model_task_mock)
    create_index_mock = Mock()
    monkeypatch.setattr('datahub.search.migrate.create_index',
                        create_index_mock)

    mock_client = mock_opensearch_client.return_value
    old_index = 'test-index'
    new_index = 'test-index-target-hash'
    current_hash = 'current-hash'
    target_hash = 'target-hash'
    mock_app = create_mock_search_app(
        current_mapping_hash=current_hash,
        target_mapping_hash=target_hash,
        write_index=old_index,
    )

    migrate_app(mock_app)

    create_index_mock.assert_called_once_with(
        new_index, mock_app.search_model._doc_type.mapping)

    mock_client.indices.update_aliases.assert_called_once_with(body={
        'actions': [
            {
                'add': {
                    'alias': 'test-read-alias',
                    'indices': [new_index],
                },
            },
            {
                'add': {
                    'alias': 'test-write-alias',
                    'indices': [new_index],
                },
            },
            {
                'remove': {
                    'alias': 'test-write-alias',
                    'indices': [old_index],
                },
            },
        ],
    }, )

    migrate_model_task_mock.apply_async.assert_called_once_with(
        args=(mock_app.name, target_hash), )
예제 #6
0
def test_migrate_app_with_app_not_needing_migration(monkeypatch, mock_es_client):
    """Test that migrate_app() migrates an app needing migration."""
    migrate_model_task_mock = Mock()
    monkeypatch.setattr('datahub.search.migrate.complete_model_migration', migrate_model_task_mock)

    mock_client = mock_es_client.return_value
    old_index = 'test-index-current-hash'
    current_hash = 'current-hash'
    target_hash = 'current-hash'
    mock_app = create_mock_search_app(
        current_mapping_hash=current_hash,
        target_mapping_hash=target_hash,
        write_index=old_index,
    )

    migrate_app(mock_app)

    mock_app.es_model.create_index.assert_not_called()
    mock_client.indices.update_aliases.assert_not_called()
    migrate_model_task_mock.apply_async.assert_not_called()