예제 #1
0
def test_has_same_source(app, simple_record):
    obj = workflow_object_class.create(
        data=simple_record,
        status=ObjectStatus.HALTED,
        data_type='hep',
    )
    obj_id = obj.id
    obj.save()
    es.indices.refresh('holdingpen-hep')

    obj2 = WorkflowObject.create(data=simple_record, data_type='hep')
    match_non_completed_wf_in_holdingpen(obj2, None)

    same_source_func = has_same_source('holdingpen_matches')

    assert same_source_func(obj2, None)
    assert obj2.extra_data['holdingpen_matches'] == [obj_id]

    # change source and match the wf in the holdingpen
    different_source_rec = dict(simple_record)
    different_source_rec['acquisition_source'] = {'source': 'different'}
    obj3 = WorkflowObject.create(data=different_source_rec, data_type='hep')

    assert match_non_completed_wf_in_holdingpen(obj3, None)
    assert not same_source_func(obj3, None)
예제 #2
0
def test_execution_with_predefined_object(app, demo_workflow):
    """Test predefined object creation."""

    with app.app_context():
        obj = WorkflowObject.create({"x": 22})
        db.session.commit()

        ident = obj.id

        obj = WorkflowObject.get(ident)
        obj.start_workflow("demo_workflow")

        obj = WorkflowObject.get(ident)
        assert obj.data == {"x": 40}

        obj = WorkflowObject.create({"x": 22})
        db.session.commit()

        ident = obj.id

        obj.start_workflow("demo_workflow", delayed=True)
        obj = WorkflowObject.get(ident)
        assert obj.data == {"x": 40}

        # Check that attributes can be changed
        obj.status = obj.known_statuses.RUNNING
        obj.data_type = "bar"
        obj.save()
        db.session.commit()

        obj = WorkflowObject.get(ident)
        assert obj.status == obj.known_statuses.RUNNING
        assert obj.data_type == "bar"
예제 #3
0
def test_has_same_source(app, simple_record):
    obj = workflow_object_class.create(
        data=simple_record,
        status=ObjectStatus.HALTED,
        data_type='hep',
    )
    obj_id = obj.id
    obj.save()
    es.indices.refresh('holdingpen-hep')

    obj2 = WorkflowObject.create(data=simple_record, data_type='hep')
    match_non_completed_wf_in_holdingpen(obj2, None)

    same_source_func = has_same_source('holdingpen_matches')

    assert same_source_func(obj2, None)
    assert obj2.extra_data['holdingpen_matches'] == [obj_id]

    # change source and match the wf in the holdingpen
    different_source_rec = dict(simple_record)
    different_source_rec['acquisition_source'] = {'source': 'different'}
    obj3 = WorkflowObject.create(data=different_source_rec, data_type='hep')

    assert match_non_completed_wf_in_holdingpen(obj3, None)
    assert not same_source_func(obj3, None)
def test_execution_with_predefined_object(app, demo_workflow):
    """Test predefined object creation."""

    with app.app_context():
        obj = WorkflowObject.create({"x": 22})
        db.session.commit()

        ident = obj.id

        obj = WorkflowObject.get(ident)
        obj.start_workflow("demo_workflow")

        obj = WorkflowObject.get(ident)
        assert obj.data == {"x": 40}

        obj = WorkflowObject.create({"x": 22})
        db.session.commit()

        ident = obj.id

        obj.start_workflow("demo_workflow", delayed=True)
        obj = WorkflowObject.get(ident)
        assert obj.data == {"x": 40}

        # Check that attributes can be changed
        obj.status = obj.known_statuses.RUNNING
        obj.data_type = "bar"
        obj.save()
        db.session.commit()

        obj = WorkflowObject.get(ident)
        assert obj.status == obj.known_statuses.RUNNING
        assert obj.data_type == "bar"
예제 #5
0
def test_inequality(obj1, obj2, app, halt_workflow):
    """Test WorkflowObject inequality functions."""
    with app.app_context():
        obj1 = WorkflowObject.create(obj1)
        obj2 = WorkflowObject.create(obj2)
        start("halttest", [obj1, obj2])

        assert obj1 != obj2
        assert obj2 != obj1
예제 #6
0
def test_create_with_default_extra_data(app):
    """Test that the extra data dictionary is not shared between
    workflow instances."""
    with app.app_context():
        obj1 = WorkflowObject.create({"x": 22})
        obj1.extra_data['foo'] = 'bar'

        obj2 = WorkflowObject.create({"x": 22})
        assert obj2.extra_data is not obj1.extra_data
