reworked this so that it now properly retries one time while still doing each test twice - once for classic and once for standard
Project: http://git-wip-us.apache.org/repos/asf/curator/repo Commit: http://git-wip-us.apache.org/repos/asf/curator/commit/acd90971 Tree: http://git-wip-us.apache.org/repos/asf/curator/tree/acd90971 Diff: http://git-wip-us.apache.org/repos/asf/curator/diff/acd90971 Branch: refs/heads/master Commit: acd90971dafd9c3b4373f45734dd9f8f88a165ce Parents: 90b39dd Author: randgalt <randg...@apache.org> Authored: Wed Jan 11 00:28:11 2017 -0500 Committer: randgalt <randg...@apache.org> Committed: Wed Jan 11 00:28:11 2017 -0500 ---------------------------------------------------------------------- .../apache/curator/test/BaseClassForTests.java | 152 +++++++++++++++---- 1 file changed, 125 insertions(+), 27 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/curator/blob/acd90971/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java ---------------------------------------------------------------------- diff --git a/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java b/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java index a5afaf2..fe4acd2 100644 --- a/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java +++ b/curator-test/src/main/java/org/apache/curator/test/BaseClassForTests.java @@ -22,16 +22,19 @@ package org.apache.curator.test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.IInvokedMethod; -import org.testng.IInvokedMethodListener; +import org.testng.IInvokedMethodListener2; +import org.testng.IRetryAnalyzer; import org.testng.ITestContext; -import org.testng.ITestNGListener; import org.testng.ITestNGMethod; import org.testng.ITestResult; +import org.testng.TestListenerAdapter; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeSuite; import java.io.IOException; import java.net.BindException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; public class BaseClassForTests { @@ -84,31 +87,7 @@ public class BaseClassForTests @BeforeSuite(alwaysRun = true) public void beforeSuite(ITestContext context) { - if ( !enabledSessionExpiredStateAware() ) - { - ITestNGListener listener = new IInvokedMethodListener() - { - @Override - public void beforeInvocation(IInvokedMethod method, ITestResult testResult) - { - int invocationCount = method.getTestMethod().getCurrentInvocationCount(); - System.setProperty("curator-use-classic-connection-handling", Boolean.toString(invocationCount == 1)); - log.info("curator-use-classic-connection-handling: " + Boolean.toString(invocationCount == 1)); - } - - @Override - public void afterInvocation(IInvokedMethod method, ITestResult testResult) - { - System.clearProperty("curator-use-classic-connection-handling"); - } - }; - context.getSuite().addListener(listener); - } - - for ( ITestNGMethod method : context.getAllTestMethods() ) - { - method.setInvocationCount(enabledSessionExpiredStateAware() ? 1 : 2); - } + context.getSuite().addListener(new MethodListener(log, enabledSessionExpiredStateAware())); } @BeforeMethod @@ -161,4 +140,123 @@ public class BaseClassForTests { return false; } + + private static class RetryContext + { + final AtomicBoolean isRetrying = new AtomicBoolean(false); + final AtomicInteger runVersion = new AtomicInteger(0); + } + + private static class RetryAnalyzer implements IRetryAnalyzer + { + private final Logger log; + private final RetryContext retryContext; + + RetryAnalyzer(Logger log, RetryContext retryContext) + { + this.log = log; + this.retryContext = retryContext; + } + + @Override + public boolean retry(ITestResult result) + { + if ( result.isSuccess() || retryContext.isRetrying.get() ) + { + retryContext.isRetrying.set(false); + return false; + } + + log.error("Retrying 1 time"); + retryContext.isRetrying.set(true); + return true; + } + } + + private static class MethodListener implements IInvokedMethodListener2 + { + private final Logger log; + private final boolean sessionExpiredStateAware; + + private static final String ATTRIBUTE_NAME = "__curator"; + + MethodListener(Logger log, boolean sessionExpiredStateAware) + { + this.log = log; + this.sessionExpiredStateAware = sessionExpiredStateAware; + } + + @Override + public void beforeInvocation(IInvokedMethod method, ITestResult testResult) + { + // NOP + } + + @Override + public void afterInvocation(IInvokedMethod method, ITestResult testResult) + { + // NOP + } + + @Override + public void beforeInvocation(IInvokedMethod method, ITestResult testResult, ITestContext context) + { + if ( method.getTestMethod().isBeforeMethodConfiguration() ) + { + TestListenerAdapter x = null; + RetryContext retryContext = (RetryContext)context.getAttribute(ATTRIBUTE_NAME); + if ( retryContext == null ) + { + retryContext = new RetryContext(); + context.setAttribute(ATTRIBUTE_NAME, retryContext); + } + + if ( !sessionExpiredStateAware ) + { + System.setProperty("curator-use-classic-connection-handling", Boolean.toString(retryContext.runVersion.get() > 0)); + log.info("curator-use-classic-connection-handling: " + Boolean.toString(retryContext.runVersion.get() > 0)); + } + } + else if ( method.isTestMethod() ) + { + method.getTestMethod().setRetryAnalyzer(new RetryAnalyzer(log, (RetryContext)context.getAttribute(ATTRIBUTE_NAME))); + } + } + + @Override + public void afterInvocation(IInvokedMethod method, ITestResult testResult, ITestContext context) + { + if ( method.getTestMethod().isBeforeSuiteConfiguration() && !sessionExpiredStateAware ) + { + for ( ITestNGMethod testMethod : context.getAllTestMethods() ) + { + testMethod.setInvocationCount(2); + } + } + + if ( method.isTestMethod() ) + { + RetryContext retryContext = (RetryContext)context.getAttribute(ATTRIBUTE_NAME); + if ( retryContext == null ) + { + log.error("No retryContext!"); + } + else + { + System.clearProperty("curator-use-classic-connection-handling"); + if ( testResult.isSuccess() ) + { + retryContext.isRetrying.set(false); + } + if ( testResult.isSuccess() || retryContext.isRetrying.get() ) + { + if ( retryContext.runVersion.incrementAndGet() > 1 ) + { + context.setAttribute(ATTRIBUTE_NAME, null); + } + } + } + } + } + } }