Testing: Ensure RepeatOnExceptionRule is available in test-jar

This moves the rule, so it is made available in the test.jar. In
addition, you can now specify the exception, which triggers a rerun
of the test in order to make it reusable for others.

Also ensured that the NettyTransportTest frees all resources inside
of its testing method instead of pre/post running methods, as those
are still called only once, even though a failed test might be repeated.
This commit is contained in:
Alexander Reelsen 2015-02-12 11:22:15 +01:00
parent f500293ffb
commit ce24e10783
2 changed files with 60 additions and 48 deletions

View File

@ -16,10 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.transport.netty;
package org.elasticsearch.test.junit.rule;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.transport.BindTransportException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
@ -27,20 +26,28 @@ import org.junit.runners.model.Statement;
/**
* A helper rule to catch all BindTransportExceptions
* and rerun the test for a configured number of times
*
* Note: Be aware, that when a test is repeated, the @After and @Before
* annotated methods are not run a second time
*
*/
public class RepeatOnBindExceptionRule implements TestRule {
public class RepeatOnExceptionRule implements TestRule {
private ESLogger logger;
private int retryCount;
private Class expectedException;
/**
*
* @param logger the es logger from the test class
* @param retryCount number of amounts to try a single test before failing
* @param expectedException The exception class you want to catch
*
*/
public RepeatOnBindExceptionRule(ESLogger logger, int retryCount) {
public RepeatOnExceptionRule(ESLogger logger, int retryCount, Class expectedException) {
this.logger = logger;
this.retryCount = retryCount;
this.expectedException = expectedException;
}
@Override
@ -55,9 +62,11 @@ public class RepeatOnBindExceptionRule implements TestRule {
try {
base.evaluate();
return;
} catch (BindTransportException t) {
caughtThrowable = t;
logger.info("Bind exception occurred, rerunning the test after [{}] failures", t, i+1);
} catch (Throwable t) {
if (t.getClass().equals(expectedException)) {
caughtThrowable = t;
logger.info("Exception [{}] occurred, rerunning the test after [{}] failures", t, t.getClass().getSimpleName(), i+1);
}
}
}
logger.error("Giving up after [{}] failures... marking test as failed", retryCount);

View File

@ -30,9 +30,10 @@ import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.test.junit.rule.RepeatOnExceptionRule;
import org.elasticsearch.test.cache.recycler.MockBigArrays;
import org.elasticsearch.threadpool.ThreadPool;
import org.junit.After;
import org.elasticsearch.transport.BindTransportException;
import org.junit.Rule;
import org.junit.Test;
@ -47,23 +48,10 @@ import static org.hamcrest.Matchers.is;
public class NettyTransportMultiPortTests extends ElasticsearchTestCase {
public static int MAX_RETRIES = 10;
private static final int MAX_RETRIES = 10;
@Rule
public RepeatOnBindExceptionRule repeatOnBindExceptionRule = new RepeatOnBindExceptionRule(logger, MAX_RETRIES);
private NettyTransport nettyTransport;
private ThreadPool threadPool;
@After
public void shutdownNettyTransport() {
if (nettyTransport != null) {
nettyTransport.stop();
}
if (threadPool != null) {
threadPool.shutdownNow();
}
}
public RepeatOnExceptionRule repeatOnBindExceptionRule = new RepeatOnExceptionRule(logger, MAX_RETRIES, BindTransportException.class);
@Test
public void testThatNettyCanBindToMultiplePorts() throws Exception {
@ -76,11 +64,14 @@ public class NettyTransportMultiPortTests extends ElasticsearchTestCase {
.put("transport.profiles.client1.port", ports[2])
.build();
startNettyTransport(settings);
assertConnectionRefused(ports[0]);
assertPortIsBound(ports[1]);
assertPortIsBound(ports[2]);
ThreadPool threadPool = new ThreadPool("tst");
try (NettyTransport ignored = startNettyTransport(settings, threadPool)) {
assertConnectionRefused(ports[0]);
assertPortIsBound(ports[1]);
assertPortIsBound(ports[2]);
} finally {
threadPool.shutdownNow();
}
}
@Test
@ -93,10 +84,13 @@ public class NettyTransportMultiPortTests extends ElasticsearchTestCase {
.put("transport.profiles.client1.port", ports[1])
.build();
startNettyTransport(settings);
assertPortIsBound(ports[0]);
assertPortIsBound(ports[1]);
ThreadPool threadPool = new ThreadPool("tst");
try (NettyTransport ignored = startNettyTransport(settings, threadPool)) {
assertPortIsBound(ports[0]);
assertPortIsBound(ports[1]);
} finally {
threadPool.shutdownNow();
}
}
@Test
@ -109,9 +103,12 @@ public class NettyTransportMultiPortTests extends ElasticsearchTestCase {
.put("transport.profiles.client1.whatever", "foo")
.build();
startNettyTransport(settings);
assertPortIsBound(ports[0]);
ThreadPool threadPool = new ThreadPool("tst");
try (NettyTransport ignored = startNettyTransport(settings, threadPool)) {
assertPortIsBound(ports[0]);
} finally {
threadPool.shutdownNow();
}
}
@Test
@ -125,11 +122,14 @@ public class NettyTransportMultiPortTests extends ElasticsearchTestCase {
.put("transport.profiles.default.port", ports[2])
.build();
startNettyTransport(settings);
assertConnectionRefused(ports[0]);
assertConnectionRefused(ports[1]);
assertPortIsBound(ports[2]);
ThreadPool threadPool = new ThreadPool("tst");
try (NettyTransport ignored = startNettyTransport(settings, threadPool)) {
assertConnectionRefused(ports[0]);
assertConnectionRefused(ports[1]);
assertPortIsBound(ports[2]);
} finally {
threadPool.shutdownNow();
}
}
@Test
@ -145,11 +145,14 @@ public class NettyTransportMultiPortTests extends ElasticsearchTestCase {
.put("transport.profiles.client1.port", ports[1])
.build();
startNettyTransport(settings);
assertPortIsBound("127.0.0.1", ports[0]);
assertPortIsBound(firstNonLoopbackAddress.getHostAddress(), ports[1]);
assertConnectionRefused(ports[1]);
ThreadPool threadPool = new ThreadPool("tst");
try (NettyTransport ignored = startNettyTransport(settings, threadPool)) {
assertPortIsBound("127.0.0.1", ports[0]);
assertPortIsBound(firstNonLoopbackAddress.getHostAddress(), ports[1]);
assertConnectionRefused(ports[1]);
} finally {
threadPool.shutdownNow();
}
}
private int[] getRandomPorts(int numberOfPorts) {
@ -166,14 +169,14 @@ public class NettyTransportMultiPortTests extends ElasticsearchTestCase {
return ports.toArray();
}
private void startNettyTransport(Settings settings) {
threadPool = new ThreadPool("tst");
private NettyTransport startNettyTransport(Settings settings, ThreadPool threadPool) {
BigArrays bigArrays = new MockBigArrays(settings, new PageCacheRecycler(settings, threadPool), new NoneCircuitBreakerService());
nettyTransport = new NettyTransport(settings, threadPool, new NetworkService(settings), bigArrays, Version.CURRENT);
NettyTransport nettyTransport = new NettyTransport(settings, threadPool, new NetworkService(settings), bigArrays, Version.CURRENT);
nettyTransport.start();
assertThat(nettyTransport.lifecycleState(), is(Lifecycle.State.STARTED));
return nettyTransport;
}
private void assertConnectionRefused(int port) throws Exception {