diff --git a/.editorconfig b/.editorconfig
index d2698fa7..9027da3a 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -58,6 +58,7 @@ dotnet_naming_rule.locals_should_be_camel_case.style = camel_case_style
dotnet_naming_symbols.locals_and_parameters.applicable_kinds = parameter, local
dotnet_naming_style.camel_case_style.capitalization = camel_case
+csharp_style_pattern_local_over_anonymous_function=true:silent
[*.xml]
indent_size = 2
diff --git a/.gitignore b/.gitignore
index e0dfee8e..fd4124b1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ scripts/
artifacts/
.dotnet
TestResults/
+*.diagsession
*.suo
*.user
bin
@@ -32,3 +33,6 @@ project.lock.json
# Read the Docs
docs/_build
/src/LastMajorVersionBinary
+
+# Mac Finder
+.DS_Store
diff --git a/CI/azp-dotnet-dist.yaml b/CI/azp-dotnet-dist.yaml
deleted file mode 100644
index dbd6ff13..00000000
--- a/CI/azp-dotnet-dist.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-steps:
- - task: CopyFiles@2
- displayName: '$(Label_DotNet) Copy nupkg to $(Build.ArtifactStagingDirectory)'
- inputs:
- SourceFolder: 'src\UiPath.CoreIpc\bin\$(DotNet_BuildConfiguration)\'
- Contents: '*.*nupkg'
- TargetFolder: '$(Build.ArtifactStagingDirectory)'
- CleanTargetFolder: true
-
- - task: PublishBuildArtifacts@1
- displayName: '$(Label_DotNet) Publish the $(DotNet_ArtifactName) to the pipeline instance'
- inputs:
- ArtifactName: '$(DotNet_ArtifactName)'
- PathtoPublish: '$(Build.ArtifactStagingDirectory)'
- ArtifactType: 'Container'
diff --git a/CI/azp-dotnet.yaml b/CI/azp-dotnet.yaml
deleted file mode 100644
index a218a77e..00000000
--- a/CI/azp-dotnet.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-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:
- command: 'test'
- projects: '**/*Tests*.csproj'
- publishTestResults: true
- testRunTitle: '.NET tests'
- arguments: '--no-build --configuration $(DotNet_BuildConfiguration) --logger "console;verbosity=detailed"'
diff --git a/CI/azp-nodejs.yaml b/CI/azp-nodejs.yaml
deleted file mode 100644
index 2b3fcbf1..00000000
--- a/CI/azp-nodejs.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-steps:
- - task: DotNetCoreCLI@2
- displayName: '$(Label_NodeJS) Restore and build "UiPath.CoreIpc.csproj"'
- inputs:
- projects: '$(DotNet_MainProjectPath)'
- arguments: '--configuration $(NodeJS_DotNet_BuildConfiguration) --framework netstandard2.0 -p:Version="$(FullVersion)"'
-
- - task: DotNetCoreCLI@2
- displayName: '$(Label_NodeJS) Restore and build "UiPath.CoreIpc.NodeInterop.csproj"'
- inputs:
- projects: '$(NodeJS_DotNetNodeInteropProject)'
- arguments: '--configuration $(NodeJS_DotNet_BuildConfiguration) --framework net5.0 -p:Version="$(FullVersion)"'
-
- - task: Npm@1
- displayName: '$(Label_NodeJS) Write $[FullVersion] to package.json'
- inputs:
- command: 'custom'
- workingDir: '$(NodeJS_ProjectPath)'
- customCommand: 'version $(FullVersion) --allow-same-version'
-
- - task: Npm@1
- displayName: '$(Label_NodeJS) Restore'
- inputs:
- command: 'install'
- workingDir: $(NodeJS_ProjectPath)
- customRegistry: 'useFeed'
- customFeed: '424ca518-1f12-456b-a4f6-888197fc15ee'
-
- - task: Npm@1
- displayName: '$(Label_NodeJS) Build'
- inputs:
- command: 'custom'
- workingDir: $(NodeJS_ProjectPath)
- customCommand: 'run build'
-
- - task: Npm@1
- displayName: '$(Label_NodeJS) Run unit tests'
- inputs:
- command: 'custom'
- workingDir: $(NodeJS_ProjectPath)
- customCommand: 'run test'
-
- - task: PublishTestResults@2
- displayName: '$(Label_NodeJS) Publish test results'
- condition: succeededOrFailed()
- inputs:
- testRunner: JUnit
- workingDir: $(NodeJS_ProjectPath)
- testResultsFiles: './src/Clients/nodejs/reports/test-results.xml'
-
- - task: PublishCodeCoverageResults@1
- displayName: '$(Label_NodeJS) Publish code coverage results'
- inputs:
- codeCoverageTool: 'cobertura'
- summaryFileLocation: './src/Clients/nodejs/reports/coverage/cobertura-coverage.xml'
diff --git a/CI/azp-start.yaml b/CI/azp-start.yaml
deleted file mode 100644
index 47a12a74..00000000
--- a/CI/azp-start.yaml
+++ /dev/null
@@ -1,50 +0,0 @@
-name: $(Date:yyyyMMdd)$(Rev:-rr)
-
-variables:
- Label_Initialization: 'Initialization:'
- Label_DotNet: '.NET:'
- Label_NodeJS: 'node.js:'
-
- DotNet_BuildConfiguration: 'Release'
- DotNet_SessionSolution: 'CoreIpc.sln'
- DotNet_MainProjectName: 'UiPath.CoreIpc'
- DotNet_MainProjectPath: './src/UiPath.CoreIpc/UiPath.CoreIpc.csproj'
- DotNet_ArtifactName: 'NuGet package'
-
- NodeJS_DotNet_BuildConfiguration: 'Debug'
- NodeJS_ProjectPath: './src/Clients/nodejs'
- NodeJS_ArchivePath: './src/Clients/nodejs.zip'
- NodeJS_ArtifactName: 'NPM package'
- NodeJS_NetCoreAppTargetDir_RelativePath: 'dotnet/UiPath.CoreIpc.NodeInterop/bin/Debug/net5.0'
- NodeJS_DotNetNodeInteropProject : './src/Clients/nodejs/dotnet/UiPath.CoreIpc.NodeInterop/UiPath.CoreIpc.NodeInterop.csproj'
- NodeJS_DotNetNodeInteropSolution: './src/Clients/nodejs/dotnet/UiPath.CoreIpc.NodeInterop.sln'
-
-jobs:
- # The following 3 jobs will run in parallel:
-
- - job:
- displayName: '.NET on Windows'
- pool:
- vmImage: 'windows-2019'
- steps:
- - template: azp-initialization.yaml
- - template: azp-dotnet.yaml
- - template: azp-dotnet-dist.yaml
-
- - job:
- displayName: 'node.js on Windows'
- pool:
- vmImage: 'windows-2019'
- 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
-
diff --git a/Directory.Build.props b/Directory.Build.props
deleted file mode 100644
index 28c4f059..00000000
--- a/Directory.Build.props
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- latest
- $(DefineConstants);WINDOWS
- $(DefineConstants);NET5_0_WINDOWS
-
-
\ No newline at end of file
diff --git a/README.md b/README.md
index 5f6d2302..587059e6 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
[![Build Status](https://uipath.visualstudio.com/CoreIpc/_apis/build/status/CI?branchName=master)](https://uipath.visualstudio.com/CoreIpc/_build/latest?definitionId=637&branchName=master)
-[![MyGet (dev)](https://img.shields.io/badge/CoreIpc-MyGet-brightgreen)](https://www.myget.org/feed/uipath-dev/package/nuget/UiPath.CoreIpc)
+[![MyGet (dev)](https://img.shields.io/badge/CoreIpc-Preview-brightgreen)](https://uipath.visualstudio.com/Public.Feeds/_packaging?_a=package&feed=UiPath-Internal&view=versions&package=UiPath.CoreIpc&protocolType=NuGet)
# CoreIpc
-WCF-like service model API for communication over named pipes. .NET Standard (.NET Core) and [Node.js](src/Clients/nodejs) clients.
+WCF-like service model API for communication over named pipes, TCP and web sockets. .NET and [Node.js and Web](src/Clients/js) clients.
- async
- json serialization
- DI integration
@@ -14,7 +14,7 @@ WCF-like service model API for communication over named pipes. .NET Standard (.N
- configurable task scheduler
- client authentication and impersonation
- access to the underlying transport with `Stream` parameters
-- SSPI encryption and signing
+- SSL
Check [the tests](https://github.com/UiPath/CoreIpc/blob/master/src/UiPath.CoreIpc.Tests/) and the sample.
```C#
@@ -31,3 +31,11 @@ var computingClient =
// call a remote method
var result = await computingClient.AddFloat(1, 4, cancellationToken);
```
+# UiPath.Rpc
+[![Build Status](https://uipath.visualstudio.com/CoreIpc/_apis/build/status/CI?branchName=master)](https://uipath.visualstudio.com/CoreIpc/_build/latest?definitionId=3428&branchName=master)
+[![MyGet (dev)](https://img.shields.io/badge/UiPath.Rpc-Preview-brightgreen)](https://uipath.visualstudio.com/Public.Feeds/_packaging?_a=package&feed=UiPath-Internal&view=versions&package=UiPath.Rpc&protocolType=NuGet)
+
+https://github.com/UiPath/coreipc/tree/master/UiPath.Rpc
+A more efficient version based on MessagePack.
+# Debug using Source Link
+[Preview builds setup](https://docs.microsoft.com/en-us/azure/devops/pipelines/artifacts/symbols?view=azure-devops#set-up-visual-studio).
\ No newline at end of file
diff --git a/src/CI/azp-dotnet-dist.yaml b/src/CI/azp-dotnet-dist.yaml
new file mode 100644
index 00000000..bafcc806
--- /dev/null
+++ b/src/CI/azp-dotnet-dist.yaml
@@ -0,0 +1,32 @@
+steps:
+ - task: CopyFiles@2
+ displayName: '$(Label_DotNet) Copy nupkg to $(Build.ArtifactStagingDirectory)'
+ inputs:
+ SourceFolder: 'src\UiPath.CoreIpc\bin\$(DotNet_BuildConfiguration)\'
+ Contents: '*.*nupkg'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)'
+ CleanTargetFolder: true
+
+ - task: PublishBuildArtifacts@1
+ displayName: '$(Label_DotNet) Publish the $(DotNet_ArtifactName) to the pipeline instance'
+ inputs:
+ ArtifactName: '$(DotNet_ArtifactName)'
+ PathtoPublish: '$(Build.ArtifactStagingDirectory)'
+ ArtifactType: 'Container'
+
+ - task: DotNetCoreCLI@2
+ displayName: 'dotnet push to UiPath-Internal'
+ condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
+ 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'))
+ inputs:
+ symbolsFolder: $(Build.SourcesDirectory)
+ searchPattern: '**/UiPath.CoreIpc/bin/**/UiPath.CoreIpc.pdb'
+ symbolServerType: teamServices
+ indexSources: false
\ No newline at end of file
diff --git a/src/CI/azp-dotnet.yaml b/src/CI/azp-dotnet.yaml
new file mode 100644
index 00000000..0af4fc84
--- /dev/null
+++ b/src/CI/azp-dotnet.yaml
@@ -0,0 +1,9 @@
+steps:
+ - task: DotNetCoreCLI@2
+ displayName: '$(Label_DotNet) Run unit tests'
+ inputs:
+ command: 'test'
+ projects: '$(DotNet_SessionSolution)'
+ publishTestResults: true
+ testRunTitle: '.NET tests'
+ arguments: ' --configuration $(DotNet_BuildConfiguration) --logger "console;verbosity=detailed" -p:Version="$(FullVersion)" -p:DefineConstantsEx="CI"'
\ No newline at end of file
diff --git a/CI/azp-initialization.yaml b/src/CI/azp-initialization.yaml
similarity index 100%
rename from CI/azp-initialization.yaml
rename to src/CI/azp-initialization.yaml
diff --git a/src/CI/azp-js.publish-npm.steps.yaml b/src/CI/azp-js.publish-npm.steps.yaml
new file mode 100644
index 00000000..f03be252
--- /dev/null
+++ b/src/CI/azp-js.publish-npm.steps.yaml
@@ -0,0 +1,32 @@
+steps:
+- checkout: none
+
+- download: current
+ artifact: 'NPM package'
+ # The destination path is $(Pipeline.Workspace)
+
+- task: NodeTool@0
+ displayName: 'Use Node.js 20.11.0'
+ inputs:
+ versionSpec: '20.11.0'
+
+- task: ExtractFiles@1
+ displayName: 'Extract Files'
+ inputs:
+ archiveFilePatterns: '$(Pipeline.Workspace)/NPM package/*.zip'
+ destinationFolder: '$(System.DefaultWorkingDirectory)/unzipped'
+ cleanDestinationFolder: true
+
+- task: Npm@1
+ displayName: 'Publish NPM (NodeJS)'
+ inputs:
+ command: 'publish'
+ workingDir: '$(System.DefaultWorkingDirectory)/unzipped/dist/prepack/node'
+ publishEndpoint: PublishNPM
+
+- task: Npm@1
+ displayName: 'Publish NPM (Web)'
+ inputs:
+ command: 'publish'
+ workingDir: '$(System.DefaultWorkingDirectory)/unzipped/dist/prepack/web'
+ publishEndpoint: PublishNPM
diff --git a/CI/azp-nodejs-dist.yaml b/src/CI/azp-nodejs-dist.yaml
similarity index 69%
rename from CI/azp-nodejs-dist.yaml
rename to src/CI/azp-nodejs-dist.yaml
index d38d2c58..3002f2ea 100644
--- a/CI/azp-nodejs-dist.yaml
+++ b/src/CI/azp-nodejs-dist.yaml
@@ -1,6 +1,6 @@
steps:
- task: ArchiveFiles@2
- displayName: '$(Label_NodeJS) Archive project directory'
+ displayName: 'Archive the project directory'
inputs:
archiveType: 'zip'
includeRootFolder: false
@@ -8,7 +8,7 @@ steps:
archiveFile: '$(NodeJS_ArchivePath)'
- task: PublishBuildArtifacts@1
- displayName: '$(Label_NodeJS) Publish the $(NodeJS_ArtifactName) to the pipeline instance'
+ displayName: 'Publish the $(NodeJS_ArtifactName) to the pipeline instance'
inputs:
ArtifactName: '$(NodeJS_ArtifactName)'
PathtoPublish: '$(NodeJS_ArchivePath)'
diff --git a/src/CI/azp-nodejs.yaml b/src/CI/azp-nodejs.yaml
new file mode 100644
index 00000000..52f7d934
--- /dev/null
+++ b/src/CI/azp-nodejs.yaml
@@ -0,0 +1,73 @@
+steps:
+ - task: UseDotNet@2
+ inputs:
+ version: 6.0.x
+
+ - task: NodeTool@0
+ displayName: 'Use Node.js 20.11.0'
+ inputs:
+ versionSpec: '20.11.0'
+
+ - task: DotNetCoreCLI@2
+ displayName: 'Build "UiPath.CoreIpc.csproj"'
+ inputs:
+ projects: '$(DotNet_MainProjectPath)'
+ arguments: '--configuration $(NodeJS_DotNet_BuildConfiguration) --framework net6.0 -p:Version="$(FullVersion)"'
+
+ - task: DotNetCoreCLI@2
+ displayName: 'Build "UiPath.CoreIpc.NodeInterop.csproj"'
+ inputs:
+ projects: '$(NodeJS_DotNetNodeInteropProject)'
+ arguments: '--configuration $(NodeJS_DotNet_BuildConfiguration) --framework net6.0 -p:Version="$(FullVersion)"'
+
+ - task: CmdLine@2
+ displayName: 'Set $[FullVersion] in package.json'
+ condition: succeeded()
+ inputs:
+ workingDirectory: '$(NodeJS_ProjectPath)'
+ script: 'npm version $(FullVersion) --allow-same-version'
+
+ - task: Npm@1
+ displayName: 'Npm Install'
+ inputs:
+ command: 'install'
+ workingDir: $(NodeJS_ProjectPath)
+ customRegistry: 'useFeed'
+ customFeed: '424ca518-1f12-456b-a4f6-888197fc15ee'
+
+ - task: CmdLine@2
+ displayName: 'Npm Run Build'
+ condition: succeeded()
+ inputs:
+ workingDirectory: $(NodeJS_ProjectPath)
+ script: 'npm run build'
+
+ - task: CmdLine@2
+ displayName: 'Npm Test'
+ condition: succeeded()
+ inputs:
+ workingDirectory: $(NodeJS_ProjectPath)
+ script: 'npm test'
+
+ - task: PublishTestResults@2
+ displayName: 'Publish Web Test Results'
+ condition: succeededOrFailed()
+ inputs:
+ testRunner: JUnit
+ workingDir: $(NodeJS_ProjectPath)
+ testResultsFiles: './src/Clients/js/reports/test/web/test-results.xml'
+
+ - task: PublishTestResults@2
+ displayName: 'Publish NodeJS Test Results'
+ condition: succeededOrFailed()
+ inputs:
+ testRunner: JUnit
+ workingDir: $(NodeJS_ProjectPath)
+ testRunTitle: '🌲 NodeJs ($(Agent.OS) $(Agent.OSArchitecture))'
+ testResultsFiles: './src/Clients/js/reports/test/node/test-results.xml'
+
+ - task: PublishCodeCoverageResults@1
+ displayName: 'Publish Code Coverage Results'
+ inputs:
+ codeCoverageTool: 'cobertura'
+ summaryFileLocation: './src/Clients/js/reports/coverage/merged/cobertura/cobertura-coverage.xml'
diff --git a/src/CI/azp-start.yaml b/src/CI/azp-start.yaml
new file mode 100644
index 00000000..d659af93
--- /dev/null
+++ b/src/CI/azp-start.yaml
@@ -0,0 +1,66 @@
+name: $(Date:yyyyMMdd)$(Rev:-rr)
+
+variables:
+ Label_Initialization: 'Initialization:'
+ Label_DotNet: '.NET:'
+ Label_NodeJS: 'node.js:'
+
+ DotNet_BuildConfiguration: 'Release'
+ DotNet_SessionSolution: './src/CoreIpc.sln'
+ 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'
+ NodeJS_ArtifactName: 'NPM package'
+ NodeJS_NetCoreAppTargetDir_RelativePath: 'dotnet/UiPath.CoreIpc.NodeInterop/bin/Debug/net6.0'
+ NodeJS_DotNetNodeInteropProject : './src/Clients/js/dotnet/UiPath.CoreIpc.NodeInterop/UiPath.CoreIpc.NodeInterop.csproj'
+ NodeJS_DotNetNodeInteropSolution: './src/Clients/js/dotnet/UiPath.CoreIpc.NodeInterop.sln'
+
+stages:
+- stage: Build
+ displayName: '🏭 Build'
+ jobs:
+ # 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:
+ 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
+
+- stage: Publish
+ displayName: 🚚 Publish
+ dependsOn: Build
+ jobs:
+ - deployment: Publish_NPM_Packages
+ displayName: '📦 Publish NPM Packages'
+ environment: 'NPM-Packages'
+ pool:
+ vmImage: ubuntu-latest
+ strategy:
+ runOnce:
+ deploy:
+ steps:
+ - template: azp-js.publish-npm.steps.yaml
\ No newline at end of file
diff --git a/CoreIpc.sln b/src/CoreIpc.sln
similarity index 81%
rename from CoreIpc.sln
rename to src/CoreIpc.sln
index fd30afaf..b69f1d5f 100644
--- a/CoreIpc.sln
+++ b/src/CoreIpc.sln
@@ -1,19 +1,18 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29519.87
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31919.166
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IpcSample.ConsoleServer", "src\IpcSample.ConsoleServer\IpcSample.ConsoleServer.csproj", "{24A3C4D2-95A2-48D9-86F2-648879EC74F4}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IpcSample.ConsoleServer", "IpcSample.ConsoleServer\IpcSample.ConsoleServer.csproj", "{24A3C4D2-95A2-48D9-86F2-648879EC74F4}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IpcSample.ConsoleClient", "src\IpcSample.ConsoleClient\IpcSample.ConsoleClient.csproj", "{8D54E62A-ECFF-4FFF-B9D1-DB343D456451}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IpcSample.ConsoleClient", "IpcSample.ConsoleClient\IpcSample.ConsoleClient.csproj", "{8D54E62A-ECFF-4FFF-B9D1-DB343D456451}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UiPath.CoreIpc", "src\UiPath.CoreIpc\UiPath.CoreIpc.csproj", "{58200319-1F71-4E22-894D-7E69E0CD0B57}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UiPath.CoreIpc", "UiPath.CoreIpc\UiPath.CoreIpc.csproj", "{58200319-1F71-4E22-894D-7E69E0CD0B57}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UiPath.CoreIpc.Tests", "src\UiPath.CoreIpc.Tests\UiPath.CoreIpc.Tests.csproj", "{892424AE-4D3A-4984-914E-9423BE8D0212}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UiPath.CoreIpc.Tests", "UiPath.CoreIpc.Tests\UiPath.CoreIpc.Tests.csproj", "{892424AE-4D3A-4984-914E-9423BE8D0212}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{676A208A-2F08-4749-A833-F8D2BCB1B147}"
ProjectSection(SolutionItems) = preProject
- Directory.Build.props = Directory.Build.props
NuGet.Config = NuGet.Config
EndProjectSection
EndProject
diff --git a/src/IpcSample.ConsoleClient/Client.cs b/src/IpcSample.ConsoleClient/Client.cs
index a884bcfa..36515be2 100644
--- a/src/IpcSample.ConsoleClient/Client.cs
+++ b/src/IpcSample.ConsoleClient/Client.cs
@@ -1,128 +1,124 @@
-using System;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
+using System.Text;
using System.Diagnostics;
using UiPath.CoreIpc.NamedPipe;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using System.Linq;
-namespace UiPath.CoreIpc.Tests
+namespace UiPath.CoreIpc.Tests;
+
+class Client
{
- class Client
+ static async Task Main(string[] args)
{
- static async Task _Main(string[] args)
+ Console.WriteLine(typeof(int).Assembly);
+ Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
+ var source = new CancellationTokenSource();
+ try
{
- Console.WriteLine(typeof(int).Assembly);
- Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
- var source = new CancellationTokenSource();
- try
+ await await Task.WhenAny(RunTestsAsync(source.Token), Task.Run(() =>
{
- await await Task.WhenAny(RunTestsAsync(source.Token), Task.Run(() =>
- {
- Console.ReadLine();
- Console.WriteLine("Cancelling...");
- source.Cancel();
- }));
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.ToString());
Console.ReadLine();
- }
+ Console.WriteLine("Cancelling...");
+ source.Cancel();
+ }));
}
-
- private static async Task RunTestsAsync(CancellationToken cancellationToken)
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.ToString());
+ Console.ReadLine();
+ }
+ }
+ private static async Task RunTestsAsync(CancellationToken cancellationToken)
+ {
+ var serviceProvider = ConfigureServices();
+ var callback = new ComputingCallback { Id = "custom made" };
+ var computingClientBuilder = new NamedPipeClientBuilder("test", serviceProvider)
+ .SerializeParametersAsObjects().CallbackInstance(callback).AllowImpersonation().RequestTimeout(TimeSpan.FromSeconds(2));
+ var stopwatch = Stopwatch.StartNew();
+ int count = 0;
+ try
{
- var serviceProvider = ConfigureServices();
- var callback = new ComputingCallback { Id = "custom made" };
- var computingClientBuilder = new NamedPipeClientBuilder("test", serviceProvider).CallbackInstance(callback).AllowImpersonation().RequestTimeout(TimeSpan.FromSeconds(2));
- var stopwatch = Stopwatch.StartNew();
- int count = 0;
- try
+ var computingClient = computingClientBuilder.ValidateAndBuild();
+ var systemClient =
+ new NamedPipeClientBuilder("test")
+ .SerializeParametersAsObjects()
+ .RequestTimeout(TimeSpan.FromSeconds(2))
+ .Logger(serviceProvider)
+ .AllowImpersonation()
+ .ValidateAndBuild();
+ for (int i = 0; i < int.MaxValue; i++)
{
- var computingClient = computingClientBuilder.ValidateAndBuild();
- var systemClient =
- new NamedPipeClientBuilder("test")
- .RequestTimeout(TimeSpan.FromSeconds(2))
- .Logger(serviceProvider)
- .AllowImpersonation()
- .ValidateAndBuild();
- while (true)
- {
- // test 1: call IPC service method with primitive types
- float result1 = await computingClient.AddFloat(1.23f, 4.56f, cancellationToken);
- count++;
- Console.WriteLine($"[TEST 1] sum of 2 floating number is: {result1}");
- // test 2: call IPC service method with complex types
- ComplexNumber result2 = await computingClient.AddComplexNumber(
- new ComplexNumber(0.1f, 0.3f),
- new ComplexNumber(0.2f, 0.6f), cancellationToken);
- Console.WriteLine($"[TEST 2] sum of 2 complexe number is: {result2.A}+{result2.B}i");
+ // test 1: call IPC service method with primitive types
+ float result1 = await computingClient.AddFloat(1.23f, 4.56f, cancellationToken);
+ count++;
+ Console.WriteLine($"[TEST 1] sum of 2 floating number is: {result1}");
+ // test 2: call IPC service method with complex types
+ ComplexNumber result2 = await computingClient.AddComplexNumber(
+ new ComplexNumber(0.1f, 0.3f),
+ new ComplexNumber(0.2f, 0.6f), cancellationToken);
+ Console.WriteLine($"[TEST 2] sum of 2 complexe number is: {result2.A}+{result2.B}i");
- // test 3: call IPC service method with an array of complex types
- ComplexNumber result3 = await computingClient.AddComplexNumbers(new[]
- {
- new ComplexNumber(0.5f, 0.4f),
- new ComplexNumber(0.2f, 0.1f),
- new ComplexNumber(0.3f, 0.5f),
- }, cancellationToken);
- Console.WriteLine($"[TEST 3] sum of 3 complexe number is: {result3.A}+{result3.B}i", cancellationToken);
+ // test 3: call IPC service method with an array of complex types
+ ComplexNumber result3 = await computingClient.AddComplexNumbers(new[]
+ {
+ new ComplexNumber(0.5f, 0.4f),
+ new ComplexNumber(0.2f, 0.1f),
+ new ComplexNumber(0.3f, 0.5f),
+ }, cancellationToken);
+ Console.WriteLine($"[TEST 3] sum of 3 complexe number is: {result3.A}+{result3.B}i", cancellationToken);
- // test 4: call IPC service method without parameter or return
- await systemClient.DoNothing(cancellationToken);
- Console.WriteLine($"[TEST 4] invoked DoNothing()");
- //((IDisposable)systemClient).Dispose();
+ // test 4: call IPC service method without parameter or return
+ await systemClient.DoNothing(cancellationToken);
+ Console.WriteLine($"[TEST 4] invoked DoNothing()");
+ //((IDisposable)systemClient).Dispose();
- // test 5: call IPC service method with enum parameter
- string text = await systemClient.ConvertText("hEllO woRd!", TextStyle.Upper, cancellationToken);
- Console.WriteLine($"[TEST 5] {text}");
+ // test 5: call IPC service method with enum parameter
+ string text = await systemClient.ConvertText("hEllO woRd!", TextStyle.Upper, cancellationToken);
+ Console.WriteLine($"[TEST 5] {text}");
- // test 6: call IPC service method returning GUID
- Guid generatedId = await systemClient.GetGuid(Guid.NewGuid(), cancellationToken);
- Console.WriteLine($"[TEST 6] generated ID is: {generatedId}");
+ // test 6: call IPC service method returning GUID
+ Guid generatedId = await systemClient.GetGuid(Guid.NewGuid(), cancellationToken);
+ Console.WriteLine($"[TEST 6] generated ID is: {generatedId}");
- // test 7: call IPC service method with byte array
- byte[] input = Encoding.UTF8.GetBytes(string.Concat(Enumerable.Range(1, 1).Select(_ => "Test")));
- byte[] reversed = await systemClient.ReverseBytes(input, cancellationToken);
- Console.WriteLine($"[TEST 7] reverse bytes");
+ // test 7: call IPC service method with byte array
+ byte[] input = Encoding.UTF8.GetBytes(string.Concat(Enumerable.Range(1, 1).Select(_ => "Test")));
+ byte[] reversed = await systemClient.ReverseBytes(input, cancellationToken);
+ Console.WriteLine($"[TEST 7] reverse bytes");
- // test 8: call IPC service method with callback
- var userName = await computingClient.SendMessage(new SystemMessage { Text = "client text" }, cancellationToken);
- Console.WriteLine($"[TEST 8] client identity : {userName}");
+ // test 8: call IPC service method with callback
+ var userName = await computingClient.SendMessage(new SystemMessage { Text = "client text" }, cancellationToken);
+ Console.WriteLine($"[TEST 8] client identity : {userName}");
- //// test 9: call IPC service method with message parameter
- ////Console.WriteLine($"[TEST 9] callback error");
- //try
- //{
- // //userName = await systemClient.SendMessage(new SystemMessage { Text = "client text" }, cancellationToken);
- //}
- //catch(Exception ex)
- //{
- // //Console.WriteLineex.Message);
- //}
- }
- var callbackProxy = (IDisposable)computingClient;
- callbackProxy.Dispose();
- callbackProxy.Dispose();
- callbackProxy.Dispose();
- }
- finally
- {
- stopwatch.Stop();
- Console.WriteLine();
- Console.WriteLine("Calls per second: " + count / stopwatch.Elapsed.TotalSeconds);
- Console.WriteLine();
+ //// test 9: call IPC service method with message parameter
+ ////Console.WriteLine($"[TEST 9] callback error");
+ //try
+ //{
+ // //userName = await systemClient.SendMessage(new SystemMessage { Text = "client text" }, cancellationToken);
+ //}
+ //catch(Exception ex)
+ //{
+ // //Console.WriteLineex.Message);
+ //}
}
- // test 10: call slow IPC service method
- //await systemClient.SlowOperation(cancellationToken);
- //Console.WriteLine($"[TEST 10] Called slow operation");
+ stopwatch.Stop();
+ var callbackProxy = (IDisposable)computingClient;
+ callbackProxy.Dispose();
+ callbackProxy.Dispose();
+ callbackProxy.Dispose();
}
-
- private static IServiceProvider ConfigureServices() =>
- new ServiceCollection()
- .AddIpcWithLogging()
- .BuildServiceProvider();
+ finally
+ {
+ stopwatch.Stop();
+ Console.WriteLine();
+ Console.WriteLine("Calls per second: " + count*8 / stopwatch.Elapsed.TotalSeconds);
+ Console.WriteLine();
+ }
+ // test 10: call slow IPC service method
+ //await systemClient.SlowOperation(cancellationToken);
+ //Console.WriteLine($"[TEST 10] Called slow operation");
}
+
+ private static IServiceProvider ConfigureServices() =>
+ new ServiceCollection()
+ .AddIpcWithLogging()
+ .BuildServiceProvider();
}
\ No newline at end of file
diff --git a/src/IpcSample.ConsoleClient/IpcSample.ConsoleClient.csproj b/src/IpcSample.ConsoleClient/IpcSample.ConsoleClient.csproj
index a79c7914..a313c304 100644
--- a/src/IpcSample.ConsoleClient/IpcSample.ConsoleClient.csproj
+++ b/src/IpcSample.ConsoleClient/IpcSample.ConsoleClient.csproj
@@ -2,8 +2,10 @@
Exe
- net5.0;net461;net5.0-windows
+ net7.0;net461;net7.0-windows
app1.manifest
+ latest
+ true
@@ -12,9 +14,9 @@
-
-
-
-
+
+
+
+
diff --git a/src/IpcSample.ConsoleClient/TcpClient.cs b/src/IpcSample.ConsoleClient/TcpClient.cs
index 1e00b4fd..0768ebc6 100644
--- a/src/IpcSample.ConsoleClient/TcpClient.cs
+++ b/src/IpcSample.ConsoleClient/TcpClient.cs
@@ -1,134 +1,136 @@
-using System;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
+using System.Text;
using System.Diagnostics;
using UiPath.CoreIpc.Tcp;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using System.Linq;
using System.Net;
-using System.IO;
-namespace UiPath.CoreIpc.Tests
+namespace UiPath.CoreIpc.Tests;
+
+class TcpClient
{
- class TcpClient
+ static readonly IPEndPoint SystemEndPoint = new(IPAddress.Loopback, 3131);
+ static async Task _Main(string[] args)
{
- static readonly IPEndPoint SystemEndPoint = new(IPAddress.Loopback, 3131);
- static async Task Main(string[] args)
+ Console.WriteLine(typeof(int).Assembly);
+ Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
+ var source = new CancellationTokenSource();
+ try
{
- Console.WriteLine(typeof(int).Assembly);
- Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
- var source = new CancellationTokenSource();
- try
+ await await Task.WhenAny(RunTestsAsync(source.Token), Task.Run(() =>
{
- await await Task.WhenAny(RunTestsAsync(source.Token), Task.Run(() =>
- {
- Console.ReadLine();
- Console.WriteLine("Cancelling...");
- source.Cancel();
- }));
- }
- catch (Exception ex)
- {
- Console.WriteLine(ex.ToString());
Console.ReadLine();
- }
+ Console.WriteLine("Cancelling...");
+ source.Cancel();
+ }));
}
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.ToString());
+ Console.ReadLine();
+ }
+ }
- private static async Task RunTestsAsync(CancellationToken cancellationToken)
+ private static async Task RunTestsAsync(CancellationToken cancellationToken)
+ {
+ var serviceProvider = ConfigureServices();
+ var callback = new ComputingCallback { Id = "custom made" };
+ var computingClientBuilder = new TcpClientBuilder(SystemEndPoint, serviceProvider)
+ .SerializeParametersAsObjects().CallbackInstance(callback)/*.EncryptAndSign("localhost")*/.RequestTimeout(TimeSpan.FromSeconds(2));
+ var stopwatch = Stopwatch.StartNew();
+ int count = 0;
+ try
{
- var serviceProvider = ConfigureServices();
- var callback = new ComputingCallback { Id = "custom made" };
- var computingClientBuilder = new TcpClientBuilder(SystemEndPoint, serviceProvider).CallbackInstance(callback).RequestTimeout(TimeSpan.FromSeconds(2));
- var stopwatch = Stopwatch.StartNew();
- int count = 0;
- try
+ var computingClient = computingClientBuilder.ValidateAndBuild();
+ var systemClient =
+ new TcpClientBuilder(SystemEndPoint)
+ .SerializeParametersAsObjects()
+ //.EncryptAndSign("localhost")
+ .RequestTimeout(TimeSpan.FromSeconds(2))
+ .Logger(serviceProvider)
+ .ValidateAndBuild();
+ var watch = Stopwatch.StartNew();
+ //using (var file = File.OpenRead(@"C:\Windows\DPINST.log"))
+ //{
+ // Console.WriteLine(await systemClient.Upload(file));
+ //}
+ for (int i =0; i<50;i++)
{
- var computingClient = computingClientBuilder.ValidateAndBuild();
- var systemClient =
- new TcpClientBuilder(SystemEndPoint)
- .RequestTimeout(TimeSpan.FromSeconds(2))
- .Logger(serviceProvider)
- .ValidateAndBuild();
- using (var file = File.OpenRead(@"C:\Windows\DPINST.log"))
- {
- Console.WriteLine(await systemClient.Upload(file));
- }
- {
- // test 1: call IPC service method with primitive types
- float result1 = await computingClient.AddFloat(1.23f, 4.56f, cancellationToken);
- count++;
- Console.WriteLine($"[TEST 1] sum of 2 floating number is: {result1}");
- // test 2: call IPC service method with complex types
- ComplexNumber result2 = await computingClient.AddComplexNumber(
- new ComplexNumber(0.1f, 0.3f),
- new ComplexNumber(0.2f, 0.6f), cancellationToken);
- Console.WriteLine($"[TEST 2] sum of 2 complexe number is: {result2.A}+{result2.B}i");
+ // test 1: call IPC service method with primitive types
+ float result1 = await computingClient.AddFloat(1.23f, 4.56f, cancellationToken);
+ count++;
+ Console.WriteLine($"[TEST 1] sum of 2 floating number is: {result1}");
+ // test 2: call IPC service method with complex types
+ ComplexNumber result2 = await computingClient.AddComplexNumber(
+ new ComplexNumber(0.1f, 0.3f),
+ new ComplexNumber(0.2f, 0.6f), cancellationToken);
+ Console.WriteLine($"[TEST 2] sum of 2 complexe number is: {result2.A}+{result2.B}i");
- // test 3: call IPC service method with an array of complex types
- ComplexNumber result3 = await computingClient.AddComplexNumbers(new[]
- {
- new ComplexNumber(0.5f, 0.4f),
- new ComplexNumber(0.2f, 0.1f),
- new ComplexNumber(0.3f, 0.5f),
- }, cancellationToken);
- Console.WriteLine($"[TEST 3] sum of 3 complexe number is: {result3.A}+{result3.B}i", cancellationToken);
+ // test 3: call IPC service method with an array of complex types
+ ComplexNumber result3 = await computingClient.AddComplexNumbers(new[]
+ {
+ new ComplexNumber(0.5f, 0.4f),
+ new ComplexNumber(0.2f, 0.1f),
+ new ComplexNumber(0.3f, 0.5f),
+ }, cancellationToken);
+ Console.WriteLine($"[TEST 3] sum of 3 complexe number is: {result3.A}+{result3.B}i", cancellationToken);
- // test 4: call IPC service method without parameter or return
- await systemClient.DoNothing(cancellationToken);
- Console.WriteLine($"[TEST 4] invoked DoNothing()");
- //((IDisposable)systemClient).Dispose();
+ // test 4: call IPC service method without parameter or return
+ //await systemClient.DoNothing(cancellationToken);
+ //Console.WriteLine($"[TEST 4] invoked DoNothing()");
+ //((IDisposable)systemClient).Dispose();
- // test 5: call IPC service method with enum parameter
- string text = await systemClient.ConvertText("hEllO woRd!", TextStyle.Upper, cancellationToken);
- Console.WriteLine($"[TEST 5] {text}");
+ // test 5: call IPC service method with enum parameter
+ string text = await systemClient.ConvertText("hEllO woRd!", TextStyle.Upper, cancellationToken);
+ Console.WriteLine($"[TEST 5] {text}");
- // test 6: call IPC service method returning GUID
- Guid generatedId = await systemClient.GetGuid(Guid.NewGuid(), cancellationToken);
- Console.WriteLine($"[TEST 6] generated ID is: {generatedId}");
+ // test 6: call IPC service method returning GUID
+ Guid generatedId = await systemClient.GetGuid(Guid.NewGuid(), cancellationToken);
+ Console.WriteLine($"[TEST 6] generated ID is: {generatedId}");
- // test 7: call IPC service method with byte array
- byte[] input = Encoding.UTF8.GetBytes(string.Concat(Enumerable.Range(1, 1).Select(_ => "Test")));
- byte[] reversed = await systemClient.ReverseBytes(input, cancellationToken);
- Console.WriteLine($"[TEST 7] reverse bytes");
+ // test 7: call IPC service method with byte array
+ byte[] input = Encoding.UTF8.GetBytes(string.Concat(Enumerable.Range(1, 1).Select(_ => "Test")));
+ byte[] reversed = await systemClient.ReverseBytes(input, cancellationToken);
+ Console.WriteLine($"[TEST 7] reverse bytes");
- // test 8: call IPC service method with callback
- var userName = await computingClient.SendMessage(new SystemMessage { Text = "client text" }, cancellationToken);
- Console.WriteLine($"[TEST 8] client identity : {userName}");
+ // test 8: call IPC service method with callback
+ var userName = await computingClient.SendMessage(new SystemMessage { Text = "client text" }, cancellationToken);
+ Console.WriteLine($"[TEST 8] client identity : {userName}");
- //// test 9: call IPC service method with message parameter
- ////Console.WriteLine($"[TEST 9] callback error");
- //try
- //{
- // //userName = await systemClient.SendMessage(new SystemMessage { Text = "client text" }, cancellationToken);
- //}
- //catch(Exception ex)
- //{
- // //Console.WriteLineex.Message);
- //}
- }
- var callbackProxy = (IDisposable)computingClient;
- callbackProxy.Dispose();
- callbackProxy.Dispose();
- callbackProxy.Dispose();
- //((IpcProxy)callbackProxy).CloseConnection();
- }
- finally
- {
- stopwatch.Stop();
- Console.WriteLine();
- Console.WriteLine("Calls per second: " + count / stopwatch.Elapsed.TotalSeconds);
- Console.WriteLine();
+ //// test 9: call IPC service method with message parameter
+ ////Console.WriteLine($"[TEST 9] callback error");
+ //try
+ //{
+ // //userName = await systemClient.SendMessage(new SystemMessage { Text = "client text" }, cancellationToken);
+ //}
+ //catch(Exception ex)
+ //{
+ // //Console.WriteLineex.Message);
+ //}
}
- // test 10: call slow IPC service method
- //await systemClient.SlowOperation(cancellationToken);
- //Console.WriteLine($"[TEST 10] Called slow operation");
+ watch.Stop();
+ Console.WriteLine(watch.ElapsedMilliseconds);
+ var callbackProxy = (IDisposable)computingClient;
+ callbackProxy.Dispose();
+ callbackProxy.Dispose();
+ callbackProxy.Dispose();
+ //((IpcProxy)callbackProxy).CloseConnection();
+ ((IpcProxy)computingClient).CloseConnection();
+ ((IpcProxy)systemClient).CloseConnection();
}
-
- private static IServiceProvider ConfigureServices() =>
- new ServiceCollection()
- .AddIpcWithLogging()
- .BuildServiceProvider();
+ finally
+ {
+ stopwatch.Stop();
+ Console.WriteLine();
+ Console.WriteLine("Calls per second: " + count / stopwatch.Elapsed.TotalSeconds);
+ Console.WriteLine();
+ }
+ // test 10: call slow IPC service method
+ //await systemClient.SlowOperation(cancellationToken);
+ //Console.WriteLine($"[TEST 10] Called slow operation");
}
+
+ private static IServiceProvider ConfigureServices() =>
+ new ServiceCollection()
+ .AddIpcWithLogging()
+ .BuildServiceProvider();
}
\ No newline at end of file
diff --git a/src/IpcSample.ConsoleClient/WebSocketClient.cs b/src/IpcSample.ConsoleClient/WebSocketClient.cs
new file mode 100644
index 00000000..e6c93422
--- /dev/null
+++ b/src/IpcSample.ConsoleClient/WebSocketClient.cs
@@ -0,0 +1,133 @@
+using System.Text;
+using System.Diagnostics;
+using UiPath.CoreIpc.WebSockets;
+using Microsoft.Extensions.DependencyInjection;
+namespace UiPath.CoreIpc.Tests;
+class WebSocketClient
+{
+ static async Task _Main(string[] args)
+ {
+ Console.WriteLine(typeof(int).Assembly);
+ Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
+ Thread.Sleep(1000);
+ var source = new CancellationTokenSource();
+ try
+ {
+ await await Task.WhenAny(RunTestsAsync(source.Token), Task.Run(() =>
+ {
+ Console.ReadLine();
+ Console.WriteLine("Cancelling...");
+ source.Cancel();
+ }));
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.ToString());
+ Console.ReadLine();
+ }
+ }
+
+ private static async Task RunTestsAsync(CancellationToken cancellationToken)
+ {
+ Uri uri = new("ws://localhost:1212/wsDemo/");
+ var serviceProvider = ConfigureServices();
+ var callback = new ComputingCallback { Id = "custom made" };
+ var computingClientBuilder = new WebSocketClientBuilder(uri, serviceProvider).SerializeParametersAsObjects()
+ .CallbackInstance(callback)/*.EncryptAndSign("localhost")*/.RequestTimeout(TimeSpan.FromSeconds(2));
+ var stopwatch = Stopwatch.StartNew();
+ int count = 0;
+ try
+ {
+ var computingClient = computingClientBuilder.ValidateAndBuild();
+ var systemClient =
+ new WebSocketClientBuilder(uri).SerializeParametersAsObjects()
+ //.EncryptAndSign("localhost")
+ .RequestTimeout(TimeSpan.FromSeconds(2))
+ .Logger(serviceProvider)
+ .ValidateAndBuild();
+ var watch = Stopwatch.StartNew();
+ //using (var file = File.OpenRead(@"C:\Windows\DPINST.log"))
+ //{
+ // Console.WriteLine(await systemClient.Upload(file));
+ //}
+ for (int i =0; i<50;i++)
+ {
+ // test 1: call IPC service method with primitive types
+ float result1 = await computingClient.AddFloat(1.23f, 4.56f, cancellationToken);
+ count++;
+ Console.WriteLine($"[TEST 1] sum of 2 floating number is: {result1}");
+ // test 2: call IPC service method with complex types
+ ComplexNumber result2 = await computingClient.AddComplexNumber(
+ new ComplexNumber(0.1f, 0.3f),
+ new ComplexNumber(0.2f, 0.6f), cancellationToken);
+ Console.WriteLine($"[TEST 2] sum of 2 complexe number is: {result2.A}+{result2.B}i");
+
+ // test 3: call IPC service method with an array of complex types
+ ComplexNumber result3 = await computingClient.AddComplexNumbers(new[]
+ {
+ new ComplexNumber(0.5f, 0.4f),
+ new ComplexNumber(0.2f, 0.1f),
+ new ComplexNumber(0.3f, 0.5f),
+ }, cancellationToken);
+ Console.WriteLine($"[TEST 3] sum of 3 complexe number is: {result3.A}+{result3.B}i", cancellationToken);
+
+ // test 4: call IPC service method without parameter or return
+ //await systemClient.DoNothing(cancellationToken);
+ //Console.WriteLine($"[TEST 4] invoked DoNothing()");
+ //((IDisposable)systemClient).Dispose();
+
+ // test 5: call IPC service method with enum parameter
+ string text = await systemClient.ConvertText("hEllO woRd!", TextStyle.Upper, cancellationToken);
+ Console.WriteLine($"[TEST 5] {text}");
+
+ // test 6: call IPC service method returning GUID
+ Guid generatedId = await systemClient.GetGuid(Guid.NewGuid(), cancellationToken);
+ Console.WriteLine($"[TEST 6] generated ID is: {generatedId}");
+
+ // test 7: call IPC service method with byte array
+ byte[] input = Encoding.UTF8.GetBytes(string.Concat(Enumerable.Range(1, 1).Select(_ => "Test")));
+ byte[] reversed = await systemClient.ReverseBytes(input, cancellationToken);
+ Console.WriteLine($"[TEST 7] reverse bytes");
+
+ // test 8: call IPC service method with callback
+ var userName = await computingClient.SendMessage(new SystemMessage { Text = "client text" }, cancellationToken);
+ Console.WriteLine($"[TEST 8] client identity : {userName}");
+
+ //// test 9: call IPC service method with message parameter
+ ////Console.WriteLine($"[TEST 9] callback error");
+ //try
+ //{
+ // //userName = await systemClient.SendMessage(new SystemMessage { Text = "client text" }, cancellationToken);
+ //}
+ //catch(Exception ex)
+ //{
+ // //Console.WriteLineex.Message);
+ //}
+ }
+ watch.Stop();
+ Console.WriteLine(watch.ElapsedMilliseconds);
+ var callbackProxy = (IDisposable)computingClient;
+ callbackProxy.Dispose();
+ callbackProxy.Dispose();
+ callbackProxy.Dispose();
+ //((IpcProxy)callbackProxy).CloseConnection();
+ ((IpcProxy)computingClient).CloseConnection();
+ ((IpcProxy)systemClient).CloseConnection();
+ }
+ finally
+ {
+ stopwatch.Stop();
+ Console.WriteLine();
+ Console.WriteLine("Calls per second: " + count / stopwatch.Elapsed.TotalSeconds);
+ Console.WriteLine();
+ }
+ // test 10: call slow IPC service method
+ //await systemClient.SlowOperation(cancellationToken);
+ //Console.WriteLine($"[TEST 10] Called slow operation");
+ }
+
+ private static IServiceProvider ConfigureServices() =>
+ new ServiceCollection()
+ .AddIpcWithLogging()
+ .BuildServiceProvider();
+}
\ No newline at end of file
diff --git a/src/IpcSample.ConsoleServer/IpcSample.ConsoleServer.csproj b/src/IpcSample.ConsoleServer/IpcSample.ConsoleServer.csproj
index 3020f96c..2c9744b6 100644
--- a/src/IpcSample.ConsoleServer/IpcSample.ConsoleServer.csproj
+++ b/src/IpcSample.ConsoleServer/IpcSample.ConsoleServer.csproj
@@ -2,8 +2,10 @@
Exe
- net5.0;net461;net5.0-windows
+ net7.0;net461;net7.0-windows
app1.manifest
+ latest
+ true
@@ -12,10 +14,10 @@
-
-
-
-
+
+
+
+
diff --git a/src/IpcSample.ConsoleServer/Server.cs b/src/IpcSample.ConsoleServer/Server.cs
index 5e83849f..8e9ad9e4 100644
--- a/src/IpcSample.ConsoleServer/Server.cs
+++ b/src/IpcSample.ConsoleServer/Server.cs
@@ -1,58 +1,49 @@
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using System;
using System.Diagnostics;
-using System.IO.Pipes;
-using System.Security.AccessControl;
-using System.Security.Principal;
-using System.Threading;
-using System.Threading.Tasks;
using UiPath.CoreIpc.NamedPipe;
-namespace UiPath.CoreIpc.Tests
+namespace UiPath.CoreIpc.Tests;
+
+class Server
{
- class Server
+ //private static readonly Timer _timer = new Timer(_ =>
+ //{
+ // Console.WriteLine("GC.Collect");
+ // GC.Collect();
+ // GC.WaitForPendingFinalizers();
+ // GC.Collect();
+ //}, null, 0, 3000);
+ static async Task Main()
{
- //private static readonly Timer _timer = new Timer(_ =>
- //{
- // Console.WriteLine("GC.Collect");
- // GC.Collect();
- // GC.WaitForPendingFinalizers();
- // GC.Collect();
- //}, null, 0, 3000);
-
- static async Task _Main()
- {
- Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
- //GuiLikeSyncContext.Install();
- Console.WriteLine(SynchronizationContext.Current);
- var serviceProvider = ConfigureServices();
- // build and run service host
- var host = new ServiceHostBuilder(serviceProvider)
- .UseNamedPipes(new NamedPipeSettings("test")
- {
- RequestTimeout = TimeSpan.FromSeconds(2),
- AccessControl = security => security.AllowCurrentUser(),
- })
- .AddEndpoint()
- .AddEndpoint()
- .ValidateAndBuild();
-
- await await Task.WhenAny(host.RunAsync(), Task.Run(() =>
+ Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
+ //GuiLikeSyncContext.Install();
+ Console.WriteLine(SynchronizationContext.Current);
+ var serviceProvider = ConfigureServices();
+ // build and run service host
+ var host = new ServiceHostBuilder(serviceProvider)
+ .UseNamedPipes(new NamedPipeSettings("test")
{
- Console.WriteLine(typeof(int).Assembly);
- Console.ReadLine();
- host.Dispose();
- }));
+ RequestTimeout = TimeSpan.FromSeconds(2),
+ //AccessControl = security => security.AllowCurrentUser(),
+ })
+ .AddEndpoint()
+ .AddEndpoint()
+ .ValidateAndBuild();
- Console.WriteLine("Server stopped.");
- }
+ await await Task.WhenAny(host.RunAsync(), Task.Run(() =>
+ {
+ Console.WriteLine(typeof(int).Assembly);
+ Console.ReadLine();
+ host.Dispose();
+ }));
- private static IServiceProvider ConfigureServices() =>
- new ServiceCollection()
- .AddIpcWithLogging()
- .AddSingleton()
- .AddSingleton()
- .BuildServiceProvider();
+ Console.WriteLine("Server stopped.");
}
+
+ private static IServiceProvider ConfigureServices() =>
+ new ServiceCollection()
+ .AddIpcWithLogging()
+ .AddSingleton()
+ .AddSingleton()
+ .BuildServiceProvider();
}
\ No newline at end of file
diff --git a/src/IpcSample.ConsoleServer/TcpServer.cs b/src/IpcSample.ConsoleServer/TcpServer.cs
index b52042a7..172a7725 100644
--- a/src/IpcSample.ConsoleServer/TcpServer.cs
+++ b/src/IpcSample.ConsoleServer/TcpServer.cs
@@ -1,59 +1,53 @@
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using System;
using System.Diagnostics;
-using System.IO.Pipes;
using System.Net;
-using System.Security.AccessControl;
-using System.Security.Principal;
-using System.Threading;
-using System.Threading.Tasks;
using UiPath.CoreIpc.Tcp;
-namespace UiPath.CoreIpc.Tests
-{
- class TcpServer
- {
- static readonly IPEndPoint SystemEndPoint = new(IPAddress.Any, 3131);
- //private static readonly Timer _timer = new Timer(_ =>
- //{
- // Console.WriteLine("GC.Collect");
- // GC.Collect();
- // GC.WaitForPendingFinalizers();
- // GC.Collect();
- //}, null, 0, 3000);
+namespace UiPath.CoreIpc.Tests;
- static async Task Main()
- {
- Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
- //GuiLikeSyncContext.Install();
- Console.WriteLine(SynchronizationContext.Current);
- var serviceProvider = ConfigureServices();
- // build and run service host
- var host = new ServiceHostBuilder(serviceProvider)
- .UseTcp(new TcpSettings(SystemEndPoint)
- {
- RequestTimeout = TimeSpan.FromSeconds(2),
- })
- .AddEndpoint()
- .AddEndpoint()
- .ValidateAndBuild();
+class TcpServer
+{
+ static readonly IPEndPoint SystemEndPoint = new(IPAddress.Any, 3131);
+ //private static readonly Timer _timer = new Timer(_ =>
+ //{
+ // Console.WriteLine("GC.Collect");
+ // GC.Collect();
+ // GC.WaitForPendingFinalizers();
+ // GC.Collect();
+ //}, null, 0, 3000);
- await await Task.WhenAny(host.RunAsync(), Task.Run(() =>
+ static async Task _Main()
+ {
+ Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
+ //GuiLikeSyncContext.Install();
+ Console.WriteLine(SynchronizationContext.Current);
+ var serviceProvider = ConfigureServices();
+ // build and run service host
+ var data = File.ReadAllBytes(@"../../../../localhost.pfx");
+ var host = new ServiceHostBuilder(serviceProvider)
+ .UseTcp(new TcpSettings(SystemEndPoint)
{
- Console.WriteLine(typeof(int).Assembly);
- Console.ReadLine();
- host.Dispose();
- }));
+ RequestTimeout = TimeSpan.FromSeconds(2),
+ //Certificate = new X509Certificate(data, "1"),
+ })
+ .AddEndpoint()
+ .AddEndpoint()
+ .ValidateAndBuild();
- Console.WriteLine("Server stopped.");
- }
+ await await Task.WhenAny(host.RunAsync(), Task.Run(() =>
+ {
+ Console.WriteLine(typeof(int).Assembly);
+ Console.ReadLine();
+ host.Dispose();
+ }));
- private static IServiceProvider ConfigureServices() =>
- new ServiceCollection()
- .AddIpcWithLogging()
- .AddSingleton()
- .AddSingleton()
- .BuildServiceProvider();
+ Console.WriteLine("Server stopped.");
}
+
+ private static IServiceProvider ConfigureServices() =>
+ new ServiceCollection()
+ .AddIpcWithLogging()
+ .AddSingleton()
+ .AddSingleton()
+ .BuildServiceProvider();
}
\ No newline at end of file
diff --git a/src/IpcSample.ConsoleServer/WebSocketServer.cs b/src/IpcSample.ConsoleServer/WebSocketServer.cs
new file mode 100644
index 00000000..322c1d65
--- /dev/null
+++ b/src/IpcSample.ConsoleServer/WebSocketServer.cs
@@ -0,0 +1,49 @@
+using Microsoft.Extensions.DependencyInjection;
+using System.Diagnostics;
+using System.Net;
+using System.Net.WebSockets;
+using UiPath.CoreIpc.WebSockets;
+namespace UiPath.CoreIpc.Tests;
+class WebSocketServer
+{
+ //private static readonly Timer _timer = new Timer(_ =>
+ //{
+ // Console.WriteLine("GC.Collect");
+ // GC.Collect();
+ // GC.WaitForPendingFinalizers();
+ // GC.Collect();
+ //}, null, 0, 3000);
+
+ static async Task _Main()
+ {
+ Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
+ //GuiLikeSyncContext.Install();
+ Console.WriteLine(SynchronizationContext.Current);
+ var serviceProvider = ConfigureServices();
+ // build and run service host
+ //var data = File.ReadAllBytes(@"../../../../localhost.pfx");
+ var host = new ServiceHostBuilder(serviceProvider)
+ .UseWebSockets(new(new HttpSysWebSocketsListener("http://localhost:1212/wsDemo/").Accept)
+ {
+ RequestTimeout = TimeSpan.FromSeconds(2),
+ //Certificate = new X509Certificate(data, "1"),
+ })
+ .AddEndpoint()
+ .AddEndpoint()
+ .ValidateAndBuild();
+ await await Task.WhenAny(host.RunAsync(), Task.Run(() =>
+ {
+ Console.WriteLine(typeof(int).Assembly);
+ Console.ReadLine();
+ host.Dispose();
+ }));
+ Console.WriteLine("Server stopped.");
+ return;
+ }
+ private static IServiceProvider ConfigureServices() =>
+ new ServiceCollection()
+ .AddIpcWithLogging()
+ .AddSingleton()
+ .AddSingleton()
+ .BuildServiceProvider();
+}
\ No newline at end of file
diff --git a/NuGet.Config b/src/NuGet.Config
similarity index 100%
rename from NuGet.Config
rename to src/NuGet.Config
diff --git a/src/UiPath.CoreIpc.Tests/ComputingTests.cs b/src/UiPath.CoreIpc.Tests/ComputingTests.cs
index 10f4f8be..6c562dd9 100644
--- a/src/UiPath.CoreIpc.Tests/ComputingTests.cs
+++ b/src/UiPath.CoreIpc.Tests/ComputingTests.cs
@@ -1,138 +1,129 @@
-using System;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Extensions.DependencyInjection;
-using Shouldly;
-using Xunit;
+namespace UiPath.CoreIpc.Tests;
-namespace UiPath.CoreIpc.Tests
+public abstract class ComputingTests : TestBase where TBuilder : ServiceClientBuilder
{
- public abstract class ComputingTests : TestBase where TBuilder : ServiceClientBuilder
+ protected readonly ServiceHost _computingHost;
+ protected readonly IComputingService _computingClient;
+ protected readonly ComputingService _computingService;
+ protected readonly ComputingCallback _computingCallback;
+ public ComputingTests()
{
- protected readonly ServiceHost _computingHost;
- protected readonly IComputingService _computingClient;
- protected readonly ComputingService _computingService;
- protected readonly ComputingCallback _computingCallback;
- public ComputingTests()
- {
- _computingCallback = new ComputingCallback { Id = System.Guid.NewGuid().ToString() };
- _computingService = (ComputingService)_serviceProvider.GetService();
- _computingHost = Configure(new ServiceHostBuilder(_serviceProvider))
- .AddEndpoint()
- .ValidateAndBuild();
- _computingHost.RunAsync(GuiScheduler);
- _computingClient = ComputingClientBuilder(GuiScheduler).ValidateAndBuild();
- }
- protected abstract TBuilder ComputingClientBuilder(TaskScheduler taskScheduler = null);
- [Fact]
- public async Task ReconnectWithEncrypt()
+ _computingCallback = new ComputingCallback { Id = Guid.NewGuid().ToString() };
+ _computingService = (ComputingService)_serviceProvider.GetService();
+ _computingHost = Configure(new ServiceHostBuilder(_serviceProvider))
+ .AddEndpoint()
+ .ValidateAndBuild();
+ _computingHost.RunAsync(GuiScheduler);
+ _computingClient = ComputingClientBuilder(GuiScheduler).SerializeParametersAsObjects().ValidateAndBuild();
+ }
+ protected abstract TBuilder ComputingClientBuilder(TaskScheduler taskScheduler = null);
+ [Fact]
+ public async Task ReconnectWithEncrypt()
+ {
+ for (int i = 0; i < 50; i++)
{
- for (int i = 0; i < 50; i++)
- {
- await _computingClient.AddFloat(1, 2);
- ((IpcProxy)_computingClient).CloseConnection();
- await _computingClient.AddFloat(1, 2);
- }
+ await _computingClient.AddFloat(1, 2);
+ ((IpcProxy)_computingClient).CloseConnection();
+ await _computingClient.AddFloat(1, 2);
}
+ }
- [Fact]
- public async Task AddFloat()
- {
- var result = await _computingClient.AddFloat(1.23f, 4.56f);
- result.ShouldBe(5.79f);
- }
+ [Fact]
+ public async Task AddFloat()
+ {
+ var result = await _computingClient.AddFloat(1.23f, 4.56f);
+ result.ShouldBe(5.79f);
+ }
- [Fact]
- public Task AddFloatConcurrently() => Task.WhenAll(Enumerable.Range(1, 100).Select(_ => AddFloat()));
+ [Fact]
+ public Task AddFloatConcurrently() => Task.WhenAll(Enumerable.Range(1, 100).Select(_ => AddFloat()));
- [Fact]
- public async Task AddComplexNumber()
- {
- var result = await _computingClient.AddComplexNumber(new ComplexNumber(1f, 3f), new ComplexNumber(2f, 5f));
- result.ShouldBe(new ComplexNumber(3f, 8f));
- }
+ [Fact]
+ public async Task AddComplexNumber()
+ {
+ var result = await _computingClient.AddComplexNumber(new ComplexNumber(1f, 3f), new ComplexNumber(2f, 5f));
+ result.ShouldBe(new ComplexNumber(3f, 8f));
+ }
- [Fact]
- public async Task ClientCancellation()
+ [Fact]
+ public async Task ClientCancellation()
+ {
+ using (var cancellationSource = new CancellationTokenSource(10))
{
- using (var cancellationSource = new CancellationTokenSource(10))
- {
- _computingClient.Infinite(cancellationSource.Token).ShouldThrow();
- }
- await AddFloat();
+ _computingClient.Infinite(cancellationSource.Token).ShouldThrow();
}
+ await AddFloat();
+ }
- [Fact]
- public async Task ClientTimeout()
- {
- var proxy = ComputingClientBuilder().RequestTimeout(TimeSpan.FromMilliseconds(10)).ValidateAndBuild();
- proxy.Infinite().ShouldThrow().Message.ShouldBe($"{nameof(_computingClient.Infinite)} timed out.");
- await proxy.GetCallbackThreadName(new Message { RequestTimeout = RequestTimeout });
- ((IDisposable)proxy).Dispose();
- ((IpcProxy)proxy).CloseConnection();
- }
+ [Fact]
+ public async Task ClientTimeout()
+ {
+ var proxy = ComputingClientBuilder().SerializeParametersAsObjects().RequestTimeout(TimeSpan.FromMilliseconds(10)).ValidateAndBuild();
+ proxy.Infinite().ShouldThrow().Message.ShouldBe($"{nameof(_computingClient.Infinite)} timed out.");
+ await proxy.GetCallbackThreadName(new Message { RequestTimeout = RequestTimeout });
+ ((IDisposable)proxy).Dispose();
+ ((IpcProxy)proxy).CloseConnection();
+ }
- [Fact]
- public async Task TimeoutPerRequest()
+ [Fact]
+ public async Task TimeoutPerRequest()
+ {
+ for (int i = 0; i < 20; i++)
{
- for (int i = 0; i < 20; i++)
+ var request = new SystemMessage { RequestTimeout = TimeSpan.FromTicks(10), Delay = 100 };
+ Exception exception = null;
+ try
+ {
+ await _computingClient.SendMessage(request);
+ }
+ catch (TimeoutException ex)
{
- var request = new SystemMessage { RequestTimeout = TimeSpan.FromTicks(1), Delay = 100 };
- Exception exception = null;
- try
- {
- await _computingClient.SendMessage(request);
- }
- catch (TimeoutException ex)
- {
- exception = ex;
- }
- catch (RemoteException ex)
- {
- exception = ex;
- ex.Is().ShouldBeTrue();
- }
- exception.Message.ShouldBe($"{nameof(_computingClient.SendMessage)} timed out.");
- await AddFloat();
+ exception = ex;
}
+ catch (RemoteException ex)
+ {
+ exception = ex;
+ ex.Is().ShouldBeTrue();
+ }
+ exception.Message.ShouldBe($"{nameof(_computingClient.SendMessage)} timed out.");
+ await AddFloat();
}
+ }
- [Fact]
- public Task InfiniteVoid() => _computingClient.InfiniteVoid();
+ [Fact]
+ public Task InfiniteVoid() => _computingClient.InfiniteVoid();
- [Fact]
- public async Task AddComplexNumbers()
+ [Fact]
+ public async Task AddComplexNumbers()
+ {
+ var result = await _computingClient.AddComplexNumbers(new[]
{
- var result = await _computingClient.AddComplexNumbers(new[]
- {
- new ComplexNumber(0.5f, 0.4f),
- new ComplexNumber(0.2f, 0.1f),
- new ComplexNumber(0.3f, 0.5f),
- });
- result.ShouldBe(new ComplexNumber(1f, 1f));
- }
+ new ComplexNumber(0.5f, 0.4f),
+ new ComplexNumber(0.2f, 0.1f),
+ new ComplexNumber(0.3f, 0.5f),
+ });
+ result.ShouldBe(new ComplexNumber(1f, 1f));
+ }
- [Fact]
- public async Task GetCallbackThreadName() => (await _computingClient.GetCallbackThreadName()).ShouldBe("GuiThread");
+ [Fact]
+ public async Task GetCallbackThreadName() => (await _computingClient.GetCallbackThreadName()).ShouldBe("GuiThread");
- [Fact]
- public Task CallbackConcurrently() => Task.WhenAll(Enumerable.Range(1, 50).Select(_ => Callback()));
+ [Fact]
+ public Task CallbackConcurrently() => Task.WhenAll(Enumerable.Range(1, 50).Select(_ => Callback()));
- [Fact]
- public async Task Callback()
- {
- var message = new SystemMessage { Text = Guid.NewGuid().ToString() };
- var returnValue = await _computingClient.SendMessage(message);
- returnValue.ShouldBe($"{Environment.UserName}_{_computingCallback.Id}_{message.Text}");
- }
+ [Fact]
+ public async Task Callback()
+ {
+ var message = new SystemMessage { Text = Guid.NewGuid().ToString() };
+ var returnValue = await _computingClient.SendMessage(message);
+ returnValue.ShouldBe($"{Environment.UserName}_{_computingCallback.Id}_{message.Text}");
+ }
- public override void Dispose()
- {
- ((IDisposable)_computingClient).Dispose();
- ((IpcProxy)_computingClient).CloseConnection();
- _computingHost.Dispose();
- base.Dispose();
- }
+ public override void Dispose()
+ {
+ ((IDisposable)_computingClient).Dispose();
+ ((IpcProxy)_computingClient).CloseConnection();
+ _computingHost.Dispose();
+ base.Dispose();
}
}
\ No newline at end of file
diff --git a/src/UiPath.CoreIpc.Tests/EndpointTests.cs b/src/UiPath.CoreIpc.Tests/EndpointTests.cs
index 65eeba18..e62db908 100644
--- a/src/UiPath.CoreIpc.Tests/EndpointTests.cs
+++ b/src/UiPath.CoreIpc.Tests/EndpointTests.cs
@@ -1,145 +1,141 @@
-using System;
-using System.Threading;
-using System.Linq;
-using System.Threading.Tasks;
-using UiPath.CoreIpc.NamedPipe;
-using Microsoft.Extensions.DependencyInjection;
-using Xunit;
-using Shouldly;
+namespace UiPath.CoreIpc.Tests;
-namespace UiPath.CoreIpc.Tests
+public class EndpointTests : IDisposable
{
- public class EndpointTests : IDisposable
+ private static TimeSpan RequestTimeout => TestBase.RequestTimeout;
+ private readonly ServiceHost _host;
+ private readonly IComputingService _computingClient;
+ private readonly ISystemService _systemClient;
+ private readonly ComputingService _computingService;
+ private readonly SystemService _systemService;
+ private readonly ComputingCallback _computingCallback;
+ private readonly SystemCallback _systemCallback;
+ private readonly IServiceProvider _serviceProvider;
+ public EndpointTests()
{
- private static TimeSpan RequestTimeout => TestBase.RequestTimeout;
- private readonly ServiceHost _host;
- private readonly IComputingService _computingClient;
- private readonly ISystemService _systemClient;
- private readonly ComputingService _computingService;
- private readonly SystemService _systemService;
- private readonly ComputingCallback _computingCallback;
- private readonly SystemCallback _systemCallback;
- private readonly IServiceProvider _serviceProvider;
- public EndpointTests()
- {
- _computingCallback = new ComputingCallback { Id = Guid.NewGuid().ToString() };
- _systemCallback = new SystemCallback { Id = Guid.NewGuid().ToString() };
- _serviceProvider = IpcHelpers.ConfigureServices();
- _computingService = (ComputingService)_serviceProvider.GetService();
- _systemService = (SystemService)_serviceProvider.GetService();
- _host = new ServiceHostBuilder(_serviceProvider)
- .UseNamedPipes(new NamedPipeSettings(PipeName) { RequestTimeout = RequestTimeout })
- .AddEndpoint()
- .AddEndpoint()
- .AddEndpoint()
- .ValidateAndBuild();
- _host.RunAsync();
- _computingClient = ComputingClientBuilder().ValidateAndBuild();
- _systemClient = CreateSystemService();
- }
- public string PipeName => nameof(EndpointTests)+GetHashCode();
- private NamedPipeClientBuilder ComputingClientBuilder(TaskScheduler taskScheduler = null) =>
- new NamedPipeClientBuilder(PipeName, _serviceProvider)
- .AllowImpersonation()
- .RequestTimeout(RequestTimeout)
- .CallbackInstance(_computingCallback)
- .TaskScheduler(taskScheduler);
- private ISystemService CreateSystemService() => SystemClientBuilder().ValidateAndBuild();
- private NamedPipeClientBuilder SystemClientBuilder() =>
- new NamedPipeClientBuilder(PipeName, _serviceProvider).CallbackInstance(_systemCallback).RequestTimeout(RequestTimeout).AllowImpersonation();
- public void Dispose()
+ _computingCallback = new ComputingCallback { Id = Guid.NewGuid().ToString() };
+ _systemCallback = new SystemCallback { Id = Guid.NewGuid().ToString() };
+ _serviceProvider = IpcHelpers.ConfigureServices();
+ _computingService = (ComputingService)_serviceProvider.GetService();
+ _systemService = (SystemService)_serviceProvider.GetService();
+ _host = new ServiceHostBuilder(_serviceProvider)
+ .UseNamedPipes(new NamedPipeSettings(PipeName) { RequestTimeout = RequestTimeout })
+ .AddEndpoint()
+ .AddEndpoint()
+ .AddEndpoint()
+ .ValidateAndBuild();
+ _host.RunAsync();
+ _computingClient = ComputingClientBuilder().ValidateAndBuild();
+ _systemClient = CreateSystemService();
+ }
+ public string PipeName => nameof(EndpointTests)+GetHashCode();
+ private NamedPipeClientBuilder ComputingClientBuilder(TaskScheduler taskScheduler = null) =>
+ new NamedPipeClientBuilder(PipeName, _serviceProvider)
+ .AllowImpersonation()
+ .RequestTimeout(RequestTimeout)
+ .CallbackInstance(_computingCallback)
+ .SerializeParametersAsObjects()
+ .TaskScheduler(taskScheduler);
+ private ISystemService CreateSystemService() => SystemClientBuilder().ValidateAndBuild();
+ private NamedPipeClientBuilder SystemClientBuilder() =>
+ new NamedPipeClientBuilder(PipeName, _serviceProvider)
+ .CallbackInstance(_systemCallback)
+ .SerializeParametersAsObjects()
+ .RequestTimeout(RequestTimeout)
+ .AllowImpersonation();
+ public void Dispose()
+ {
+ ((IDisposable)_computingClient).Dispose();
+ ((IDisposable)_systemClient).Dispose();
+ ((IpcProxy)_computingClient).CloseConnection();
+ ((IpcProxy)_systemClient).CloseConnection();
+ _host.Dispose();
+ }
+ [Fact]
+ public Task CallbackConcurrently() => Task.WhenAll(Enumerable.Range(1, 50).Select(_ => CallbackCore()));
+ [Fact]
+ public async Task Callback()
+ {
+ for (int index = 0; index < 50; index++)
{
- ((IDisposable)_computingClient).Dispose();
- ((IDisposable)_systemClient).Dispose();
+ await CallbackCore();
((IpcProxy)_computingClient).CloseConnection();
- ((IpcProxy)_systemClient).CloseConnection();
- _host.Dispose();
- }
- [Fact]
- public Task CallbackConcurrently() => Task.WhenAll(Enumerable.Range(1, 50).Select(_ => CallbackCore()));
- [Fact]
- public async Task Callback()
- {
- for (int index = 0; index < 50; index++)
- {
- await CallbackCore();
- ((IpcProxy)_computingClient).CloseConnection();
- }
}
+ }
- private async Task CallbackCore()
+ private async Task CallbackCore()
+ {
+ var proxy = new NamedPipeClientBuilder(PipeName)
+ .SerializeParametersAsObjects().RequestTimeout(RequestTimeout).AllowImpersonation().ValidateAndBuild();
+ var message = new SystemMessage { Text = Guid.NewGuid().ToString() };
+ var computingTask = _computingClient.SendMessage(message);
+ var systemTask = _systemClient.SendMessage(message);
+ var computingBaseTask = proxy.AddFloat(1, 2);
+ await Task.WhenAll(computingTask, systemTask, computingBaseTask);
+ systemTask.Result.ShouldBe($"{Environment.UserName}_{_systemCallback.Id}_{message.Text}");
+ computingTask.Result.ShouldBe($"{Environment.UserName}_{_computingCallback.Id}_{message.Text}");
+ computingBaseTask.Result.ShouldBe(3);
+ }
+
+ [Fact]
+ public async Task MissingCallback()
+ {
+ RemoteException exception = null;
+ try
{
- var proxy = new NamedPipeClientBuilder(PipeName).RequestTimeout(RequestTimeout).AllowImpersonation().ValidateAndBuild();
- var message = new SystemMessage { Text = Guid.NewGuid().ToString() };
- var computingTask = _computingClient.SendMessage(message);
- var systemTask = _systemClient.SendMessage(message);
- var computingBaseTask = proxy.AddFloat(1, 2);
- await Task.WhenAll(computingTask, systemTask, computingBaseTask);
- systemTask.Result.ShouldBe($"{Environment.UserName}_{_systemCallback.Id}_{message.Text}");
- computingTask.Result.ShouldBe($"{Environment.UserName}_{_computingCallback.Id}_{message.Text}");
- computingBaseTask.Result.ShouldBe(3);
+ await _systemClient.MissingCallback(new SystemMessage());
}
-
- [Fact]
- public async Task MissingCallback()
+ catch (RemoteException ex)
{
- RemoteException exception = null;
- try
- {
- await _systemClient.MissingCallback(new SystemMessage());
- }
- catch (RemoteException ex)
- {
- exception = ex;
- }
- exception.Message.ShouldBe("Callback contract mismatch. Requested System.IDisposable, but it's UiPath.CoreIpc.Tests.ISystemCallback.");
- exception.Is().ShouldBeTrue();
+ exception = ex;
}
- [Fact]
- public Task CancelServerCall() => CancelServerCallCore(10);
+ exception.Message.ShouldBe("Callback contract mismatch. Requested System.IDisposable, but it's UiPath.CoreIpc.Tests.ISystemCallback.");
+ exception.Is().ShouldBeTrue();
+ }
+ [Fact]
+ public Task CancelServerCall() => CancelServerCallCore(10);
- async Task CancelServerCallCore(int counter)
+ async Task CancelServerCallCore(int counter)
+ {
+ for (int i = 0; i < counter; i++)
{
- for (int i = 0; i < counter; i++)
+ var request = new SystemMessage { RequestTimeout = Timeout.InfiniteTimeSpan, Delay = Timeout.Infinite };
+ Task sendMessageResult;
+ using (var cancellationSource = new CancellationTokenSource())
{
- var request = new SystemMessage { RequestTimeout = Timeout.InfiniteTimeSpan, Delay = Timeout.Infinite };
- Task sendMessageResult;
- using (var cancellationSource = new CancellationTokenSource())
- {
- sendMessageResult = _systemClient.MissingCallback(request, cancellationSource.Token);
- var newGuid = Guid.NewGuid();
- (await _systemClient.GetGuid(newGuid)).ShouldBe(newGuid);
- await Task.Delay(1);
- cancellationSource.Cancel();
- sendMessageResult.ShouldThrow();
- newGuid = Guid.NewGuid();
- (await _systemClient.GetGuid(newGuid)).ShouldBe(newGuid);
- }
- ((IDisposable)_systemClient).Dispose();
+ sendMessageResult = _systemClient.MissingCallback(request, cancellationSource.Token);
+ var newGuid = Guid.NewGuid();
+ (await _systemClient.GetGuid(newGuid)).ShouldBe(newGuid);
+ await Task.Delay(1);
+ cancellationSource.Cancel();
+ sendMessageResult.ShouldThrow();
+ newGuid = Guid.NewGuid();
+ (await _systemClient.GetGuid(newGuid)).ShouldBe(newGuid);
}
- }
-
- [Fact]
- public async Task DuplicateCallbackProxies()
- {
- await _systemClient.GetThreadName();
- var proxy = CreateSystemService();
- var message = proxy.GetThreadName().ShouldThrow().Message;
- message.ShouldStartWith("Duplicate callback proxy instance EndpointTests");
- message.ShouldEndWith(". Consider using a singleton callback proxy.");
+ ((IDisposable)_systemClient).Dispose();
}
}
- public interface ISystemCallback
+
+ [Fact]
+ public async Task DuplicateCallbackProxies()
{
- Task GetId(Message message = null);
+ await _systemClient.GetThreadName();
+ var proxy = CreateSystemService();
+ var message = proxy.GetThreadName().ShouldThrow().Message;
+ message.ShouldStartWith("Duplicate callback proxy instance EndpointTests");
+ message.ShouldEndWith(". Consider using a singleton callback proxy.");
}
- public class SystemCallback : ISystemCallback
+}
+public interface ISystemCallback
+{
+ Task GetId(Message message = null);
+}
+public class SystemCallback : ISystemCallback
+{
+ public string Id { get; set; }
+ public async Task GetId(Message message)
{
- public string Id { get; set; }
- public async Task GetId(Message message)
- {
- message.Client.ShouldBeNull();
- return Id;
- }
+ message.Client.ShouldBeNull();
+ return Id;
}
}
\ No newline at end of file
diff --git a/src/UiPath.CoreIpc.Tests/Implementation/ComputingCallback.cs b/src/UiPath.CoreIpc.Tests/Implementation/ComputingCallback.cs
index 169adbac..7938f812 100644
--- a/src/UiPath.CoreIpc.Tests/Implementation/ComputingCallback.cs
+++ b/src/UiPath.CoreIpc.Tests/Implementation/ComputingCallback.cs
@@ -1,23 +1,18 @@
-using Shouldly;
-using System.Threading;
-using System.Threading.Tasks;
+namespace UiPath.CoreIpc.Tests;
-namespace UiPath.CoreIpc.Tests
+public interface IComputingCallback
{
- public interface IComputingCallback
+ Task GetId(Message message);
+ Task GetThreadName();
+}
+public class ComputingCallback : IComputingCallback
+{
+ public string Id { get; set; }
+ public async Task GetId(Message message)
{
- Task GetId(Message message);
- Task GetThreadName();
+ message.Client.ShouldBeNull();
+ return Id;
}
- public class ComputingCallback : IComputingCallback
- {
- public string Id { get; set; }
- public async Task GetId(Message message)
- {
- message.Client.ShouldBeNull();
- return Id;
- }
- public async Task GetThreadName() => Thread.CurrentThread.Name;
- }
+ public async Task GetThreadName() => Thread.CurrentThread.Name;
}
\ No newline at end of file
diff --git a/src/UiPath.CoreIpc.Tests/Implementation/ComputingService.cs b/src/UiPath.CoreIpc.Tests/Implementation/ComputingService.cs
index bec2febf..908ee1f0 100644
--- a/src/UiPath.CoreIpc.Tests/Implementation/ComputingService.cs
+++ b/src/UiPath.CoreIpc.Tests/Implementation/ComputingService.cs
@@ -1,134 +1,136 @@
using Microsoft.Extensions.Logging;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-namespace UiPath.CoreIpc.Tests
+namespace UiPath.CoreIpc.Tests;
+
+public interface IInvalid : IDisposable
{
- public interface IInvalid : IDisposable
- {
- }
+}
- public interface IDuplicateMessage
- {
- Task Test(Message message1, Message message2);
- }
+public interface IDuplicateMessage
+{
+ Task Test(Message message1, Message message2);
+}
- public interface IUploadNotification
- {
- Task Upload(Stream stream);
- }
+public interface IUploadNotification
+{
+ Task Upload(Stream stream);
+}
- public interface IDerivedStreamDownload
- {
- Task Download();
- }
+public interface IDerivedStreamDownload
+{
+ Task Download();
+}
- public interface IDuplicateStreams
- {
- Task Upload(Stream stream, Stream stream2);
- }
+public interface IDuplicateStreams
+{
+ Task Upload(Stream stream, Stream stream2);
+}
- public interface IDerivedStreamUpload
- {
- Task Upload(MemoryStream stream);
- }
+public interface IDerivedStreamUpload
+{
+ Task Upload(MemoryStream stream);
+}
- public interface IMessageFirst
- {
- Task Test(Message message1, int x);
- }
+public interface IMessageFirst
+{
+ Task Test(Message message1, int x);
+}
+
+public interface IInvalidCancellationToken
+{
+ Task Test(CancellationToken token, int x);
+}
- public interface IInvalidCancellationToken
+public interface IComputingServiceBase
+{
+ Task AddFloat(float x, float y, CancellationToken cancellationToken = default);
+}
+public interface IComputingService : IComputingServiceBase
+{
+ Task AddComplexNumber(ComplexNumber x, ComplexNumber y, CancellationToken cancellationToken = default);
+ Task AddComplexNumbers(IEnumerable numbers, CancellationToken cancellationToken = default);
+ Task SendMessage(SystemMessage message, CancellationToken cancellationToken = default);
+ Task Infinite(CancellationToken cancellationToken = default);
+ Task InfiniteVoid(CancellationToken cancellationToken = default);
+ Task GetCallbackThreadName(Message message = null, CancellationToken cancellationToken = default);
+}
+
+public struct ComplexNumber
+{
+ public float A { get; set; }
+ public float B { get; set; }
+
+ public ComplexNumber(float a, float b)
{
- Task Test(CancellationToken token, int x);
+ A = a;
+ B = b;
}
+}
+
+public enum TextStyle
+{
+ TitleCase,
+ Upper
+}
- public interface IComputingServiceBase
+public class ConvertTextArgs
+{
+ public TextStyle TextStyle { get; set; } = TextStyle.Upper;
+
+ public string Text { get; set; } = string.Empty;
+}
+
+public class ComputingService : IComputingService
+{
+ private readonly ILogger _logger;
+
+ public ComputingService(ILogger logger) // inject dependencies in constructor
{
- Task AddFloat(float x, float y, CancellationToken cancellationToken = default);
+ _logger = logger;
}
- public interface IComputingService : IComputingServiceBase
+
+ public async Task AddComplexNumber(ComplexNumber x, ComplexNumber y, CancellationToken cancellationToken = default)
{
- Task AddComplexNumber(ComplexNumber x, ComplexNumber y, CancellationToken cancellationToken = default);
- Task AddComplexNumbers(IEnumerable numbers, CancellationToken cancellationToken = default);
- Task SendMessage(SystemMessage message, CancellationToken cancellationToken = default);
- Task Infinite(CancellationToken cancellationToken = default);
- Task InfiniteVoid(CancellationToken cancellationToken = default);
- Task GetCallbackThreadName(Message message = null, CancellationToken cancellationToken = default);
+ _logger.LogInformation($"{nameof(AddComplexNumber)} called.");
+ return new ComplexNumber(x.A + y.A, x.B + y.B);
}
- public struct ComplexNumber
+ public async Task AddComplexNumbers(IEnumerable numbers, CancellationToken cancellationToken = default)
{
- public float A { get; set; }
- public float B { get; set; }
-
- public ComplexNumber(float a, float b)
+ _logger.LogInformation($"{nameof(AddComplexNumbers)} called.");
+ var result = new ComplexNumber(0, 0);
+ foreach (ComplexNumber number in numbers)
{
- A = a;
- B = b;
+ result = new ComplexNumber(result.A + number.A, result.B + number.B);
}
+ return result;
}
- public enum TextStyle
+ public async Task AddFloat(float x, float y, CancellationToken cancellationToken = default)
{
- TitleCase,
- Upper
+ //Trace.WriteLine($"{nameof(AddFloat)} called.");
+ _logger.LogInformation($"{nameof(AddFloat)} called.");
+ return x + y;
}
- public class ComputingService : IComputingService
- {
- private readonly ILogger _logger;
- public ComputingService(ILogger logger) // inject dependencies in constructor
- {
- _logger = logger;
- }
-
- public async Task AddComplexNumber(ComplexNumber x, ComplexNumber y, CancellationToken cancellationToken = default)
- {
- _logger.LogInformation($"{nameof(AddComplexNumber)} called.");
- return new ComplexNumber(x.A + y.A, x.B + y.B);
- }
-
- public async Task AddComplexNumbers(IEnumerable numbers, CancellationToken cancellationToken = default)
- {
- _logger.LogInformation($"{nameof(AddComplexNumbers)} called.");
- var result = new ComplexNumber(0, 0);
- foreach (ComplexNumber number in numbers)
- {
- result = new ComplexNumber(result.A + number.A, result.B + number.B);
- }
- return result;
- }
-
- public async Task AddFloat(float x, float y, CancellationToken cancellationToken = default)
- {
- //Trace.WriteLine($"{nameof(AddFloat)} called.");
- _logger.LogInformation($"{nameof(AddFloat)} called.");
- return x + y;
- }
-
- public async Task Infinite(CancellationToken cancellationToken = default)
- {
- await Task.Delay(Timeout.Infinite, cancellationToken);
- return true;
- }
+ public async Task Infinite(CancellationToken cancellationToken = default)
+ {
+ await Task.Delay(Timeout.Infinite, cancellationToken);
+ return true;
+ }
- public Task InfiniteVoid(CancellationToken cancellationToken = default) =>Task.Delay(Timeout.Infinite, cancellationToken);
+ public Task InfiniteVoid(CancellationToken cancellationToken = default) =>Task.Delay(Timeout.Infinite, cancellationToken);
- public async Task SendMessage(SystemMessage message, CancellationToken cancellationToken = default)
- {
- await Task.Delay(message.Delay, cancellationToken);
- var client = message.Client;
- var callback = message.GetCallback();
- var clientId = await callback.GetId(message);
- string returnValue = "";
- client.Impersonate(() => returnValue = client.GetUserName() + "_" + clientId + "_" + message.Text);
- return returnValue;
- }
-
- public async Task GetCallbackThreadName(Message message, CancellationToken cancellationToken = default) => await message.GetCallback().GetThreadName();
+ public async Task SendMessage(SystemMessage message, CancellationToken cancellationToken = default)
+ {
+ await Task.Delay(message.Delay, cancellationToken);
+ var client = message.Client;
+ var callback = message.GetCallback();
+ var clientId = await callback.GetId(message);
+ string returnValue = "";
+ client.Impersonate(() => returnValue = client.GetUserName() + "_" + clientId + "_" + message.Text);
+ return returnValue;
}
+
+ public async Task GetCallbackThreadName(Message message, CancellationToken cancellationToken = default) => await message.GetCallback().GetThreadName();
}
\ No newline at end of file
diff --git a/src/UiPath.CoreIpc.Tests/Implementation/IpcHelpers.cs b/src/UiPath.CoreIpc.Tests/Implementation/IpcHelpers.cs
index 389cb15d..41a9292f 100644
--- a/src/UiPath.CoreIpc.Tests/Implementation/IpcHelpers.cs
+++ b/src/UiPath.CoreIpc.Tests/Implementation/IpcHelpers.cs
@@ -1,56 +1,77 @@
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using System;
-using System.Diagnostics;
-using System.Linq;
+using Microsoft.Extensions.Logging;
+using System.Net;
+using System.Net.WebSockets;
using UiPath.CoreIpc.Tests;
-namespace UiPath.CoreIpc
+namespace UiPath.CoreIpc;
+
+public static class IpcHelpers
{
- public static class IpcHelpers
+ public static TInterface ValidateAndBuild(this ServiceClientBuilder builder) where TInterface : class where TDerived : ServiceClientBuilder
{
- public static TInterface ValidateAndBuild(this ServiceClientBuilder builder) where TInterface : class where TDerived : ServiceClientBuilder
- {
#if DEBUG
- Validator.Validate(builder);
+ Validator.Validate(builder);
#endif
- return builder.Build();
- }
- public static ServiceHost ValidateAndBuild(this ServiceHostBuilder serviceHostBuilder)
- {
+ return builder.Build();
+ }
+ public static ServiceHost ValidateAndBuild(this ServiceHostBuilder serviceHostBuilder)
+ {
#if DEBUG
- Validator.Validate(serviceHostBuilder);
+ Validator.Validate(serviceHostBuilder);
#endif
- return serviceHostBuilder.Build();
- }
- public static IServiceProvider ConfigureServices() =>
- new ServiceCollection()
- .AddLogging(b => b.AddTraceSource(new SourceSwitch("", "All")))
- .AddIpc()
- .AddSingleton()
- .AddSingleton()
- .AddSingleton()
- .BuildServiceProvider();
- public static string GetUserName(this IClient client)
+ return serviceHostBuilder.Build();
+ }
+ public static IServiceProvider ConfigureServices() =>
+ new ServiceCollection()
+ .AddLogging(b => b.AddTraceSource(new SourceSwitch("", "All")))
+ .AddIpc()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .BuildServiceProvider();
+ public static string GetUserName(this IClient client)
+ {
+ string userName = null;
+ client.Impersonate(() => userName = Environment.UserName);
+ return userName;
+ }
+ public static IServiceCollection AddIpcWithLogging(this IServiceCollection services, bool logToConsole = false)
+ {
+ services.AddLogging(builder =>
{
- string userName = null;
- client.Impersonate(() => userName = Environment.UserName);
- return userName;
- }
- public static IServiceCollection AddIpcWithLogging(this IServiceCollection services, bool logToConsole = false)
+ //if (logToConsole)
+ //{
+ // builder.AddConsole();
+ //}
+ //foreach (var listener in Trace.Listeners.Cast().Where(l => !(l is DefaultTraceListener)))
+ //{
+ // builder.AddTraceSource(new SourceSwitch(listener.Name, "All"), listener);
+ //}
+ });
+ return services.AddIpc();
+ }
+}
+public class HttpSysWebSocketsListener : IDisposable
+{
+ HttpListener _httpListener = new();
+ public HttpSysWebSocketsListener(string uriPrefix)
+ {
+ _httpListener.Prefixes.Add(uriPrefix);
+ _httpListener.Start();
+ }
+ public async Task Accept(CancellationToken token)
+ {
+ while (true)
{
- services.AddLogging(builder =>
+ var listenerContext = await _httpListener.GetContextAsync();
+ if (listenerContext.Request.IsWebSocketRequest)
{
- if (logToConsole)
- {
- builder.AddConsole();
- }
- foreach(var listener in Trace.Listeners.Cast().Where(l => !(l is DefaultTraceListener)))
- {
- builder.AddTraceSource(new SourceSwitch(listener.Name, "All"), listener);
- }
- });
- return services.AddIpc();
+ var webSocketContext = await listenerContext.AcceptWebSocketAsync(subProtocol: null);
+ return webSocketContext.WebSocket;
+ }
+ listenerContext.Response.StatusCode = 400;
+ listenerContext.Response.Close();
}
}
+ public void Dispose() => _httpListener.Stop();
}
\ No newline at end of file
diff --git a/src/UiPath.CoreIpc.Tests/Implementation/OneWayStreamWrapper.cs b/src/UiPath.CoreIpc.Tests/Implementation/OneWayStreamWrapper.cs
index ec230fda..b63c41c6 100644
--- a/src/UiPath.CoreIpc.Tests/Implementation/OneWayStreamWrapper.cs
+++ b/src/UiPath.CoreIpc.Tests/Implementation/OneWayStreamWrapper.cs
@@ -1,109 +1,104 @@
// Copyright (c) Andrew Arnott. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-using System;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-namespace UiPath.CoreIpc.Tests
+namespace UiPath.CoreIpc.Tests;
+
+internal class OneWayStreamWrapper : Stream
{
- internal class OneWayStreamWrapper : Stream
- {
- private readonly Stream innerStream;
- private readonly bool canRead;
- private readonly bool canWrite;
+ private readonly Stream innerStream;
+ private readonly bool canRead;
+ private readonly bool canWrite;
- internal OneWayStreamWrapper(Stream innerStream, bool canRead = false, bool canWrite = false)
+ internal OneWayStreamWrapper(Stream innerStream, bool canRead = false, bool canWrite = false)
+ {
+ if (canRead == canWrite)
{
- if (canRead == canWrite)
- {
- throw new ArgumentException("Exactly one operation (read or write) must be true.");
- }
- this.innerStream = innerStream ?? throw new ArgumentNullException(nameof(innerStream));
- this.canRead = canRead;
- this.canWrite = canWrite;
+ throw new ArgumentException("Exactly one operation (read or write) must be true.");
}
+ this.innerStream = innerStream ?? throw new ArgumentNullException(nameof(innerStream));
+ this.canRead = canRead;
+ this.canWrite = canWrite;
+ }
- public override bool CanRead => this.canRead && this.innerStream.CanRead;
+ public override bool CanRead => this.canRead && this.innerStream.CanRead;
- public override bool CanSeek => false;
+ public override bool CanSeek => false;
- public override bool CanWrite => this.canWrite && this.innerStream.CanWrite;
+ public override bool CanWrite => this.canWrite && this.innerStream.CanWrite;
- public override long Length => throw new NotSupportedException();
+ public override long Length => throw new NotSupportedException();
- public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
+ public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
- public override void Flush()
+ public override void Flush()
+ {
+ if (this.CanWrite)
+ {
+ this.innerStream.Flush();
+ }
+ else
{
- if (this.CanWrite)
- {
- this.innerStream.Flush();
- }
- else
- {
- throw new NotSupportedException();
- }
+ throw new NotSupportedException();
}
+ }
- public override int Read(byte[] buffer, int offset, int count)
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ if (this.CanRead)
+ {
+ return this.innerStream.Read(buffer, offset, count);
+ }
+ else
{
- if (this.CanRead)
- {
- return this.innerStream.Read(buffer, offset, count);
- }
- else
- {
- throw new NotSupportedException();
- }
+ throw new NotSupportedException();
}
+ }
- public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ if (this.CanRead)
{
- if (this.CanRead)
- {
- return this.innerStream.ReadAsync(buffer, offset, count, cancellationToken);
- }
- else
- {
- throw new NotSupportedException();
- }
+ return this.innerStream.ReadAsync(buffer, offset, count, cancellationToken);
}
+ else
+ {
+ throw new NotSupportedException();
+ }
+ }
- public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
+ public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
- public override void SetLength(long value) => throw new NotSupportedException();
+ public override void SetLength(long value) => throw new NotSupportedException();
- public override void Write(byte[] buffer, int offset, int count)
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ if (this.CanWrite)
+ {
+ this.innerStream.Write(buffer, offset, count);
+ }
+ else
{
- if (this.CanWrite)
- {
- this.innerStream.Write(buffer, offset, count);
- }
- else
- {
- throw new NotSupportedException();
- }
+ throw new NotSupportedException();
}
+ }
- public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ if (this.CanWrite)
+ {
+ return this.innerStream.WriteAsync(buffer, offset, count, cancellationToken);
+ }
+ else
{
- if (this.CanWrite)
- {
- return this.innerStream.WriteAsync(buffer, offset, count, cancellationToken);
- }
- else
- {
- throw new NotSupportedException();
- }
+ throw new NotSupportedException();
}
+ }
- protected override void Dispose(bool disposing)
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
{
- if (disposing)
- {
- this.innerStream.Dispose();
- }
+ this.innerStream.Dispose();
}
}
}
\ No newline at end of file
diff --git a/src/UiPath.CoreIpc.Tests/Implementation/SystemService.cs b/src/UiPath.CoreIpc.Tests/Implementation/SystemService.cs
index f724f98c..049f4e36 100644
--- a/src/UiPath.CoreIpc.Tests/Implementation/SystemService.cs
+++ b/src/UiPath.CoreIpc.Tests/Implementation/SystemService.cs
@@ -1,179 +1,175 @@
-using System;
-using System.Diagnostics;
-using System.Globalization;
-using System.IO;
-using System.Linq;
+using System.Globalization;
using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-namespace UiPath.CoreIpc.Tests
+namespace UiPath.CoreIpc.Tests;
+
+public interface ISystemService
+{
+ Task DoNothing(CancellationToken cancellationToken = default);
+ Task VoidThreadName(CancellationToken cancellationToken = default);
+ Task VoidSyncThrow(CancellationToken cancellationToken = default);
+ Task GetThreadName(CancellationToken cancellationToken = default);
+ Task ConvertText(string text, TextStyle style, CancellationToken cancellationToken = default);
+ Task ConvertTextWithArgs(ConvertTextArgs args, CancellationToken cancellationToken = default);
+ Task GetGuid(Guid guid, CancellationToken cancellationToken = default);
+ Task ReverseBytes(byte[] input, CancellationToken cancellationToken = default);
+ Task SlowOperation(CancellationToken cancellationToken = default);
+ Task MissingCallback(SystemMessage message, CancellationToken cancellationToken = default);
+ Task Infinite(CancellationToken cancellationToken = default);
+ Task ImpersonateCaller(Message message = null, CancellationToken cancellationToken = default);
+ Task SendMessage(SystemMessage message, CancellationToken cancellationToken = default);
+ Task Upload(Stream stream, int delay = 0, CancellationToken cancellationToken = default);
+ Task Download(string text, CancellationToken cancellationToken = default);
+ Task Echo(Stream input, CancellationToken cancellationToken = default);
+ Task UploadNoRead(Stream memoryStream, int delay = 0, CancellationToken cancellationToken = default);
+}
+
+public class SystemMessage : Message
{
- public interface ISystemService
+ public string Text { get; set; }
+ public int Delay { get; set; }
+}
+public class SystemService : ISystemService
+{
+ public SystemService()
{
- Task DoNothing(CancellationToken cancellationToken = default);
- Task VoidThreadName(CancellationToken cancellationToken = default);
- Task VoidSyncThrow(CancellationToken cancellationToken = default);
- Task GetThreadName(CancellationToken cancellationToken = default);
- Task ConvertText(string text, TextStyle style, CancellationToken cancellationToken = default);
- Task GetGuid(Guid guid, CancellationToken cancellationToken = default);
- Task ReverseBytes(byte[] input, CancellationToken cancellationToken = default);
- Task SlowOperation(CancellationToken cancellationToken = default);
- Task MissingCallback(SystemMessage message, CancellationToken cancellationToken = default);
- Task Infinite(CancellationToken cancellationToken = default);
- Task ImpersonateCaller(Message message = null, CancellationToken cancellationToken = default);
- Task SendMessage(SystemMessage message, CancellationToken cancellationToken = default);
- Task Upload(Stream stream, int delay = 0, CancellationToken cancellationToken = default);
- Task Download(string text, CancellationToken cancellationToken = default);
- Task Echo(Stream input, CancellationToken cancellationToken = default);
- Task UploadNoRead(Stream memoryStream, int delay = 0, CancellationToken cancellationToken = default);
}
- public class SystemMessage : Message
+ public async Task Infinite(CancellationToken cancellationToken = default)
{
- public string Text { get; set; }
- public int Delay { get; set; }
+ await Task.Delay(Timeout.Infinite, cancellationToken);
+ return true;
}
- public class SystemService : ISystemService
- {
- public SystemService()
- {
- }
-
- public async Task Infinite(CancellationToken cancellationToken = default)
- {
- await Task.Delay(Timeout.Infinite, cancellationToken);
- return true;
- }
+ public async Task ConvertTextWithArgs(ConvertTextArgs args, CancellationToken cancellationToken = default)
+ => await ConvertText(args.Text, args.TextStyle, cancellationToken);
- public async Task ConvertText(string text, TextStyle style, CancellationToken cancellationToken = default)
+ public async Task ConvertText(string text, TextStyle style, CancellationToken cancellationToken = default)
+ {
+ switch (style)
{
- switch (style)
- {
- case TextStyle.TitleCase:
- return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(text);
- case TextStyle.Upper:
- return CultureInfo.InvariantCulture.TextInfo.ToUpper(text);
- default:
- return text;
- }
+ case TextStyle.TitleCase:
+ return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(text);
+ case TextStyle.Upper:
+ return CultureInfo.InvariantCulture.TextInfo.ToUpper(text);
+ default:
+ return text;
}
+ }
- public async Task SendMessage(SystemMessage message, CancellationToken cancellationToken = default)
- {
- var client = message.Client;
- var callback = message.GetCallback();
- var clientId = await callback.GetId(message);
- string returnValue = "";
- client.Impersonate(() => returnValue = client.GetUserName() + "_" + clientId + "_" + message.Text);
- return returnValue;
- }
+ public async Task SendMessage(SystemMessage message, CancellationToken cancellationToken = default)
+ {
+ var client = message.Client;
+ var callback = message.GetCallback();
+ var clientId = await callback.GetId(message);
+ string returnValue = "";
+ client.Impersonate(() => returnValue = client.GetUserName() + "_" + clientId + "_" + message.Text);
+ return returnValue;
+ }
- public bool DidNothing { get; set; }
+ public bool DidNothing { get; set; }
- public async Task DoNothing(CancellationToken cancellationToken = default)
- {
- const int Timeout =
+ public async Task DoNothing(CancellationToken cancellationToken = default)
+ {
+ const int Timeout =
#if CI
- 100;
+ 100;
#else
- 10;
+ 10;
#endif
- await Task.Delay(Timeout);
- DidNothing = true;
- }
+ await Task.Delay(Timeout);
+ DidNothing = true;
+ }
- public async Task GetGuid(Guid guid, CancellationToken cancellationToken = default)
- {
- //throw new Exception("sssss");
- return guid;
- }
+ public async Task GetGuid(Guid guid, CancellationToken cancellationToken = default)
+ {
+ //throw new Exception("sssss");
+ return guid;
+ }
- public async Task ReverseBytes(byte[] input, CancellationToken cancellationToken = default)
- {
- return input.Reverse().ToArray();
- }
+ public async Task ReverseBytes(byte[] input, CancellationToken cancellationToken = default)
+ {
+ return input.Reverse().ToArray();
+ }
- public async Task MissingCallback(SystemMessage message, CancellationToken cancellationToken = default)
+ public async Task MissingCallback(SystemMessage message, CancellationToken cancellationToken = default)
+ {
+ if (message.Delay != 0)
{
- if (message.Delay != 0)
- {
- await Task.Delay(message.Delay, cancellationToken);
- }
- var domainName = "";
- var client = message.Client;
- //client.RunAs(() => domainName = "test");
- //try
- //{
- message.GetCallback();
- //}
- //catch(Exception ex)
- //{
- // Console.WriteLine(ex.ToString());
- //}
- return client.GetUserName() +" " + domainName;
+ await Task.Delay(message.Delay, cancellationToken);
}
+ var domainName = "";
+ var client = message.Client;
+ //client.RunAs(() => domainName = "test");
+ //try
+ //{
+ message.GetCallback();
+ //}
+ //catch(Exception ex)
+ //{
+ // Console.WriteLine(ex.ToString());
+ //}
+ return client.GetUserName() +" " + domainName;
+ }
- public async Task SlowOperation(CancellationToken cancellationToken = default)
+ public async Task SlowOperation(CancellationToken cancellationToken = default)
+ {
+ Console.WriteLine("SlowOperation " + Thread.CurrentThread.Name);
+ try
{
- Console.WriteLine("SlowOperation " + Thread.CurrentThread.Name);
- try
+ for(int i = 0; i < 5; i++)
{
- for(int i = 0; i < 5; i++)
+ await Task.Delay(1000, cancellationToken);
+ Console.WriteLine("SlowOperation "+Thread.CurrentThread.Name);
+ if(cancellationToken.IsCancellationRequested)
{
- await Task.Delay(1000, cancellationToken);
- Console.WriteLine("SlowOperation "+Thread.CurrentThread.Name);
- if(cancellationToken.IsCancellationRequested)
- {
- Console.WriteLine("SlowOperation Cancelled.");
- return false;
- }
+ Console.WriteLine("SlowOperation Cancelled.");
+ return false;
}
}
- catch(Exception ex)
- {
- Console.WriteLine(ex.ToString());
- }
- Console.WriteLine("SlowOperation finished. "+ (cancellationToken.IsCancellationRequested ? "cancelled " : "") + Thread.CurrentThread.Name);
- return true;
}
+ catch(Exception ex)
+ {
+ Console.WriteLine(ex.ToString());
+ }
+ Console.WriteLine("SlowOperation finished. "+ (cancellationToken.IsCancellationRequested ? "cancelled " : "") + Thread.CurrentThread.Name);
+ return true;
+ }
- public string ThreadName;
+ public string ThreadName;
- public Task VoidSyncThrow(CancellationToken cancellationToken = default) => throw new NotImplementedException();
+ public Task VoidSyncThrow(CancellationToken cancellationToken = default) => throw new NotImplementedException();
- public async Task VoidThreadName(CancellationToken cancellationToken = default) => ThreadName = Thread.CurrentThread.Name;
+ public async Task VoidThreadName(CancellationToken cancellationToken = default) => ThreadName = Thread.CurrentThread.Name;
- public async Task GetThreadName(CancellationToken cancellationToken = default) => Thread.CurrentThread.Name;
+ public async Task GetThreadName(CancellationToken cancellationToken = default) => Thread.CurrentThread.Name;
- public async Task ImpersonateCaller(Message message = null, CancellationToken cancellationToken = default)
- {
- var client = message.Client;
- string returnValue = "";
- client.Impersonate(() => returnValue = client.GetUserName());
- return returnValue;
- }
+ public async Task ImpersonateCaller(Message message = null, CancellationToken cancellationToken = default)
+ {
+ var client = message.Client;
+ string returnValue = "";
+ client.Impersonate(() => returnValue = client.GetUserName());
+ return returnValue;
+ }
- public async Task Upload(Stream stream, int delay = 0, CancellationToken cancellationToken = default)
- {
- await Task.Delay(delay);
- return await new StreamReader(stream).ReadToEndAsync();
- }
+ public async Task Upload(Stream stream, int delay = 0, CancellationToken cancellationToken = default)
+ {
+ await Task.Delay(delay);
+ return await new StreamReader(stream).ReadToEndAsync();
+ }
- public async Task UploadNoRead(Stream stream, int delay = 0, CancellationToken cancellationToken = default)
- {
- await Task.Delay(delay);
- return "";
- }
+ public async Task UploadNoRead(Stream stream, int delay = 0, CancellationToken cancellationToken = default)
+ {
+ await Task.Delay(delay);
+ return "";
+ }
- public async Task Download(string text, CancellationToken cancellationToken = default) => new MemoryStream(Encoding.UTF8.GetBytes(text));
+ public async Task Download(string text, CancellationToken cancellationToken = default) => new MemoryStream(Encoding.UTF8.GetBytes(text));
- public async Task Echo(Stream input, CancellationToken cancellationToken = default)
- {
- var result = new MemoryStream();
- await input.CopyToAsync(result);
- result.Position = 0;
- return result;
- }
+ public async Task Echo(Stream input, CancellationToken cancellationToken = default)
+ {
+ var result = new MemoryStream();
+ await input.CopyToAsync(result);
+ result.Position = 0;
+ return result;
}
}
\ No newline at end of file
diff --git a/src/UiPath.CoreIpc.Tests/NamedPipeTests.cs b/src/UiPath.CoreIpc.Tests/NamedPipeTests.cs
index 8b59da38..e81f1eaa 100644
--- a/src/UiPath.CoreIpc.Tests/NamedPipeTests.cs
+++ b/src/UiPath.CoreIpc.Tests/NamedPipeTests.cs
@@ -1,60 +1,53 @@
-using System;
-using System.IO.Pipes;
+using System.IO.Pipes;
using System.Security.Principal;
-using System.Threading.Tasks;
-using Shouldly;
-using UiPath.CoreIpc.NamedPipe;
-using Xunit;
-namespace UiPath.CoreIpc.Tests
+namespace UiPath.CoreIpc.Tests;
+
+public class SystemNamedPipeTests : SystemTests>
{
- public class SystemNamedPipeTests : SystemTests>
+ string _pipeName = "system";
+ protected override ServiceHostBuilder Configure(ServiceHostBuilder serviceHostBuilder) =>
+ serviceHostBuilder.UseNamedPipes(Configure(new NamedPipeSettings(_pipeName+GetHashCode())));
+ protected override NamedPipeClientBuilder CreateSystemClientBuilder() =>
+ new NamedPipeClientBuilder(_pipeName+GetHashCode()).AllowImpersonation();
+ [Fact]
+ public void PipeExists()
{
- string _pipeName = "system";
- protected override ServiceHostBuilder Configure(ServiceHostBuilder serviceHostBuilder) =>
- serviceHostBuilder.UseNamedPipes(Configure(new NamedPipeSettings(_pipeName+GetHashCode())));
- protected override NamedPipeClientBuilder CreateSystemClientBuilder() =>
- new NamedPipeClientBuilder(_pipeName+GetHashCode()).AllowImpersonation();
- [Fact]
- public void PipeExists()
- {
- IOHelpers.PipeExists(System.Guid.NewGuid().ToString()).ShouldBeFalse();
- IOHelpers.PipeExists("system"+GetHashCode(), 30).ShouldBeTrue();
- }
- [Fact]
- public Task ServerName() => SystemClientBuilder().ServerName(Environment.MachineName).ValidateAndBuild().GetGuid(System.Guid.Empty);
- [Fact]
- public override void BeforeCallServerSide()
- {
- _pipeName = "beforeCall";
- base.BeforeCallServerSide();
- }
-#if WINDOWS
- [Fact]
- public async Task PipeSecurityForWindows()
- {
- _pipeName = "protected";
- using var protectedService = new ServiceHostBuilder(_serviceProvider)
- .UseNamedPipes(Configure(new NamedPipeSettings(_pipeName+GetHashCode())
- {
- AccessControl = pipeSecurity => pipeSecurity.Deny(WellKnownSidType.WorldSid, PipeAccessRights.FullControl)
- }))
- .AddEndpoint()
- .ValidateAndBuild();
- _ = protectedService.RunAsync();
- await CreateSystemService().DoNothing().ShouldThrowAsync();
- }
-#endif
+ IOHelpers.PipeExists(System.Guid.NewGuid().ToString()).ShouldBeFalse();
+ IOHelpers.PipeExists("system"+GetHashCode(), 50).ShouldBeTrue();
}
- public class ComputingNamedPipeTests : ComputingTests>
+ [Fact]
+ public Task ServerName() => SystemClientBuilder().ValidateAndBuild().GetGuid(System.Guid.Empty);
+ [Fact]
+ public override void BeforeCallServerSide()
{
- protected override ServiceHostBuilder Configure(ServiceHostBuilder serviceHostBuilder) =>
- serviceHostBuilder.UseNamedPipes(Configure(new NamedPipeSettings("computing"+GetHashCode()){ EncryptAndSign = true }));
- protected override NamedPipeClientBuilder ComputingClientBuilder(TaskScheduler taskScheduler = null) =>
- new NamedPipeClientBuilder("computing" + GetHashCode(), _serviceProvider)
- .AllowImpersonation()
- .EncryptAndSign()
- .RequestTimeout(RequestTimeout)
- .CallbackInstance(_computingCallback)
- .TaskScheduler(taskScheduler);
+ _pipeName = "beforeCall";
+ base.BeforeCallServerSide();
}
+#if WINDOWS
+ [Fact]
+ public async Task PipeSecurityForWindows()
+ {
+ _pipeName = "protected";
+ using var protectedService = new ServiceHostBuilder(_serviceProvider)
+ .UseNamedPipes(Configure(new NamedPipeSettings(_pipeName+GetHashCode())
+ {
+ AccessControl = pipeSecurity => pipeSecurity.Deny(WellKnownSidType.WorldSid, PipeAccessRights.FullControl)
+ }))
+ .AddEndpoint()
+ .ValidateAndBuild();
+ _ = protectedService.RunAsync();
+ await CreateSystemService().DoNothing().ShouldThrowAsync();
+ }
+#endif
+}
+public class ComputingNamedPipeTests : ComputingTests>
+{
+ protected override ServiceHostBuilder Configure(ServiceHostBuilder serviceHostBuilder) =>
+ serviceHostBuilder.UseNamedPipes(Configure(new NamedPipeSettings("computing" + GetHashCode())));
+ protected override NamedPipeClientBuilder ComputingClientBuilder(TaskScheduler taskScheduler = null) =>
+ new NamedPipeClientBuilder("computing" + GetHashCode(), _serviceProvider)
+ .AllowImpersonation()
+ .RequestTimeout(RequestTimeout)
+ .CallbackInstance(_computingCallback)
+ .TaskScheduler(taskScheduler);
}
\ No newline at end of file
diff --git a/src/UiPath.CoreIpc.Tests/NestedStreamTests.cs b/src/UiPath.CoreIpc.Tests/NestedStreamTests.cs
index 97a73415..b30d6f93 100644
--- a/src/UiPath.CoreIpc.Tests/NestedStreamTests.cs
+++ b/src/UiPath.CoreIpc.Tests/NestedStreamTests.cs
@@ -1,378 +1,370 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.IO.Compression;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Xunit;
-
-namespace UiPath.CoreIpc.Tests
+using System.IO.Compression;
+
+namespace UiPath.CoreIpc.Tests;
+
+public class NestedStreamTests
{
- public class NestedStreamTests
- {
- private const int DefaultNestedLength = 10;
+ private const int DefaultNestedLength = 10;
- private MemoryStream underlyingStream;
+ private MemoryStream underlyingStream;
- private NestedStream stream;
+ private NestedStream stream;
- protected static readonly TimeSpan UnexpectedTimeout = Debugger.IsAttached ? Timeout.InfiniteTimeSpan : TimeSpan.FromSeconds(10);
+ protected static readonly TimeSpan UnexpectedTimeout = Debugger.IsAttached ? Timeout.InfiniteTimeSpan : TimeSpan.FromSeconds(10);
- private readonly CancellationTokenSource _timeoutTokenSource = new(UnexpectedTimeout);
+ private readonly CancellationTokenSource _timeoutTokenSource = new(UnexpectedTimeout);
- public NestedStreamTests()
- {
- var random = new Random();
- var buffer = new byte[20];
- random.NextBytes(buffer);
- this.underlyingStream = new MemoryStream(buffer);
- this.stream = this.underlyingStream.ReadSlice(DefaultNestedLength);
- }
+ public NestedStreamTests()
+ {
+ var random = new Random();
+ var buffer = new byte[20];
+ random.NextBytes(buffer);
+ this.underlyingStream = new MemoryStream(buffer);
+ this.stream = this.underlyingStream.ReadSlice(DefaultNestedLength);
+ }
- protected CancellationToken TimeoutToken => Debugger.IsAttached ? CancellationToken.None : _timeoutTokenSource.Token;
+ protected CancellationToken TimeoutToken => Debugger.IsAttached ? CancellationToken.None : _timeoutTokenSource.Token;
- [Fact]
- public void CanSeek()
- {
- Assert.True(this.stream.CanSeek);
- this.stream.Dispose();
- Assert.False(this.stream.CanSeek);
- }
+ [Fact]
+ public void CanSeek()
+ {
+ Assert.True(this.stream.CanSeek);
+ this.stream.Dispose();
+ Assert.False(this.stream.CanSeek);
+ }
- [Fact]
- public void CanSeek_NonSeekableStream()
- {
- using var gzipStream = new GZipStream(Stream.Null, CompressionMode.Decompress);
- using var stream = gzipStream.ReadSlice(10);
+ [Fact]
+ public void CanSeek_NonSeekableStream()
+ {
+ using var gzipStream = new GZipStream(Stream.Null, CompressionMode.Decompress);
+ using var stream = gzipStream.ReadSlice(10);
- Assert.False(stream.CanSeek);
- stream.Dispose();
- Assert.False(stream.CanSeek);
- }
+ Assert.False(stream.CanSeek);
+ stream.Dispose();
+ Assert.False(stream.CanSeek);
+ }
- [Fact]
- public void Length()
- {
- Assert.Equal(DefaultNestedLength, this.stream.Length);
- }
+ [Fact]
+ public void Length()
+ {
+ Assert.Equal(DefaultNestedLength, this.stream.Length);
+ }
- [Fact]
- public void Length_NonSeekableStream()
+ [Fact]
+ public void Length_NonSeekableStream()
+ {
+ using (var gzipStream = new GZipStream(Stream.Null, CompressionMode.Decompress))
+ using (var stream = gzipStream.ReadSlice(10))
{
- using (var gzipStream = new GZipStream(Stream.Null, CompressionMode.Decompress))
- using (var stream = gzipStream.ReadSlice(10))
- {
- Assert.Throws(() => stream.Length);
- }
+ stream.Length.ShouldBe(10);
}
+ }
- [Fact]
- public void Position()
- {
- byte[] buffer = new byte[DefaultNestedLength];
-
- Assert.Equal(0, this.stream.Position);
- var bytesRead = this.stream.Read(buffer, 0, 5);
- Assert.Equal(bytesRead, this.stream.Position);
+ [Fact]
+ public void Position()
+ {
+ byte[] buffer = new byte[DefaultNestedLength];
- this.stream.Position = 0;
- byte[] buffer2 = new byte[DefaultNestedLength];
- bytesRead = this.stream.Read(buffer2, 0, 5);
- Assert.Equal(bytesRead, this.stream.Position);
- Assert.Equal(buffer, buffer2);
- }
+ Assert.Equal(0, this.stream.Position);
+ var bytesRead = this.stream.Read(buffer, 0, 5);
+ Assert.Equal(bytesRead, this.stream.Position);
- [Fact]
- public void Position_NonSeekableStream()
- {
- using var nonSeekableWrapper = new OneWayStreamWrapper(this.underlyingStream, canRead: true);
- using var stream = nonSeekableWrapper.ReadSlice(10);
-
- Assert.Equal(0, stream.Position);
- Assert.Throws(() => stream.Position = 3);
- Assert.Equal(0, stream.Position);
- stream.ReadByte();
- Assert.Equal(1, stream.Position);
- }
-
- [Fact]
- public void IsDisposed()
- {
- Assert.False(stream.IsDisposed);
- this.stream.Dispose();
- Assert.True(stream.IsDisposed);
- }
+ this.stream.Position = 0;
+ byte[] buffer2 = new byte[DefaultNestedLength];
+ bytesRead = this.stream.Read(buffer2, 0, 5);
+ Assert.Equal(bytesRead, this.stream.Position);
+ Assert.Equal(buffer, buffer2);
+ }
- [Fact]
- public void Dispose_IncompleteDisposesUnderylingStream()
- {
- this.stream.Dispose();
- Assert.False(this.underlyingStream.CanSeek);
- }
+ [Fact]
+ public void Position_NonSeekableStream()
+ {
+ using var nonSeekableWrapper = new OneWayStreamWrapper(this.underlyingStream, canRead: true);
+ using var stream = nonSeekableWrapper.ReadSlice(10);
+
+ Assert.Equal(0, stream.Position);
+ Assert.Throws(() => stream.Position = 3);
+ Assert.Equal(0, stream.Position);
+ stream.ReadByte();
+ Assert.Equal(1, stream.Position);
+ }
- [Fact]
- public void Dispose_DoesNotDisposeUnderylingStream()
- {
- this.stream.Read(new byte[DefaultNestedLength], 0, DefaultNestedLength);
- this.stream.Dispose();
- Assert.True(this.underlyingStream.CanSeek);
- // A sanity check that if it were disposed, our assertion above would fail.
- this.underlyingStream.Dispose();
- Assert.False(this.underlyingStream.CanSeek);
- }
+ [Fact]
+ public void IsDisposed()
+ {
+ Assert.False(stream.IsDisposed);
+ this.stream.Dispose();
+ Assert.True(stream.IsDisposed);
+ }
- [Fact]
- public void SetLength()
- {
- Assert.Throws(() => this.stream.SetLength(0));
- }
+ [Fact]
+ public void Dispose_IncompleteDisposesUnderylingStream()
+ {
+ this.stream.Dispose();
+ Assert.False(this.underlyingStream.CanSeek);
+ }
- [Fact]
- public void Seek_Current()
- {
- Assert.Equal(0, this.stream.Position);
- Assert.Equal(0, this.stream.Seek(0, SeekOrigin.Current));
- Assert.Equal(0, this.underlyingStream.Position);
- Assert.Throws(() => this.stream.Seek(-1, SeekOrigin.Current));
- Assert.Equal(0, this.underlyingStream.Position);
-
- Assert.Equal(5, this.stream.Seek(5, SeekOrigin.Current));
- Assert.Equal(5, this.underlyingStream.Position);
- Assert.Equal(5, this.stream.Seek(0, SeekOrigin.Current));
- Assert.Equal(5, this.underlyingStream.Position);
- Assert.Equal(4, this.stream.Seek(-1, SeekOrigin.Current));
- Assert.Equal(4, this.underlyingStream.Position);
- Assert.Throws(() => this.stream.Seek(-10, SeekOrigin.Current));
- Assert.Equal(4, this.underlyingStream.Position);
-
- Assert.Equal(0, this.stream.Seek(0, SeekOrigin.Begin));
- Assert.Equal(0, this.stream.Position);
-
- Assert.Equal(DefaultNestedLength + 1, this.stream.Seek(DefaultNestedLength + 1, SeekOrigin.Current));
- Assert.Equal(DefaultNestedLength + 1, this.underlyingStream.Position);
- Assert.Equal((2 * DefaultNestedLength) + 1, this.stream.Seek(DefaultNestedLength, SeekOrigin.Current));
- Assert.Equal((2 * DefaultNestedLength) + 1, this.underlyingStream.Position);
- Assert.Equal((2 * DefaultNestedLength) + 1, this.stream.Seek(0, SeekOrigin.Current));
- Assert.Equal((2 * DefaultNestedLength) + 1, this.underlyingStream.Position);
- Assert.Equal(1, this.stream.Seek(-2 * DefaultNestedLength, SeekOrigin.Current));
- Assert.Equal(1, this.underlyingStream.Position);
-
- this.stream.Dispose();
- Assert.Throws(() => this.stream.Seek(0, SeekOrigin.Begin));
- }
+ [Fact]
+ public void Dispose_DoesNotDisposeUnderylingStream()
+ {
+ this.stream.Read(new byte[DefaultNestedLength], 0, DefaultNestedLength);
+ this.stream.Dispose();
+ Assert.True(this.underlyingStream.CanSeek);
+ // A sanity check that if it were disposed, our assertion above would fail.
+ this.underlyingStream.Dispose();
+ Assert.False(this.underlyingStream.CanSeek);
+ }
- [Fact]
- public void Sook_WithNonStartPositionInUnderlyingStream()
- {
- this.underlyingStream.Position = 1;
- this.stream = this.underlyingStream.ReadSlice(5);
+ [Fact]
+ public void SetLength()
+ {
+ Assert.Throws(() => this.stream.SetLength(0));
+ }
- Assert.Equal(0, this.stream.Position);
- Assert.Equal(2, this.stream.Seek(2, SeekOrigin.Current));
- Assert.Equal(3, this.underlyingStream.Position);
- }
+ [Fact]
+ public void Seek_Current()
+ {
+ Assert.Equal(0, this.stream.Position);
+ Assert.Equal(0, this.stream.Seek(0, SeekOrigin.Current));
+ Assert.Equal(0, this.underlyingStream.Position);
+ Assert.Throws(() => this.stream.Seek(-1, SeekOrigin.Current));
+ Assert.Equal(0, this.underlyingStream.Position);
+
+ Assert.Equal(5, this.stream.Seek(5, SeekOrigin.Current));
+ Assert.Equal(5, this.underlyingStream.Position);
+ Assert.Equal(5, this.stream.Seek(0, SeekOrigin.Current));
+ Assert.Equal(5, this.underlyingStream.Position);
+ Assert.Equal(4, this.stream.Seek(-1, SeekOrigin.Current));
+ Assert.Equal(4, this.underlyingStream.Position);
+ Assert.Throws(() => this.stream.Seek(-10, SeekOrigin.Current));
+ Assert.Equal(4, this.underlyingStream.Position);
+
+ Assert.Equal(0, this.stream.Seek(0, SeekOrigin.Begin));
+ Assert.Equal(0, this.stream.Position);
+
+ Assert.Equal(DefaultNestedLength + 1, this.stream.Seek(DefaultNestedLength + 1, SeekOrigin.Current));
+ Assert.Equal(DefaultNestedLength + 1, this.underlyingStream.Position);
+ Assert.Equal((2 * DefaultNestedLength) + 1, this.stream.Seek(DefaultNestedLength, SeekOrigin.Current));
+ Assert.Equal((2 * DefaultNestedLength) + 1, this.underlyingStream.Position);
+ Assert.Equal((2 * DefaultNestedLength) + 1, this.stream.Seek(0, SeekOrigin.Current));
+ Assert.Equal((2 * DefaultNestedLength) + 1, this.underlyingStream.Position);
+ Assert.Equal(1, this.stream.Seek(-2 * DefaultNestedLength, SeekOrigin.Current));
+ Assert.Equal(1, this.underlyingStream.Position);
+
+ this.stream.Dispose();
+ Assert.Throws(() => this.stream.Seek(0, SeekOrigin.Begin));
+ }
- [Fact]
- public void Seek_Begin()
- {
- Assert.Equal(0, this.stream.Position);
- Assert.Throws(() => this.stream.Seek(-1, SeekOrigin.Begin));
- Assert.Equal(0, this.underlyingStream.Position);
+ [Fact]
+ public void Sook_WithNonStartPositionInUnderlyingStream()
+ {
+ this.underlyingStream.Position = 1;
+ this.stream = this.underlyingStream.ReadSlice(5);
- Assert.Equal(0, this.stream.Seek(0, SeekOrigin.Begin));
- Assert.Equal(0, this.underlyingStream.Position);
+ Assert.Equal(0, this.stream.Position);
+ Assert.Equal(2, this.stream.Seek(2, SeekOrigin.Current));
+ Assert.Equal(3, this.underlyingStream.Position);
+ }
- Assert.Equal(5, this.stream.Seek(5, SeekOrigin.Begin));
- Assert.Equal(5, this.underlyingStream.Position);
+ [Fact]
+ public void Seek_Begin()
+ {
+ Assert.Equal(0, this.stream.Position);
+ Assert.Throws(() => this.stream.Seek(-1, SeekOrigin.Begin));
+ Assert.Equal(0, this.underlyingStream.Position);
- Assert.Equal(DefaultNestedLength, this.stream.Seek(DefaultNestedLength, SeekOrigin.Begin));
- Assert.Equal(DefaultNestedLength, this.underlyingStream.Position);
+ Assert.Equal(0, this.stream.Seek(0, SeekOrigin.Begin));
+ Assert.Equal(0, this.underlyingStream.Position);
- Assert.Equal(DefaultNestedLength + 1, this.stream.Seek(DefaultNestedLength + 1, SeekOrigin.Begin));
- Assert.Equal(DefaultNestedLength + 1, this.underlyingStream.Position);
+ Assert.Equal(5, this.stream.Seek(5, SeekOrigin.Begin));
+ Assert.Equal(5, this.underlyingStream.Position);
- this.stream.Dispose();
- Assert.Throws(() => this.stream.Seek(0, SeekOrigin.Begin));
- }
+ Assert.Equal(DefaultNestedLength, this.stream.Seek(DefaultNestedLength, SeekOrigin.Begin));
+ Assert.Equal(DefaultNestedLength, this.underlyingStream.Position);
- [Fact]
- public void Seek_End()
- {
- Assert.Equal(0, this.stream.Position);
- Assert.Equal(9, this.stream.Seek(-1, SeekOrigin.End));
- Assert.Equal(9, this.underlyingStream.Position);
+ Assert.Equal(DefaultNestedLength + 1, this.stream.Seek(DefaultNestedLength + 1, SeekOrigin.Begin));
+ Assert.Equal(DefaultNestedLength + 1, this.underlyingStream.Position);
- Assert.Equal(DefaultNestedLength, this.stream.Seek(0, SeekOrigin.End));
- Assert.Equal(DefaultNestedLength, this.underlyingStream.Position);
+ this.stream.Dispose();
+ Assert.Throws(() => this.stream.Seek(0, SeekOrigin.Begin));
+ }
- Assert.Equal(DefaultNestedLength + 5, this.stream.Seek(5, SeekOrigin.End));
- Assert.Equal(DefaultNestedLength + 5, this.underlyingStream.Position);
+ [Fact]
+ public void Seek_End()
+ {
+ Assert.Equal(0, this.stream.Position);
+ Assert.Equal(9, this.stream.Seek(-1, SeekOrigin.End));
+ Assert.Equal(9, this.underlyingStream.Position);
- Assert.Throws(() => this.stream.Seek(-20, SeekOrigin.Begin));
- Assert.Equal(DefaultNestedLength + 5, this.underlyingStream.Position);
+ Assert.Equal(DefaultNestedLength, this.stream.Seek(0, SeekOrigin.End));
+ Assert.Equal(DefaultNestedLength, this.underlyingStream.Position);
- this.stream.Dispose();
- Assert.Throws(() => this.stream.Seek(0, SeekOrigin.End));
- }
+ Assert.Equal(DefaultNestedLength + 5, this.stream.Seek(5, SeekOrigin.End));
+ Assert.Equal(DefaultNestedLength + 5, this.underlyingStream.Position);
- [Fact]
- public void Flush()
- {
- Assert.Throws(() => this.stream.Flush());
- }
+ Assert.Throws(() => this.stream.Seek(-20, SeekOrigin.Begin));
+ Assert.Equal(DefaultNestedLength + 5, this.underlyingStream.Position);
- [Fact]
- public async Task FlushAsync()
- {
- await Assert.ThrowsAsync(() => this.stream.FlushAsync());
- }
+ this.stream.Dispose();
+ Assert.Throws(() => this.stream.Seek(0, SeekOrigin.End));
+ }
- [Fact]
- public void CanRead()
- {
- Assert.True(this.stream.CanRead);
- this.stream.Dispose();
- Assert.False(this.stream.CanRead);
- }
+ [Fact]
+ public void Flush()
+ {
+ Assert.Throws(() => this.stream.Flush());
+ }
- [Fact]
- public void CanWrite()
- {
- Assert.False(this.stream.CanWrite);
- this.stream.Dispose();
- Assert.False(this.stream.CanWrite);
- }
+ [Fact]
+ public async Task FlushAsync()
+ {
+ await Assert.ThrowsAsync(() => this.stream.FlushAsync());
+ }
- [Fact]
- public async Task WriteAsync_Throws()
- {
- await Assert.ThrowsAsync(() => this.stream.WriteAsync(new byte[1], 0, 1));
- }
+ [Fact]
+ public void CanRead()
+ {
+ Assert.True(this.stream.CanRead);
+ this.stream.Dispose();
+ Assert.False(this.stream.CanRead);
+ }
- [Fact]
- public void Write_Throws()
- {
- Assert.Throws(() => this.stream.Write(new byte[1], 0, 1));
- }
+ [Fact]
+ public void CanWrite()
+ {
+ Assert.False(this.stream.CanWrite);
+ this.stream.Dispose();
+ Assert.False(this.stream.CanWrite);
+ }
- [Fact]
- public async Task ReadAsync_Empty_ReturnsZero()
- {
- Assert.Equal(0, await this.stream.ReadAsync(Array.Empty(), 0, 0, default));
- }
+ [Fact]
+ public async Task WriteAsync_Throws()
+ {
+ await Assert.ThrowsAsync(() => this.stream.WriteAsync(new byte[1], 0, 1));
+ }
- [Fact]
- public async Task Read_BeyondEndOfStream_ReturnsZero()
- {
- // Seek beyond the end of the stream
- this.stream.Seek(1, SeekOrigin.End);
+ [Fact]
+ public void Write_Throws()
+ {
+ Assert.Throws(() => this.stream.Write(new byte[1], 0, 1));
+ }
- byte[] buffer = new byte[this.underlyingStream.Length];
+ [Fact]
+ public async Task ReadAsync_Empty_ReturnsZero()
+ {
+ Assert.Equal(0, await this.stream.ReadAsync(Array.Empty(), 0, 0, default));
+ }
- Assert.Equal(0, await this.stream.ReadAsync(buffer, 0, buffer.Length, this.TimeoutToken));
- }
+ [Fact]
+ public async Task Read_BeyondEndOfStream_ReturnsZero()
+ {
+ // Seek beyond the end of the stream
+ this.stream.Seek(1, SeekOrigin.End);
- [Fact]
- public async Task ReadAsync_NoMoreThanGiven()
- {
- byte[] buffer = new byte[this.underlyingStream.Length];
- int bytesRead = await this.stream.ReadAsync(buffer, 0, buffer.Length, this.TimeoutToken);
- Assert.Equal(DefaultNestedLength, bytesRead);
+ byte[] buffer = new byte[this.underlyingStream.Length];
- Assert.Equal(0, await this.stream.ReadAsync(buffer, bytesRead, buffer.Length - bytesRead, this.TimeoutToken));
- Assert.Equal(DefaultNestedLength, this.underlyingStream.Position);
- }
+ Assert.Equal(0, await this.stream.ReadAsync(buffer, 0, buffer.Length, this.TimeoutToken));
+ }
- [Fact]
- public void Read_NoMoreThanGiven()
- {
- byte[] buffer = new byte[this.underlyingStream.Length];
- int bytesRead = this.stream.Read(buffer, 0, buffer.Length);
- Assert.Equal(DefaultNestedLength, bytesRead);
+ [Fact]
+ public async Task ReadAsync_NoMoreThanGiven()
+ {
+ byte[] buffer = new byte[this.underlyingStream.Length];
+ int bytesRead = await this.stream.ReadAsync(buffer, 0, buffer.Length, this.TimeoutToken);
+ Assert.Equal(DefaultNestedLength, bytesRead);
- Assert.Equal(0, this.stream.Read(buffer, bytesRead, buffer.Length - bytesRead));
- Assert.Equal(DefaultNestedLength, this.underlyingStream.Position);
- }
+ Assert.Equal(0, await this.stream.ReadAsync(buffer, bytesRead, buffer.Length - bytesRead, this.TimeoutToken));
+ Assert.Equal(DefaultNestedLength, this.underlyingStream.Position);
+ }
- [Fact]
- public void Read_Empty_ReturnsZero()
- {
- Assert.Equal(0, this.stream.Read(Array.Empty(), 0, 0));
- }
+ [Fact]
+ public void Read_NoMoreThanGiven()
+ {
+ byte[] buffer = new byte[this.underlyingStream.Length];
+ int bytesRead = this.stream.Read(buffer, 0, buffer.Length);
+ Assert.Equal(DefaultNestedLength, bytesRead);
- [Fact]
- public async Task ReadAsync_WhenLengthIsInitially0()
- {
- this.stream = this.underlyingStream.ReadSlice(0);
- Assert.Equal(0, await this.stream.ReadAsync(new byte[1], 0, 1, this.TimeoutToken));
- }
+ Assert.Equal(0, this.stream.Read(buffer, bytesRead, buffer.Length - bytesRead));
+ Assert.Equal(DefaultNestedLength, this.underlyingStream.Position);
+ }
- [Fact]
- public void Read_WhenLengthIsInitially0()
- {
- this.stream = this.underlyingStream.ReadSlice(0);
- Assert.Equal(0, this.stream.Read(new byte[1], 0, 1));
- }
+ [Fact]
+ public void Read_Empty_ReturnsZero()
+ {
+ Assert.Equal(0, this.stream.Read(Array.Empty(), 0, 0));
+ }
- [Fact]
- public void CreationDoesNotReadFromUnderlyingStream()
- {
- Assert.Equal(0, this.underlyingStream.Position);
- }
+ [Fact]
+ public async Task ReadAsync_WhenLengthIsInitially0()
+ {
+ this.stream = this.underlyingStream.ReadSlice(0);
+ Assert.Equal(0, await this.stream.ReadAsync(new byte[1], 0, 1, this.TimeoutToken));
+ }
- [Fact]
- public void Read_UnderlyingStreamReturnsFewerBytesThanRequested()
- {
- var buffer = new byte[20];
- int firstBlockLength = DefaultNestedLength / 2;
- this.underlyingStream.SetLength(firstBlockLength);
- Assert.Equal(firstBlockLength, this.stream.Read(buffer, 0, buffer.Length));
- this.underlyingStream.SetLength(DefaultNestedLength * 2);
- Assert.Equal(DefaultNestedLength - firstBlockLength, this.stream.Read(buffer, 0, buffer.Length));
- }
+ [Fact]
+ public void Read_WhenLengthIsInitially0()
+ {
+ this.stream = this.underlyingStream.ReadSlice(0);
+ Assert.Equal(0, this.stream.Read(new byte[1], 0, 1));
+ }
- [Fact]
- public async Task ReadAsync_UnderlyingStreamReturnsFewerBytesThanRequested()
- {
- var buffer = new byte[20];
- int firstBlockLength = DefaultNestedLength / 2;
- this.underlyingStream.SetLength(firstBlockLength);
- Assert.Equal(firstBlockLength, await this.stream.ReadAsync(buffer, 0, buffer.Length));
- this.underlyingStream.SetLength(DefaultNestedLength * 2);
- Assert.Equal(DefaultNestedLength - firstBlockLength, await this.stream.ReadAsync(buffer, 0, buffer.Length));
- }
+ [Fact]
+ public void CreationDoesNotReadFromUnderlyingStream()
+ {
+ Assert.Equal(0, this.underlyingStream.Position);
+ }
- [Fact]
- public void Read_ValidatesArguments()
- {
- var buffer = new byte[20];
+ [Fact]
+ public void Read_UnderlyingStreamReturnsFewerBytesThanRequested()
+ {
+ var buffer = new byte[20];
+ int firstBlockLength = DefaultNestedLength / 2;
+ this.underlyingStream.SetLength(firstBlockLength);
+ Assert.Equal(firstBlockLength, this.stream.Read(buffer, 0, buffer.Length));
+ this.underlyingStream.SetLength(DefaultNestedLength * 2);
+ Assert.Equal(DefaultNestedLength - firstBlockLength, this.stream.Read(buffer, 0, buffer.Length));
+ }
- Assert.Throws(() => this.stream.Read(null!, 0, 0));
- Assert.Throws(() => this.stream.Read(buffer, -1, buffer.Length));
- Assert.Throws(() => this.stream.Read(buffer, 0, -1));
- Assert.Throws(() => this.stream.Read(buffer, 1, buffer.Length));
- }
+ [Fact]
+ public async Task ReadAsync_UnderlyingStreamReturnsFewerBytesThanRequested()
+ {
+ var buffer = new byte[20];
+ int firstBlockLength = DefaultNestedLength / 2;
+ this.underlyingStream.SetLength(firstBlockLength);
+ Assert.Equal(firstBlockLength, await this.stream.ReadAsync(buffer, 0, buffer.Length));
+ this.underlyingStream.SetLength(DefaultNestedLength * 2);
+ Assert.Equal(DefaultNestedLength - firstBlockLength, await this.stream.ReadAsync(buffer, 0, buffer.Length));
+ }
- [Fact]
- public async Task ReadAsync_ValidatesArguments()
- {
- var buffer = new byte[20];
+ [Fact]
+ public void Read_ValidatesArguments()
+ {
+ var buffer = new byte[20];
- await Assert.ThrowsAsync