Skip to content

Commit 5f58fa1

Browse files
authored
Merge pull request #753 from Project-MONAI/AC-2022
Ac 2022
2 parents c2d6ccb + 176efb7 commit 5f58fa1

File tree

4 files changed

+171
-10
lines changed

4 files changed

+171
-10
lines changed

src/TaskManager/Plug-ins/Argo/ArgoPlugin.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ private void ProcessTaskPluginArguments(Workflow workflow)
434434
Guard.Against.Null(workflow);
435435

436436
var resources = Event.GetTaskPluginArgumentsParameter<Dictionary<string, string>>(Keys.ArgoResource);
437-
var priorityClassName = Event.GetTaskPluginArgumentsParameter(Keys.TaskPriorityClassName);
437+
var priorityClassName = Event.GetTaskPluginArgumentsParameter(Keys.TaskPriorityClassName) ?? "standard";
438438
var argoParameters = Event.GetTaskPluginArgumentsParameter<Dictionary<string, string>>(Keys.ArgoParameters);
439439

440440
if (argoParameters is not null)
@@ -462,16 +462,9 @@ private void ProcessTaskPluginArguments(Workflow workflow)
462462
AddRequest(resources, template, ResourcesKeys.CpuReservation);
463463
AddRequest(resources, template, ResourcesKeys.MemoryReservation);
464464
AddRequest(resources, template, ResourcesKeys.GpuLimit);
465-
466-
if (priorityClassName is not null)
467-
{
468-
template.PriorityClassName = priorityClassName;
469-
}
470-
}
471-
if (priorityClassName is not null)
472-
{
473-
workflow.Spec.PodPriorityClassName = priorityClassName;
465+
template.PriorityClassName = priorityClassName;
474466
}
467+
workflow.Spec.PodPriorityClassName = priorityClassName;
475468
}
476469

477470
private static void AddLimit(Dictionary<string, string>? resources, Template2 template, ResourcesKey key)

src/WorkflowManager/WorkflowManager/Validators/WorkflowValidator.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class WorkflowValidator
4141
public static readonly string Separator = ";";
4242
private const string Comma = ", ";
4343
private readonly ILogger<WorkflowValidator> _logger;
44+
public static readonly string TaskPriorityClassName = "priority";
4445

4546
/// <summary>
4647
/// Initializes a new instance of the <see cref="WorkflowValidator"/> class.
@@ -335,6 +336,18 @@ private void ValidateArgoTask(TaskObject currentTask)
335336
{
336337
Errors.Add($"Task: '{currentTask.Id}' workflow_template_name must be specified{Comma}this corresponds to an Argo template name.");
337338
}
339+
340+
if (currentTask.Args.ContainsKey(TaskPriorityClassName))
341+
{
342+
switch (currentTask.Args[TaskPriorityClassName].ToLower())
343+
{
344+
case "high" or "standard" or "low":
345+
break;
346+
default:
347+
Errors.Add($"Task: '{currentTask.Id}' TaskPriorityClassName must be one of \"high\"{Comma} \"standard\" or \"low\"");
348+
break;
349+
}
350+
}
338351
}
339352

340353
private void ValidateClinicalReviewTask(TaskObject[] tasks, TaskObject currentTask)

tests/UnitTests/TaskManager.Argo.Tests/ArgoPluginTest.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,68 @@ public async Task ArgoPlugin_CreateArgoTemplate_Valid_json_Calls_Client()
806806
Times.Once);
807807
}
808808

