using w4c_workflows.Models; using w4c_workflows.Services.Execution; using Xunit; namespace w4c_workflows.Tests; public class TaskRunMessageTests { private static WorkflowRun NewRun() => new() { Id = Guid.Parse("11111111-1111-1111-1111-111111111111"), WorkflowId = Guid.NewGuid(), TenantId = "t1", Status = RunStatus.Running, }; private static WorkflowTask NewTask() => new() { Id = Guid.Parse("22222222-2222-2222-2222-222222222222"), WorkflowId = Guid.NewGuid(), Key = "root", Language = "shell", Mode = WorkflowMode.Function, EntryJson = "{\"file\":\"root.sh\",\"function\":\"main\"}", EnvJson = "{\"FOO\":\"bar\"}", }; [Fact] public void Serializes_fields_the_worker_can_parse_back() { var fields = TaskRunMessage.ToFields( NewRun(), NewTask(), "{\"x\":1}", "/repo/workflows", 2); var invocation = TaskInvocation.FromFields(fields); Assert.Equal(TaskInvocation.TypeValue, invocation.Type); Assert.Equal("11111111-1111-1111-1111-111111111111", invocation.RunId); Assert.Equal("22222222-2222-2222-2222-222222222222", invocation.TaskId); Assert.Equal("root", invocation.TaskKey); Assert.Equal("shell", invocation.Language); Assert.Equal("root.sh", invocation.EntryFile); Assert.Equal("main", invocation.EntryFunction); Assert.Equal("{\"x\":1}", invocation.Input); Assert.Equal("/repo/workflows", invocation.WorkingDir); Assert.Equal("t1", invocation.TenantId); Assert.Equal(2, invocation.Attempt); Assert.Equal("bar", invocation.Env["FOO"]); } [Fact] public void Omits_optional_fields_when_absent() { var task = NewTask(); task.EntryJson = "{\"file\":\"a.sh\"}"; // no function task.EnvJson = null; var fields = TaskRunMessage.ToFields(NewRun(), task, null, null, 1); var invocation = TaskInvocation.FromFields(fields); Assert.Null(invocation.EntryFunction); Assert.Null(invocation.Input); Assert.Null(invocation.WorkingDir); Assert.Empty(invocation.Env); Assert.Equal(1, invocation.Attempt); } [Fact] public void Carries_server_reference_when_set_and_omits_when_absent() { // S8: a task targeting a managed server serializes the server id through the // wire contract so the worker can execute it remotely instead of locally. var withServer = NewTask(); withServer.Server = "srv-07"; var fields = TaskRunMessage.ToFields(NewRun(), withServer, null, null, 1); Assert.Equal("srv-07", fields["server"]); var invocation = TaskInvocation.FromFields(fields); Assert.Equal("srv-07", invocation.Server); // No server field => local subprocess path (the default) => null. var withoutServer = NewTask(); var bareFields = TaskRunMessage.ToFields(NewRun(), withoutServer, null, null, 1); Assert.False(bareFields.ContainsKey("server")); Assert.Null(TaskInvocation.FromFields(bareFields).Server); } }