Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit bbbf587

Browse files
committed
Merge pull request #2419 from stephentoub/ipc_tests
Inter-process communication tests
2 parents 1bcb7dc + 3f16960 commit bbbf587

File tree

16 files changed

+2461
-39
lines changed

16 files changed

+2461
-39
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 14
4+
VisualStudioVersion = 14.0.22823.1
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InterProcessCommunication.Tests", "tests\InterProcessCommunication\InterProcessCommunication.Tests.csproj", "{C8B651EA-21B8-45B3-9617-3BA952D0F12B}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InterProcessCommunication.TestConsoleApp", "tests\InterProcessCommunication\InterProcessCommunication.TestConsoleApp\InterProcessCommunication.TestConsoleApp.csproj", "{F5E941C8-AF2F-47AB-A066-FF25470CE382}"
9+
EndProject
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{EFFF9E5B-58A0-4D0E-891D-40EF450FE7DA}"
11+
ProjectSection(SolutionItems) = preProject
12+
..\.nuget\packages.Windows_NT.config = ..\.nuget\packages.Windows_NT.config
13+
EndProjectSection
14+
EndProject
15+
Global
16+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
17+
Linux_Debug|Any CPU = Linux_Debug|Any CPU
18+
Linux_Release|Any CPU = Linux_Release|Any CPU
19+
OSX_Debug|Any CPU = OSX_Debug|Any CPU
20+
OSX_Release|Any CPU = OSX_Release|Any CPU
21+
Windows_Debug|Any CPU = Windows_Debug|Any CPU
22+
Windows_Release|Any CPU = Windows_Release|Any CPU
23+
EndGlobalSection
24+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
25+
{C8B651EA-21B8-45B3-9617-3BA952D0F12B}.Linux_Debug|Any CPU.ActiveCfg = Debug|Any CPU
26+
{C8B651EA-21B8-45B3-9617-3BA952D0F12B}.Linux_Debug|Any CPU.Build.0 = Debug|Any CPU
27+
{C8B651EA-21B8-45B3-9617-3BA952D0F12B}.Linux_Release|Any CPU.ActiveCfg = Release|Any CPU
28+
{C8B651EA-21B8-45B3-9617-3BA952D0F12B}.Linux_Release|Any CPU.Build.0 = Release|Any CPU
29+
{C8B651EA-21B8-45B3-9617-3BA952D0F12B}.OSX_Debug|Any CPU.ActiveCfg = Debug|Any CPU
30+
{C8B651EA-21B8-45B3-9617-3BA952D0F12B}.OSX_Debug|Any CPU.Build.0 = Debug|Any CPU
31+
{C8B651EA-21B8-45B3-9617-3BA952D0F12B}.OSX_Release|Any CPU.ActiveCfg = Release|Any CPU
32+
{C8B651EA-21B8-45B3-9617-3BA952D0F12B}.OSX_Release|Any CPU.Build.0 = Release|Any CPU
33+
{C8B651EA-21B8-45B3-9617-3BA952D0F12B}.Windows_Debug|Any CPU.ActiveCfg = Debug|Any CPU
34+
{C8B651EA-21B8-45B3-9617-3BA952D0F12B}.Windows_Debug|Any CPU.Build.0 = Debug|Any CPU
35+
{C8B651EA-21B8-45B3-9617-3BA952D0F12B}.Windows_Release|Any CPU.ActiveCfg = Release|Any CPU
36+
{C8B651EA-21B8-45B3-9617-3BA952D0F12B}.Windows_Release|Any CPU.Build.0 = Release|Any CPU
37+
{F5E941C8-AF2F-47AB-A066-FF25470CE382}.Linux_Debug|Any CPU.ActiveCfg = Debug|Any CPU
38+
{F5E941C8-AF2F-47AB-A066-FF25470CE382}.Linux_Debug|Any CPU.Build.0 = Debug|Any CPU
39+
{F5E941C8-AF2F-47AB-A066-FF25470CE382}.Linux_Release|Any CPU.ActiveCfg = Release|Any CPU
40+
{F5E941C8-AF2F-47AB-A066-FF25470CE382}.Linux_Release|Any CPU.Build.0 = Release|Any CPU
41+
{F5E941C8-AF2F-47AB-A066-FF25470CE382}.OSX_Debug|Any CPU.ActiveCfg = Debug|Any CPU
42+
{F5E941C8-AF2F-47AB-A066-FF25470CE382}.OSX_Debug|Any CPU.Build.0 = Debug|Any CPU
43+
{F5E941C8-AF2F-47AB-A066-FF25470CE382}.OSX_Release|Any CPU.ActiveCfg = Release|Any CPU
44+
{F5E941C8-AF2F-47AB-A066-FF25470CE382}.OSX_Release|Any CPU.Build.0 = Release|Any CPU
45+
{F5E941C8-AF2F-47AB-A066-FF25470CE382}.Windows_Debug|Any CPU.ActiveCfg = Debug|Any CPU
46+
{F5E941C8-AF2F-47AB-A066-FF25470CE382}.Windows_Debug|Any CPU.Build.0 = Debug|Any CPU
47+
{F5E941C8-AF2F-47AB-A066-FF25470CE382}.Windows_Release|Any CPU.ActiveCfg = Release|Any CPU
48+
{F5E941C8-AF2F-47AB-A066-FF25470CE382}.Windows_Release|Any CPU.Build.0 = Release|Any CPU
49+
EndGlobalSection
50+
GlobalSection(SolutionProperties) = preSolution
51+
HideSolutionNode = FALSE
52+
EndGlobalSection
53+
EndGlobal
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System.IO;
5+
using System.IO.Pipes;
6+
using Xunit;
7+
8+
namespace InterProcessCommunication.Tests
9+
{
10+
public class AnonymousPipesTests : IpcTestBase
11+
{
12+
[Fact]
13+
public void PingPong()
14+
{
15+
// Create two anonymous pipes, one for each direction of communication.
16+
// Then spawn another process to communicate with.
17+
using (var outbound = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable))
18+
using (var inbound = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable))
19+
using (var remote = RemoteInvoke("PingPong_OtherProcess", outbound.GetClientHandleAsString(), inbound.GetClientHandleAsString()))
20+
{
21+
// Close our local copies of the handles now that we've passed them of to the other process
22+
outbound.DisposeLocalCopyOfClientHandle();
23+
inbound.DisposeLocalCopyOfClientHandle();
24+
25+
// Ping-pong back and forth by writing then reading bytes one at a time.
26+
for (byte i = 0; i < 10; i++)
27+
{
28+
outbound.WriteByte(i);
29+
int received = inbound.ReadByte();
30+
Assert.Equal(i, received);
31+
}
32+
}
33+
}
34+
35+
public static int PingPong_OtherProcess(string inHandle, string outHandle)
36+
{
37+
// Create the clients associated with the supplied handles
38+
using (var inbound = new AnonymousPipeClientStream(PipeDirection.In, inHandle))
39+
using (var outbound = new AnonymousPipeClientStream(PipeDirection.Out, outHandle))
40+
{
41+
// Repeatedly read then write a byte from and to the server
42+
for (int i = 0; i < 10; i++)
43+
{
44+
int b = inbound.ReadByte();
45+
outbound.WriteByte((byte)b);
46+
}
47+
}
48+
return SuccessExitCode;
49+
}
50+
51+
}
52+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Threading;
6+
using Xunit;
7+
8+
namespace InterProcessCommunication.Tests
9+
{
10+
public class EventWaitHandleTests : IpcTestBase
11+
{
12+
[ActiveIssue("https://github.com/dotnet/coreclr/issues/1237", PlatformID.AnyUnix)]
13+
[Theory]
14+
[InlineData(EventResetMode.ManualReset)]
15+
[InlineData(EventResetMode.AutoReset)]
16+
public void PingPong(EventResetMode mode)
17+
{
18+
// Create names for the two events
19+
string outboundName = Guid.NewGuid().ToString("N");
20+
string inboundName = Guid.NewGuid().ToString("N");
21+
22+
// Create the two events and the other process with which to synchronize
23+
using (var inbound = new EventWaitHandle(true, mode, inboundName))
24+
using (var outbound = new EventWaitHandle(false, mode, outboundName))
25+
using (var remote = RemoteInvoke("PingPong_OtherProcess", mode.ToString(), outboundName, inboundName))
26+
{
27+
// Repeatedly wait for one event and then set the other
28+
for (int i = 0; i < 10; i++)
29+
{
30+
Assert.True(inbound.WaitOne(FailWaitTimeoutMilliseconds));
31+
if (mode == EventResetMode.ManualReset)
32+
{
33+
inbound.Reset();
34+
}
35+
outbound.Set();
36+
}
37+
}
38+
}
39+
40+
public static int PingPong_OtherProcess(string modeName, string inboundName, string outboundName)
41+
{
42+
EventResetMode mode = (EventResetMode)Enum.Parse(typeof(EventResetMode), modeName);
43+
44+
// Open the two events
45+
using (var inbound = EventWaitHandle.OpenExisting(inboundName))
46+
using (var outbound = EventWaitHandle.OpenExisting(outboundName))
47+
{
48+
// Repeatedly wait for one event and then set the other
49+
for (int i = 0; i < 10; i++)
50+
{
51+
Assert.True(inbound.WaitOne(FailWaitTimeoutMilliseconds));
52+
if (mode == EventResetMode.ManualReset)
53+
{
54+
inbound.Reset();
55+
}
56+
outbound.Set();
57+
}
58+
}
59+
60+
return SuccessExitCode;
61+
}
62+
63+
}
64+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
4+
<PropertyGroup>
5+
<ProjectGuid>{F5E941C8-AF2F-47AB-A066-FF25470CE382}</ProjectGuid>
6+
<OutputType>Exe</OutputType>
7+
<RootNamespace>InterProcessCommunication.Tests</RootNamespace>
8+
<AssemblyName>InterProcessCommunication.TestConsoleApp</AssemblyName>
9+
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
10+
</PropertyGroup>
11+
<!-- Default configurations to help VS understand the configurations -->
12+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
13+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
14+
<ItemGroup>
15+
<Compile Include="TestConsoleApp.cs" />
16+
</ItemGroup>
17+
<ItemGroup>
18+
<None Include="project.json" />
19+
</ItemGroup>
20+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
21+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Reflection;
6+
7+
namespace InterProcessCommunication.Tests
8+
{
9+
/// <summary>
10+
/// Provides an entry point in a new process that will load a specified method and invoke it.
11+
/// </summary>
12+
static class Program
13+
{
14+
static int Main(string[] args)
15+
{
16+
// The program expects to be passed the target assembly name to load, the type
17+
// from that assembly to find, and the method from that assembly to invoke.
18+
// Any additional arguments are passed as strings to the method.
19+
if (args.Length < 3)
20+
{
21+
Console.Error.WriteLine("Usage: TestConsoleApp assemblyName typeName methodName");
22+
return -1;
23+
}
24+
string assemblyName = args[0];
25+
string typeName = args[1];
26+
string methodName = args[2];
27+
string[] additionalArgs = args.Length > 3 ?
28+
args.Subarray(3, args.Length - 3) :
29+
Array.Empty<string>();
30+
31+
// Load the specified assembly, type, and method, then invoke the method.
32+
// The program's exit code is the return value of the invoked method.
33+
try
34+
{
35+
Assembly a = Assembly.Load(new AssemblyName(assemblyName));
36+
Type t = a.GetType(typeName);
37+
MethodInfo mi = t.GetTypeInfo().GetDeclaredMethod(methodName);
38+
return (int)mi.Invoke(null, additionalArgs);
39+
}
40+
catch (Exception exc)
41+
{
42+
Console.Error.WriteLine("Exception from TestConsoleApp: " + exc);
43+
return -2;
44+
}
45+
}
46+
47+
private static T[] Subarray<T>(this T[] arr, int offset, int count)
48+
{
49+
var newArr = new T[count];
50+
Array.Copy(arr, offset, newArr, 0, count);
51+
return newArr;
52+
}
53+
}
54+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"dependencies": {
3+
"System.Console": "4.0.0-beta-*",
4+
"System.IO": "4.0.10-beta-*",
5+
"System.Runtime": "4.0.20-beta-*",
6+
"System.Threading.Tasks": "4.0.10-beta-*"
7+
},
8+
"frameworks": {
9+
"dnxcore50": {}
10+
}
11+
}

0 commit comments

Comments
 (0)