Author: erans Date: Tue Mar 29 10:28:37 2011 New Revision: 1086539 URL: http://svn.apache.org/viewvc?rev=1086539&view=rev Log: MATH-423 The "@Retry" annotation allows to select the number of retries of a Junit test method (provided that the test class is itself annotated with "@RunWith(RetryRunner.class).
Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/Retry.java (with props) commons/proper/math/trunk/src/test/java/org/apache/commons/math/RetryRunnerTest.java (with props) Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/RetryRunner.java Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/Retry.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/Retry.java?rev=1086539&view=auto ============================================================================== --- commons/proper/math/trunk/src/test/java/org/apache/commons/math/Retry.java (added) +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/Retry.java Tue Mar 29 10:28:37 2011 @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.math; + +import java.lang.annotation.*; + +/** + * Annotation that enables test retries. + * @version $Id$ + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface Retry { + int value() default 2; +} Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math/Retry.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/RetryRunner.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/RetryRunner.java?rev=1086539&r1=1086538&r2=1086539&view=diff ============================================================================== --- commons/proper/math/trunk/src/test/java/org/apache/commons/math/RetryRunner.java (original) +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/RetryRunner.java Tue Mar 29 10:28:37 2011 @@ -28,13 +28,11 @@ import org.junit.runners.model.Statement * @version $Revision$ $Date$ */ public class RetryRunner extends BlockJUnit4ClassRunner { - - /** Maximal number of test run attempts. */ - private static final int MAX_ATTEMPTS = 3; - - /** Simple constructor. - * @param testClass class to test - * @throws InitializationError if default runner cannot be built + /** + * Simple constructor. + * + * @param testClass Class to test. + * @throws InitializationError if default runner cannot be built. */ public RetryRunner(final Class<?> testClass) throws InitializationError { @@ -42,37 +40,42 @@ public class RetryRunner extends BlockJU } @Override - public Statement methodInvoker(FrameworkMethod method, Object test) { + public Statement methodInvoker(final FrameworkMethod method, + Object test) { final Statement singleTryStatement = super.methodInvoker(method, test); return new Statement() { - - /** Evaluate the statement. + /** + * Evaluate the statement. * We attempt several runs for the test, at most MAX_ATTEMPTS. * if one attempt succeeds, we succeed, if all attempts fail, we * fail with the reason corresponding to the last attempt */ public void evaluate() throws Throwable { Throwable failureReason = null; - for (int i = 0; i < MAX_ATTEMPTS; ++i) { - try { - - // do one test run attempt - singleTryStatement.evaluate(); - - // attempt succeeded, stop evaluation here - return; - } catch (Throwable t) { - // attempt failed, store the reason why - failureReason = t; + final Retry retry = method.getAnnotation(Retry.class); + if (retry == null) { + // Do a single test run attempt. + singleTryStatement.evaluate(); + } else { + final int numRetries = retry.value(); + + for (int i = 0; i < numRetries; ++i) { + try { + // Do a single test run attempt. + singleTryStatement.evaluate(); + // Attempt succeeded, stop evaluation here. + return; + } catch (Throwable t) { + // Attempt failed, store the reason. + failureReason = t; + } } - } - - // all attempts failed - throw failureReason; + // All attempts failed. + throw failureReason; + } } }; } - } Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/RetryRunnerTest.java URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/RetryRunnerTest.java?rev=1086539&view=auto ============================================================================== --- commons/proper/math/trunk/src/test/java/org/apache/commons/math/RetryRunnerTest.java (added) +++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/RetryRunnerTest.java Tue Mar 29 10:28:37 2011 @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.math; + +import java.util.Random; + +import org.apache.commons.math.exception.MathRuntimeException; + +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Test for the "Retry" functionality (retrying Junit test methods). + */ +@RunWith(RetryRunner.class) +public class RetryRunnerTest { + final Random rng = new Random(); + + /** + * Shows that an always failing test will fail even if it is retried. + */ + @Test(expected=MathRuntimeException.class) + @Retry + public void testRetryFailAlways() { + throw new MathRuntimeException(); + } + + /** + * Shows that a test that sometimes fail might succeed if it is retried. + * In this case the high number of retries makes it quite unlikely that + * the exception will be thrown by all of the calls. + */ + @Test + @Retry(100) + public void testRetryFailSometimes() { + if (rng.nextBoolean()) { + throw new MathRuntimeException(); + } + } +} Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math/RetryRunnerTest.java ------------------------------------------------------------------------------ svn:eol-style = native