Beispiel #1
0
    def test_034_creating_reporter_demands_presence_of_task(self):
        from invenio_checker.api import create_reporter
        from sqlalchemy.exc import IntegrityError

        # Create a reporter for a task that does not exist
        with pytest.raises(IntegrityError):
            create_reporter(TestApi.reporter_data)
Beispiel #2
0
    def test_035_one_reporter_of_each_plugin_allowed_per_task(self):
        """Attach a reporter to a task and see if it's actually attached."""
        from invenio_checker.api import create_task, create_reporter
        from sqlalchemy.orm.exc import FlushError

        # Given a task that has a reporter
        create_task(TestApi.task_data)
        create_reporter(TestApi.reporter_data)

        # Try to attach the same reporter on it
        with pytest.raises(FlushError):
            create_reporter(TestApi.reporter_data)
Beispiel #3
0
    def test_0115_delete_task_with_reporter_deletes_task_and_reporter(self):
        from invenio_checker.api import create_task, create_reporter
        from invenio_checker.api import delete_task

        # Given a task..
        task_data = TestApi.task_data
        Query = get_Query(task_data)
        new_task = create_task(task_data)
        self.create_records(small_rng)

        # ..with a reporter attached
        new_reporter = create_reporter(TestApi.reporter_data)

        # Delete the task
        delete_task(task_data['name'])

        # Assert the reporter is gone as well
        assert CheckerReporter.query.filter(CheckerReporter.rule_name == task_data['name']).first() == None
Beispiel #4
0
    def test_033_reporter_is_registered(self):
        """Attach a reporter to a task and see if it's actually attached."""
        from invenio_checker.api import create_task, create_reporter
        from invenio_checker.models import get_reporter_db

        # Given a task
        new_task = create_task(TestApi.task_data)

        # Attach a reporter to it
        new_reporter = create_reporter(TestApi.reporter_data)

        # Make sure the reporter was created
        reporter_from_db = get_reporter_db(**TestApi.reporter_data)
        assert reporter_from_db.plugin == TestApi.reporter_data['plugin']
        assert reporter_from_db.rule_name == TestApi.reporter_data['rule_name']

        # and attached to the task
        assert new_task.reporters == [new_reporter]
Beispiel #5
0
    def test_0105_run_initialized_reporters_only_when_not_spinning(self):
        from invenio_checker.clients.master import StatusMaster
        from invenio_checker.api import create_task, run_task, create_reporter

        # Given a task with a reporter
        task_data = TestApi.task_data
        new_task = create_task(task_data)
        new_reporter = create_reporter(TestApi.reporter_data)
        Query = get_Query(task_data)
        self.create_records(small_rng)

        # ..while tracking the reporter's initialization
        reporterA = reimport_module('tests.demo_package.checkerext.reporters.reporterA')
        reporterA.get_reporter = MagicMock()

        # ..as well as calls to the task conflict resolver
        conflict_resolver = Mock(side_effect=({MagicMock(uuid=1)}, {}))
        mock_manager = Mock()
        mock_manager.attach_mock(reporterA.get_reporter, 'get_reporter')
        mock_manager.attach_mock(conflict_resolver, 'conflict_resolver')

        with patch('invenio_checker.models.CheckerRule.filepath', filepath_without_class):
            with patch('invenio_checker.models.Query', Query):
                with patch('invenio_checker.models.CheckerReporter.module', reporterA):
                    with patch('invenio_checker.conftest.conftest_checker._worker_conflicts_with_currently_running',
                               conflict_resolver):
                        task_id = run_task(task_data['name'])

        # (Better safe than (very) sorry)
        execution = CheckerRuleExecution.query.filter(CheckerRuleExecution.uuid == task_id).one()
        assert execution.status == StatusMaster.completed

        # Ensure that the reporter was not initialized before no conflicts were remaining
        from ..conftest import contains_sublist
        assert contains_sublist(
            [call[0] for call in mock_manager.mock_calls],  # func names
            [
                'conflict_resolver',
                'conflict_resolver',
                'get_reporter',
            ]
        )
Beispiel #6
0
    def test_0110_run_calls_reporters_when_check_wants_to_log(self):
        from invenio_checker.clients.master import StatusMaster
        from invenio_checker.api import run_task, create_task, create_reporter

        # Given a task..
        task_data = TestApi.task_data
        new_task = create_task(task_data)
        # ..with a reporter attached
        new_reporter = create_reporter(TestApi.reporter_data)
        # and some records in the database
        self.create_records(small_rng)

        reporterA = reimport_module('tests.demo_package.checkerext.reporters.reporterA')
        Query = get_Query(task_data)

        with patch('invenio_checker.models.CheckerRule.filepath', filepath_with_class):
            with patch('invenio_checker.models.Query', Query):
                with patch('invenio_checker.models.CheckerReporter.module', reporterA):
                    task_id = run_task(task_data['name'])

        execution = CheckerRuleExecution.query.filter(CheckerRuleExecution.uuid == task_id).one()
        assert execution.status == StatusMaster.completed
        assert reported_reports == len(small_rng)
