Skip to content

Commit fb61cbc

Browse files
esttenoriorogerbarretomarkwallace-microsoft
authored
.Net: Processes UTs causing Build pipeline errors (#11008)
### Description Fixing intermittent build failure caused by Process Local Unittest that used shared Counter Step Fixes #11019 ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [x] The code builds clean without any errors or warnings - [x] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [x] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone 😄 --------- Co-authored-by: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com> Co-authored-by: Mark Wallace <127216156+markwallace-microsoft@users.noreply.github.com>
1 parent d2f8ff6 commit fb61cbc

File tree

6 files changed

+79
-36
lines changed

6 files changed

+79
-36
lines changed

dotnet/src/Experimental/Process.UnitTests/Runtime.Local/LocalMapTests.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
using System.IO;
55
using System.Linq;
66
using System.Threading.Tasks;
7+
using SemanticKernel.Process.TestsShared.Services;
8+
using SemanticKernel.Process.TestsShared.Setup;
79
using SemanticKernel.Process.TestsShared.Steps;
810
using Xunit;
911

@@ -311,15 +313,16 @@ public async Task ProcessMapResultWithTargetExtraAsync()
311313
.SendEventTo(new ProcessFunctionTargetBuilder(unionStep, UnionStep.SumSquareFunction));
312314

313315
KernelProcess processInstance = process.Build();
314-
Kernel kernel = new();
316+
CounterService counterService = new();
317+
Kernel kernel = KernelSetup.SetupKernelWithCounterService(counterService);
315318

316319
// Act
317320
await using LocalKernelProcessContext processContext = await this.RunProcessAsync(kernel, processInstance, new int[] { 1, 2, 3, 4, 5 }, "Start");
318321

319322
// Assert
320323
UnionState unionState = await GetUnionStateAsync(processContext);
321324
Assert.Equal(55L, unionState.SquareResult);
322-
Assert.Equal(5, CommonSteps.CountStep.GetCount(CounterName));
325+
Assert.Equal(5, counterService.GetCount());
323326
}
324327

325328
/// <summary>

dotnet/src/Experimental/Process.UnitTests/Runtime.Local/LocalProxyTests.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System;
33
using System.Threading.Tasks;
44
using SemanticKernel.Process.TestsShared.CloudEvents;
5+
using SemanticKernel.Process.TestsShared.Services;
6+
using SemanticKernel.Process.TestsShared.Setup;
57
using SemanticKernel.Process.TestsShared.Steps;
68
using Xunit;
79

@@ -34,7 +36,8 @@ public async Task ProcessWithProxyWithSingleTopicCalledTwiceAsync()
3436
counterStep.OnFunctionResult().EmitExternalEvent(proxyStep, this._topic1);
3537

3638
KernelProcess processInstance = process.Build();
37-
Kernel kernel = new();
39+
CounterService counterService = new();
40+
Kernel kernel = KernelSetup.SetupKernelWithCounterService(counterService);
3841

3942
// Act
4043
await using (LocalKernelProcessContext processContext = await this.RunProcessAsync(kernel, processInstance, null, this._startProcessEvent, externalMessageChannel: mockProxyClient))
@@ -95,7 +98,8 @@ public async Task ProcessWithCyclesAndProxyWithTwoTopicsAsync()
9598
var mockProxyClient = new MockCloudEventClient();
9699
ProcessBuilder process = this.GetSampleProcessWithProxyEmittingTwoTopics(nameof(ProcessWithCyclesAndProxyWithTwoTopicsAsync), counterName: nameof(ProcessWithCyclesAndProxyWithTwoTopicsAsync));
97100
KernelProcess processInstance = process.Build();
98-
Kernel kernel = new();
101+
CounterService counterService = new();
102+
Kernel kernel = KernelSetup.SetupKernelWithCounterService(counterService);
99103

100104
// Act
101105
await using (LocalKernelProcessContext processContext = await this.RunProcessAsync(kernel, processInstance, null, this._startProcessEvent, externalMessageChannel: mockProxyClient))
@@ -138,7 +142,8 @@ public async Task ProcessWithProxyIn2LevelsNestedProcessEmitsTwoTopicsAsync()
138142
.SendEventTo(innerProcess.WhereInputEventIs(this._startProcessEvent));
139143

140144
KernelProcess processInstance = process.Build();
141-
Kernel kernel = new();
145+
CounterService counterService = new();
146+
Kernel kernel = KernelSetup.SetupKernelWithCounterService(counterService);
142147

