When validating a workflow, don't run the master workflow multiple times, its a huge waste of time.

Provide decent data when calling get_study_associate(s) scripts.
This commit is contained in:
Dan 2021-11-22 17:17:19 -05:00
parent 5bb7dbfb19
commit 4a1285b8e0
6 changed files with 54 additions and 18 deletions

View File

@ -5,7 +5,7 @@ from flask import g
from crc import session
from crc.api.common import ApiError, ApiErrorSchema
from crc.models.api_models import WorkflowApiSchema
from crc.models.file import FileModel, LookupDataSchema
from crc.models.file import FileModel
from crc.models.study import StudyModel, WorkflowMetadata, StudyStatus
from crc.models.task_event import TaskEventModel, TaskEvent, TaskEventSchema
from crc.models.workflow import WorkflowModel, WorkflowSpecModelSchema, WorkflowSpecModel, WorkflowSpecCategoryModel, \
@ -101,8 +101,10 @@ def drop_workflow_spec_library(spec_id,library_id):
libraries: WorkflowLibraryModel = session.query(WorkflowLibraryModel).filter_by(workflow_spec_id=spec_id).all()
return WorkflowLibraryModelSchema(many=True).dump(libraries)
def validate_workflow_specification(spec_id, study_id=None, test_until=None):
try:
WorkflowService.raise_if_disabled(spec_id, study_id)
WorkflowService.test_spec(spec_id, study_id, test_until)
WorkflowService.test_spec(spec_id, study_id, test_until, required_only=True)
except ApiError as ae:

View File

@ -18,7 +18,20 @@ example : get_study_associate('sbp3ey') => {'uid':'sbp3ey','role':'Unicorn Herde
def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
if len(args) < 1:
raise ApiError('no_user_id_specified', 'A uva uid is the sole argument to this function')
return {'uid': 'sbp3ey', 'role': 'Unicorn Herder', 'send_email': False, 'access': True}
return {'uid': 'sbp3ey',
'role': 'Unicorn Herder',
'send_email': False,
'access': True,
'ldap_info': {
'uid': 'sbp3ey',
'display_name': "Simply Delightful",
'email_address': 'sbp3ey@virginia.edu',
'telephone_number': '',
'title': '',
'department': '',
'affiliation': '',
'sponsor_type': '',
}}
def do_task(self, task, study_id, workflow_id, *args, **kwargs):
if len(args) < 1:

View File

@ -20,8 +20,28 @@ example : get_study_associates() => [{'uid':'sbp3ey','role':'Unicorn Herder', 's
def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
study_associates = [
{'uid': 'dhf8r', 'role': 'Chief Bee Keeper', 'send_email': True, 'access': True},
{'uid': 'lb3dp', 'role': 'Chief Cat Herder', 'send_email': True, 'access': True}
{'uid': 'dhf8r', 'role': 'Chief Bee Keeper', 'send_email': True, 'access': True,
'ldap_info': {
'uid': 'dhf8r',
'display_name': "Dan Funk",
'email_address': 'dhf8r@virginia.edu',
'telephone_number': '',
'title': '',
'department': '',
'affiliation': '',
'sponsor_type': '',
}},
{'uid': 'lb3dp', 'role': 'Chief Cat Herder', 'send_email': True, 'access': True,
'ldap_info': {
'uid': 'dhf8r',
'display_name': "Dan Funk",
'email_address': 'dhf8r@virginia.edu',
'telephone_number': '',
'title': '',
'department': '',
'affiliation': '',
'sponsor_type': ''
}},
]
return study_associates

View File

@ -165,15 +165,10 @@ Please note this is just a few examples, ALL known document types are returned i
)
def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
"""For validation only, pretend no results come back from pb"""
self.check_args(args, 2)
# Assure the reference file exists (a bit hacky, but we want to raise this error early, and cleanly.)
FileService.get_reference_file_data(DocumentService.DOCUMENT_LIST)
FileService.get_reference_file_data(StudyService.INVESTIGATOR_LIST)
# we call the real do_task so we can
# seed workflow validations with settings from studies in PB Mock
# in order to test multiple paths thru the workflow
return self.do_task(task, study_id, workflow_id, args[0])
return self.do_task(task, study_id, workflow_id, *args, **kwargs)
@timeit
def do_task(self, task, study_id, workflow_id, *args, **kwargs):

View File

@ -123,6 +123,16 @@ class WorkflowService(object):
workflow_model.study_id,
str(e)))
@staticmethod
def raise_if_disabled(spec_id, study_id):
"""Raise an exception of the workflow is not enabled and can not be executed."""
if study_id is not None:
study_model = session.query(StudyModel).filter(StudyModel.id == study_id).first()
spec_model = session.query(WorkflowSpecModel).filter(WorkflowSpecModel.id == spec_id).first()
status = StudyService._get_study_status(study_model)
if spec_model.id in status and status[spec_model.id]['status'] == 'disabled':
raise ApiError(code='disabled_workflow', message=f"This workflow is disabled. {status[spec_model.id]['message']}")
@staticmethod
@timeit
def test_spec(spec_id, validate_study_id=None, test_until=None, required_only=False):
@ -130,19 +140,12 @@ class WorkflowService(object):
Not fool-proof, but a good sanity check. Returns the final data
output form the last task if successful.
test_until
test_until - stop running the validation when you reach this task spec.
required_only can be set to true, in which case this will run the
spec, only completing the required fields, rather than everything.
"""
# Get workflow state dictionary, make sure workflow is not disabled.
if validate_study_id is not None:
study_model = session.query(StudyModel).filter(StudyModel.id == validate_study_id).first()
spec_model = session.query(WorkflowSpecModel).filter(WorkflowSpecModel.id == spec_id).first()
status = StudyService._get_study_status(study_model)
if spec_model.id in status and status[spec_model.id]['status'] == 'disabled':
raise ApiError(code='disabled_workflow', message=f"This workflow is disabled. {status[spec_model.id]['message']}")
workflow_model = WorkflowService.make_test_workflow(spec_id, validate_study_id)
try:
processor = WorkflowProcessor(workflow_model, validate_only=True)

View File

@ -25,3 +25,6 @@ class TestValidateEndEvent(BaseTest):
self.assertEqual(8, e.line_number)
self.assertEqual('{%- if value = 1 -%}', e.error_line)
self.assertEqual('verify_end_event.bpmn', e.file_name)