Fix sporadic failures in DatagramUnicastTest

Motivation:

DatagramUnitcastTest sometimes fails with BindException for an unknown reason.

Modifications:

Retry up to 3 times with a new free port when bind() fails with BindException

Result:

More build stability
This commit is contained in:
Trustin Lee 2015-06-01 17:31:14 +09:00
parent 5f59591a72
commit 4d79be44ef
2 changed files with 41 additions and 9 deletions

View File

@ -48,4 +48,9 @@ public abstract class AbstractDatagramTest extends AbstractComboTestsuiteTest<Bo
bootstrap2.localAddress(0).remoteAddress(addr); bootstrap2.localAddress(0).remoteAddress(addr);
bootstrap2.option(ChannelOption.ALLOCATOR, allocator); bootstrap2.option(ChannelOption.ALLOCATOR, allocator);
} }
protected void refreshLocalAddress(Bootstrap bootstrap) {
addr = new InetSocketAddress(NetUtil.LOCALHOST4, TestUtils.getFreePort());
bootstrap.localAddress(addr);
}
} }

View File

@ -21,11 +21,13 @@ import io.netty.buffer.CompositeByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption; import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket; import io.netty.channel.socket.DatagramPacket;
import org.junit.Test; import org.junit.Test;
import java.net.BindException;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -127,17 +129,22 @@ public class DatagramUnicastTest extends AbstractDatagramTest {
throws Throwable { throws Throwable {
final CountDownLatch latch = new CountDownLatch(count); final CountDownLatch latch = new CountDownLatch(count);
sb.handler(new SimpleChannelInboundHandler<DatagramPacket>() { sb.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new SimpleChannelInboundHandler<DatagramPacket>() {
@Override @Override
public void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { public void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
ByteBuf buf = msg.content(); ByteBuf buf = msg.content();
assertEquals(bytes.length, buf.readableBytes()); assertEquals(bytes.length, buf.readableBytes());
for (int i = 0; i < bytes.length; i++) { for (byte b: bytes) {
assertEquals(bytes[i], buf.readByte()); assertEquals(b, buf.readByte());
} }
latch.countDown(); latch.countDown();
} }
}); });
}
});
cb.handler(new SimpleChannelInboundHandler<Object>() { cb.handler(new SimpleChannelInboundHandler<Object>() {
@Override @Override
@ -146,7 +153,27 @@ public class DatagramUnicastTest extends AbstractDatagramTest {
} }
}); });
Channel sc = sb.bind().sync().channel(); Channel sc = null;
BindException bindFailureCause = null;
for (int i = 0; i < 3; i ++) {
try {
sc = sb.bind().sync().channel();
break;
} catch (Exception e) {
if (e instanceof BindException) {
logger.warn("Failed to bind to a free port; trying again", e);
bindFailureCause = (BindException) e;
refreshLocalAddress(sb);
} else {
throw e;
}
}
}
if (sc == null) {
throw bindFailureCause;
}
Channel cc; Channel cc;
if (bindClient) { if (bindClient) {
cc = cb.bind().sync().channel(); cc = cb.bind().sync().channel();