예제 #7
0
def test_stop_matched_holdingpen_wfs(app, simple_record):
    # need to run a wf in order to assign to it the wf definition and a uuid
    # for it

    obj = workflow_object_class.create(
        data_type='hep',
        **simple_record
    )
    workflow_uuid = start('article', object_id=obj.id)
    eng = WorkflowEngine.from_uuid(workflow_uuid)
    obj = eng.processed_objects[0]
    obj.status = ObjectStatus.HALTED
    obj.save()
    obj_id = obj.id
    current_search.flush_and_refresh('holdingpen-hep')

    obj2 = WorkflowObject.create(data_type='hep', **simple_record)
    obj2_id = obj2.id

    match_non_completed_wf_in_holdingpen(obj2, None)
    assert obj2.extra_data['holdingpen_matches'] == [obj_id]

    stop_matched_holdingpen_wfs(obj2, None)

    stopped_wf = workflow_object_class.get(obj_id)
    assert stopped_wf.status == ObjectStatus.COMPLETED
    assert stopped_wf.extra_data['stopped-by-wf'] == obj2_id
예제 #8
0
def test_stop_matched_holdingpen_wfs(app, simple_record):
    # need to run a wf in order to assign to it the wf definition and a uuid
    # for it

    obj = workflow_object_class.create(
        data_type='hep',
        **simple_record
    )
    workflow_uuid = start('article', object_id=obj.id)
    eng = WorkflowEngine.from_uuid(workflow_uuid)
    obj = eng.processed_objects[0]
    obj.status = ObjectStatus.HALTED
    obj.save()
    obj_id = obj.id
    es.indices.refresh('holdingpen-hep')

    obj2 = WorkflowObject.create(data_type='hep', **simple_record)
    obj2_id = obj2.id

    match_non_completed_wf_in_holdingpen(obj2, None)
    assert obj2.extra_data['holdingpen_matches'] == [obj_id]

    stop_matched_holdingpen_wfs(obj2, None)

    stopped_wf = workflow_object_class.get(obj_id)
    assert stopped_wf.status == ObjectStatus.COMPLETED
    assert stopped_wf.extra_data['stopped-by-wf'] == obj2_id
예제 #9
0
def test_errors(app, error_workflow):
    """Test halt task."""
    assert 'errortest' in app.extensions['invenio-workflows'].workflows

    with app.app_context():
        with pytest.raises(WorkflowsMissingData):
            start('errortest')

        with pytest.raises(WorkflowDefinitionError):
            start('doesnotexist', 100)

        with pytest.raises(WorkflowsMissingObject):
            start('errortest', object_id=-1)

        obj = WorkflowObject.create({"id": 0})
        db.session.commit()

        obj_id = obj.id
        with pytest.raises(ZeroDivisionError):
            start('errortest', object_id=obj_id)

        obj = WorkflowObject.get(obj_id)

        assert obj.known_statuses.ERROR == obj.status
        assert obj.data == {"id": 0, "foo": "bar"}
def test_errors(app, error_workflow):
    """Test halt task."""
    assert 'errortest' in app.extensions['invenio-workflows'].workflows

    with app.app_context():
        with pytest.raises(WorkflowsMissingData):
            start('errortest')

        with pytest.raises(WorkflowDefinitionError):
            start('doesnotexist', 100)

        with pytest.raises(WorkflowsMissingObject):
            start('errortest', object_id=-1)

        obj = WorkflowObject.create({"id": 0})
        db.session.commit()

        obj_id = obj.id
        with pytest.raises(ZeroDivisionError):
            start('errortest', object_id=obj_id)

        obj = WorkflowObject.get(obj_id)

        assert obj.known_statuses.ERROR == obj.status
        assert obj.data == {"id": 0, "foo": "bar"}
def test_equality(app, halt_workflow):
    """Test WorkflowObject comparison functions."""
    with app.app_context():
        obj1 = WorkflowObject.create({"x": 22})
        obj2 = WorkflowObject.create({"x": 22})
        start("halttest", [obj1, obj2])

        ident1 = obj1.id
        ident2 = obj2.id

        obj1 = WorkflowObject.get(ident1)
        obj2 = WorkflowObject.get(ident2)
        assert obj1 == obj2

        obj3 = WorkflowObject.create({"x": 22})
        obj4 = WorkflowObject.create({"x": 2})
        assert obj4 != obj3
