Skip to content

Commit 3506106

Browse files
tests working
1 parent 7bfd50f commit 3506106

14 files changed

+232
-69
lines changed

src/UiPath.Ipc.Tests/ComputingTests.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,71 @@ protected override ClientBase ConfigTransportAgnostic(ClientBase client)
4040
}
4141
};
4242
#endregion
43+
44+
[Theory, IpcAutoData]
45+
public async Task Calls_ShouldWork(float x, float y)
46+
=> await Proxy.AddFloats(x, y).ShouldBeAsync(x + y);
47+
48+
[Theory, IpcAutoData]
49+
public Task ConcurrentCalls_ShouldWork(float sameX, float sameY) => Task.WhenAll(Enumerable.Range(1, 100).Select(_ => Calls_ShouldWork(sameX, sameY)));
50+
51+
[Theory, IpcAutoData]
52+
public async Task CallsWithStructParamsAndReturns_ShouldWork(ComplexNumber a, ComplexNumber b)
53+
=> await Proxy.AddComplexNumbers(a, b).ShouldBeAsync(a + b);
54+
55+
[Fact]
56+
public async Task ClientCancellations_ShouldWork()
57+
{
58+
using var cts = new CancellationTokenSource();
59+
60+
var taskWaiting = Proxy.Wait(Timeout.InfiniteTimeSpan, cts.Token);
61+
62+
await Task.Delay(Constants.Timeout_Short);
63+
64+
taskWaiting.IsCompleted.ShouldBeFalse();
65+
66+
cts.Cancel();
67+
68+
await taskWaiting.ShouldCompleteInAsync(Constants.Timeout_Short).ShouldThrowAsync<OperationCanceledException>(); // in-process scheduling fast
69+
70+
await Proxy.Wait(TimeSpan.Zero).ShouldCompleteInAsync(Constants.Timeout_IpcRoundtrip).ShouldBeAsync(true); // connection still alive
71+
}
72+
73+
[Fact, OverrideConfig(typeof(ShortClientTimeout))]
74+
public async Task ClientTimeouts_ShouldWork()
75+
{
76+
await Proxy.Wait(Timeout.InfiniteTimeSpan).ShouldThrowAsync<TimeoutException>();
77+
78+
await Proxy.GetCallbackThreadName(
79+
duration: TimeSpan.FromMilliseconds(500),
80+
message: new()
81+
{
82+
RequestTimeout = TimeSpan.FromSeconds(2)
83+
})
84+
.ShouldBeAsync(Names.GuiThreadName)
85+
.ShouldNotThrowAsync();
86+
}
87+
88+
private sealed class ShortClientTimeout : OverrideConfig
89+
{
90+
public override ClientBase Override(ClientBase client)
91+
=> client with { RequestTimeout = TimeSpan.FromMilliseconds(10) };
92+
}
93+
94+
[Theory, IpcAutoData]
95+
public async Task CallsWithArraysOfStructsAsParams_ShouldWork(ComplexNumber a, ComplexNumber b, ComplexNumber c)
96+
=> await Proxy.AddComplexNumberList([a, b, c]).ShouldBeAsync(a + b + c);
97+
98+
[Fact]
99+
public async Task Callbacks_ShouldWork()
100+
=> await Proxy.GetCallbackThreadName(duration: TimeSpan.Zero).ShouldBeAsync(Names.GuiThreadName);
101+
102+
[Fact]
103+
public async Task CallbacksWithParams_ShouldWork()
104+
=> await Proxy.MultiplyInts(7, 1).ShouldBeAsync(7);
105+
106+
[Fact]
107+
public async Task ConcurrentCallbacksWithParams_ShouldWork()
108+
=> await Task.WhenAll(
109+
Enumerable.Range(1, 50).Select(_ => CallbacksWithParams_ShouldWork()));
43110
}

src/UiPath.Ipc.Tests/Helpers/Constants.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ internal static class Constants
1212
/// Considering a service method which returns instantly, and the time it takes for UiPath.Ipc to complete a full roundtrip from calling to receiving the result,
1313
/// this value represents an exagerated timeout beyond which it's clear that a bug has occurred, even when running on a CI agent under load.
1414
/// </summary>
15-
public static readonly TimeSpan Timeout_IpcRoundtrip = TimeSpan.FromMilliseconds(600);
15+
public static readonly TimeSpan Timeout_IpcRoundtrip = TimeSpan.FromMilliseconds(800);
1616

17-
public static readonly TimeSpan Timeout_Short = TimeSpan.FromMilliseconds(100);
17+
public static readonly TimeSpan Timeout_Short = TimeSpan.FromMilliseconds(300);
1818
}

src/UiPath.Ipc.Tests/Helpers/IpcAutoDataAttribute.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public IpcAutoDataAttribute() : base(CreateFixture)
1212
private static Fixture CreateFixture()
1313
{
1414
var fixture = new Fixture();
15+
new SupportMutableValueTypesCustomization().Customize(fixture);
1516
return fixture;
1617
}
1718
}

src/UiPath.Ipc.Tests/Helpers/IpcHelpers.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ public static ServiceProvider ConfigureServices(ITestOutputHelper outputHelper)
1818

1919
.AddSingleton<ComputingService>()
2020
.AddSingletonAlias<IComputingService, ComputingService>()
21-
.AddSingletonAlias<IComputingServiceBase, ComputingService>()
2221

2322
.BuildServiceProvider();
2423

src/UiPath.Ipc.Tests/Helpers/ShouldlyHelpers.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@ public static async Task ShouldBeAsync<T>(this Task<T> task, T expected, [Caller
1818
}
1919
}
2020

21+
public static async Task<T> ShouldNotBeNullAsync<T>(this Task<T> task, [CallerArgumentExpression(nameof(task))] string? taskExpression = null)
22+
where T : class
23+
{
24+
var actual = await task;
25+
try
26+
{
27+
return actual.ShouldNotBeNull();
28+
}
29+
catch
30+
{
31+
throw new ShouldAssertException($"The provided expression `{taskExpression}`\r\n\tshouldn't have yielded null but did.");
32+
}
33+
}
34+
35+
2136
public static async Task<T> ShouldNotThrowAsyncAnd<T>(this Task<T> task, [CallerArgumentExpression(nameof(task))] string? taskExpression = null)
2237
{
2338
try
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace UiPath.Ipc.Tests;
2+
3+
public sealed class ArithmeticCallback : IArithmeticCallback
4+
{
5+
public async Task<int> Increment(int x) => x + 1;
6+
}
7+

src/UiPath.Ipc.Tests/Services/Computing.cs

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/UiPath.Ipc.Tests/Services/ComputingCallback.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,9 @@
33
public sealed class ComputingCallback : IComputingCallback
44
{
55
public Guid Id { get; } = Guid.NewGuid();
6-
}
6+
7+
public async Task<string> GetThreadName() => Thread.CurrentThread.Name!;
8+
9+
public async Task<int> AddInts(int x, int y) => x + y;
10+
}
11+
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+

2+
using Microsoft.Extensions.Logging;
3+
4+
namespace UiPath.Ipc.Tests;
5+
6+
public sealed class ComputingService(ILogger<ComputingService> logger) : IComputingService
7+
{
8+
public async Task<float> AddFloats(float a, float b, CancellationToken ct = default)
9+
{
10+
logger.LogInformation($"{nameof(AddFloats)} called.");
11+
return a + b;
12+
}
13+
14+
public async Task<ComplexNumber> AddComplexNumbers(ComplexNumber a, ComplexNumber b)
15+
{
16+
logger.LogInformation($"{nameof(AddComplexNumbers)} called.");
17+
return a + b;
18+
}
19+
20+
public async Task<bool> Wait(TimeSpan duration, CancellationToken ct = default)
21+
{
22+
await Task.Delay(duration, ct);
23+
return true;
24+
}
25+
26+
public async Task<string> GetCallbackThreadName(TimeSpan duration, Message message = null!, CancellationToken cancellationToken = default)
27+
{
28+
await Task.Delay(duration);
29+
return await message.GetCallback<IComputingCallback>().GetThreadName();
30+
}
31+
32+
public async Task<ComplexNumber> AddComplexNumberList(IReadOnlyList<ComplexNumber> numbers)
33+
{
34+
var result = ComplexNumber.Zero;
35+
foreach (var number in numbers)
36+
{
37+
result += number;
38+
}
39+
return result;
40+
}
41+
42+
public async Task<int> MultiplyInts(int x, int y, Message message = null!)
43+
{
44+
var callback = message.GetCallback<IComputingCallback>();
45+
46+
var result = 0;
47+
for (int i = 0; i < y; i++)
48+
{
49+
result = await callback.AddInts(result, x);
50+
}
51+
52+
return result;
53+
}
54+
}
Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,39 @@
1-
namespace UiPath.Ipc.Tests;
1+

2+
namespace UiPath.Ipc.Tests;
23

3-
public interface IComputingServiceBase
4+
public interface IComputingService
45
{
6+
Task<float> AddFloats(float x, float y, CancellationToken ct = default);
7+
Task<ComplexNumber> AddComplexNumbers(ComplexNumber a, ComplexNumber b);
8+
Task<bool> Wait(TimeSpan duration, CancellationToken ct = default);
9+
Task<string> GetCallbackThreadName(TimeSpan duration, Message message = null!, CancellationToken cancellationToken = default);
10+
Task<ComplexNumber> AddComplexNumberList(IReadOnlyList<ComplexNumber> numbers);
11+
Task<int> MultiplyInts(int x, int y, Message message = null!);
512
}
613

7-
public interface IComputingService : IComputingServiceBase
14+
public interface IComputingCallback
815
{
16+
Task<string> GetThreadName();
17+
Task<int> AddInts(int x, int y);
918
}
1019

11-
public interface IComputingCallback
20+
public interface IArithmeticCallback
1221
{
22+
Task<int> Increment(int x);
1323
}
24+
25+
public readonly record struct ComplexNumber
26+
{
27+
public static readonly ComplexNumber Zero = default;
28+
public static ComplexNumber operator +(ComplexNumber a, ComplexNumber b)
29+
=> new()
30+
{
31+
I = a.I + b.I,
32+
J = a.J + b.J
33+
};
34+
35+
public required float I { get; init; }
36+
public required float J { get; init; }
37+
38+
public override string ToString() => $"[{I}, {J}]";
39+
}

0 commit comments

Comments
 (0)