public async Task PingPong_Async() { // Create names for two pipes string outName = PipeStreamConformanceTests.GetUniquePipeName(); string inName = PipeStreamConformanceTests.GetUniquePipeName(); // Create the two named pipes, one for each direction, then create // another process with which to communicate using (var outbound = new NamedPipeServerStream(outName, PipeDirection.Out)) using (var inbound = new NamedPipeClientStream(".", inName, PipeDirection.In)) using (RemoteExecutor.Invoke(new Action <string, string>(PingPong_OtherProcess), outName, inName)) { // Wait for both pipes to be connected await Task.WhenAll(outbound.WaitForConnectionAsync(), inbound.ConnectAsync()); // Repeatedly write then read a byte to and from the other process var data = new byte[1]; for (byte i = 0; i < 10; i++) { data[0] = i; await outbound.WriteAsync(data, 0, data.Length); data[0] = 0; int received = await inbound.ReadAsync(data, 0, data.Length); Assert.Equal(1, received); Assert.Equal(i, data[0]); } } }
public void Allow_Connection_UnderDifferentUsers_ForClientReading(bool useTimeSpan) { string name = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream( name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) { Task serverTask = server.WaitForConnectionAsync(CancellationToken.None); _testAccountImpersonator.RunImpersonated(() => { using (var client = new NamedPipeClientStream(".", name, PipeDirection.In)) { if (useTimeSpan) { client.Connect(TimeSpan.FromMilliseconds(10_000)); } else { client.Connect(10_000); } } }); Assert.True(serverTask.Wait(10_000)); } }
[PlatformSpecific(TestPlatforms.Windows)] // Unix implementation uses bidirectional sockets public static void Windows_BufferSizeRoundtripping() { int desiredBufferSize = 10; string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, desiredBufferSize, desiredBufferSize)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.In)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); Assert.Equal(desiredBufferSize, server.OutBufferSize); Assert.Equal(desiredBufferSize, client.InBufferSize); } using (var server = new NamedPipeServerStream(pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, desiredBufferSize, desiredBufferSize)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.Out)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); Assert.Equal(desiredBufferSize, server.InBufferSize); Assert.Equal(0, client.OutBufferSize); } }
[PlatformSpecific(TestPlatforms.Windows)] // Win32 P/Invokes to verify the user name public async Task Windows_GetImpersonationUserName_Succeed(TokenImpersonationLevel level, bool expectedResult) { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName)) { using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, level)) { string expectedUserName; Task serverTask = server.WaitForConnectionAsync(); client.Connect(); await serverTask; Assert.Equal(expectedResult, InteropTest.TryGetImpersonationUserName(server.SafePipeHandle, out expectedUserName)); if (!expectedResult) { Assert.Equal(string.Empty, expectedUserName); Assert.Throws <IOException>(() => server.GetImpersonationUserName()); } else { string actualUserName = server.GetImpersonationUserName(); Assert.NotNull(actualUserName); Assert.False(string.IsNullOrWhiteSpace(actualUserName)); Assert.Equal(expectedUserName, actualUserName); } } } }
public static void Unix_BufferSizeRoundtripping(PipeDirection direction) { int desiredBufferSize = 0; string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, desiredBufferSize, desiredBufferSize)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); desiredBufferSize = server.OutBufferSize * 2; } using (var server = new NamedPipeServerStream(pipeName, direction, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, desiredBufferSize, desiredBufferSize)) using (var client = new NamedPipeClientStream(".", pipeName, direction == PipeDirection.In ? PipeDirection.Out : PipeDirection.In)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); if ((direction & PipeDirection.Out) != 0) { Assert.InRange(server.OutBufferSize, desiredBufferSize, int.MaxValue); } if ((direction & PipeDirection.In) != 0) { Assert.InRange(server.InBufferSize, desiredBufferSize, int.MaxValue); } } }
public static void CreateMultipleConcurrentServers_ConnectMultipleClients(PipeOptions extraPipeOptions) { var pipeServers = new NamedPipeServerStream[5]; var pipeClients = new NamedPipeClientStream[pipeServers.Length]; try { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); for (var i = 0; i < pipeServers.Length; i++) { pipeServers[i] = new NamedPipeServerStream( pipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough | extraPipeOptions); pipeClients[i] = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous | extraPipeOptions); pipeClients[i].Connect(15_000); } } finally { for (var i = 0; i < pipeServers.Length; i++) { pipeServers[i]?.Dispose(); pipeClients[i]?.Dispose(); } } }
public static void Unix_GetHandleOfNewServerStream_Throws_InvalidOperationException() { using (var pipe = new NamedPipeServerStream(PipeStreamConformanceTests.GetUniquePipeName(), PipeDirection.Out, 1, PipeTransmissionMode.Byte)) { Assert.Throws <InvalidOperationException>(() => pipe.SafePipeHandle); } }
public void InheritHandles_AvailableInChildProcess() { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.In)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.Out, PipeOptions.None, TokenImpersonationLevel.None, HandleInheritability.Inheritable)) { Task.WaitAll(server.WaitForConnectionAsync(), client.ConnectAsync()); using (RemoteExecutor.Invoke(new Action <string>(ChildFunc), client.SafePipeHandle.DangerousGetHandle().ToString())) { client.Dispose(); for (int i = 0; i < 5; i++) { Assert.Equal(i, server.ReadByte()); } } } void ChildFunc(string handle) { using (var childClient = new NamedPipeClientStream(PipeDirection.Out, isAsync: false, isConnected: true, new SafePipeHandle((IntPtr)long.Parse(handle, CultureInfo.InvariantCulture), ownsHandle: true))) { for (int i = 0; i < 5; i++) { childClient.WriteByte((byte)i); } } } }
[PlatformSpecific(TestPlatforms.Windows)] // Uses P/Invokes public async Task RunAsClient_Windows(TokenImpersonationLevel tokenImpersonationLevel) { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, tokenImpersonationLevel)) { Task serverTask = server.WaitForConnectionAsync(); client.Connect(); await serverTask; bool ran = false; if (tokenImpersonationLevel == TokenImpersonationLevel.None) { Assert.Throws <IOException>(() => server.RunAsClient(() => ran = true)); Assert.False(ran, "Expected delegate to not have been invoked"); } else { server.RunAsClient(() => ran = true); Assert.True(ran, "Expected delegate to have been invoked"); } } }
public void MaxNumberOfServerInstances_TooManyServers_Throws() { string name = PipeStreamConformanceTests.GetUniquePipeName(); using (new NamedPipeServerStream(name, PipeDirection.InOut, 1)) { // NPSS was created with max of 1, so creating another fails. Assert.Throws <IOException>(() => new NamedPipeServerStream(name, PipeDirection.InOut, 1)); } using (new NamedPipeServerStream(name, PipeDirection.InOut, 3)) { // NPSS was created with max of 3, but NPSS not only validates against the original max but also // against the max of the stream being created, so since there's already 1 and this specifies max == 1, it fails. Assert.Throws <UnauthorizedAccessException>(() => new NamedPipeServerStream(name, PipeDirection.InOut, 1)); using (new NamedPipeServerStream(name, PipeDirection.InOut, 2)) // lower max ignored using (new NamedPipeServerStream(name, PipeDirection.InOut, 4)) // higher max ignored { // NPSS was created with a max of 3, and we're creating a 4th, so it fails. Assert.Throws <IOException>(() => new NamedPipeServerStream(name, PipeDirection.InOut, 3)); } using (new NamedPipeServerStream(name, PipeDirection.InOut, 3)) using (new NamedPipeServerStream(name, PipeDirection.InOut, 3)) { // NPSS was created with a max of 3, and we've already created 3, so it fails, // even if the new stream tries to raise it. Assert.Throws <IOException>(() => new NamedPipeServerStream(name, PipeDirection.InOut, 4)); Assert.Throws <IOException>(() => new NamedPipeServerStream(name, PipeDirection.InOut, 2)); } } }
protected override (NamedPipeServerStream Server, NamedPipeClientStream Client) CreateServerAndClientStreams() { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous); return(server, client); }
[PlatformSpecific(TestPlatforms.Windows)] // accessing SafePipeHandle on Unix fails for a non-connected stream public static void Windows_CreateFromAlreadyBoundHandle_Throws_ArgumentException(PipeDirection direction) { // The pipe is already bound using (var pipe = new NamedPipeServerStream(PipeStreamConformanceTests.GetUniquePipeName(), direction, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) { AssertExtensions.Throws <ArgumentException>("handle", () => new NamedPipeServerStream(direction, true, true, pipe.SafePipeHandle)); } }
[PlatformSpecific(TestPlatforms.Windows)] // NumberOfServerInstances > 1 isn't supported and has undefined behavior on Unix public static void Windows_ServerCloneWithDifferentDirection_Throws_UnauthorizedAccessException() { string uniqueServerName = PipeStreamConformanceTests.GetUniquePipeName(); using (NamedPipeServerStream server = new NamedPipeServerStream(uniqueServerName, PipeDirection.In, 2, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) { Assert.Throws <UnauthorizedAccessException>(() => new NamedPipeServerStream(uniqueServerName, PipeDirection.Out)); } }
[PlatformSpecific(TestPlatforms.Windows)] // NumberOfServerInstances > 1 isn't supported and has undefined behavior on Unix public static void ServerCountOverMaxServerInstances_Throws_IOException() { string uniqueServerName = PipeStreamConformanceTests.GetUniquePipeName(); using (NamedPipeServerStream server = new NamedPipeServerStream(uniqueServerName, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) { Assert.Throws <IOException>(() => new NamedPipeServerStream(uniqueServerName)); } }
[PlatformSpecific(TestPlatforms.Windows)] // accessing SafePipeHandle on Unix fails for a non-connected stream public static void Windows_CreateFromDisposedServerHandle_Throws_ObjectDisposedException(PipeDirection direction) { // The pipe is closed when we try to make a new Stream with it var pipe = new NamedPipeServerStream(PipeStreamConformanceTests.GetUniquePipeName(), direction, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); SafePipeHandle handle = pipe.SafePipeHandle; pipe.Dispose(); Assert.Throws <ObjectDisposedException>(() => new NamedPipeServerStream(direction, true, true, pipe.SafePipeHandle).Dispose()); }
public void ClientConnect_Throws_Timeout_When_Pipe_Not_Found() { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (NamedPipeClientStream client = new NamedPipeClientStream(pipeName)) { Assert.Throws <TimeoutException>(() => client.Connect(91)); } }
[PlatformSpecific(TestPlatforms.Windows)] // can't access SafePipeHandle on Unix until after connection created public static void CreateWithNegativeOneServerInstances_DefaultsToMaxServerInstances() { // When passed -1 as the maxnumberofserverisntances, the NamedPipeServerStream.Windows class // will translate that to the platform specific maximum number (255) using (var server = new NamedPipeServerStream(PipeStreamConformanceTests.GetUniquePipeName(), PipeDirection.InOut, -1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) using (var server2 = new NamedPipeServerStream(PipeDirection.InOut, false, true, server.SafePipeHandle)) using (var server3 = new NamedPipeServerStream(PipeDirection.InOut, false, true, server.SafePipeHandle)) { } }
public async Task ClientConnectAsync_Throws_Timeout_When_Pipe_Not_Found(CancellationToken cancellationToken) { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (NamedPipeClientStream client = new NamedPipeClientStream(pipeName)) { Task waitingClient = client.ConnectAsync(92, cancellationToken); await Assert.ThrowsAsync <TimeoutException>(() => { return(waitingClient); }); } }
public static void CreateServer_ConnectClient_UsingUnixAbsolutePath() { string name = Path.Combine("/tmp", PipeStreamConformanceTests.GetUniquePipeName()); using (var server = new NamedPipeServerStream(name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.CurrentUserOnly)) { using (var client = new NamedPipeClientStream(".", name, PipeDirection.InOut, PipeOptions.CurrentUserOnly)) { client.Connect(); } } }
public static void CreateServer_ConnectClient() { string name = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream(name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.CurrentUserOnly)) { using (var client = new NamedPipeClientStream(".", name, PipeDirection.InOut, PipeOptions.CurrentUserOnly)) { // Should not fail to connect since both, the server and client have the same owner. client.Connect(); } } }
public async Task PipeTransmissionMode_Returns_Byte() { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.Out)) { await Task.WhenAll(server.WaitForConnectionAsync(), client.ConnectAsync()); Assert.Equal(PipeTransmissionMode.Byte, server.TransmissionMode); Assert.Equal(PipeTransmissionMode.Byte, client.TransmissionMode); } }
public void InvalidReadMode_Throws_ArgumentOutOfRangeException(PipeDirection serverDirection, PipeDirection clientDirection) { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, serverDirection, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)) using (var client = new NamedPipeClientStream(".", pipeName, clientDirection)) { Task clientConnect = client.ConnectAsync(); server.WaitForConnection(); clientConnect.Wait(); Assert.Throws <ArgumentOutOfRangeException>(() => server.ReadMode = (PipeTransmissionMode)999); Assert.Throws <ArgumentOutOfRangeException>(() => client.ReadMode = (PipeTransmissionMode)999); } }
public static void Connection_UnderSameUser_SingleSide_CurrentUserOnly_Works(PipeOptions serverPipeOptions, PipeOptions clientPipeOptions) { string name = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream(name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, serverPipeOptions)) using (var client = new NamedPipeClientStream(".", name, PipeDirection.InOut, clientPipeOptions)) { Task[] tasks = new[] { Task.Run(() => server.WaitForConnection()), Task.Run(() => client.Connect()) }; Assert.True(Task.WaitAll(tasks, 20_000)); } }
[PlatformSpecific(TestPlatforms.AnyUnix)] // Uses P/Invoke to verify the user name public async Task Unix_GetImpersonationUserName_Succeed() { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName)) using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation)) { Task serverTask = server.WaitForConnectionAsync(); client.Connect(); await serverTask; string name = server.GetImpersonationUserName(); Assert.NotNull(name); Assert.False(string.IsNullOrWhiteSpace(name)); } }
[PlatformSpecific(TestPlatforms.Windows)] // Unix doesn't support MaxNumberOfServerInstances public async Task Windows_Get_NumberOfServerInstances_Succeed() { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 3)) { using (var client = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation)) { Task serverTask = server.WaitForConnectionAsync(); client.Connect(); await serverTask; Assert.True(InteropTest.TryGetNumberOfServerInstances(client.SafePipeHandle, out uint expectedNumberOfServerInstances), "GetNamedPipeHandleState failed"); Assert.Equal(expectedNumberOfServerInstances, (uint)client.NumberOfServerInstances); } } }
[PlatformSpecific(TestPlatforms.Windows)] // Unix ignores MaxNumberOfServerInstances and second client also connects. public void ClientConnect_Throws_Timeout_When_Pipe_Busy() { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (NamedPipeServerStream server = new NamedPipeServerStream(pipeName)) using (NamedPipeClientStream firstClient = new NamedPipeClientStream(pipeName)) using (NamedPipeClientStream secondClient = new NamedPipeClientStream(pipeName)) { const int timeout = 10_000; Task[] clientAndServerTasks = new[] { firstClient.ConnectAsync(timeout), Task.Run(() => server.WaitForConnection()) }; Assert.True(Task.WaitAll(clientAndServerTasks, timeout)); Assert.Throws <TimeoutException>(() => secondClient.Connect(93)); } }
public static void CreateMultipleServers_ConnectMultipleClients() { string name1 = PipeStreamConformanceTests.GetUniquePipeName(); string name2 = PipeStreamConformanceTests.GetUniquePipeName(); string name3 = PipeStreamConformanceTests.GetUniquePipeName(); using (var server1 = new NamedPipeServerStream(name1, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.CurrentUserOnly)) using (var server2 = new NamedPipeServerStream(name2, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.CurrentUserOnly)) using (var server3 = new NamedPipeServerStream(name3, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.CurrentUserOnly)) { using (var client1 = new NamedPipeClientStream(".", name1, PipeDirection.InOut, PipeOptions.CurrentUserOnly)) using (var client2 = new NamedPipeClientStream(".", name2, PipeDirection.InOut, PipeOptions.CurrentUserOnly)) using (var client3 = new NamedPipeClientStream(".", name3, PipeDirection.InOut, PipeOptions.CurrentUserOnly)) { client1.Connect(); client2.Connect(); client3.Connect(); } } }
[PlatformSpecific(TestPlatforms.Windows)] // Unix implementation uses bidirectional sockets public void ConnectWithConflictingDirections_Throws_UnauthorizedAccessException() { string serverName1 = PipeStreamConformanceTests.GetUniquePipeName(); using (NamedPipeServerStream server = new NamedPipeServerStream(serverName1, PipeDirection.Out)) using (NamedPipeClientStream client = new NamedPipeClientStream(".", serverName1, PipeDirection.Out)) { Assert.Throws <UnauthorizedAccessException>(() => client.Connect()); Assert.False(client.IsConnected); } string serverName2 = PipeStreamConformanceTests.GetUniquePipeName(); using (NamedPipeServerStream server = new NamedPipeServerStream(serverName2, PipeDirection.In)) using (NamedPipeClientStream client = new NamedPipeClientStream(".", serverName2, PipeDirection.In)) { Assert.Throws <UnauthorizedAccessException>(() => client.Connect()); Assert.False(client.IsConnected); } }
[PlatformSpecific(TestPlatforms.Windows)] // Unix ignores MaxNumberOfServerInstances and second client also connects. public async Task ClientConnectAsync_With_Cancellation_Throws_Timeout_When_Pipe_Busy(CancellationToken cancellationToken) { string pipeName = PipeStreamConformanceTests.GetUniquePipeName(); using (NamedPipeServerStream server = new NamedPipeServerStream(pipeName)) using (NamedPipeClientStream firstClient = new NamedPipeClientStream(pipeName)) using (NamedPipeClientStream secondClient = new NamedPipeClientStream(pipeName)) { const int timeout = 10_000; Task[] clientAndServerTasks = new[] { firstClient.ConnectAsync(timeout), Task.Run(() => server.WaitForConnection()) }; Assert.True(Task.WaitAll(clientAndServerTasks, timeout)); Task waitingClient = secondClient.ConnectAsync(94, cancellationToken); await Assert.ThrowsAsync <TimeoutException>(() => { return(waitingClient); }); } }
public async Task MultipleServers_ServeMultipleClientsConcurrently(int numServers) { string name = PipeStreamConformanceTests.GetUniquePipeName(); var servers = new NamedPipeServerStream[numServers]; var clients = new NamedPipeClientStream[servers.Length]; try { for (int i = 0; i < servers.Length; i++) { servers[i] = new NamedPipeServerStream(name, PipeDirection.InOut, numServers, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); } for (int i = 0; i < clients.Length; i++) { clients[i] = new NamedPipeClientStream(".", name, PipeDirection.InOut, PipeOptions.Asynchronous); } Task[] serverWaits = (from server in servers select server.WaitForConnectionAsync()).ToArray(); Task[] clientWaits = (from client in clients select client.ConnectAsync()).ToArray(); await serverWaits.Concat(clientWaits).ToArray().WhenAllOrAnyFailed(); Task[] serverSends = (from server in servers select server.WriteAsync(new byte[1], 0, 1)).ToArray(); Task <int>[] clientReceives = (from client in clients select client.ReadAsync(new byte[1], 0, 1)).ToArray(); await serverSends.Concat(clientReceives).ToArray().WhenAllOrAnyFailed(); } finally { for (int i = 0; i < clients.Length; i++) { clients[i]?.Dispose(); } for (int i = 0; i < servers.Length; i++) { servers[i]?.Dispose(); } } }