예제 #12
0
def test_equality(app, halt_workflow):
    """Test WorkflowObject comparison functions."""
    with app.app_context():
        obj1 = WorkflowObject.create({"x": 22})
        obj2 = WorkflowObject.create({"x": 22})
        start("halttest", [obj1, obj2])

        ident1 = obj1.id
        ident2 = obj2.id

        obj1 = WorkflowObject.get(ident1)
        obj2 = WorkflowObject.get(ident2)
        assert obj1 == obj2

        obj3 = WorkflowObject.create({"x": 22})
        obj4 = WorkflowObject.create({"x": 2})
        assert obj4 != obj3
def test_task_info(app, halt_workflow):
    """Test WorkflowObject comparison functions."""
    with app.app_context():
        obj = WorkflowObject.create({"x": 22})
        start("halttest", obj)
        ident = obj.id
        obj = WorkflowObject.get(ident)
        task_info = obj.get_current_task_info()
        assert task_info["name"] == "halt_engine"
예제 #14
0
def test_task_info(app, halt_workflow):
    """Test WorkflowObject comparison functions."""
    with app.app_context():
        obj = WorkflowObject.create({"x": 22})
        start("halttest", obj)
        ident = obj.id
        obj = WorkflowObject.get(ident)
        task_info = obj.get_current_task_info()
        assert task_info["name"] == "halt_engine"
예제 #15
0
def test_pending_holdingpen_matches_wf_if_not_completed(app, simple_record):
    obj = workflow_object_class.create(
        data=simple_record,
        status=ObjectStatus.HALTED,
        data_type='hep',
    )
    obj_id = obj.id
    obj.save()
    es.indices.refresh('holdingpen-hep')

    obj2 = WorkflowObject.create(data=simple_record, data_type='hep')
    assert match_non_completed_wf_in_holdingpen(obj2, None)
    assert obj2.extra_data['holdingpen_matches'] == [obj_id]

    obj = workflow_object_class.get(obj_id)
    obj.status = ObjectStatus.COMPLETED
    obj.save()
    es.indices.refresh('holdingpen-hep')

    # doesn't match anymore because obj is COMPLETED
    assert not match_non_completed_wf_in_holdingpen(obj2, None)
예제 #16
0
def test_pending_holdingpen_matches_wf_if_not_completed(app, simple_record):
    obj = workflow_object_class.create(
        data=simple_record,
        status=ObjectStatus.HALTED,
        data_type='hep',
    )
    obj_id = obj.id
    obj.save()
    es.indices.refresh('holdingpen-hep')

    obj2 = WorkflowObject.create(data=simple_record, data_type='hep')
    assert match_non_completed_wf_in_holdingpen(obj2, None)
    assert obj2.extra_data['holdingpen_matches'] == [obj_id]

    obj = workflow_object_class.get(obj_id)
    obj.status = ObjectStatus.COMPLETED
    obj.save()
    es.indices.refresh('holdingpen-hep')

    # doesn't match anymore because obj is COMPLETED
    assert not match_non_completed_wf_in_holdingpen(obj2, None)
예제 #17
0
def test_match_previously_rejected_wf_in_holdingpen(app, simple_record):
    obj = workflow_object_class.create(
        status=ObjectStatus.COMPLETED,
        data_type='hep',
        **simple_record
    )
    obj_id = obj.id
    obj.extra_data['approved'] = False  # reject it
    obj.save()
    es.indices.refresh('holdingpen-hep')

    obj2 = WorkflowObject.create(data_type='hep', **simple_record)
    assert match_previously_rejected_wf_in_holdingpen(obj2, None)
    assert obj2.extra_data['previously_rejected_matches'] == [obj_id]

    obj = workflow_object_class.get(obj_id)
    obj.status = ObjectStatus.HALTED
    obj.save()
    es.indices.refresh('holdingpen-hep')

    # doesn't match anymore because obj is COMPLETED
    assert not match_previously_rejected_wf_in_holdingpen(obj2, None)
