Make Multicast tests more robust (#9053)
Motivation:
86dd388637
reverted the usage of IPv6 Multicast test. This commit makes the whole multicast testing a lot more robust by selecting the correct interface in any case and also reverts the `@Ignore`
Modifications:
- More robust multicast testing by selecting the right NetworkInterface
- Remove the `@Ignore` again for the IPv6 test
Result:
More robust multicast testing
This commit is contained in:
parent
635fc9eae0
commit
438a4d5467
@ -16,16 +16,9 @@
|
|||||||
package io.netty.testsuite.transport.socket;
|
package io.netty.testsuite.transport.socket;
|
||||||
|
|
||||||
import io.netty.channel.socket.InternetProtocolFamily;
|
import io.netty.channel.socket.InternetProtocolFamily;
|
||||||
import org.junit.Ignore;
|
|
||||||
|
|
||||||
public class DatagramMulticastIPv6Test extends DatagramMulticastTest {
|
public class DatagramMulticastIPv6Test extends DatagramMulticastTest {
|
||||||
|
|
||||||
@Ignore("Fails on some systems")
|
|
||||||
@Override
|
|
||||||
public void testMulticast() throws Throwable {
|
|
||||||
super.testMulticast();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected InternetProtocolFamily internetProtocolFamily() {
|
protected InternetProtocolFamily internetProtocolFamily() {
|
||||||
return InternetProtocolFamily.IPv6;
|
return InternetProtocolFamily.IPv6;
|
||||||
|
@ -31,10 +31,15 @@ import org.junit.Assume;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
import java.net.Inet6Address;
|
import java.net.Inet6Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.MulticastSocket;
|
||||||
|
import java.net.NetworkInterface;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
@ -50,6 +55,10 @@ public class DatagramMulticastTest extends AbstractDatagramTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testMulticast(Bootstrap sb, Bootstrap cb) throws Throwable {
|
public void testMulticast(Bootstrap sb, Bootstrap cb) throws Throwable {
|
||||||
|
NetworkInterface iface = multicastNetworkInterface();
|
||||||
|
Assume.assumeNotNull("No NetworkInterface found that supports multicast and " +
|
||||||
|
internetProtocolFamily(), iface);
|
||||||
|
|
||||||
MulticastTestHandler mhandler = new MulticastTestHandler();
|
MulticastTestHandler mhandler = new MulticastTestHandler();
|
||||||
|
|
||||||
sb.handler(new SimpleChannelInboundHandler<Object>() {
|
sb.handler(new SimpleChannelInboundHandler<Object>() {
|
||||||
@ -61,29 +70,27 @@ public class DatagramMulticastTest extends AbstractDatagramTest {
|
|||||||
|
|
||||||
cb.handler(mhandler);
|
cb.handler(mhandler);
|
||||||
|
|
||||||
sb.option(ChannelOption.IP_MULTICAST_IF, NetUtil.LOOPBACK_IF);
|
sb.option(ChannelOption.IP_MULTICAST_IF, iface);
|
||||||
sb.option(ChannelOption.SO_REUSEADDR, true);
|
sb.option(ChannelOption.SO_REUSEADDR, true);
|
||||||
cb.option(ChannelOption.IP_MULTICAST_IF, NetUtil.LOOPBACK_IF);
|
cb.option(ChannelOption.IP_MULTICAST_IF, iface);
|
||||||
cb.option(ChannelOption.SO_REUSEADDR, true);
|
cb.option(ChannelOption.SO_REUSEADDR, true);
|
||||||
|
|
||||||
Channel sc = sb.bind(newSocketAddress()).sync().channel();
|
Channel sc = sb.bind(newSocketAddress(iface)).sync().channel();
|
||||||
|
|
||||||
InetSocketAddress addr = (InetSocketAddress) sc.localAddress();
|
InetSocketAddress addr = (InetSocketAddress) sc.localAddress();
|
||||||
cb.localAddress(addr.getPort());
|
cb.localAddress(addr.getPort());
|
||||||
|
|
||||||
DatagramChannel cc = (DatagramChannel) cb.bind().sync().channel();
|
DatagramChannel cc = (DatagramChannel) cb.bind().sync().channel();
|
||||||
|
|
||||||
String group = internetProtocolFamily() == InternetProtocolFamily.IPv4 ?
|
InetSocketAddress groupAddress = SocketUtils.socketAddress(groupAddress(), addr.getPort());
|
||||||
"230.0.0.1" : "FF01:0:0:0:0:0:0:101";
|
|
||||||
InetSocketAddress groupAddress = SocketUtils.socketAddress(group, addr.getPort());
|
|
||||||
|
|
||||||
cc.joinGroup(groupAddress, NetUtil.LOOPBACK_IF).sync();
|
cc.joinGroup(groupAddress, iface).sync();
|
||||||
|
|
||||||
sc.writeAndFlush(new DatagramPacket(Unpooled.copyInt(1), groupAddress)).sync();
|
sc.writeAndFlush(new DatagramPacket(Unpooled.copyInt(1), groupAddress)).sync();
|
||||||
assertTrue(mhandler.await());
|
assertTrue(mhandler.await());
|
||||||
|
|
||||||
// leave the group
|
// leave the group
|
||||||
cc.leaveGroup(groupAddress, NetUtil.LOOPBACK_IF).sync();
|
cc.leaveGroup(groupAddress, iface).sync();
|
||||||
|
|
||||||
// sleep a second to make sure we left the group
|
// sleep a second to make sure we left the group
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
@ -126,24 +133,63 @@ public class DatagramMulticastTest extends AbstractDatagramTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
|
||||||
public void assumeInternetProtocolFamilySupported() {
|
|
||||||
Assume.assumeTrue(isSupported(internetProtocolFamily() == InternetProtocolFamily.IPv4 ?
|
|
||||||
Inet4Address.class : Inet6Address.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isSupported(Class<? extends InetAddress> addressType) {
|
|
||||||
Enumeration<InetAddress> addresses = NetUtil.LOOPBACK_IF.getInetAddresses();
|
|
||||||
while (addresses.hasMoreElements()) {
|
|
||||||
if (addressType.isAssignableFrom(addresses.nextElement().getClass())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> newFactories() {
|
protected List<TestsuitePermutation.BootstrapComboFactory<Bootstrap, Bootstrap>> newFactories() {
|
||||||
return SocketTestPermutation.INSTANCE.datagram(internetProtocolFamily());
|
return SocketTestPermutation.INSTANCE.datagram(internetProtocolFamily());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private InetSocketAddress newAnySocketAddress() throws UnknownHostException {
|
||||||
|
switch (internetProtocolFamily()) {
|
||||||
|
case IPv4:
|
||||||
|
return new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0);
|
||||||
|
case IPv6:
|
||||||
|
return new InetSocketAddress(InetAddress.getByName("::"), 0);
|
||||||
|
default:
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private InetSocketAddress newSocketAddress(NetworkInterface iface) {
|
||||||
|
Enumeration<InetAddress> addresses = iface.getInetAddresses();
|
||||||
|
while (addresses.hasMoreElements()) {
|
||||||
|
InetAddress address = addresses.nextElement();
|
||||||
|
if (internetProtocolFamily().addressType().isAssignableFrom(address.getClass())) {
|
||||||
|
return new InetSocketAddress(address, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkInterface multicastNetworkInterface() throws IOException {
|
||||||
|
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
|
||||||
|
while (interfaces.hasMoreElements()) {
|
||||||
|
NetworkInterface iface = interfaces.nextElement();
|
||||||
|
if (iface.isUp() && iface.supportsMulticast()) {
|
||||||
|
Enumeration<InetAddress> addresses = iface.getInetAddresses();
|
||||||
|
while (addresses.hasMoreElements()) {
|
||||||
|
InetAddress address = addresses.nextElement();
|
||||||
|
if (internetProtocolFamily().addressType().isAssignableFrom(address.getClass())) {
|
||||||
|
MulticastSocket socket = new MulticastSocket(newAnySocketAddress());
|
||||||
|
socket.setReuseAddress(true);
|
||||||
|
socket.setNetworkInterface(iface);
|
||||||
|
try {
|
||||||
|
socket.send(new java.net.DatagramPacket(new byte[] { 1, 2, 3, 4 }, 4,
|
||||||
|
new InetSocketAddress(groupAddress(), 12345)));
|
||||||
|
return iface;
|
||||||
|
} catch (IOException ignore) {
|
||||||
|
// Try the next interface
|
||||||
|
} finally {
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String groupAddress() {
|
||||||
|
return internetProtocolFamily() == InternetProtocolFamily.IPv4 ?
|
||||||
|
"230.0.0.1" : "FF01:0:0:0:0:0:0:101";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user