Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce execution time of Socket handle inheritance tests #31813

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Threading;

namespace System.Net.Sockets.Tests
{
internal static class SocketTestExtensions
Expand Down Expand Up @@ -49,5 +51,30 @@ public static (Socket, Socket) CreateConnectedSocketPair()

return (client, server);
}

// Tries to connect within the provided timeout interval
// Useful to speed up "can not connect" assertions on Windows
public static bool TryConnect(this Socket socket, EndPoint remoteEndpoint, int millisecondsTimeout)
{
// To avoid race conditions, ManualResetEventSlim is left undisposed,
// letting SafeHandle's finalizer do the cleanup work, if needed
var mre = new ManualResetEventSlim(false);
using var sea = new SocketAsyncEventArgs()
{
RemoteEndPoint = remoteEndpoint,
UserToken = mre
};

sea.Completed += (s, e) => ((ManualResetEventSlim)e.UserToken).Set();

bool pending = socket.ConnectAsync(sea);
if (!pending || mre.Wait(millisecondsTimeout))
{
return sea.SocketError == SocketError.Success;
}

Socket.CancelConnectAsync(sea); // this will close the socket!
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ public void Ctor_Raw_NotSupported_ExpectedError(AddressFamily addressFamily, Pro
[InlineData(false, 2)]
public void CtorAndAccept_SocketNotKeptAliveViaInheritance(bool validateClientOuter, int acceptApiOuter)
{
// 300 ms should be long enough to connect if the socket is actually present & listening.
const int ConnectionTimeoutMs = 300;

// Run the test in another process so as to not have trouble with other tests
// launching child processes that might impact inheritance.
RemoteExecutor.Invoke((validateClientString, acceptApiString) =>
Expand Down Expand Up @@ -186,11 +189,13 @@ public void CtorAndAccept_SocketNotKeptAliveViaInheritance(bool validateClientOu
listener.Dispose();
using (var tmpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
Assert.ThrowsAny<SocketException>(() => tmpClient.Connect(ep));
}
bool connected = tmpClient.TryConnect(ep, ConnectionTimeoutMs);

// Let the child process terminate.
serverPipe.WriteByte(42);
// Let the child process terminate.
serverPipe.WriteByte(42);

Assert.False(connected);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,13 @@ public async Task DuplicateAndClose_TcpListener()
Assert.Equal(TestMessage, receivedMessage);
}

[OuterLoop] // long-running
[PlatformSpecific(TestPlatforms.Windows)]
[Fact]
public void DuplicateSocket_IsNotInheritable()
{
// 300 ms should be long enough to connect if the socket is actually present & listening.
const int ConnectionTimeoutMs = 300;

// The test is based on CreateSocket.CtorAndAccept_SocketNotKeptAliveViaInheritance,
// but contains simpler validation logic, sufficient to test the behavior on Windows
static void RunTest()
Expand Down Expand Up @@ -202,10 +204,9 @@ static void ChildProcessBody(string clientPipeHandle)
listenerDuplicate.Dispose();

// Validate that we after closing the listening socket, we're not able to connect:
SocketException ex = Assert.ThrowsAny<SocketException>(() => client.Connect(ep));
Debug.Print(ex.Message);

bool connected = client.TryConnect(ep, ConnectionTimeoutMs);
serverPipe.WriteByte(42);
Assert.False(connected);
}
}

Expand Down