예제 #18
0
def test_match_previously_rejected_wf_in_holdingpen(app, simple_record):
    obj = workflow_object_class.create(
        status=ObjectStatus.COMPLETED,
        data_type='hep',
        **simple_record
    )
    obj_id = obj.id
    obj.extra_data['approved'] = False  # reject it
    obj.save()
    current_search.flush_and_refresh('holdingpen-hep')

    obj2 = WorkflowObject.create(data_type='hep', **simple_record)
    assert match_previously_rejected_wf_in_holdingpen(obj2, None)
    assert obj2.extra_data['previously_rejected_matches'] == [obj_id]

    obj = workflow_object_class.get(obj_id)
    obj.status = ObjectStatus.HALTED
    obj.save()
    current_search.flush_and_refresh('holdingpen-hep')

    # doesn't match anymore because obj is COMPLETED
    assert not match_previously_rejected_wf_in_holdingpen(obj2, None)
예제 #19
0
def import_holdingpen_record(parent_objs, obj, eng):
    """Import an hp record."""
    from invenio_db import db
    from workflow.engine_db import WorkflowStatus
    from invenio_workflows import (
        Workflow, WorkflowObject, ObjectStatus
    )
    engine_model = Workflow(
        name=WORKFLOW_NAME_MAP.get(eng['name'], eng['name']),
        created=iso8601.parse_date(eng['created']),
        modified=iso8601.parse_date(eng['modified']),
        id_user=eng['id_user'],
        status=WorkflowStatus(eng['status']),
        uuid=eng['uuid'],
    )
    engine_model.extra_data = eng['extra_data']

    db.session.add(engine_model)
    try:
        db.session.commit()
    except IntegrityError:
        # The model has already been added to the DB.
        db.session.rollback()

    # First create parents
    if parent_objs:
        for parent in parent_objs:
            object_model = WorkflowObject.create(
                {},  # Pass empty data (filled later)
                id=parent['id'],
                created=iso8601.parse_date(eng['created']),
                modified=iso8601.parse_date(eng['modified']),
                data_type=DATA_TYPE_MAP.get(parent['data_type'], parent['data_type']),
                id_user=parent['id_user'],
                id_workflow=parent['id_workflow'],
                id_parent=parent['id_parent'],
                status=ObjectStatus(parent['status']),
                callback_pos=parent['extra_data']['_task_counter'],
            )

            object_model.data = obj['data']
            object_model.extra_data = obj['extra_data']
            fix_object_model(eng, object_model)
            object_model.save()

    # And then the object
    object_model = WorkflowObject.create(
        {},  # Pass empty data (filled later)
        id=obj['id'],
        created=iso8601.parse_date(eng['created']),
        modified=iso8601.parse_date(eng['modified']),
        data_type=DATA_TYPE_MAP.get(obj['data_type'], obj['data_type']),
        id_user=obj['id_user'],
        id_workflow=obj['id_workflow'],
        id_parent=obj['id_parent'],
        status=ObjectStatus(obj['status']),
        callback_pos=obj['extra_data']['_task_counter'],
    )

    object_model.data = obj['data']
    object_model.extra_data = obj['extra_data']
    fix_object_model(eng, object_model)
    object_model.save()
    db.session.commit()
