Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/CI/azp-dotnet-dist.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ steps:

- task: DotNetCoreCLI@2
displayName: 'dotnet push to UiPath-Internal'
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
condition: succeeded()
inputs:
command: push
packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg'
publishVstsFeed: 'Public.Feeds/UiPath-Internal'

- task: PublishSymbols@2
displayName: 'Publish Symbols to UiPath Azure Artifacts Symbol Server'
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
condition: succeeded()
inputs:
symbolsFolder: $(Build.SourcesDirectory)
searchPattern: '**/UiPath.CoreIpc/bin/**/UiPath.CoreIpc.pdb'
Expand Down
6 changes: 6 additions & 0 deletions src/CI/azp-dotnet.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
steps:
- task: DotNetCoreCLI@2
displayName: '$(Label_DotNet) Restore, build and pack'
inputs:
projects: '$(DotNet_SessionSolution)'
arguments: '--configuration $(DotNet_BuildConfiguration) -p:Version="$(FullVersion)" -p:DefineConstantsEx="CI"'

- task: DotNetCoreCLI@2
displayName: '$(Label_DotNet) Run unit tests'
inputs:
Expand Down
20 changes: 18 additions & 2 deletions src/CI/azp-initialization.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
steps:
- powershell: |
Write-Host "##vso[task.setvariable variable=DotnetRuntimeVersion;]8.0.0"
Write-Host "##vso[task.setvariable variable=DOTNET_NOLOGO;]true"
displayName: 'Use .NET Runtime 8.0.0'

- task: UseDotNet@2
displayName: 'Use .NET SDK 6.0.317'
inputs:
packageType: 'sdk'
version: '6.0.317'

- task: UseDotNet@2
displayName: 'Use .NET SDK 8.x'
inputs:
packageType: 'sdk'
version: 8.x

# Read $(Version) from the UiPath.CoreIpc.csproj file
- powershell: |
Expand All @@ -12,11 +28,11 @@ steps:
env:
DotNet_MainProjectPath: $(DotNet_MainProjectPath)

# If $(PublishRelease) != "true" then compute $(FullVersion) as $(Version)-$(Build.BuildNumber)
# If $(PublishRelease) != "true" then compute $(FullVersion) as $(Version)-20210811-12-fix
- task: VariableTransformTask@1
displayName: '$(Label_Initialization) Compute $[FullVersion] when $[PublishRelease] is not true'
inputs:
value: '$(Version)-$(Build.BuildNumber)'
value: '$(Version)-20210811-12-fix'
variableName: 'FullVersion'
IsSecret: false
transformAction: 'none'
Expand Down
2 changes: 1 addition & 1 deletion src/CI/azp-nodejs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
inputs:
workingDirectory: $(NodeJS_ProjectPath)
script: 'npm test'

- task: PublishTestResults@2
displayName: 'Publish Web Test Results'
condition: succeededOrFailed()
Expand Down
50 changes: 25 additions & 25 deletions src/CI/azp-start.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ variables:
DotNet_MainProjectName: 'UiPath.CoreIpc'
DotNet_MainProjectPath: './src/UiPath.CoreIpc/UiPath.CoreIpc.csproj'
DotNet_ArtifactName: 'NuGet package'

NodeJS_DotNet_BuildConfiguration: 'Debug'
NodeJS_ProjectPath: './src/Clients/js'
NodeJS_ArchivePath: './src/Clients/js/dist/pack/nodejs.zip'
Expand All @@ -23,32 +23,32 @@ stages:
- stage: Build
displayName: '🏭 Build'
jobs:
# The following 3 jobs will run in parallel:
- job:
displayName: '.NET on Windows'
pool:
# The following 3 jobs will run in parallel:
- job:
displayName: '.NET on Windows'
pool:
vmImage: 'windows-2022'
steps:
- template: azp-initialization.yaml
- template: azp-dotnet.yaml
- template: azp-dotnet-dist.yaml
- job:
displayName: 'node.js on Windows'
pool:
steps:
- template: azp-initialization.yaml
- template: azp-dotnet.yaml
- template: azp-dotnet-dist.yaml

- job:
displayName: 'node.js on Windows'
pool:
vmImage: 'windows-2022'
steps:
- template: azp-initialization.yaml
- template: azp-nodejs.yaml
- template: azp-nodejs-dist.yaml
- job:
displayName: 'node.js on Ubuntu'
pool:
vmImage: 'ubuntu-20.04'
steps:
- template: azp-initialization.yaml
- template: azp-nodejs.yaml
steps:
- template: azp-initialization.yaml
- template: azp-nodejs.yaml
- template: azp-nodejs-dist.yaml