809+
[Fact(DisplayName = "podPriorityClassName gets set if not given in workflow")]
810+
public async Task ArgoPlugin_Ensures_podPriorityClassName_is_set()
811+
{
812+
var argoTemplate = LoadArgoTemplate("SimpleTemplate.yml");
813+
Assert.NotNull(argoTemplate);
814+
815+
SetUpSimpleArgoWorkFlow(argoTemplate);
816+
817+
var message = GenerateTaskDispatchEventWithValidArguments();
818+
819+
WorkflowCreateRequest? requestMade = default;
820+
ArgoClient.Setup(a => a.Argo_CreateWorkflowAsync(It.IsAny<string>(), It.IsAny<WorkflowCreateRequest>(), It.IsAny<CancellationToken>()))
821+
.Callback<string, WorkflowCreateRequest, CancellationToken>((name, request, token) =>
822+
{
823+
requestMade = request;
824+
});
825+
826+
var defaultClassName = "standard";
827+
var runner = new ArgoPlugin(ServiceScopeFactory.Object, _logger.Object, Options, message);
828+
var result = await runner.ExecuteTask(CancellationToken.None).ConfigureAwait(false);
829+
830+
Assert.NotNull(requestMade);
831+
Assert.Equal(defaultClassName, requestMade.Workflow.Spec.PodPriorityClassName);
832+
833+
foreach (var template in requestMade.Workflow.Spec.Templates)
834+
{
835+
Assert.Equal(defaultClassName, template.PriorityClassName);
836+
}
837+
}
838+
839+
[Fact(DisplayName = "podPriorityClassName gets set if given in workflow")]
840+
public async Task ArgoPlugin_Ensures_podPriorityClassName_is_set_as_given()
841+
{
842+
var argoTemplate = LoadArgoTemplate("SimpleTemplate.yml");
843+
Assert.NotNull(argoTemplate);
844+
845+
SetUpSimpleArgoWorkFlow(argoTemplate);
846+
847+
var message = GenerateTaskDispatchEventWithValidArguments();
848+
849+
var givenClassName = "fred";
850+
message.TaskPluginArguments.Add("priority", givenClassName);
851+
852+
WorkflowCreateRequest? requestMade = default;
853+
ArgoClient.Setup(a => a.Argo_CreateWorkflowAsync(It.IsAny<string>(), It.IsAny<WorkflowCreateRequest>(), It.IsAny<CancellationToken>()))
854+
.Callback<string, WorkflowCreateRequest, CancellationToken>((name, request, token) =>
855+
{
856+
requestMade = request;
857+
});
858+
859+
var runner = new ArgoPlugin(ServiceScopeFactory.Object, _logger.Object, Options, message);
860+
var result = await runner.ExecuteTask(CancellationToken.None).ConfigureAwait(false);
861+
862+
Assert.NotNull(requestMade);
863+
Assert.Equal(givenClassName, requestMade.Workflow.Spec.PodPriorityClassName);
864+
865+
foreach (var template in requestMade.Workflow.Spec.Templates)
866+
{
867+
Assert.Equal(givenClassName, template.PriorityClassName);
868+
}
869+
}
870+
809871
private void SetUpSimpleArgoWorkFlow(WorkflowTemplate argoTemplate)
810872
{
811873
Assert.NotNull(argoTemplate);

tests/UnitTests/WorkflowManager.Tests/Validators/WorkflowValidatorTests.cs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using System;
1818
using System.Security.Cryptography.Xml;
1919
using System.Threading.Tasks;
20+
using Amazon.Runtime.Internal.Transform;
2021
using Microsoft.Extensions.Logging;
2122
using Monai.Deploy.WorkflowManager.Common.Interfaces;
2223
using Monai.Deploy.WorkflowManager.Contracts.Models;
@@ -535,5 +536,97 @@ public async Task ValidateWorkflow_ValidateWorkflow_ReturnsNoErrors()
535536
Assert.True(errors.Count == 0);
536537
}
537538
}
539+
540+
[Fact]
541+
public async Task ValidateWorkflow_Incorrect_podPriorityClassName_ReturnsErrors()
542+
{
543+
var workflow = new Workflow
544+
{
545+
Name = "Workflowname1",
546+
Description = "Workflowdesc1",
547+
Version = "1",
548+
InformaticsGateway = new InformaticsGateway
549+
{
550+
AeTitle = "aetitle",
551+
ExportDestinations = new string[] { "oneDestination", "twoDestination", "threeDestination" }
552+
},
553+
Tasks = new TaskObject[]
554+
{
555+
new TaskObject
556+
{
557+
Args = new System.Collections.Generic.Dictionary<string, string>{
558+
{ "priority" ,"god" },
559+
{ "workflow_template_name" ,"spot"}
560+
},
561+
Id = "rootTask",
562+
Type = "argo",
563+
Description = "TestDesc",
564+
Artifacts = new ArtifactMap
565+
{
566+
Input = new Artifact[]{
567+
new Artifact
568+
{
569+
Name = "non_unique_artifact",
570+
Value = "Example Value"
571+
}
572+
}
573+
}
574+
},
575+
}
576+
};
577+
578+
_workflowService.Setup(w => w.GetByNameAsync(It.IsAny<string>()))
579+
.ReturnsAsync(null, TimeSpan.FromSeconds(.1));
580+
581+
var errors = await _workflowValidator.ValidateWorkflow(workflow);
582+
583+
Assert.Single(errors);
584+
}
585+
586+
[Fact]
587+
public async Task ValidateWorkflow_correct_podPriorityClassName_ReturnsNoErrors()
588+
{
589+
var workflow = new Workflow
590+
{
591+
Name = "Workflowname1",
592+
Description = "Workflowdesc1",
593+
Version = "1",
594+
InformaticsGateway = new InformaticsGateway
595+
{
596+
AeTitle = "aetitle",
597+
ExportDestinations = new string[] { "oneDestination", "twoDestination", "threeDestination" }
598+
},
599+
Tasks = new TaskObject[]
600+
{
601+
new TaskObject
602+
{
603+
Args = new System.Collections.Generic.Dictionary<string, string>{
604+
{ "priority" ,"high" },
605+
{ "workflow_template_name" ,"spot"}
606+
},
607+
Id = "rootTask",
608+
Type = "argo",
609+
Description = "TestDesc",
610+
Artifacts = new ArtifactMap
611+
{
612+
Input = new Artifact[]{
613+
new Artifact
614+
{
615+
Name = "non_unique_artifact",
616+
Value = "Example Value"
617+
}
618+
}
619+
}
620+
},
621+
}
622+
};
623+
624+
_workflowService.Setup(w => w.GetByNameAsync(It.IsAny<string>()))
625+
.ReturnsAsync(null, TimeSpan.FromSeconds(.1));
626+
627+
var errors = await _workflowValidator.ValidateWorkflow(workflow);
628+
629+
Assert.Empty(errors);
630+
}
538631
}
539632
}

0 commit comments

Comments
 (0)