From 529bfc34b378432d2c2a939168a64c6d64944ea2 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Tue, 16 Mar 2021 13:35:51 -0400 Subject: [PATCH 1/6] We now check for an infinite loop during validation. This happened when testing for a Department Chair in a workflow. Our mocked data for study_info script did not have a Department Chair --- crc/services/workflow_service.py | 54 ++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/crc/services/workflow_service.py b/crc/services/workflow_service.py index cc73e383..cae421cc 100644 --- a/crc/services/workflow_service.py +++ b/crc/services/workflow_service.py @@ -95,31 +95,37 @@ class WorkflowService(object): WorkflowService.delete_test_data() raise ApiError.from_workflow_exception("workflow_validation_exception", str(we), we) + count = 0 while not processor.bpmn_workflow.is_completed(): - try: - processor.bpmn_workflow.get_deep_nav_list() # Assure no errors with navigation. - processor.bpmn_workflow.do_engine_steps() - tasks = processor.bpmn_workflow.get_tasks(SpiffTask.READY) - for task in tasks: - if task.task_spec.lane is not None and task.task_spec.lane not in task.data: - raise ApiError.from_task("invalid_role", - f"This task is in a lane called '{task.task_spec.lane}', The " - f" current task data must have information mapping this role to " - f" a unique user id.", task) - task_api = WorkflowService.spiff_task_to_api_task( - task, - add_docs_and_forms=True) # Assure we try to process the documentation, and raise those errors. - # make sure forms have a form key - if hasattr(task_api, 'form') and task_api.form is not None and task_api.form.key == '': - raise ApiError(code='missing_form_key', - message='Forms must include a Form Key.', - task_id=task.id, - task_name=task.get_name()) - WorkflowService.populate_form_with_random_data(task, task_api, required_only) - processor.complete_task(task) - except WorkflowException as we: - WorkflowService.delete_test_data() - raise ApiError.from_workflow_exception("workflow_validation_exception", str(we), we) + if count < 1000: + try: + processor.bpmn_workflow.get_deep_nav_list() # Assure no errors with navigation. + processor.bpmn_workflow.do_engine_steps() + tasks = processor.bpmn_workflow.get_tasks(SpiffTask.READY) + for task in tasks: + if task.task_spec.lane is not None and task.task_spec.lane not in task.data: + raise ApiError.from_task("invalid_role", + f"This task is in a lane called '{task.task_spec.lane}', The " + f" current task data must have information mapping this role to " + f" a unique user id.", task) + task_api = WorkflowService.spiff_task_to_api_task( + task, + add_docs_and_forms=True) # Assure we try to process the documentation, and raise those errors. + # make sure forms have a form key + if hasattr(task_api, 'form') and task_api.form is not None and task_api.form.key == '': + raise ApiError(code='missing_form_key', + message='Forms must include a Form Key.', + task_id=task.id, + task_name=task.get_name()) + WorkflowService.populate_form_with_random_data(task, task_api, required_only) + processor.complete_task(task) + count += 1 + except WorkflowException as we: + WorkflowService.delete_test_data() + raise ApiError.from_workflow_exception("workflow_validation_exception", str(we), we) + else: + raise ApiError.from_workflow_exception(code='validation_loop', + message=f'There appears to be an infinite loop in the validation. spec_id: {spec_id}') WorkflowService.delete_test_data() WorkflowService._process_documentation(processor.bpmn_workflow.last_task.parent.parent) From e2ba19748dadb29be963d6b217fd10d5ed6f5e32 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Tue, 16 Mar 2021 13:36:55 -0400 Subject: [PATCH 2/6] Added department chair to the mocked data for study_info script. The missing department chair caused an infinite loop in a workflow that checked for a department chair. --- crc/scripts/study_info.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crc/scripts/study_info.py b/crc/scripts/study_info.py index 90bbd866..af0c4d55 100644 --- a/crc/scripts/study_info.py +++ b/crc/scripts/study_info.py @@ -80,7 +80,12 @@ class StudyInfo(Script): 'display': 'Optional', 'unique': 'Yes', 'user_id': 'asd3v', - 'error': 'Unable to locate a user with id asd3v in LDAP'} + 'error': 'Unable to locate a user with id asd3v in LDAP'}, + 'DEPT_CH': { + 'label': 'Department Chair', + 'display': 'Always', + 'unique': 'Yes', + 'user_id': 'lb3dp'} }, "documents": { 'AD_CoCApp': {'category1': 'Ancillary Document', 'category2': 'CoC Application', 'category3': '', From 938079cf5906b821b110f66a768bf38be7e0d134 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Wed, 17 Mar 2021 14:52:19 -0400 Subject: [PATCH 3/6] Lowered count ceiling to 100, from 1000. This significantly increased validation time, from about 3 minutes to about 10 seconds. Changed ApiError call to from_task, instead of from_workflow_exception. --- crc/services/workflow_service.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crc/services/workflow_service.py b/crc/services/workflow_service.py index cae421cc..edabd433 100644 --- a/crc/services/workflow_service.py +++ b/crc/services/workflow_service.py @@ -97,7 +97,7 @@ class WorkflowService(object): count = 0 while not processor.bpmn_workflow.is_completed(): - if count < 1000: + if count < 100: # check for infinite loop try: processor.bpmn_workflow.get_deep_nav_list() # Assure no errors with navigation. processor.bpmn_workflow.do_engine_steps() @@ -124,8 +124,9 @@ class WorkflowService(object): WorkflowService.delete_test_data() raise ApiError.from_workflow_exception("workflow_validation_exception", str(we), we) else: - raise ApiError.from_workflow_exception(code='validation_loop', - message=f'There appears to be an infinite loop in the validation. spec_id: {spec_id}') + raise ApiError.from_task(code='validation_loop', + message=f'There appears to be an infinite loop in the validation. Task is {task.task_spec.description}', + task=task) WorkflowService.delete_test_data() WorkflowService._process_documentation(processor.bpmn_workflow.last_task.parent.parent) From c4b52f85af7288e003c679772b44b98a48bee492 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Wed, 17 Mar 2021 14:52:50 -0400 Subject: [PATCH 4/6] Test and workflow for testing infinite loop code. --- tests/data/infinite_loop/infinite_loop.bpmn | 97 +++++++++++++++++++ tests/workflow/test_workflow_infinite_loop.py | 13 +++ 2 files changed, 110 insertions(+) create mode 100644 tests/data/infinite_loop/infinite_loop.bpmn create mode 100644 tests/workflow/test_workflow_infinite_loop.py diff --git a/tests/data/infinite_loop/infinite_loop.bpmn b/tests/data/infinite_loop/infinite_loop.bpmn new file mode 100644 index 00000000..7fb41c13 --- /dev/null +++ b/tests/data/infinite_loop/infinite_loop.bpmn @@ -0,0 +1,97 @@ + + + + + Flow_0ldlhrt + + + + Flow_0ldlhrt + Flow_05mrx8v + Flow_0pddur1 + investigators = study_info('investigators') + + + + Investigators: {{ investigators }} + Flow_0pddur1 + Flow_03m3cuy + + + Flow_03m3cuy + Flow_05mrx8v + Flow_1212fe2 + + + + + hasattr(investigators, 'DEPT_CH') + + + Flow_14jn215 + + + + # Thank You + Flow_1212fe2 + Flow_14jn215 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/workflow/test_workflow_infinite_loop.py b/tests/workflow/test_workflow_infinite_loop.py new file mode 100644 index 00000000..a9846084 --- /dev/null +++ b/tests/workflow/test_workflow_infinite_loop.py @@ -0,0 +1,13 @@ +from tests.base_test import BaseTest +from crc import app +import json + + +class TestWorkflowInfiniteLoop(BaseTest): + + def test_workflow_infinite_loop(self): + self.load_example_data() + spec_model = self.load_test_spec('infinite_loop') + rv = self.app.get('/v1.0/workflow-specification/%s/validate' % spec_model.id, headers=self.logged_in_headers()) + json_data = json.loads(rv.get_data(as_text=True)) + self.assertIn('There appears to be an infinite loop', json_data[0]['message']) From d9bf2a8a816e2e65d72c5a2caaeb124defd2ec62 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Tue, 23 Mar 2021 13:12:13 -0400 Subject: [PATCH 5/6] Change location of `CR Connect` string. Move it left, closer to the logo --- crc/templates/mail_main_template.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crc/templates/mail_main_template.html b/crc/templates/mail_main_template.html index c8841ddc..b9f9ac7e 100644 --- a/crc/templates/mail_main_template.html +++ b/crc/templates/mail_main_template.html @@ -89,6 +89,10 @@ padding-top: 10px; } + td#logo-td { + width: 50px; + } + .footer, .header { clear: both; margin-top: 10px; @@ -361,7 +365,7 @@ -
+ From 115f9db5d932d53609fbcad0c2d1b8beb9ef36b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Mar 2021 21:42:47 +0000 Subject: [PATCH 6/6] Bump lxml from 4.6.2 to 4.6.3 in /deploy Bumps [lxml](https://github.com/lxml/lxml) from 4.6.2 to 4.6.3. - [Release notes](https://github.com/lxml/lxml/releases) - [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt) - [Commits](https://github.com/lxml/lxml/compare/lxml-4.6.2...lxml-4.6.3) Signed-off-by: dependabot[bot] --- deploy/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/requirements.txt b/deploy/requirements.txt index 8cca38b5..f20a4a5c 100644 --- a/deploy/requirements.txt +++ b/deploy/requirements.txt @@ -37,7 +37,7 @@ jdcal==1.4.1 jinja2==2.11.3 jsonschema==3.2.0 ldap3==2.8.1 -lxml==4.6.2 +lxml==4.6.3 mako==1.1.3 markdown==3.3.3 markupsafe==1.1.1