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"
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
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
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
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
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
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"
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)
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)
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)
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)