* [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.
public static class NetworkHelpers
{
public static class NetworkHelpers
{
+ static Random rndPort = new Random ();
+
public static int FindFreePort ()
{
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 ()
{
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) { }
+ }