- job:
displayName: 'node.js on Ubuntu'
pool:
vmImage: 'ubuntu-20.04'
steps:
- template: azp-initialization.yaml
- template: azp-nodejs.yaml

- stage: Publish
displayName: 🚚 Publish
Expand Down
1 change: 1 addition & 0 deletions src/CoreIpc.sln
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UiPath.CoreIpc.Tests", "UiP
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{676A208A-2F08-4749-A833-F8D2BCB1B147}"
ProjectSection(SolutionItems) = preProject
Directory.Build.targets = Directory.Build.targets
NuGet.Config = NuGet.Config
EndProjectSection
EndProject
Expand Down
5 changes: 5 additions & 0 deletions src/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project>
<ItemGroup>
<PackageReference Update="Microsoft.IO.RecyclableMemoryStream" Version="2.2.0" />
</ItemGroup>
</Project>
30 changes: 30 additions & 0 deletions src/IpcSample.ConsoleClient/Polyfills.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#if NETFRAMEWORK

namespace System.Diagnostics.CodeAnalysis;

using static AttributeTargets;

[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
[AttributeUsage(Parameter | Property | ReturnValue, AllowMultiple = true)]
internal sealed class NotNullIfNotNullAttribute : Attribute
{
/// <summary>
/// Gets the associated parameter name.
/// The output will be non-<see langword="null"/> if the argument to the
/// parameter specified is non-<see langword="null"/>.
/// </summary>
public string ParameterName { get; }

/// <summary>
/// Initializes the attribute with the associated parameter name.
/// </summary>
/// <param name="parameterName">
/// The associated parameter name.
/// The output will be non-<see langword="null"/> if the argument to the
/// parameter specified is non-<see langword="null"/>.
/// </param>
public NotNullIfNotNullAttribute(string parameterName) =>
ParameterName = parameterName;
}
#endif
40 changes: 40 additions & 0 deletions src/UiPath.CoreIpc.Tests/Implementation/SystemService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System.Globalization;
using System.IO.Pipes;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;

namespace UiPath.CoreIpc.Tests;
Expand All @@ -22,13 +25,19 @@ public interface ISystemService
Task<Stream> Download(string text, CancellationToken cancellationToken = default);
Task<Stream> Echo(Stream input, CancellationToken cancellationToken = default);
Task<string> UploadNoRead(Stream memoryStream, int delay = 0, CancellationToken cancellationToken = default);
Task<bool> CancelIoPipe(CancelIoPipeMessage message = null, CancellationToken cancellationToken = default);
Task<bool> Delay(int delay = 0, CancellationToken cancellationToken = default);
}

public class SystemMessage : Message
{
public string Text { get; set; }
public int Delay { get; set; }
}
public class CancelIoPipeMessage : Message
{
public int[]? MsDelays { get; set; }
}
public class SystemService : ISystemService
{
public SystemService()
Expand Down Expand Up @@ -172,4 +181,35 @@ public async Task<Stream> Echo(Stream input, CancellationToken cancellationToken
result.Position = 0;
return result;
}

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CancelIoEx(IntPtr handle, IntPtr lpOverlapped);
public async Task<bool> CancelIoPipe(CancelIoPipeMessage message = null, CancellationToken cancellationToken = default)
{
Debug.WriteLine("###################### CancelIoPipe");
await Task.Delay(50);
#if WINDOWS
var serverFieldInfo = message.Client.GetType().GetField("_server", BindingFlags.NonPublic | BindingFlags.Instance);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this to other things (InternalsVisibleTo)

var pipeStream = serverFieldInfo.GetValue(message.Client) as PipeStream;

var canceled = CancelIoEx(pipeStream.SafePipeHandle.DangerousGetHandle(), IntPtr.Zero);

foreach (var msDelay in message.MsDelays ?? [])
{
await Task.Delay(msDelay);
canceled = CancelIoEx(pipeStream.SafePipeHandle.DangerousGetHandle(), IntPtr.Zero);
}

await Task.Delay(50);
return canceled;
#else
return false;
#endif
}

public async Task<bool> Delay(int delay = 0, CancellationToken cancellationToken = default)
{
await Task.Delay(delay, cancellationToken);
return true;
}
}
41 changes: 36 additions & 5 deletions src/UiPath.CoreIpc.Tests/NamedPipeTests.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
using System.IO.Pipes;
using System.IO;
using System.IO.Pipes;
using System.Security.Principal;
namespace UiPath.CoreIpc.Tests;