Beispiel #7
0
def submit_task():
    """Insert or modify an existing task and its reporters."""
    from invenio_checker.clients.supervisor import run_task

    def failure(type_, errors):
        assert type_ in ('general', 'validation')
        return jsonify({'failure_type': type_, 'errors': errors}), 400

    def success():
        return jsonify({})

    # Recreate the forms that we have previously served to the user so that we
    # can validate.
    form_origin = get_NewTaskForm(request.form)
    form_plugin = get_ArgForm(request.form['plugin'], request.form)
    if not (form_origin.validate() & form_plugin.validate()):
        form_errors = defaultdict(list)
        for field, errors in chain(form_origin.errors.items(),
                                   form_plugin.errors.items()):
            form_errors[field].extend(errors)
        return failure('validation', form_errors)

    # Get a dictionary that we can pass as kwargs to the database object,
    form_for_db = dict(form_origin.data)
    # but first, pop metadata out of it.
    modify = form_for_db.pop('modify')
    original_name = form_for_db.pop('original_name')
    requested_action = form_for_db.pop('requested_action')
    reporter_names = set(form_for_db.pop('reporters'))
    form_for_db['arguments'] = form_plugin.data_for_db

    try:

        # Create or edit task
        if modify:
            task = edit_task(original_name, form_for_db, commit=False)
        else:
            task = create_task(form_for_db, commit=False)

        # Create or edit reporters and attach them as well
        for reporter_name in reporter_names:
            form_reporter = get_ArgForm(reporter_name, request.form)
            try:
                reporter = get_reporter_db(form_reporter.plugin_name, original_name)
            except NoResultFound:
                create_reporter({'plugin': form_reporter.plugin_name,
                                 'rule_name': task.name,
                                 'arguments': form_reporter.data_for_db},
                                 commit=False)
            else:
                edit_reporter(reporter,
                              {'plugin': form_reporter.plugin_name,
                               'rule_name': task.name,
                               'arguments': form_reporter.data_for_db},
                              commit=False)
        if modify:
            # Delete reporters that are no longer selected
            attached_reporter_plugin_names = {reporter.plugin for reporter in task.reporters}
            for plugin_name_to_remove in attached_reporter_plugin_names - reporter_names:
                ex_reporter = get_reporter_db(plugin_name_to_remove, original_name)
                remove_reporter(ex_reporter, commit=False)

        db.session.commit()
    except Exception as e:
        db.session.rollback()
        return failure('general', format_exc())

    if requested_action.startswith('submit_run'):
        try:
            run_task(task.name)
        except Exception as e:
            return failure('general', format_exc())

    return success()
Beispiel #8
0
def submit_task():
    """Insert or modify an existing task and its reporters."""
    from invenio_checker.clients.supervisor import run_task

    def failure(type_, errors):
        assert type_ in ('general', 'validation')
        return jsonify({'failure_type': type_, 'errors': errors}), 400

    def success():
        return jsonify({})

    # Recreate the forms that we have previously served to the user so that we
    # can validate.
    form_origin = get_NewTaskForm(request.form)
    form_plugin = get_ArgForm(request.form['plugin'], request.form)
    if not (form_origin.validate() & form_plugin.validate()):
        form_errors = defaultdict(list)
        for field, errors in chain(form_origin.errors.items(),
                                   form_plugin.errors.items()):
            form_errors[field].extend(errors)
        return failure('validation', form_errors)

    # Get a dictionary that we can pass as kwargs to the database object,
    form_for_db = dict(form_origin.data)
    # but first, pop metadata out of it.
    modify = form_for_db.pop('modify')
    original_name = form_for_db.pop('original_name')
    requested_action = form_for_db.pop('requested_action')
    reporter_names = set(form_for_db.pop('reporters'))
    form_for_db['arguments'] = form_plugin.data_for_db

    try:

        # Create or edit task
        if modify:
            task = edit_task(original_name, form_for_db, commit=False)
        else:
            task = create_task(form_for_db, commit=False)

        # Create or edit reporters and attach them as well
        for reporter_name in reporter_names:
            form_reporter = get_ArgForm(reporter_name, request.form)
            try:
                reporter = get_reporter_db(form_reporter.plugin_name,
                                           original_name)
            except NoResultFound:
                create_reporter(
                    {
                        'plugin': form_reporter.plugin_name,
                        'rule_name': task.name,
                        'arguments': form_reporter.data_for_db
                    },
                    commit=False)
            else:
                edit_reporter(reporter, {
                    'plugin': form_reporter.plugin_name,
                    'rule_name': task.name,
                    'arguments': form_reporter.data_for_db
                },
                              commit=False)
        if modify:
            # Delete reporters that are no longer selected
            attached_reporter_plugin_names = {
                reporter.plugin
                for reporter in task.reporters
            }
            for plugin_name_to_remove in attached_reporter_plugin_names - reporter_names:
                ex_reporter = get_reporter_db(plugin_name_to_remove,
                                              original_name)
                remove_reporter(ex_reporter, commit=False)

        db.session.commit()
    except Exception as e:
        db.session.rollback()
        return failure('general', format_exc())

    if requested_action.startswith('submit_run'):
        try:
            run_task(task.name)
        except Exception as e:
            return failure('general', format_exc())

    return success()