diff --git a/src/CI/azp-start.yaml b/src/CI/azp-start.yaml index d659af93..e4ee9980 100644 --- a/src/CI/azp-start.yaml +++ b/src/CI/azp-start.yaml @@ -45,7 +45,7 @@ stages: - job: displayName: 'node.js on Ubuntu' pool: - vmImage: 'ubuntu-20.04' + vmImage: 'ubuntu-22.04' steps: - template: azp-initialization.yaml - template: azp-nodejs.yaml diff --git a/src/UiPath.CoreIpc.Tests/ComputingTests.cs b/src/UiPath.CoreIpc.Tests/ComputingTests.cs index 6c562dd9..1559193f 100644 --- a/src/UiPath.CoreIpc.Tests/ComputingTests.cs +++ b/src/UiPath.CoreIpc.Tests/ComputingTests.cs @@ -16,6 +16,7 @@ public ComputingTests() _computingHost.RunAsync(GuiScheduler); _computingClient = ComputingClientBuilder(GuiScheduler).SerializeParametersAsObjects().ValidateAndBuild(); } + protected abstract TBuilder ComputingClientBuilder(TaskScheduler taskScheduler = null); [Fact] public async Task ReconnectWithEncrypt() diff --git a/src/UiPath.CoreIpc.Tests/NamedPipeTests.cs b/src/UiPath.CoreIpc.Tests/NamedPipeTests.cs index e81f1eaa..38e2c5ec 100644 --- a/src/UiPath.CoreIpc.Tests/NamedPipeTests.cs +++ b/src/UiPath.CoreIpc.Tests/NamedPipeTests.cs @@ -23,6 +23,10 @@ public override void BeforeCallServerSide() _pipeName = "beforeCall"; base.BeforeCallServerSide(); } + + public override void Initialize() + { + } #if WINDOWS [Fact] public async Task PipeSecurityForWindows() @@ -50,4 +54,8 @@ protected override NamedPipeClientBuilder .RequestTimeout(RequestTimeout) .CallbackInstance(_computingCallback) .TaskScheduler(taskScheduler); + + public override void Initialize() + { + } } \ No newline at end of file diff --git a/src/UiPath.CoreIpc.Tests/TcpTests..cs b/src/UiPath.CoreIpc.Tests/TcpTests..cs index cca919c5..88efdaf2 100644 --- a/src/UiPath.CoreIpc.Tests/TcpTests..cs +++ b/src/UiPath.CoreIpc.Tests/TcpTests..cs @@ -14,10 +14,20 @@ public override async void BeforeCallServerSide() base.BeforeCallServerSide(); } IPEndPoint GetEndPoint() => new(IPAddress.Loopback, _port); + + public override void Initialize() + { + _port = GetAvailablePort(); + } } public class ComputingTcpTests : ComputingTests> { - protected static readonly IPEndPoint ComputingEndPoint = new(IPAddress.Loopback, 2121+GetCount()); + public override void Initialize() + { + ComputingEndPoint = new(IPAddress.Loopback, GetAvailablePort()); + } + + protected IPEndPoint ComputingEndPoint; protected override TcpClientBuilder ComputingClientBuilder(TaskScheduler taskScheduler = null) => new TcpClientBuilder(ComputingEndPoint, _serviceProvider) .RequestTimeout(RequestTimeout) diff --git a/src/UiPath.CoreIpc.Tests/TestBase.cs b/src/UiPath.CoreIpc.Tests/TestBase.cs index 98d75a4e..656268fa 100644 --- a/src/UiPath.CoreIpc.Tests/TestBase.cs +++ b/src/UiPath.CoreIpc.Tests/TestBase.cs @@ -20,10 +20,25 @@ public abstract class TestBase : IDisposable //} public TestBase() { + Initialize(); + _guiThread.SynchronizationContext.Send(() => Thread.CurrentThread.Name = "GuiThread"); _serviceProvider = IpcHelpers.ConfigureServices(); } + public int GetAvailablePort() + { + var endPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Loopback, 0); + var listener = new System.Net.Sockets.TcpListener(endPoint); + listener.Start(); + int port = ((System.Net.IPEndPoint)listener.LocalEndpoint).Port; + listener.Stop(); + + return port; + } + + public abstract void Initialize(); + protected static int GetCount() => Interlocked.Increment(ref Count); protected TaskScheduler GuiScheduler => _guiThread.Scheduler; diff --git a/src/UiPath.CoreIpc.Tests/WebSocketTests.cs b/src/UiPath.CoreIpc.Tests/WebSocketTests.cs index 0661160c..0f7ca92f 100644 --- a/src/UiPath.CoreIpc.Tests/WebSocketTests.cs +++ b/src/UiPath.CoreIpc.Tests/WebSocketTests.cs @@ -18,7 +18,7 @@ public override void Dispose() [Fact] public override async void BeforeCallServerSide() { - _port++; + _port = GetAvailablePort(); base.BeforeCallServerSide(); } #if !NET461 @@ -26,16 +26,25 @@ public override async void BeforeCallServerSide() public override Task UploadNoRead() => base.UploadNoRead(); #endif string GetEndPoint() => $"://localhost:{_port}/"; + public override void Initialize() + { + _port = GetAvailablePort(); + } } public class ComputingWebSocketsTests : ComputingTests> { - protected static readonly string ComputingEndPoint = $"://localhost:{1212+GetCount()}/"; + protected string ComputingEndPoint; HttpSysWebSocketsListener _listener; protected override WebSocketClientBuilder ComputingClientBuilder(TaskScheduler taskScheduler = null) => new WebSocketClientBuilder(new("ws"+ComputingEndPoint), _serviceProvider) .RequestTimeout(RequestTimeout) .CallbackInstance(_computingCallback) .TaskScheduler(taskScheduler); + + public override void Initialize() + { + ComputingEndPoint = $"://localhost:{GetAvailablePort()}/"; + } protected override ServiceHostBuilder Configure(ServiceHostBuilder serviceHostBuilder) { _listener = new HttpSysWebSocketsListener("http" + ComputingEndPoint); diff --git a/src/UiPath.CoreIpc/Connection.cs b/src/UiPath.CoreIpc/Connection.cs index e4404147..394bc0e3 100644 --- a/src/UiPath.CoreIpc/Connection.cs +++ b/src/UiPath.CoreIpc/Connection.cs @@ -46,6 +46,7 @@ public Connection(Stream network, ISerializer serializer, ILogger logger, string internal async ValueTask RemoteCall(Request request, CancellationToken token) { var requestCompletion = Rent(); + requestCompletion.MethodName = request.MethodName; var requestId = request.Id; _requests[requestId] = requestCompletion; var tokenRegistration = token.UnsafeRegister(_cancelRequest, requestId); @@ -211,7 +212,7 @@ private async Task ReceiveLoop() var length = BitConverter.ToInt32(_buffer, startIndex: 1); if (length > _maxMessageSize) { - throw new InvalidDataException($"Message too large. The maximum message size is {_maxMessageSize / (1024 * 1024)} megabytes."); + throw new InvalidDataException($"Message too large. {Environment.NewLine} The maximum message size is {_maxMessageSize / (1024 * 1024)} megabytes. {Environment.NewLine} Active method calls: {string.Join(Environment.NewLine, _requests.Values.Select(r => r.MethodName))}"); } _nestedStream.Reset(length); await HandleMessage(); diff --git a/src/UiPath.CoreIpc/TaskCompletionPool.cs b/src/UiPath.CoreIpc/TaskCompletionPool.cs index 11f9ece9..b09c6a81 100644 --- a/src/UiPath.CoreIpc/TaskCompletionPool.cs +++ b/src/UiPath.CoreIpc/TaskCompletionPool.cs @@ -7,6 +7,7 @@ internal static class TaskCompletionPool public sealed class ManualResetValueTaskSource : IValueTaskSource, IValueTaskSource { private ManualResetValueTaskSourceCore _core; // mutable struct; do not make this readonly + public string MethodName { get; set; } public bool RunContinuationsAsynchronously { get => _core.RunContinuationsAsynchronously; set => _core.RunContinuationsAsynchronously = value; } public short Version => _core.Version; public ValueTask ValueTask() => new(this, Version);