-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Re-enable dual-mode socket tests that were disabled on Linux\Mac #1481
Comments
These tests are skipped on Linux/Mac, we should revisit them for 2.1. |
Related: #1712 Third option: introduce centralized logic to distribute non-ephemeral ports to test cases in a thread-safe way. |
Triage: It needs a test refactor we postponed for years, we don't see urgency to do it in final weeks of 6.0. (Unless we expect to discover critical dual-stack bugs during the process, but this is super unlikely) |
* We have new exports that are needed. * Unshare IDynamicInterfaceCastableSupport. I thought it would be shareable, but it uses SR and throws various exceptions. Maybe not so shareable after all.
Maybe a utility like this would do the trick? public class PortBlocker : IDisposable
{
private Socket _ipv4Socket;
private Socket _ipv6Socket;
public int Port { get; private set; }
public PortBlocker(SocketType socketType = SocketType.Stream, ProtocolType protocolType = ProtocolType.Tcp)
{
// This is just a sketch.
// _ipv6Socket.Bind() may fail, so the code block below has to run in a loop until both binds are succesful!
_ipv4Socket = new Socket(AddressFamily.InterNetwork, socketType, protocolType);
Port = _ipv4Socket.BindToAnonymousPort(IPAddress.Loopback);
_ipv6Socket = new Socket(AddressFamily.InterNetworkV6, socketType, protocolType);
_ipv6Socket.Bind(new IPEndPoint(IPAddress.Loopback, Port));
}
// This could help solving the race condition between step 4-5 mentioned by the OP.
// Instead of creating a new socket, a test could just take the one created by this class.
// This will ensure that the port of the other address family is still blocked.
public Socket GetSocket(AddressFamily addressFamily)
=> addressFamily == AddressFamily.InterNetwork ? _ipv4Socket : _ipv6Socket;
public void Dispose()
{
_ipv4Socket.Dispose();
_ipv6Socket.Dispose();
}
} |
We should re-enable tests that were disabled on Linux\Mac. The tests would randomly fail because of the way that port allocation is different than on Windows. On Linux\Mac, when asking for an available free port, the returned port number is a random unused port. On Windows, it is incremental and eventually rolls over.
These tests are negative tests that connect to a V4 port and then send\listen on a V6 port (or vise-versa) of the same number expecting an unused port and thus failure case. However, in Linux\Mac there is a chance that the port is active instead of unused, causing the test to succeed, and\or interfering with a 'good' test. The port may be active on Windows too, causing similar problems, but the odds are much less as any given test run should not have active ports open that longs.
Two options to re-enable these tests:
For these to work, all other tests should be done running, including tests in other assemblies (at least those tests which use sockets).
An alternative way to re-enable these tests is to keep them in the current assembly, but change the logic to something like this to preserve the original intent of making sure the socket is isn't 'dual mode':
This alternative approach will increase reliability but there is a small chance between 4 and 5 another test grabbed that port.
However, if 3 succeeds then it probably proves that the socket wasn't dual mode because you can't bind to the same port + family twice; thus perhaps the test can stop there and not include 4-6.
See issues dotnet/corefx#16548, dotnet/corefx#9017, dotnet/corefx#13213, dotnet/corefx#17362, dotnet/corefx#17154, dotnet/corefx#13967
Tests that were disabled below, located in DualModeSocketTest.cs. Note history should be checked for each of the commits as there are cases of Linux vs. Mac differences in the original test code which needs to be accounted for when the tests are enabled again.
https://github.com/dotnet/corefx/blob/master/src/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs
The text was updated successfully, but these errors were encountered: