From: Alexander Köplinger Date: Fri, 4 Aug 2017 18:22:50 +0000 (+0200) Subject: [bcl] Grab free ports randomly in NetworkHelpers (#5312) X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=24c3624fee9c8fd643a9c7faba185e04f62f4993 [bcl] Grab free ports randomly in NetworkHelpers (#5312) * [bcl] Grab free ports randomly in NetworkHelpers We're frequently seeing "address already in use" errors on Jenkins. The theory is that when we're running tests and grab the next free port via our custom NetworkHelpers we're getting a port which will also be returned to a simultaneously running test (e.g. another chroot) because we're closing the TcpListener and thus releasing the port until we start using it in actual test code. By that time the other test might've already opened the port, causing our test to fail. Instead we now try to use a random port in the range 10000-60000 and try if it's available. This doesn't completely fix the inherent race but should hopefully make it way less likely. --- diff --git a/mcs/class/test-helpers/NetworkHelpers.cs b/mcs/class/test-helpers/NetworkHelpers.cs index fcb63961d23..7ebc1fc9c15 100644 --- a/mcs/class/test-helpers/NetworkHelpers.cs +++ b/mcs/class/test-helpers/NetworkHelpers.cs @@ -6,17 +6,25 @@ namespace MonoTests.Helpers { public static class NetworkHelpers { + static Random rndPort = new Random (); + public static int FindFreePort () { - TcpListener l = new TcpListener(IPAddress.Loopback, 0); - l.Start(); - int port = ((IPEndPoint)l.LocalEndpoint).Port; - l.Stop(); - return port; + return LocalEphemeralEndPoint ().Port; } + public static IPEndPoint LocalEphemeralEndPoint () { - return new IPEndPoint (IPAddress.Loopback, FindFreePort()); + while (true) { + var ep = new IPEndPoint (IPAddress.Loopback, rndPort.Next (10000, 60000)); + var socket = new Socket (ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + + try { + socket.Bind (ep); + socket.Close (); + return ep; + } catch (SocketException) { } + } } } }