From 1a376cfcde0bc89b59d9c5049a5e99bd973048a4 Mon Sep 17 00:00:00 2001 From: Siri Varma Vegiraju Date: Thu, 10 Oct 2024 10:32:03 -0700 Subject: [PATCH 1/2] Make context mockable Signed-off-by: Siri Varma Vegiraju --- all.sln | 7 +++ .../DaprWorkflowActivityContext.cs | 37 ++++++++++++++ src/Dapr.Workflow/WorkflowActivityContext.cs | 14 ++--- src/Dapr.Workflow/WorkflowRuntimeOptions.cs | 4 +- .../Dapr.Workflow.Test.csproj | 25 +++++++++ .../WorkflowActivityTest.cs | 51 +++++++++++++++++++ 6 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 src/Dapr.Workflow/DaprWorkflowActivityContext.cs create mode 100644 test/Dapr.Workflow.Test/Dapr.Workflow.Test.csproj create mode 100644 test/Dapr.Workflow.Test/WorkflowActivityTest.cs diff --git a/all.sln b/all.sln index 228047852..34248e70d 100644 --- a/all.sln +++ b/all.sln @@ -118,6 +118,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test.Actors.Genera EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cryptography", "examples\Client\Cryptography\Cryptography.csproj", "{C74FBA78-13E8-407F-A173-4555AEE41FF3}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Workflow.Test", "test\Dapr.Workflows.Test\Dapr.Workflow.Test.csproj", "{7CA93D67-C551-430E-AA2C-BC64B77F7908}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -290,6 +292,10 @@ Global {C74FBA78-13E8-407F-A173-4555AEE41FF3}.Debug|Any CPU.Build.0 = Debug|Any CPU {C74FBA78-13E8-407F-A173-4555AEE41FF3}.Release|Any CPU.ActiveCfg = Release|Any CPU {C74FBA78-13E8-407F-A173-4555AEE41FF3}.Release|Any CPU.Build.0 = Release|Any CPU + {7CA93D67-C551-430E-AA2C-BC64B77F7908}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7CA93D67-C551-430E-AA2C-BC64B77F7908}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7CA93D67-C551-430E-AA2C-BC64B77F7908}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7CA93D67-C551-430E-AA2C-BC64B77F7908}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -343,6 +349,7 @@ Global {AF89083D-4715-42E6-93E9-38497D12A8A6} = {DD020B34-460F-455F-8D17-CF4A949F100B} {B5CDB0DC-B26D-48F1-B934-FE5C1C991940} = {DD020B34-460F-455F-8D17-CF4A949F100B} {C74FBA78-13E8-407F-A173-4555AEE41FF3} = {A7F41094-8648-446B-AECD-DCC2CC871F73} + {7CA93D67-C551-430E-AA2C-BC64B77F7908} = {DD020B34-460F-455F-8D17-CF4A949F100B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {65220BF2-EAE1-4CB2-AA58-EBE80768CB40} diff --git a/src/Dapr.Workflow/DaprWorkflowActivityContext.cs b/src/Dapr.Workflow/DaprWorkflowActivityContext.cs new file mode 100644 index 000000000..cf902dea4 --- /dev/null +++ b/src/Dapr.Workflow/DaprWorkflowActivityContext.cs @@ -0,0 +1,37 @@ +// ------------------------------------------------------------------------ +// Copyright 2022 The Dapr Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +namespace Dapr.Workflow +{ + using System; + using Microsoft.DurableTask; + + /// + /// Defines properties and methods for task activity context objects. + /// + public class DaprWorkflowActivityContext : WorkflowActivityContext + { + readonly TaskActivityContext innerContext; + + internal DaprWorkflowActivityContext(TaskActivityContext innerContext) + { + this.innerContext = innerContext ?? throw new ArgumentNullException(nameof(innerContext)); + } + + /// + public override TaskName Name => this.innerContext.Name; + + /// + public override string InstanceId => this.innerContext.InstanceId; + } +} diff --git a/src/Dapr.Workflow/WorkflowActivityContext.cs b/src/Dapr.Workflow/WorkflowActivityContext.cs index eec32f008..a77c3ef91 100644 --- a/src/Dapr.Workflow/WorkflowActivityContext.cs +++ b/src/Dapr.Workflow/WorkflowActivityContext.cs @@ -13,29 +13,21 @@ namespace Dapr.Workflow { - using System; using Microsoft.DurableTask; /// /// Defines properties and methods for task activity context objects. /// - public class WorkflowActivityContext + public abstract class WorkflowActivityContext { - readonly TaskActivityContext innerContext; - - internal WorkflowActivityContext(TaskActivityContext innerContext) - { - this.innerContext = innerContext ?? throw new ArgumentNullException(nameof(innerContext)); - } - /// /// Gets the name of the activity. /// - public TaskName Name => this.innerContext.Name; + public abstract TaskName Name { get; } /// /// Gets the unique ID of the current workflow instance. /// - public string InstanceId => this.innerContext.InstanceId; + public abstract string InstanceId { get; } } } diff --git a/src/Dapr.Workflow/WorkflowRuntimeOptions.cs b/src/Dapr.Workflow/WorkflowRuntimeOptions.cs index adc925777..e2fbf913a 100644 --- a/src/Dapr.Workflow/WorkflowRuntimeOptions.cs +++ b/src/Dapr.Workflow/WorkflowRuntimeOptions.cs @@ -90,7 +90,7 @@ public void RegisterActivity(string name, Func(name, (innerContext, input) => { - WorkflowActivityContext activityContext = new(innerContext); + WorkflowActivityContext activityContext = new DaprWorkflowActivityContext(innerContext); return implementation(activityContext, input); }); WorkflowLoggingService.LogActivityName(name); @@ -167,7 +167,7 @@ public ActivityWrapper(IWorkflowActivity activity) public Task RunAsync(TaskActivityContext context, object? input) { - return this.activity.RunAsync(new WorkflowActivityContext(context), input); + return this.activity.RunAsync(new DaprWorkflowActivityContext(context), input); } } } diff --git a/test/Dapr.Workflow.Test/Dapr.Workflow.Test.csproj b/test/Dapr.Workflow.Test/Dapr.Workflow.Test.csproj new file mode 100644 index 000000000..15e626772 --- /dev/null +++ b/test/Dapr.Workflow.Test/Dapr.Workflow.Test.csproj @@ -0,0 +1,25 @@ + + + Dapr.Workflow.Tests + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + diff --git a/test/Dapr.Workflow.Test/WorkflowActivityTest.cs b/test/Dapr.Workflow.Test/WorkflowActivityTest.cs new file mode 100644 index 000000000..9fd96e60b --- /dev/null +++ b/test/Dapr.Workflow.Test/WorkflowActivityTest.cs @@ -0,0 +1,51 @@ +// ------------------------------------------------------------------------ +// Copyright 2021 The Dapr Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ------------------------------------------------------------------------ + +namespace Dapr.Workflow.Test +{ + using Moq; + using System.Threading.Tasks; + using Xunit; + + /// + /// Contains tests for WorkflowActivityContext. + /// + public class WorkflowActivityTest + { + private IWorkflowActivity workflowActivity; + + private Mock workflowActivityContextMock; + + [Fact] + public async Task RunAsync_ShouldReturnCorrectContextInstanceId() + { + this.workflowActivity = new TestDaprWorkflowActivity(); + this.workflowActivityContextMock = new Mock(); + + this.workflowActivityContextMock.Setup((x) => x.InstanceId).Returns("instanceId"); + + string result = (string) await this.workflowActivity.RunAsync(this.workflowActivityContextMock.Object, "input"); + + Assert.Equal("instanceId", result); + } + + + public class TestDaprWorkflowActivity : WorkflowActivity + { + public override Task RunAsync(WorkflowActivityContext context, string input) + { + return Task.FromResult(context.InstanceId); + } + } + } +} From f51def0bd7e35349aeb84f1155eb86fba35f9e23 Mon Sep 17 00:00:00 2001 From: Siri Varma Vegiraju Date: Thu, 10 Oct 2024 10:38:13 -0700 Subject: [PATCH 2/2] Fix project Signed-off-by: Siri Varma Vegiraju --- all.sln | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/all.sln b/all.sln index 34248e70d..0425b00f2 100644 --- a/all.sln +++ b/all.sln @@ -118,7 +118,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.E2E.Test.Actors.Genera EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cryptography", "examples\Client\Cryptography\Cryptography.csproj", "{C74FBA78-13E8-407F-A173-4555AEE41FF3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Workflow.Test", "test\Dapr.Workflows.Test\Dapr.Workflow.Test.csproj", "{7CA93D67-C551-430E-AA2C-BC64B77F7908}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dapr.Workflow.Test", "test\Dapr.Workflow.Test\Dapr.Workflow.Test.csproj", "{7CA93D67-C551-430E-AA2C-BC64B77F7908}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution