Fix NioEventLoopTest#testChannelsRegistered flakiness (#9650)
Motivation NioEventLoopTest#testChannelsRegistered() fails intermittently due to use of SingleThreadEventLoop#channelsRegistered() which is not threadsafe and unreliable when called from outside the event loop. Modifications Add static registeredChannels method to NioEventLoopTest and AbstractSingleThreadEventLoopTest to call from the tests via event loop instead of directly. Result Hopefully fewer test failures
This commit is contained in:
parent
271d8de9ec
commit
99a4cecec6
@ -20,6 +20,7 @@ import static org.junit.Assert.assertFalse;
|
|||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -42,7 +43,7 @@ import io.netty.util.concurrent.Future;
|
|||||||
public abstract class AbstractSingleThreadEventLoopTest {
|
public abstract class AbstractSingleThreadEventLoopTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testChannelsRegistered() {
|
public void testChannelsRegistered() throws Exception {
|
||||||
EventLoopGroup group = newEventLoopGroup();
|
EventLoopGroup group = newEventLoopGroup();
|
||||||
final SingleThreadEventLoop loop = (SingleThreadEventLoop) group.next();
|
final SingleThreadEventLoop loop = (SingleThreadEventLoop) group.next();
|
||||||
|
|
||||||
@ -50,28 +51,38 @@ public abstract class AbstractSingleThreadEventLoopTest {
|
|||||||
final Channel ch1 = newChannel();
|
final Channel ch1 = newChannel();
|
||||||
final Channel ch2 = newChannel();
|
final Channel ch2 = newChannel();
|
||||||
|
|
||||||
int rc = loop.registeredChannels();
|
int rc = registeredChannels(loop);
|
||||||
boolean channelCountSupported = rc != -1;
|
boolean channelCountSupported = rc != -1;
|
||||||
|
|
||||||
if (channelCountSupported) {
|
if (channelCountSupported) {
|
||||||
assertEquals(0, loop.registeredChannels());
|
assertEquals(0, registeredChannels(loop));
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(loop.register(ch1).syncUninterruptibly().isSuccess());
|
assertTrue(loop.register(ch1).syncUninterruptibly().isSuccess());
|
||||||
assertTrue(loop.register(ch2).syncUninterruptibly().isSuccess());
|
assertTrue(loop.register(ch2).syncUninterruptibly().isSuccess());
|
||||||
if (channelCountSupported) {
|
if (channelCountSupported) {
|
||||||
assertEquals(2, loop.registeredChannels());
|
assertEquals(2, registeredChannels(loop));
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(ch1.deregister().syncUninterruptibly().isSuccess());
|
assertTrue(ch1.deregister().syncUninterruptibly().isSuccess());
|
||||||
if (channelCountSupported) {
|
if (channelCountSupported) {
|
||||||
assertEquals(1, loop.registeredChannels());
|
assertEquals(1, registeredChannels(loop));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
group.shutdownGracefully();
|
group.shutdownGracefully();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only reliable if run from event loop
|
||||||
|
private static int registeredChannels(final SingleThreadEventLoop loop) throws Exception {
|
||||||
|
return loop.submit(new Callable<Integer>() {
|
||||||
|
@Override
|
||||||
|
public Integer call() {
|
||||||
|
return loop.registeredChannels();
|
||||||
|
}
|
||||||
|
}).get(1, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public void shutdownBeforeStart() throws Exception {
|
public void shutdownBeforeStart() throws Exception {
|
||||||
|
@ -23,6 +23,7 @@ import io.netty.channel.EventLoopGroup;
|
|||||||
import io.netty.channel.EventLoopTaskQueueFactory;
|
import io.netty.channel.EventLoopTaskQueueFactory;
|
||||||
import io.netty.channel.SelectStrategy;
|
import io.netty.channel.SelectStrategy;
|
||||||
import io.netty.channel.SelectStrategyFactory;
|
import io.netty.channel.SelectStrategyFactory;
|
||||||
|
import io.netty.channel.SingleThreadEventLoop;
|
||||||
import io.netty.channel.socket.ServerSocketChannel;
|
import io.netty.channel.socket.ServerSocketChannel;
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
import io.netty.util.IntSupplier;
|
import io.netty.util.IntSupplier;
|
||||||
@ -42,6 +43,7 @@ import java.nio.channels.Selector;
|
|||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.nio.channels.spi.SelectorProvider;
|
import java.nio.channels.spi.SelectorProvider;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
@ -269,7 +271,7 @@ public class NioEventLoopTest extends AbstractEventLoopTest {
|
|||||||
|
|
||||||
@Ignore
|
@Ignore
|
||||||
@Test
|
@Test
|
||||||
public void testChannelsRegistered() {
|
public void testChannelsRegistered() throws Exception {
|
||||||
NioEventLoopGroup group = new NioEventLoopGroup(1);
|
NioEventLoopGroup group = new NioEventLoopGroup(1);
|
||||||
final NioEventLoop loop = (NioEventLoop) group.next();
|
final NioEventLoop loop = (NioEventLoop) group.next();
|
||||||
|
|
||||||
@ -277,19 +279,29 @@ public class NioEventLoopTest extends AbstractEventLoopTest {
|
|||||||
final Channel ch1 = new NioServerSocketChannel();
|
final Channel ch1 = new NioServerSocketChannel();
|
||||||
final Channel ch2 = new NioServerSocketChannel();
|
final Channel ch2 = new NioServerSocketChannel();
|
||||||
|
|
||||||
assertEquals(0, loop.registeredChannels());
|
assertEquals(0, registeredChannels(loop));
|
||||||
|
|
||||||
assertTrue(loop.register(ch1).syncUninterruptibly().isSuccess());
|
assertTrue(loop.register(ch1).syncUninterruptibly().isSuccess());
|
||||||
assertTrue(loop.register(ch2).syncUninterruptibly().isSuccess());
|
assertTrue(loop.register(ch2).syncUninterruptibly().isSuccess());
|
||||||
assertEquals(2, loop.registeredChannels());
|
assertEquals(2, registeredChannels(loop));
|
||||||
|
|
||||||
assertTrue(ch1.deregister().syncUninterruptibly().isSuccess());
|
assertTrue(ch1.deregister().syncUninterruptibly().isSuccess());
|
||||||
assertEquals(1, loop.registeredChannels());
|
assertEquals(1, registeredChannels(loop));
|
||||||
} finally {
|
} finally {
|
||||||
group.shutdownGracefully();
|
group.shutdownGracefully();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only reliable if run from event loop
|
||||||
|
private static int registeredChannels(final SingleThreadEventLoop loop) throws Exception {
|
||||||
|
return loop.submit(new Callable<Integer>() {
|
||||||
|
@Override
|
||||||
|
public Integer call() {
|
||||||
|
return loop.registeredChannels();
|
||||||
|
}
|
||||||
|
}).get(1, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCustomQueue() {
|
public void testCustomQueue() {
|
||||||
final AtomicBoolean called = new AtomicBoolean();
|
final AtomicBoolean called = new AtomicBoolean();
|
||||||
|
Loading…
Reference in New Issue
Block a user