def test_api(app, demo_halt_workflow):
    """Test WorkflowObject api function."""
    with app.app_context():
        # Test WorkflowObject.(create|query|get)
        # ======================================
        obj = WorkflowObject.create({"x": 22})
        db.session.commit()

        ident = obj.id

        obj = WorkflowObject.get(ident)
        obj.start_workflow("demo_halt_workflow")

        # Fetch object via query API
        objects = WorkflowObject.query(id=ident)
        assert len(objects) == 1
        obj = objects[0]

        # Workflow should have completed as x was always > 10
        # x = 22 + 20 - 2 = 40
        assert obj.data == {"x": 40}
        assert obj.status == obj.known_statuses.COMPLETED

        # Test WorkflowObject.restart_previous
        # ====================================
        # Workflow should now halt as x will be less than 10
        obj = WorkflowObject.create({"x": -20})
        db.session.commit()

        ident = obj.id

        obj.start_workflow("demo_halt_workflow", delayed=True)
        obj = WorkflowObject.get(ident)

        # x = -20 + 20 = 0
        assert obj.data == {"x": 0}
        # No action associated, so it should be waiting
        assert obj.status == obj.known_statuses.WAITING

        # To add 20 to x, we now restart previous task and now it should
        # not halt and complete fully
        obj.restart_previous()
        obj = WorkflowObject.get(ident)

        # x = 0 + 20 - 2 = 18
        assert obj.data == {"x": 18}
        assert obj.status == obj.known_statuses.COMPLETED

        # Test WorkflowObject.restart_next
        # ================================
        obj = WorkflowObject.create({"x": -100})
        db.session.commit()

        ident = obj.id

        obj.start_workflow("demo_halt_workflow")
        obj = WorkflowObject.get(ident)

        # x = -100 + 20 = -80
        assert obj.data == {"x": -80}
        assert obj.status == obj.known_statuses.WAITING

        obj.restart_next()
        obj = WorkflowObject.get(ident)

        # x = -80 - 2 = -82
        assert obj.data == {"x": -82}
        assert obj.status == obj.known_statuses.COMPLETED

        # Test WorkflowObject.restart_current
        # ===================================
        obj = WorkflowObject.create({"x": -100})
        db.session.commit()

        ident = obj.id

        obj.start_workflow("demo_halt_workflow")
        obj = WorkflowObject.get(ident)

        # x = -100 + 20 = -80
        assert obj.data == {"x": -80}
        assert obj.status == obj.known_statuses.WAITING

        obj.restart_current()
        obj = WorkflowObject.get(ident)

        # x = -80 - 2 = -82
        assert obj.data == {"x": -80}
        assert obj.status == obj.known_statuses.WAITING

        # Test WorkflowObject.delete
        # ==========================
        obj.delete()
        with pytest.raises(WorkflowsMissingObject):
            WorkflowObject.get(ident)
예제 #21
0
def test_api(app, demo_halt_workflow):
    """Test WorkflowObject api function."""
    with app.app_context():
        # Test WorkflowObject.(create|query|get)
        # ======================================
        obj = WorkflowObject.create({"x": 22})
        db.session.commit()

        ident = obj.id

        obj = WorkflowObject.get(ident)
        obj.start_workflow("demo_halt_workflow")

        # Fetch object via query API
        objects = WorkflowObject.query(id=ident)
        assert len(objects) == 1
        obj = objects[0]

        # Workflow should have completed as x was always > 10
        # x = 22 + 20 - 2 = 40
        assert obj.data == {"x": 40}
        assert obj.status == obj.known_statuses.COMPLETED

        # Test WorkflowObject.restart_previous
        # ====================================
        # Workflow should now halt as x will be less than 10
        obj = WorkflowObject.create({"x": -20})
        db.session.commit()

        ident = obj.id

        obj.start_workflow("demo_halt_workflow", delayed=True)
        obj = WorkflowObject.get(ident)

        # x = -20 + 20 = 0
        assert obj.data == {"x": 0}
        # No action associated, so it should be waiting
        assert obj.status == obj.known_statuses.WAITING

        # To add 20 to x, we now restart previous task and now it should
        # not halt and complete fully
        obj.restart_previous()
        obj = WorkflowObject.get(ident)

        # x = 0 + 20 - 2 = 18
        assert obj.data == {"x": 18}
        assert obj.status == obj.known_statuses.COMPLETED

        # Test WorkflowObject.restart_next
        # ================================
        obj = WorkflowObject.create({"x": -100})
        db.session.commit()

        ident = obj.id

        obj.start_workflow("demo_halt_workflow")
        obj = WorkflowObject.get(ident)

        # x = -100 + 20 = -80
        assert obj.data == {"x": -80}
        assert obj.status == obj.known_statuses.WAITING

        obj.restart_next()
        obj = WorkflowObject.get(ident)

        # x = -80 - 2 = -82
        assert obj.data == {"x": -82}
        assert obj.status == obj.known_statuses.COMPLETED

        # Test WorkflowObject.restart_current
        # ===================================
        obj = WorkflowObject.create({"x": -100})
        db.session.commit()

        ident = obj.id

        obj.start_workflow("demo_halt_workflow")
        obj = WorkflowObject.get(ident)

        # x = -100 + 20 = -80
        assert obj.data == {"x": -80}
        assert obj.status == obj.known_statuses.WAITING

        obj.restart_current()
        obj = WorkflowObject.get(ident)

        # x = -80 - 2 = -82
        assert obj.data == {"x": -80}
        assert obj.status == obj.known_statuses.WAITING

        # Test WorkflowObject.delete
        # ==========================
        obj.delete()
        with pytest.raises(WorkflowsMissingObject):
            WorkflowObject.get(ident)