public class SystemNamedPipeTests : SystemTests<NamedPipeClientBuilder<ISystemService>>
{
string _pipeName = "system";
protected override ServiceHostBuilder Configure(ServiceHostBuilder serviceHostBuilder) =>
serviceHostBuilder.UseNamedPipes(Configure(new NamedPipeSettings(_pipeName+GetHashCode())));
protected override NamedPipeClientBuilder<ISystemService> CreateSystemClientBuilder() =>
new NamedPipeClientBuilder<ISystemService>(_pipeName+GetHashCode()).AllowImpersonation();
serviceHostBuilder.UseNamedPipes(Configure(new NamedPipeSettings(_pipeName + GetHashCode())));
protected override NamedPipeClientBuilder<ISystemService> CreateSystemClientBuilder() =>
new NamedPipeClientBuilder<ISystemService>(_pipeName + GetHashCode()).AllowImpersonation();
[Fact]
public void PipeExists()
{
IOHelpers.PipeExists(System.Guid.NewGuid().ToString()).ShouldBeFalse();
IOHelpers.PipeExists("system"+GetHashCode(), 50).ShouldBeTrue();
IOHelpers.PipeExists("system" + GetHashCode(), 50).ShouldBeTrue();
}
[Fact]
public Task ServerName() => SystemClientBuilder().ValidateAndBuild().GetGuid(System.Guid.Empty);
Expand All @@ -38,6 +39,36 @@ public async Task PipeSecurityForWindows()
_ = protectedService.RunAsync();
await CreateSystemService().DoNothing().ShouldThrowAsync<UnauthorizedAccessException>();
}

[Theory]
[InlineData(new int[0])]
[InlineData(100)]
[InlineData(1100)]
[InlineData(10, 10, 10, 10)]
public async Task PipeCancelIoOnServer_AnyNoOfTimes(params int[] msDelays)
{
// Any number of kernel32.CancelIoEx calls should not cause the client to give up on the connection.
(await _systemClient.CancelIoPipe(new() { MsDelays = msDelays })).ShouldBeTrue();

//Make sure the connection is still working
(await _systemClient.Delay()).ShouldBeTrue();
}

[Fact]
public async Task PipeCancelIoOnClient()
{
(await _systemClient.Delay()).ShouldBeTrue();

var delayTask = _systemClient.Delay(500);
await Task.Delay(100);
var pipeStream = ((IpcProxy)_systemClient).Connection.Network as PipeStream;
SystemService.CancelIoEx(pipeStream.SafePipeHandle.DangerousGetHandle(), IntPtr.Zero).ShouldBeTrue();

(await delayTask).ShouldBeTrue();

//Make sure the connection is still working
(await _systemClient.Delay()).ShouldBeTrue();
}
#endif
}
public class ComputingNamedPipeTests : ComputingTests<NamedPipeClientBuilder<IComputingService, IComputingCallback>>
Expand Down
2 changes: 1 addition & 1 deletion src/UiPath.CoreIpc.Tests/SystemTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace UiPath.CoreIpc.Tests;
public abstract class SystemTests<TBuilder> : TestBase where TBuilder : ServiceClientBuilder<TBuilder, ISystemService>
{
protected ServiceHost _systemHost;
protected ISystemService _systemClient;
protected readonly ISystemService _systemClient;
protected readonly SystemService _systemService;
public SystemTests()
{
Expand Down
5 changes: 3 additions & 2 deletions src/UiPath.CoreIpc.Tests/TestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ public abstract class TestBase : IDisposable
protected static int Count = -1;
public static readonly TimeSpan RequestTimeout =
#if CI
TimeSpan.FromSeconds(2) +
TimeSpan.FromSeconds(3) +
#endif
(Debugger.IsAttached ? TimeSpan.FromDays(1) : TimeSpan.FromSeconds(2));
TimeSpan.FromSeconds(3);
// (Debugger.IsAttached ? TimeSpan.FromDays(1) : TimeSpan.FromSeconds(2));
protected readonly IServiceProvider _serviceProvider;
protected readonly AsyncContext _guiThread = new AsyncContextThread().Context;

Expand Down
1 change: 1 addition & 0 deletions src/UiPath.CoreIpc.Tests/UiPath.CoreIpc.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<DefineConstants>$(DefineConstants);$(DefineConstantsEx)</DefineConstants>
<LangVersion>latest</LangVersion>
<ImplicitUsings>true</ImplicitUsings>
<Nullable>annotations</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/UiPath.CoreIpc.Tests/WebSocketTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
namespace UiPath.CoreIpc.Tests;
public class SystemWebSocketTests : SystemTests<WebSocketClientBuilder<ISystemService>>
{
int _port = 1313 + GetCount();
int _port = 51313 + GetCount();
HttpSysWebSocketsListener _listener;
protected override ServiceHostBuilder Configure(ServiceHostBuilder serviceHostBuilder)
{
Expand Down
Loading