143148
// Act
144149
await using (LocalKernelProcessContext processContext = await this.RunProcessAsync(kernel, processInstance, null, this._startProcessEvent, externalMessageChannel: mockProxyClient))
@@ -187,7 +192,8 @@ public async Task ProcessWithProxyIn4LevelsNestedProcessEmitsTwoTopicsAsync()
187192
.SendEventTo(innerProcess.WhereInputEventIs(this._startProcessEvent));
188193

189194
KernelProcess processInstance = process.Build();
190-
Kernel kernel = new();
195+
CounterService counterService = new();
196+
Kernel kernel = KernelSetup.SetupKernelWithCounterService(counterService);
191197

192198
// Act
193199
await using (LocalKernelProcessContext processContext = await this.RunProcessAsync(kernel, processInstance, null, this._startProcessEvent, externalMessageChannel: mockProxyClient))
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using System.Threading;
4+
5+
namespace SemanticKernel.Process.TestsShared.Services;
6+
7+
internal sealed class CounterService : ICounterService
8+
{
9+
internal int _counter = 0;
10+
public int GetCount()
11+
{
12+
return this._counter;
13+
}
14+
15+
public int IncreaseCount()
16+
{
17+
Interlocked.Increment(ref this._counter);
18+
return this._counter;
19+
}
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
namespace SemanticKernel.Process.TestsShared.Services;
3+
4+
/// <summary>
5+
/// Interface for Counter Service used by <see cref="TestsShared.Steps.CommonSteps.CountStep"/>
6+
/// </summary>
7+
public interface ICounterService
8+
{
9+
/// <summary>
10+
/// Increase count
11+
/// </summary>
12+
/// <returns></returns>
13+
int IncreaseCount();
14+
15+
/// <summary>
16+
/// Get current count
17+
/// </summary>
18+
/// <returns></returns>
19+
int GetCount();
20+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
using Microsoft.Extensions.DependencyInjection;
3+
using Microsoft.SemanticKernel;
4+
using SemanticKernel.Process.TestsShared.Services;
5+
6+
namespace SemanticKernel.Process.TestsShared.Setup;
7+
8+
internal static class KernelSetup
9+
{
10+
public static Kernel SetupKernelWithCounterService(CounterService counterService)
11+
{
12+
IKernelBuilder builder = Kernel.CreateBuilder();
13+
14+
builder.Services.AddSingleton<ICounterService>(counterService);
15+
16+
return builder.Build();
17+
}
18+
}

dotnet/src/InternalUtilities/process/TestsShared/Steps/CommonSteps.cs

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// Copyright (c) Microsoft. All rights reserved.
22
using System;
3-
using System.Collections.Generic;
43
using System.Threading.Tasks;
54
using Microsoft.SemanticKernel;
5+
using SemanticKernel.Process.TestsShared.Services;
66

77
namespace SemanticKernel.Process.TestsShared.Steps;
88

@@ -20,39 +20,18 @@ public sealed class CountStep : KernelProcessStep
2020
{
2121
public const string CountFunction = nameof(Count);
2222

23-
private string _name = null!;
24-
private static readonly Dictionary<string, long> s_counters = new();
25-
26-
public override ValueTask ActivateAsync(KernelProcessStepState state)
23+
private readonly ICounterService _counter;
24+
public CountStep(ICounterService counterService)
2725
{
28-
this._name = state.Name;
29-
return default;
26+
this._counter = counterService;
3027
}
3128

3229
[KernelFunction]
3330
public string Count()
3431
{
35-
lock (s_counters)
36-
{
37-
if (s_counters.TryGetValue(this._name, out var counter))
38-
{
39-
s_counters[this._name] = counter + 1;
40-
}
41-
else
42-
{
43-
s_counters[this._name] = 1;
44-
}
45-
46-
return s_counters[this._name].ToString();
47-
}
48-
}
32+
int count = this._counter.IncreaseCount();
4933

50-
public static long GetCount(string name)
51-
{
52-
lock (s_counters)
53-
{
54-
return s_counters[name];
55-
}
34+
return count.ToString();
5635
}
5736
}
5837

@@ -108,7 +87,4 @@ public string Echo(string message)
10887
return message;
10988
}
11089
}
111-
112-
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
113-
11490
}

0 commit comments

Comments
 (0)