diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Features/WorkflowTaskArtifacts.feature b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Features/WorkflowTaskArtifacts.feature index 76764f783..880594f9f 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Features/WorkflowTaskArtifacts.feature +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Features/WorkflowTaskArtifacts.feature @@ -121,3 +121,40 @@ Scenario: Task with context.executions.task_id.artifacts.artifact_name is trigge Examples: | testData | taskUpdateMessage | | TwoTask_Context.Executions.Task_id.Artifact.Artifact_Name_Mandatory=False | TwoTask_Context.Executions.Task_id.Artifact.Artifact_Name_Mandatory=False_No_Outputs | + +@TaskArtifacts_TaskUpdate +Scenario: Task with context.executions.task_id.output_dir is triggered when mandatory files exist resulting in a Sucessful Task Dispatch + Given I have a clinical workflow + And I have a Workflow Instance with artifacts full_patient_metadata in minio + When I publish a Task Update Message with artifacts output_metadata in minio + Then I can see Workflow Instance is updated with Task Update Information + And 1 Task Dispatch event is published + And I can see Workflow Instance is updated with Task Dispatch Information + Examples: + | testData | + | TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=True | + | TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=False | + | TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=Null | + +@TaskArtifacts_TaskUpdate +Scenario: Task with context.executions.task_id.output_dir is not triggered when mandatory files are missing + Given I have a clinical workflow + And I have a Workflow Instance with artifacts full_patient_metadata in minio + When I publish a Task Update Message with no artifacts + Then A Task Dispatch event is not published + Examples: + | testData | + | TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=True | + | TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=Null | + +@TaskArtifacts_TaskUpdate +Scenario: Task with context.executions.task_id.output_dir is triggered when non mandatory files are missing + Given I have a clinical workflow + And I have a Workflow Instance with artifacts full_patient_metadata in minio + When I publish a Task Update Message with no artifacts + Then I can see Workflow Instance is updated with Task Update Information + And 1 Task Dispatch event is published + And I can see Workflow Instance is updated with Task Dispatch Information + Examples: + | testData | taskUpdateMessage | + | TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=False | TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=False_No_Outputs | diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/Assertions.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/Assertions.cs index df952478b..58f2b5343 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/Assertions.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/Support/Assertions.cs @@ -153,15 +153,27 @@ public void AssertTaskDispatchEvent(TaskDispatchEvent taskDispatchEvent, Workflo taskDispatchEvent.PayloadId.Should().Match(workflowInstance.PayloadId); taskDispatchEvent.ExecutionId.Should().Match(workflowInstanceTask?.ExecutionId); + var previousTaskExecution = workflowInstance.Tasks.FirstOrDefault(x => x.TaskId.Equals + (workflowInstance?.Tasks?.FirstOrDefault(x => !string.IsNullOrEmpty(x.PreviousTaskId))?.PreviousTaskId)); + if (taskDispatchEvent.Inputs.Count > 0) { + if (taskUpdateEvent != null) { - AssertInputArtifactsForTaskDispatch(workflowRevisionTask, workflowInstance.PayloadId, taskDispatchEvent.Inputs, taskUpdateEvent); + AssertInputArtifactsForTaskDispatch(workflowRevisionTask, + workflowInstance.PayloadId, + taskDispatchEvent.Inputs, + taskUpdateEvent, + previousTaskExecution?.OutputDirectory); } else { - AssertInputArtifactsForTaskDispatch(workflowRevisionTask, workflowInstance.PayloadId, taskDispatchEvent.Inputs); + AssertInputArtifactsForTaskDispatch(workflowRevisionTask, + workflowInstance.PayloadId, + taskDispatchEvent.Inputs, + null, + previousTaskExecution?.OutputDirectory); } } @@ -190,7 +202,10 @@ internal void AssertWorkflowInstanceAfterTaskDispatch(WorkflowInstance workflowI workflowInstanceTask?.Status.Should().Be(TaskExecutionStatus.Dispatched); workflowInstanceTask?.TaskType.Should().Be(workflowRevisionTask?.Type); AssertOutputDirectory(workflowInstanceTask, taskDispatchEvent.PayloadId, workflowInstance.Id); - AssertInputArtifactsForWorkflowInstance(workflowRevisionTask, taskDispatchEvent.PayloadId, workflowInstanceTask, previousTaskExecution); + if (workflowInstanceTask.InputArtifacts.Any()) + { + AssertInputArtifactsForWorkflowInstance(workflowRevisionTask, taskDispatchEvent.PayloadId, workflowInstanceTask, previousTaskExecution); + } } public void AssertPayload(Payload payload, Payload? actualPayload) diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/TaskUpdateTestData.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/TaskUpdateTestData.cs index 63f1eea15..a8985a6a4 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/TaskUpdateTestData.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/TaskUpdateTestData.cs @@ -36,6 +36,37 @@ public static string GetRelativePathForOutputArtifacts(string name) return $"{workflowInstance?.PayloadId}/workflows/{workflowInstance?.Id}/{executionId}"; } + public static TaskUpdateEvent CreateTaskUpdateEvent(string workflowInstanceName) + { + return new TaskUpdateEvent() + { + WorkflowInstanceId = Helper.GetWorkflowInstanceByName(workflowInstanceName).WorkflowInstance.Id, + ExecutionId = Helper.GetWorkflowInstanceByName(workflowInstanceName).WorkflowInstance.Tasks[0].ExecutionId, + CorrelationId = Guid.NewGuid().ToString(), + Reason = FailureReason.None, + Message = "Task Message", + TaskId = Helper.GetWorkflowInstanceByName(workflowInstanceName).WorkflowInstance.Tasks[0].TaskId, + Outputs = new List + { + new Messaging.Common.Storage() + { + Name = "output", + Endpoint = "//output.dcm", + Credentials = new Messaging.Common.Credentials() + { + AccessKey = "test1", + AccessToken = "test", + }, + Bucket = "bucket1", + RelativeRootPath = GetRelativePathForOutputArtifacts(workflowInstanceName) + } + }, + Metadata = new Dictionary() + { + } + }; + } + public static List TestData = new List() { new TaskUpdateTestData() @@ -656,6 +687,37 @@ public static string GetRelativePathForOutputArtifacts(string name) } } }, + new TaskUpdateTestData() + { + Name = "TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=True", + TaskUpdateEvent = CreateTaskUpdateEvent("TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=True") + }, + new TaskUpdateTestData() + { + Name = "TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=False", + TaskUpdateEvent = CreateTaskUpdateEvent("TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=False") + }, + new TaskUpdateTestData() + { + Name = "TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=Null", + TaskUpdateEvent = CreateTaskUpdateEvent("TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=Null") + }, + new TaskUpdateTestData() + { + Name = "TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=False_No_Outputs", + TaskUpdateEvent = new TaskUpdateEvent() + { + WorkflowInstanceId = Helper.GetWorkflowInstanceByName("TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=False").WorkflowInstance.Id, + ExecutionId = Helper.GetWorkflowInstanceByName("TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=False").WorkflowInstance.Tasks[0].ExecutionId, + CorrelationId = Guid.NewGuid().ToString(), + Reason = FailureReason.None, + Message = "Task Message", + TaskId = Helper.GetWorkflowInstanceByName("TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=False").WorkflowInstance.Tasks[0].TaskId, + Metadata = new Dictionary() + { + } + } + }, }; } } diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowInstanceTestData.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowInstanceTestData.cs index 89025cd47..f41c0957f 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowInstanceTestData.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowInstanceTestData.cs @@ -31,6 +31,41 @@ public class WorkflowInstanceTestData public static class WorkflowInstancesTestData { + public static WorkflowInstance CreateWorkflowInstance(string workflowName) + { + var id = Guid.NewGuid().ToString(); + var payloadId = Guid.NewGuid().ToString(); + var executionId = Guid.NewGuid().ToString(); + return new WorkflowInstance() + { + Id = id, + AeTitle = Helper.GetWorkflowByName(workflowName).WorkflowRevision.Workflow.InformaticsGateway.AeTitle, + WorkflowId = Helper.GetWorkflowByName(workflowName).WorkflowRevision.WorkflowId, + PayloadId = payloadId, + StartTime = DateTime.Now, + Status = Status.Created, + BucketId = TestExecutionConfig.MinioConfig.Bucket, + InputMetaData = new Dictionary() + { + { "", "" } + }, + Tasks = new List + { + new TaskExecution() + { + ExecutionId = executionId, + TaskId = Helper.GetWorkflowByName(workflowName).WorkflowRevision.Workflow.Tasks[0].Id, + TaskType = Helper.GetWorkflowByName(workflowName).WorkflowRevision?.Workflow.Tasks[0].Type, + Status = TaskExecutionStatus.Accepted, + InputArtifacts = null, + OutputArtifacts = null, + OutputDirectory = $"{payloadId}/workflows/{id}/{executionId}" + } + } + }; + } + + public static List TestData = new List() { new WorkflowInstanceTestData() @@ -967,6 +1002,21 @@ public static class WorkflowInstancesTestData } } }, + new WorkflowInstanceTestData() + { + Name = "TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=True", + WorkflowInstance = CreateWorkflowInstance("TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=True") + }, + new WorkflowInstanceTestData() + { + Name = "TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=False", + WorkflowInstance = CreateWorkflowInstance("TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=False") + }, + new WorkflowInstanceTestData() + { + Name = "TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=Null", + WorkflowInstance = CreateWorkflowInstance("TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=Null") + }, }; } } diff --git a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowRevisionTestData.cs b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowRevisionTestData.cs index 0c6a1193a..f98e3fd34 100644 --- a/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowRevisionTestData.cs +++ b/tests/IntegrationTests/WorkflowExecutor.IntegrationTests/TestData/WorkflowRevisionTestData.cs @@ -1924,6 +1924,179 @@ public static class WorkflowRevisionsTestData } } }, + new WorkflowRevisionTestData() + { + Name = "TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=True", + WorkflowRevision = new WorkflowRevision() + { + Id = Guid.NewGuid().ToString(), + WorkflowId = Guid.NewGuid().ToString(), + Revision = 1, + Workflow = new Workflow() + { + Name = "Artifact 1", + Description = "Artifact 1", + Version = "1", + Tasks = new TaskObject[] + { + new TaskObject + { + Id = "artifact_task_1", + Type = "Artifact_task", + Description = "Artifact Workflow 1 Task 1", + Artifacts = new ArtifactMap() + { + Input = new Artifact[] + { + new Artifact { Name = "Dicom", Value = "{{ context.input.dicom }}" }, + }, + }, + TaskDestinations = new TaskDestination[] + { + new TaskDestination{ Name = "artifact_task_2" } + } + }, + new TaskObject + { + Id = "artifact_task_2", + Type = "Artifact_task", + Description = "Artifact Workflow 1 Task 2", + Artifacts = new ArtifactMap() + { + Input = new Artifact[] + { + new Artifact + { + Name = "output", + Value = "{{ context.executions.artifact_task_1.output_dir }}", + Mandatory = true + }, + }, + }, + }, + }, + InformaticsGateway = new InformaticsGateway() + { + AeTitle = "Artifact_AE" + } + } + } + }, + new WorkflowRevisionTestData() + { + Name = "TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=False", + WorkflowRevision = new WorkflowRevision() + { + Id = Guid.NewGuid().ToString(), + WorkflowId = Guid.NewGuid().ToString(), + Revision = 1, + Workflow = new Workflow() + { + Name = "Artifact 1", + Description = "Artifact 1", + Version = "1", + Tasks = new TaskObject[] + { + new TaskObject + { + Id = "artifact_task_1", + Type = "Artifact_task", + Description = "Artifact Workflow 1 Task 1", + Artifacts = new ArtifactMap() + { + Input = new Artifact[] + { + new Artifact { Name = "Dicom", Value = "{{ context.input.dicom }}" }, + }, + }, + TaskDestinations = new TaskDestination[] + { + new TaskDestination{ Name = "artifact_task_2" } + } + }, + new TaskObject + { + Id = "artifact_task_2", + Type = "Artifact_task", + Description = "Artifact Workflow 1 Task 2", + Artifacts = new ArtifactMap() + { + Input = new Artifact[] + { + new Artifact + { + Name = "output", + Value = "{{ context.executions.artifact_task_1.output_dir }}", + Mandatory = false + }, + }, + }, + }, + }, + InformaticsGateway = new InformaticsGateway() + { + AeTitle = "Artifact_AE" + } + } + } + }, + new WorkflowRevisionTestData() + { + Name = "TwoTask_Context.Executions.Task_id.Output_Dir_Mandatory=Null", + WorkflowRevision = new WorkflowRevision() + { + Id = Guid.NewGuid().ToString(), + WorkflowId = Guid.NewGuid().ToString(), + Revision = 1, + Workflow = new Workflow() + { + Name = "Artifact 1", + Description = "Artifact 1", + Version = "1", + Tasks = new TaskObject[] + { + new TaskObject + { + Id = "artifact_task_1", + Type = "Artifact_task", + Description = "Artifact Workflow 1 Task 1", + Artifacts = new ArtifactMap() + { + Input = new Artifact[] + { + new Artifact { Name = "Dicom", Value = "{{ context.input.dicom }}" }, + }, + }, + TaskDestinations = new TaskDestination[] + { + new TaskDestination{ Name = "artifact_task_2" } + } + }, + new TaskObject + { + Id = "artifact_task_2", + Type = "Artifact_task", + Description = "Artifact Workflow 1 Task 2", + Artifacts = new ArtifactMap() + { + Input = new Artifact[] + { + new Artifact + { + Name = "output", + Value = "{{ context.executions.artifact_task_1.output_dir }}" + }, + }, + }, + }, + }, + InformaticsGateway = new InformaticsGateway() + { + AeTitle = "Artifact_AE" + } + } + } + }, }; } }