diff --git a/shared/workspaces/test/test_workflow_service.py b/shared/workspaces/test/test_workflow_service.py index 3f770b747b654a4db97e3efb96503f9d0142d392..3a8f2f9a2d6e1c97413fc39c4cc41d06d888cf0e 100644 --- a/shared/workspaces/test/test_workflow_service.py +++ b/shared/workspaces/test/test_workflow_service.py @@ -37,7 +37,12 @@ from messaging.messenger import SenderIF from mock_alchemy.mocking import UnifiedAlchemyMagicMock from workspaces.capability.services.capability_service import Router -from workspaces.workflow.schema import Workflow, WorkflowRequest, WorkflowRequestFile +from workspaces.workflow.schema import ( + Workflow, + WorkflowRequest, + WorkflowRequestFile, + WorkflowTemplate, +) from workspaces.workflow.services.interfaces import WorkflowInfoIF from workspaces.workflow.services.workflow_info import WorkflowInfo from workspaces.workflow.services.workflow_service import WorkflowService @@ -414,3 +419,11 @@ class TestWorkflowService: def test_get_dagfile_log(self, mock_workflow_service: WorkflowService): log_path = mock_workflow_service._get_dag_logfile_name(pathlib.Path("fake.dag")) assert log_path.name == "fake.dag.dagman.log" + + +def test_condor_name_utility(): + t = WorkflowTemplate() + t.filename = "foo.dag" + t.content = b"{{#make_condor_jobid}}T10t10/J2030+2093.23{{/make_condor_jobid}}" + file = t.render({}) + assert file.content == b"T10t10/J2030-2093-23" diff --git a/shared/workspaces/workspaces/workflow/schema.py b/shared/workspaces/workspaces/workflow/schema.py index f422d9eb6be2716c36a3d210ea25a45baef158a9..2ad5457628c25c5aff78db2decbfd958136934ca 100644 --- a/shared/workspaces/workspaces/workflow/schema.py +++ b/shared/workspaces/workspaces/workflow/schema.py @@ -17,7 +17,7 @@ # along with Workspaces. If not, see <https://www.gnu.org/licenses/>. import datetime import logging -from typing import Dict, List +from typing import Callable, Dict, List import chevron import pendulum @@ -118,6 +118,11 @@ class WorkflowTemplate(JSONSerializable): :param argument: argument(s) needed for template render :return: an AbstractFile rendered from mustache template """ + # add some rendering helpers to the argument + render_helpers = {"make_condor_jobid": self.make_condor_jobid} + argument = {**render_helpers, **argument} + + # render contents = chevron.render(self.content.decode("ascii"), argument) logger.debug( "rendering %s with argument %s to %s", @@ -147,6 +152,12 @@ class WorkflowTemplate(JSONSerializable): def from_json(cls, json: dict) -> any: return WorkflowTemplate(json["filename"], json["content"]) + @staticmethod + def make_condor_jobid(content: str, renderer: Callable[[str], str]): + # get the rendered content + rendered = renderer(content) + return rendered.replace(".", "-").replace("+", "-") + def __repr__(self): return f"<WorkflowTemplate filename={self.filename} for workflow={self.workflow_name}>"