diff --git a/dotnet/src/Experimental/Process.UnitTests/Runtime.Local/LocalMapTests.cs b/dotnet/src/Experimental/Process.UnitTests/Runtime.Local/LocalMapTests.cs index eb454c1e1858..8c238c985f91 100644 --- a/dotnet/src/Experimental/Process.UnitTests/Runtime.Local/LocalMapTests.cs +++ b/dotnet/src/Experimental/Process.UnitTests/Runtime.Local/LocalMapTests.cs @@ -261,8 +261,7 @@ public async Task ProcessMapResultWithTargetInvalidAsync() .SendEventTo(new ProcessFunctionTargetBuilder(mapStep)); // CountStep is not part of the map operation, rather it has been defined on the "outer" process. - CommonSteps.CountStep.Index = 0; // Reset static state (test hack) - ProcessStepBuilder countStep = process.AddStepFromType(); + ProcessStepBuilder countStep = process.AddStepFromType(name: nameof(ProcessMapResultWithTargetInvalidAsync)); mapStep.MapOperation .OnEvent(ComputeStep.SquareEventId) .SendEventTo(new ProcessFunctionTargetBuilder(countStep)); @@ -287,7 +286,6 @@ public async Task ProcessMapResultWithTargetInvalidAsync() public async Task ProcessMapResultWithTargetExtraAsync() { // Arrange - CommonSteps.CountStep.Index = 0; ProcessBuilder process = new(nameof(ProcessMapResultProcessOperationAsync)); ProcessBuilder mapProcess = new("MapOperation"); @@ -296,7 +294,8 @@ public async Task ProcessMapResultWithTargetExtraAsync() .OnInputEvent("Anything") .SendEventTo(new ProcessFunctionTargetBuilder(computeStep)); - ProcessStepBuilder countStep = mapProcess.AddStepFromType(); + const string CounterName = nameof(ProcessMapResultWithTargetExtraAsync); + ProcessStepBuilder countStep = mapProcess.AddStepFromType(name: CounterName); computeStep .OnEvent(ComputeStep.SquareEventId) .SendEventTo(new ProcessFunctionTargetBuilder(countStep)); @@ -320,7 +319,7 @@ public async Task ProcessMapResultWithTargetExtraAsync() // Assert UnionState unionState = await GetUnionStateAsync(processContext); Assert.Equal(55L, unionState.SquareResult); - Assert.Equal(5, CommonSteps.CountStep.Index); + Assert.Equal(5, CommonSteps.CountStep.GetCount(CounterName)); } /// diff --git a/dotnet/src/Experimental/Process.UnitTests/Runtime.Local/LocalProxyTests.cs b/dotnet/src/Experimental/Process.UnitTests/Runtime.Local/LocalProxyTests.cs index ab732fcaec1a..5f1bad04fcdd 100644 --- a/dotnet/src/Experimental/Process.UnitTests/Runtime.Local/LocalProxyTests.cs +++ b/dotnet/src/Experimental/Process.UnitTests/Runtime.Local/LocalProxyTests.cs @@ -27,7 +27,7 @@ public async Task ProcessWithProxyWithSingleTopicCalledTwiceAsync() var mockProxyClient = new MockCloudEventClient(); ProcessBuilder process = new(nameof(ProcessWithProxyWithSingleTopicCalledTwiceAsync)); - var counterStep = process.AddStepFromType(); + var counterStep = process.AddStepFromType(name: nameof(ProcessWithProxyWithSingleTopicCalledTwiceAsync)); var proxyStep = process.AddProxyStep([this._topic1, this._topic2]); process.OnInputEvent(this._startProcessEvent).SendEventTo(new(counterStep)); @@ -75,7 +75,7 @@ public void ProcessWithProxyFailsToCreateDueMissingTopicRegistration() var mockProxyClient = new MockCloudEventClient(); ProcessBuilder process = new(nameof(ProcessWithProxyFailsToCreateDueMissingTopicRegistration)); - var counterStep = process.AddStepFromType(); + var counterStep = process.AddStepFromType(name: nameof(ProcessWithProxyFailsToCreateDueMissingTopicRegistration)); var proxyStep = process.AddProxyStep([this._topic1]); process.OnInputEvent(this._startProcessEvent).SendEventTo(new(counterStep)); @@ -92,9 +92,8 @@ public void ProcessWithProxyFailsToCreateDueMissingTopicRegistration() public async Task ProcessWithCyclesAndProxyWithTwoTopicsAsync() { // Arrange - CommonSteps.CountStep.Index = 0; var mockProxyClient = new MockCloudEventClient(); - ProcessBuilder process = this.GetSampleProcessWithProxyEmittingTwoTopics(nameof(ProcessWithCyclesAndProxyWithTwoTopicsAsync)); + ProcessBuilder process = this.GetSampleProcessWithProxyEmittingTwoTopics(nameof(ProcessWithCyclesAndProxyWithTwoTopicsAsync), counterName: nameof(ProcessWithCyclesAndProxyWithTwoTopicsAsync)); KernelProcess processInstance = process.Build(); Kernel kernel = new(); @@ -129,10 +128,10 @@ public async Task ProcessWithCyclesAndProxyWithTwoTopicsAsync() public async Task ProcessWithProxyIn2LevelsNestedProcessEmitsTwoTopicsAsync() { // Arrange - CommonSteps.CountStep.Index = 0; var mockProxyClient = new MockCloudEventClient(); ProcessBuilder process = new(nameof(ProcessWithProxyIn2LevelsNestedProcessEmitsTwoTopicsAsync)); - var innerProcess = process.AddStepFromProcess(this.GetSampleProcessWithProxyEmittingTwoTopics($"Inner-{nameof(ProcessWithProxyIn2LevelsNestedProcessEmitsTwoTopicsAsync)}")); + var innerProcess = process.AddStepFromProcess(this.GetSampleProcessWithProxyEmittingTwoTopics( + $"Inner-{nameof(ProcessWithProxyIn2LevelsNestedProcessEmitsTwoTopicsAsync)}", counterName: nameof(ProcessWithProxyIn2LevelsNestedProcessEmitsTwoTopicsAsync))); process .OnInputEvent(this._startProcessEvent) @@ -172,14 +171,16 @@ public async Task ProcessWithProxyIn2LevelsNestedProcessEmitsTwoTopicsAsync() public async Task ProcessWithProxyIn4LevelsNestedProcessEmitsTwoTopicsAsync() { // Arrange - CommonSteps.CountStep.Index = 0; var mockProxyClient = new MockCloudEventClient(); ProcessBuilder process = new(nameof(ProcessWithProxyIn4LevelsNestedProcessEmitsTwoTopicsAsync)); var innerProcess = process.AddStepFromProcess( this.GetNestedProcess( processName: $"Inner1-{nameof(ProcessWithProxyIn4LevelsNestedProcessEmitsTwoTopicsAsync)}", - internalProcess: this.GetSampleProcessWithProxyEmittingTwoTopics($"Inner2-{nameof(ProcessWithProxyIn4LevelsNestedProcessEmitsTwoTopicsAsync)}"), - inputEventName: this._startProcessEvent)); + internalProcess: this.GetSampleProcessWithProxyEmittingTwoTopics( + $"Inner2-{nameof(ProcessWithProxyIn4LevelsNestedProcessEmitsTwoTopicsAsync)}", + $"Inner2_{nameof(ProcessWithProxyIn4LevelsNestedProcessEmitsTwoTopicsAsync)}"), + inputEventName: this._startProcessEvent, + counterName: $"Inner1_{nameof(ProcessWithProxyIn4LevelsNestedProcessEmitsTwoTopicsAsync)}")); process .OnInputEvent(this._startProcessEvent) @@ -211,10 +212,10 @@ public async Task ProcessWithProxyIn4LevelsNestedProcessEmitsTwoTopicsAsync() Assert.Equal(1, mockProxyClient.UninitializationCounter); } - private ProcessBuilder GetNestedProcess(string processName, ProcessBuilder internalProcess, string inputEventName) + private ProcessBuilder GetNestedProcess(string processName, ProcessBuilder internalProcess, string inputEventName, string counterName) { ProcessBuilder process = new(processName); - var innerProcess = process.AddStepFromProcess(this.GetSampleProcessWithProxyEmittingTwoTopics($"Inner-{processName}")); + var innerProcess = process.AddStepFromProcess(this.GetSampleProcessWithProxyEmittingTwoTopics($"Inner-{processName}", counterName)); process .OnInputEvent(inputEventName) @@ -223,11 +224,11 @@ private ProcessBuilder GetNestedProcess(string processName, ProcessBuilder inter return process; } - private ProcessBuilder GetSampleProcessWithProxyEmittingTwoTopics(string processName) + private ProcessBuilder GetSampleProcessWithProxyEmittingTwoTopics(string processName, string counterName) { ProcessBuilder process = new(processName); - var counterStep = process.AddStepFromType(); + var counterStep = process.AddStepFromType(name: counterName); var evenNumberStep = process.AddStepFromType(); var proxyStep = process.AddProxyStep([this._topic1, this._topic2]); diff --git a/dotnet/src/InternalUtilities/process/TestsShared/Steps/CommonSteps.cs b/dotnet/src/InternalUtilities/process/TestsShared/Steps/CommonSteps.cs index e462eca069cf..95311014c992 100644 --- a/dotnet/src/InternalUtilities/process/TestsShared/Steps/CommonSteps.cs +++ b/dotnet/src/InternalUtilities/process/TestsShared/Steps/CommonSteps.cs @@ -1,6 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. using System; -using System.Threading; +using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.SemanticKernel; @@ -20,15 +20,39 @@ public sealed class CountStep : KernelProcessStep { public const string CountFunction = nameof(Count); -#pragma warning disable CA2211 - // workaround for unit testing evaluation purposes - public static int Index = 0; -#pragma warning restore CA2211 + private string _name = null!; + private static readonly Dictionary s_counters = new(); + + public override ValueTask ActivateAsync(KernelProcessStepState state) + { + this._name = state.Name; + return default; + } + [KernelFunction] public string Count() { - Interlocked.Increment(ref Index); - return Index.ToString(); + lock (s_counters) + { + if (s_counters.TryGetValue(this._name, out var counter)) + { + s_counters[this._name] = counter + 1; + } + else + { + s_counters[this._name] = 1; + } + + return s_counters[this._name].ToString(); + } + } + + public static long GetCount(string name) + { + lock (s_counters) + { + return s_counters[name]; + } } }