using w4c_workflows.Services.Execution; using Xunit; namespace w4c_workflows.Tests; public class ExecutionContractTests { [Fact] public void TaskInvocation_parses_a_full_job_field_set() { var fields = new Dictionary { ["type"] = "task.run", ["run_id"] = "run-1", ["task_id"] = "task-1", ["task_key"] = "validate", ["language"] = "python", ["entry_file"] = "validate.py", ["entry_function"] = "main", ["env"] = "{\"FOO\":\"bar\"}", ["input"] = "{\"n\":5}", ["working_dir"] = "/tmp/wf", ["tenant_id"] = "t1", ["attempt"] = "2", }; var inv = TaskInvocation.FromFields(fields); Assert.Equal("task.run", inv.Type); Assert.Equal("run-1", inv.RunId); Assert.Equal("validate", inv.TaskKey); Assert.Equal("python", inv.Language); Assert.Equal("validate.py", inv.EntryFile); Assert.Equal("main", inv.EntryFunction); Assert.Equal("bar", inv.Env["FOO"]); Assert.Equal("{\"n\":5}", inv.Input); Assert.Equal("/tmp/wf", inv.WorkingDir); Assert.Equal("t1", inv.TenantId); Assert.Equal(2, inv.Attempt); } [Fact] public void TaskInvocation_defaults_attempt_and_optional_fields() { var fields = new Dictionary { ["type"] = "task.run", ["run_id"] = "r", ["task_id"] = "t", ["task_key"] = "k", ["language"] = "shell", ["entry_file"] = "a.sh", ["tenant_id"] = "t1", }; var inv = TaskInvocation.FromFields(fields); Assert.Equal(1, inv.Attempt); Assert.Null(inv.EntryFunction); Assert.Null(inv.Input); Assert.Empty(inv.Env); } [Fact] public void TaskInvocation_rejects_missing_required_field() { var fields = new Dictionary { ["type"] = "task.run" }; Assert.Throws(() => TaskInvocation.FromFields(fields)); } [Fact] public void TaskResultMessage_round_trips_result_fields() { var inv = Invocation.For("shell", "a.sh", input: "{\"x\":1}"); var result = new ExecutionResult( true, 0, "out", "err", "{\"ok\":true}", null, TimeSpan.FromMilliseconds(123)); var fields = TaskResultMessage.ToFields(inv, result); Assert.Equal("task.result", fields["type"]); Assert.Equal("run-1", fields["run_id"]); Assert.Equal("succeeded", fields["status"]); Assert.Equal("0", fields["exit_code"]); Assert.Equal("{\"ok\":true}", fields["output"]); Assert.False(fields.ContainsKey("error")); } [Fact] public void TaskResultMessage_includes_error_on_failure() { var inv = Invocation.For("shell", "a.sh"); var result = new ExecutionResult( false, 3, string.Empty, "boom", null, "boom", TimeSpan.FromMilliseconds(10)); var fields = TaskResultMessage.ToFields(inv, result); Assert.Equal("failed", fields["status"]); Assert.Equal("3", fields["exit_code"]); Assert.Equal("boom", fields["error"]); Assert.False(fields.ContainsKey("output")); } }