You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2015/08/21 22:29:35 UTC
[8/9] incubator-geode git commit: More examples and rules
More examples and rules
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/d0c03307
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/d0c03307
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/d0c03307
Branch: refs/heads/feature/GEODE-217
Commit: d0c033074b239162ea6d2f5fde7ac8e329402a24
Parents: 33d2c1c
Author: Kirk Lund <kl...@pivotal.io>
Authored: Fri Aug 21 13:27:27 2015 -0700
Committer: Kirk Lund <kl...@pivotal.io>
Committed: Fri Aug 21 13:27:27 2015 -0700
----------------------------------------------------------------------
.../test/assertj/AssertJExampleJUnitTest.java | 119 ++++++++
.../CatchExceptionExampleDUnitTest.java | 59 ++++
.../CatchExceptionExampleJUnitTest.java | 99 +++++++
.../JUnitParamsExampleJUnitTest.java | 36 +++
.../com/gemstone/gemfire/test/junit/Repeat.java | 26 ++
.../test/junit/rules/ExpectedTimeoutRule.java | 164 +++++++++++
.../gemfire/test/junit/rules/RepeatRule.java | 57 ++++
.../tests/ExpectedTimeoutRuleJUnitTest.java | 206 ++++++++++++++
.../junit/rules/tests/JUnitRuleTestSuite.java | 16 ++
.../junit/rules/tests/RepeatRuleJUnitTest.java | 278 +++++++++++++++++++
.../RetryRuleGlobalWithErrorJUnitTest.java | 247 ++++++++++++++++
.../RetryRuleGlobalWithExceptionJUnitTest.java | 253 +++++++++++++++++
.../tests/RetryRuleLocalWithErrorJUnitTest.java | 206 ++++++++++++++
.../RetryRuleLocalWithExceptionJUnitTest.java | 221 +++++++++++++++
14 files changed, 1987 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-core/src/test/java/com/gemstone/gemfire/test/assertj/AssertJExampleJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/assertj/AssertJExampleJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/assertj/AssertJExampleJUnitTest.java
new file mode 100755
index 0000000..aaa6a84
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/assertj/AssertJExampleJUnitTest.java
@@ -0,0 +1,119 @@
+package com.gemstone.gemfire.test.assertj;
+
+import static org.assertj.core.api.Assertions.*;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class AssertJExampleJUnitTest {
+
+ private Character aragorn;
+ private Character boromir;
+ private Character elrond;
+ private Character frodo;
+ private Character galadriel;
+ private Character gandalf;
+ private Character gimli;
+ private Character legolas;
+ private Character merry;
+ private Character pippin;
+ private Character sauron;
+ private Character sam;
+
+ private Ring narya;
+ private Ring nenya;
+ private Ring oneRing;
+ private Ring vilya;
+
+ private Set<Character> fellowshipOfTheRing;
+ private Map<Ring, Character> ringBearers;
+
+ @Before
+ public void setUp() {
+ this.aragorn = new Character("Aragorn");
+ this.boromir = new Character("Boromir");
+ this.elrond = new Character("Elrond");
+ this.frodo = new Character("Frodo");
+ this.galadriel = new Character("Galadriel");
+ this.gandalf = new Character("Gandalf");
+ this.gimli = new Character("Gimli");
+ this.legolas = new Character("Legolas");
+ this.merry = new Character("Merry");
+ this.pippin = new Character("Pippin");
+ this.sauron = new Character("Sauron");
+ this.sam = new Character("Sam");
+
+ this.narya = new Ring();
+ this.nenya = new Ring();
+ this.oneRing = new Ring();
+ this.vilya = new Ring();
+
+ this.fellowshipOfTheRing = new HashSet<Character>();
+ this.fellowshipOfTheRing.add(this.aragorn);
+ this.fellowshipOfTheRing.add(this.boromir);
+ this.fellowshipOfTheRing.add(this.frodo);
+ this.fellowshipOfTheRing.add(this.gandalf);
+ this.fellowshipOfTheRing.add(this.gimli);
+ this.fellowshipOfTheRing.add(this.legolas);
+ this.fellowshipOfTheRing.add(this.merry);
+ this.fellowshipOfTheRing.add(this.pippin);
+ this.fellowshipOfTheRing.add(this.sam);
+
+ this.ringBearers = new HashMap<Ring, Character>();
+ this.ringBearers.put(this.oneRing, this.frodo);
+ this.ringBearers.put(this.nenya, this.galadriel);
+ this.ringBearers.put(this.narya, this.gandalf);
+ this.ringBearers.put(this.vilya, this.elrond);
+ }
+
+ @Test
+ public void exampleShouldPass() {
+ // common assertions
+ assertThat(frodo.getName()).isEqualTo("Frodo");
+ assertThat(frodo).isNotEqualTo(sauron)
+ .isIn(fellowshipOfTheRing);
+
+ // String specific assertions
+ assertThat(frodo.getName()).startsWith("Fro")
+ .endsWith("do")
+ .isEqualToIgnoringCase("frodo");
+
+ // collection specific assertions
+ assertThat(fellowshipOfTheRing).hasSize(9)
+ .contains(frodo, sam)
+ .doesNotContain(sauron);
+
+ // using extracting magical feature to check fellowshipOfTheRing characters name :)
+ assertThat(fellowshipOfTheRing).extracting("name").contains("Boromir", "Gandalf", "Frodo", "Legolas")
+ .doesNotContain("Sauron", "Elrond");
+
+ // map specific assertions, ringBearers initialized with the elves rings and the one ring bearers.
+ assertThat(ringBearers).hasSize(4)
+ .contains(entry(oneRing, frodo), entry(nenya, galadriel))
+ .doesNotContainEntry(oneRing, aragorn);
+ }
+
+ protected static class Character {
+ private final String name;
+ public Character(final String name) {
+ this.name = name;
+ }
+ public String getName() {
+ return this.name;
+ }
+ }
+
+ protected static class Ring {
+ public Ring() {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionExampleDUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionExampleDUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionExampleDUnitTest.java
new file mode 100755
index 0000000..845c46d
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionExampleDUnitTest.java
@@ -0,0 +1,59 @@
+package com.gemstone.gemfire.test.catchexception;
+
+import static com.googlecode.catchexception.CatchException.*;
+import static com.googlecode.catchexception.apis.BDDCatchException.when;
+import static org.assertj.core.api.BDDAssertions.*;
+
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.test.dunit.DistributedTestCase;
+import com.gemstone.gemfire.test.dunit.Host;
+import com.gemstone.gemfire.test.dunit.RMIException;
+import com.gemstone.gemfire.test.dunit.SerializableCallable;
+import com.gemstone.gemfire.test.dunit.VM;
+import com.gemstone.gemfire.test.junit.categories.DistributedTest;
+
+/**
+ * Using Catch-Exception works well for remote exceptions and asserting details
+ * about root cause of RMIExceptions in DUnit tests.
+ */
+@Category(DistributedTest.class)
+public class CatchExceptionExampleDUnitTest extends DistributedTestCase {
+ private static final long serialVersionUID = 1L;
+
+ private static final String REMOTE_THROW_EXCEPTION_MESSAGE = "Throwing remoteThrowException";
+
+ @Test
+ public void testRemoteInvocationWithException() {
+ Host host = Host.getHost(0);
+ VM vm = host.getVM(0);
+
+ when(vm).invoke(new ThrowBasicTestException());
+
+ then(caughtException())
+ .isInstanceOf(RMIException.class)
+ .hasCause(new BasicTestException(REMOTE_THROW_EXCEPTION_MESSAGE));
+ }
+
+ protected static class ThrowBasicTestException extends SerializableCallable<Object> {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Object call() throws Exception {
+ throw new BasicTestException(REMOTE_THROW_EXCEPTION_MESSAGE);
+ }
+ }
+
+ protected static class BasicTestException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public BasicTestException() {
+ super();
+ }
+
+ public BasicTestException(String message) {
+ super(message);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionExampleJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionExampleJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionExampleJUnitTest.java
new file mode 100755
index 0000000..73dc361
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/catchexception/CatchExceptionExampleJUnitTest.java
@@ -0,0 +1,99 @@
+package com.gemstone.gemfire.test.catchexception;
+
+import static com.googlecode.catchexception.CatchException.*;
+import static com.googlecode.catchexception.apis.BDDCatchException.when;
+import static com.googlecode.catchexception.apis.CatchExceptionHamcrestMatchers.*;
+import static org.assertj.core.api.BDDAssertions.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+/**
+ * Simple unit tests exercising Catch-Exception with AssertJ, Hamcrest and JUnit.
+ */
+@Category(UnitTest.class)
+public class CatchExceptionExampleJUnitTest {
+
+ @Test
+ public void catchExceptionShouldCatchException() {
+ List<?> myList = new ArrayList<Object>();
+
+ // when: we try to get the first element of the list
+ // then: catch the exception if any is thrown
+ catchException(myList).get(1);
+
+ // then: we expect an IndexOutOfBoundsException
+ assertThat(caughtException(), is(instanceOf(IndexOutOfBoundsException.class)));
+ }
+
+ @Test
+ public void verifyExceptionShouldCatchException() {
+ List<?> myList = new ArrayList<Object>();
+
+ // when: we try to get the first element of the list
+ // then: catch the exception if any is thrown
+ // then: we expect an IndexOutOfBoundsException
+ verifyException(myList, IndexOutOfBoundsException.class).get(1);
+ }
+
+ @Test
+ public void whenShouldCatchExceptionAndUseAssertJAssertion() {
+ // given: an empty list
+ List<?> myList = new ArrayList<Object>();
+
+ // when: we try to get the first element of the list
+ when(myList).get(1);
+
+ // then: we expect an IndexOutOfBoundsException
+ then(caughtException())
+ .isInstanceOf(IndexOutOfBoundsException.class)
+ .hasMessage("Index: 1, Size: 0")
+ .hasNoCause();
+ }
+
+ @Test
+ public void catchExceptionShouldCatchExceptionAndUseHamcrestAssertion() {
+ // given: an empty list
+ List<?> myList = new ArrayList<Object>();
+
+ // when: we try to get the first element of the list
+ catchException(myList).get(1);
+
+ // then: we expect an IndexOutOfBoundsException with message "Index: 1, Size: 0"
+ assertThat(caughtException(),
+ allOf(
+ instanceOf(IndexOutOfBoundsException.class),
+ hasMessage("Index: 1, Size: 0"),
+ hasNoCause()
+ )
+ );
+ }
+
+ @Test
+ public void shouldCatchFromThrowException() throws Exception {
+ String message = "error message";
+
+ catchException(this).throwException(message);
+
+ assertThat(caughtException(), is(instanceOf(Exception.class)));
+ }
+
+ @Test
+ public void shouldVerifyFromThrowException() throws Exception {
+ String message = "error message";
+
+ verifyException(this).throwException(message);
+ }
+
+ // fails if private
+ protected void throwException(final String message) throws Exception {
+ throw new Exception(message);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-core/src/test/java/com/gemstone/gemfire/test/junitparams/JUnitParamsExampleJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/junitparams/JUnitParamsExampleJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/junitparams/JUnitParamsExampleJUnitTest.java
new file mode 100755
index 0000000..4e14fa7
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/junitparams/JUnitParamsExampleJUnitTest.java
@@ -0,0 +1,36 @@
+package com.gemstone.gemfire.test.junitparams;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+
+@Category(UnitTest.class)
+@RunWith(JUnitParamsRunner.class)
+public class JUnitParamsExampleJUnitTest {
+ @Test
+ @Parameters({"17, false",
+ "22, true" })
+ public void personIsAdult(int age, boolean valid) throws Exception {
+ assertThat(true, is(true));
+ assertThat(new Person(age).isAdult(), is(valid));
+ }
+
+ protected static class Person {
+ private static final int MIN_AGE_OF_ADULT = 18;
+ private final int age;
+ public Person(final int age) {
+ this.age = age;
+ }
+ public Boolean isAdult() {
+ return this.age >= MIN_AGE_OF_ADULT;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/Repeat.java
----------------------------------------------------------------------
diff --git a/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/Repeat.java b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/Repeat.java
new file mode 100755
index 0000000..b76d160
--- /dev/null
+++ b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/Repeat.java
@@ -0,0 +1,26 @@
+package com.gemstone.gemfire.test.junit;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The Repeat class is a Java Annotation enabling an annotated test suite class test case method to be repeated
+ * a specified number of iterations.
+ *
+ * @author John Blum
+ * @see java.lang.annotation.Annotation
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ ElementType.METHOD })
+@SuppressWarnings("unused")
+public @interface Repeat {
+
+ public static int DEFAULT = 1;
+
+ int value() default DEFAULT;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/ExpectedTimeoutRule.java
----------------------------------------------------------------------
diff --git a/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/ExpectedTimeoutRule.java b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/ExpectedTimeoutRule.java
new file mode 100755
index 0000000..bf6456f
--- /dev/null
+++ b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/ExpectedTimeoutRule.java
@@ -0,0 +1,164 @@
+package com.gemstone.gemfire.test.junit.rules;
+
+import static org.junit.Assert.assertThat;
+
+import java.util.concurrent.TimeUnit;
+
+import org.hamcrest.Matcher;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Expect an Exception within a specified timeout.
+ *
+ * @author Kirk Lund
+ * @since 8.2
+ */
+public class ExpectedTimeoutRule implements TestRule {
+
+ /**
+ * @return a Rule that expects no timeout (identical to behavior without this Rule)
+ */
+ public static ExpectedTimeoutRule none() {
+ return new ExpectedTimeoutRule();
+ }
+
+ private ExpectedException delegate;
+ private boolean expectsThrowable;
+ private long minDuration;
+ private long maxDuration;
+ private TimeUnit timeUnit;
+
+ private ExpectedTimeoutRule() {
+ this.delegate = ExpectedException.none();
+ }
+
+ public ExpectedTimeoutRule expectMinimumDuration(final long minDuration) {
+ this.minDuration = minDuration;
+ return this;
+ }
+ public ExpectedTimeoutRule expectMaximumDuration(final long maxDuration) {
+ this.maxDuration = maxDuration;
+ return this;
+ }
+ public ExpectedTimeoutRule expectTimeUnit(final TimeUnit timeUnit) {
+ this.timeUnit = timeUnit;
+ return this;
+ }
+
+ public ExpectedTimeoutRule handleAssertionErrors() {
+ this.delegate.handleAssertionErrors();
+ return this;
+ }
+
+ public ExpectedTimeoutRule handleAssumptionViolatedExceptions() {
+ this.delegate.handleAssumptionViolatedExceptions();
+ return this;
+ }
+
+ /**
+ * Adds {@code matcher} to the list of requirements for any thrown
+ * exception.
+ */
+ public void expect(final Matcher<?> matcher) {
+ this.delegate.expect(matcher);
+ }
+
+ /**
+ * Adds to the list of requirements for any thrown exception that it should
+ * be an instance of {@code type}
+ */
+ public void expect(final Class<? extends Throwable> type) {
+ this.delegate.expect(type);
+ this.expectsThrowable = true;
+ }
+
+ /**
+ * Adds to the list of requirements for any thrown exception that it should
+ * <em>contain</em> string {@code substring}
+ */
+ public void expectMessage(final String substring) {
+ this.delegate.expectMessage(substring);
+ }
+
+ /**
+ * Adds {@code matcher} to the list of requirements for the message returned
+ * from any thrown exception.
+ */
+ public void expectMessage(final Matcher<String> matcher) {
+ this.delegate.expectMessage(matcher);
+ }
+
+ /**
+ * Adds {@code matcher} to the list of requirements for the cause of
+ * any thrown exception.
+ */
+ public void expectCause(final Matcher<? extends Throwable> expectedCause) {
+ this.delegate.expectCause(expectedCause);
+ }
+
+ public boolean expectsTimeout() {
+ return minDuration > 0 || maxDuration > 0;
+ }
+
+ public boolean expectsThrowable() {
+ return expectsThrowable = true;
+ }
+
+ @Override
+ public Statement apply(final Statement base, final Description description) {
+ Statement next = delegate.apply(base, description);
+ return new ExpectedTimeoutStatement(next);
+ }
+
+ private void handleTime(final Long duration) {
+ if (expectsTimeout()) {
+ assertThat(timeUnit.convert(duration, TimeUnit.NANOSECONDS), new TimeMatcher(timeUnit, minDuration, maxDuration));
+ }
+ }
+
+ private static class TimeMatcher extends org.hamcrest.TypeSafeMatcher<Long> {
+
+ private final TimeUnit timeUnit;
+ private final long minDuration;
+ private final long maxDuration;
+
+ public TimeMatcher(final TimeUnit timeUnit, final long minDuration, final long maxDuration) {
+ this.timeUnit = timeUnit;
+ this.minDuration = minDuration;
+ this.maxDuration = maxDuration;
+ }
+
+ @Override
+ public boolean matchesSafely(final Long duration) {
+ return duration >= this.minDuration && duration <= this.maxDuration;
+ }
+
+ @Override
+ public void describeTo(final org.hamcrest.Description description) {
+ description.appendText("expects duration to be greater than or equal to ")
+ .appendValue(this.minDuration)
+ .appendText(" and less than or equal to ")
+ .appendValue(this.maxDuration)
+ .appendText(" ")
+ .appendValue(this.timeUnit);
+ }
+ }
+
+ private class ExpectedTimeoutStatement extends Statement {
+ private final Statement next;
+
+ public ExpectedTimeoutStatement(final Statement base) {
+ next = base;
+ }
+
+ @Override
+ public void evaluate() throws Throwable {
+ long start = System.nanoTime();
+ next.evaluate();
+ handleTime(System.nanoTime() - start);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/RepeatRule.java
----------------------------------------------------------------------
diff --git a/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/RepeatRule.java b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/RepeatRule.java
new file mode 100755
index 0000000..ef66d48
--- /dev/null
+++ b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/RepeatRule.java
@@ -0,0 +1,57 @@
+package com.gemstone.gemfire.test.junit.rules;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import com.gemstone.gemfire.test.junit.Repeat;
+
+/**
+ * The RepeatRule class is a JUnit TestRule that enables an appropriately @Repeat annotated test case method
+ * to be repeated a specified number of times.
+ *
+ * TODO: disallow 0 because @Retry(0) is equivalent to @Ignore apparently
+ *
+ * @author John Blum
+ * @see org.junit.rules.TestRule
+ * @see org.junit.runner.Description
+ * @see org.junit.runners.model.Statement
+ */
+@SuppressWarnings("unused")
+public class RepeatRule implements TestRule {
+
+ protected static final int DEFAULT_REPETITIONS = 1;
+
+ @Override
+ public Statement apply(final Statement statement, final Description description) {
+ return new Statement() {
+ @Override public void evaluate() throws Throwable {
+ RepeatRule.this.evaluate(statement, description);
+ }
+ };
+ }
+
+ protected void evaluate(final Statement statement, final Description description) throws Throwable {
+ if (isTest(description)) {
+ Repeat repeat = description.getAnnotation(Repeat.class);
+
+ for (int count = 0, repetitions = getRepetitions(repeat); count < repetitions; count++) {
+ statement.evaluate();
+ }
+ }
+ }
+
+ private int getRepetitions(final Repeat repeat) {
+ int repetitions = DEFAULT_REPETITIONS;
+
+ if (repeat != null) {
+ repetitions = repeat.value();
+ }
+
+ return repetitions;
+ }
+
+ private boolean isTest(final Description description) {
+ return (description.isSuite() || description.isTest());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/ExpectedTimeoutRuleJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/ExpectedTimeoutRuleJUnitTest.java b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/ExpectedTimeoutRuleJUnitTest.java
new file mode 100755
index 0000000..8a14f67
--- /dev/null
+++ b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/ExpectedTimeoutRuleJUnitTest.java
@@ -0,0 +1,206 @@
+package com.gemstone.gemfire.test.junit.rules.tests;
+
+import static org.hamcrest.core.StringContains.*;
+import static org.hamcrest.core.Is.*;
+import static org.hamcrest.core.IsInstanceOf.*;
+import static org.junit.Assert.*;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+import com.gemstone.gemfire.test.junit.rules.ExpectedTimeoutRule;
+
+/**
+ * Unit tests for ExpectedTimeout JUnit Rule.
+ *
+ * @author Kirk Lund
+ * @since 8.2
+ */
+@Category(UnitTest.class)
+public class ExpectedTimeoutRuleJUnitTest {
+
+ @Test
+ public void passesUnused() {
+ Result result = runTest(PassingTestShouldPassWhenUnused.class);
+
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void failsWithoutExpectedException() {
+ Result result = runTest(FailsWithoutExpectedException.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString("Expected test to throw an instance of " + TimeoutException.class.getName()));
+ }
+
+ @Test
+ public void failsWithoutExpectedTimeoutException() {
+ Result result = runTest(FailsWithoutExpectedTimeoutException.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString("Expected test to throw (an instance of " + TimeoutException.class.getName() + " and exception with message a string containing \"" + FailsWithoutExpectedTimeoutException.message + "\")"));
+ }
+
+ @Test
+ public void failsWithExpectedTimeoutButWrongError() {
+ Result result = runTest(FailsWithExpectedTimeoutButWrongError.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString(NullPointerException.class.getName()));
+ }
+
+ @Test
+ public void passesWithExpectedTimeoutAndTimeoutException() {
+ Result result = runTest(PassesWithExpectedTimeoutAndTimeoutException.class);
+
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void failsWhenTimeoutIsEarly() {
+ Result result = runTest(FailsWhenTimeoutIsEarly.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString("Expected test to throw (an instance of " + TimeoutException.class.getName() + " and exception with message a string containing \"" + FailsWhenTimeoutIsEarly.message + "\")"));
+ }
+
+ @Test
+ public void failsWhenTimeoutIsLate() {
+ Result result = runTest(FailsWhenTimeoutIsLate.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString("Expected test to throw (an instance of " + TimeoutException.class.getName() + " and exception with message a string containing \"" + FailsWhenTimeoutIsLate.message + "\")"));
+ }
+
+ private static Result runTest(Class<?> test) {
+ JUnitCore junitCore = new JUnitCore();
+ return junitCore.run(Request.aClass(test).getRunner());
+ }
+
+ public static class AbstractExpectedTimeoutRuleTest {
+ @Rule
+ public ExpectedTimeoutRule timeout = ExpectedTimeoutRule.none();
+ }
+
+ public static class PassingTestShouldPassWhenUnused extends AbstractExpectedTimeoutRuleTest {
+ @Test
+ public void passesUnused() throws Exception {
+ }
+ }
+
+ public static class FailsWithoutExpectedException extends AbstractExpectedTimeoutRuleTest {
+ @Test
+ public void failsWithoutExpectedException() throws Exception {
+ timeout.expect(TimeoutException.class);
+ }
+ }
+
+ public static class FailsWithoutExpectedTimeoutException extends AbstractExpectedTimeoutRuleTest {
+ public static final String message = "this is a message for FailsWithoutExpectedTimeoutException";
+ @Test
+ public void failsWithoutExpectedTimeoutAndTimeoutException() throws Exception {
+ timeout.expect(TimeoutException.class);
+ timeout.expectMessage(message);
+ timeout.expectMinimumDuration(10);
+ timeout.expectMaximumDuration(1000);
+ timeout.expectTimeUnit(TimeUnit.MILLISECONDS);
+ Thread.sleep(100);
+ }
+ }
+
+ public static class FailsWithExpectedTimeoutButWrongError extends AbstractExpectedTimeoutRuleTest {
+ public static final String message = "this is a message for FailsWithExpectedTimeoutButWrongError";
+ @Test
+ public void failsWithExpectedTimeoutButWrongError() throws Exception {
+ timeout.expect(TimeoutException.class);
+ timeout.expectMessage(message);
+ timeout.expectMinimumDuration(10);
+ timeout.expectMaximumDuration(1000);
+ timeout.expectTimeUnit(TimeUnit.MILLISECONDS);
+ Thread.sleep(100);
+ throw new NullPointerException();
+ }
+ }
+
+ public static class PassesWithExpectedTimeoutAndTimeoutException extends AbstractExpectedTimeoutRuleTest {
+ public static final String message = "this is a message for PassesWithExpectedTimeoutAndTimeoutException";
+ public static final Class<TimeoutException> exceptionClass = TimeoutException.class;
+ @Test
+ public void passesWithExpectedTimeoutAndTimeoutException() throws Exception {
+ timeout.expect(exceptionClass);
+ timeout.expectMessage(message);
+ timeout.expectMinimumDuration(10);
+ timeout.expectMaximumDuration(1000);
+ timeout.expectTimeUnit(TimeUnit.MILLISECONDS);
+ Thread.sleep(100);
+ throw new TimeoutException(message);
+ }
+ }
+
+ public static class FailsWhenTimeoutIsEarly extends AbstractExpectedTimeoutRuleTest {
+ public static final String message = "this is a message for FailsWhenTimeoutIsEarly";
+ @Test
+ public void failsWhenTimeoutIsEarly() throws Exception {
+ timeout.expect(TimeoutException.class);
+ timeout.expectMessage(message);
+ timeout.expectMinimumDuration(1000);
+ timeout.expectMaximumDuration(2000);
+ timeout.expectTimeUnit(TimeUnit.MILLISECONDS);
+ Thread.sleep(10);
+ }
+ }
+
+ public static class FailsWhenTimeoutIsLate extends AbstractExpectedTimeoutRuleTest {
+ public static final String message = "this is a message for FailsWhenTimeoutIsLate";
+ @Test
+ public void failsWhenTimeoutIsLate() throws Exception {
+ timeout.expect(TimeoutException.class);
+ timeout.expectMessage(message);
+ timeout.expectMinimumDuration(10);
+ timeout.expectMaximumDuration(20);
+ timeout.expectTimeUnit(TimeUnit.MILLISECONDS);
+ Thread.sleep(100);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/JUnitRuleTestSuite.java
----------------------------------------------------------------------
diff --git a/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/JUnitRuleTestSuite.java b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/JUnitRuleTestSuite.java
new file mode 100755
index 0000000..ff102f7
--- /dev/null
+++ b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/JUnitRuleTestSuite.java
@@ -0,0 +1,16 @@
+package com.gemstone.gemfire.test.junit.rules.tests;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ ExpectedTimeoutRuleJUnitTest.class,
+ RepeatRuleJUnitTest.class,
+ RetryRuleGlobalWithErrorJUnitTest.class,
+ RetryRuleGlobalWithExceptionJUnitTest.class,
+ RetryRuleLocalWithErrorJUnitTest.class,
+ RetryRuleLocalWithExceptionJUnitTest.class,
+})
+public class JUnitRuleTestSuite {
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RepeatRuleJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RepeatRuleJUnitTest.java b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RepeatRuleJUnitTest.java
new file mode 100755
index 0000000..5e69f03
--- /dev/null
+++ b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RepeatRuleJUnitTest.java
@@ -0,0 +1,278 @@
+package com.gemstone.gemfire.test.junit.rules.tests;
+
+import static org.hamcrest.Matchers.*;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.hamcrest.core.StringContains.containsString;
+import static org.junit.Assert.*;
+
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+import com.gemstone.gemfire.test.junit.Repeat;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+import com.gemstone.gemfire.test.junit.rules.RepeatRule;
+
+/**
+ * Unit tests for Repeat JUnit Rule.
+ *
+ * @author Kirk Lund
+ */
+@Category(UnitTest.class)
+public class RepeatRuleJUnitTest {
+
+ private static final String ASSERTION_ERROR_MESSAGE = "failing test";
+
+ @Test
+ public void failingTestShouldFailOneTimeWhenRepeatIsUnused() {
+ Result result = runTest(FailingTestShouldFailOneTimeWhenRepeatIsUnused.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals("Failures: " + failures, 1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString(ASSERTION_ERROR_MESSAGE));
+ assertThat(FailingTestShouldFailOneTimeWhenRepeatIsUnused.count, is(1));
+ }
+
+ @Test
+ public void passingTestShouldPassOneTimeWhenRepeatIsUnused() {
+ Result result = runTest(PassingTestShouldPassOneTimeWhenRepeatIsUnused.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassingTestShouldPassOneTimeWhenRepeatIsUnused.count, is(1));
+ }
+
+ @Test
+ public void failingTestShouldBeSkippedWhenRepeatIsZero() {
+ Result result = runTest(FailingTestShouldBeSkippedWhenRepeatIsZero.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(FailingTestShouldBeSkippedWhenRepeatIsZero.count, is(0));
+ }
+
+ @Test
+ public void passingTestShouldBeSkippedWhenRepeatIsZero() {
+ Result result = runTest(PassingTestShouldBeSkippedWhenRepeatIsZero.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassingTestShouldBeSkippedWhenRepeatIsZero.count, is(0));
+ }
+
+ @Test
+ public void failingTestShouldFailOneTimeWhenRepeatIsOne() {
+ Result result = runTest(FailingTestShouldFailOneTimeWhenRepeatIsOne.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals("Failures: " + failures, 1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString(ASSERTION_ERROR_MESSAGE));
+ assertThat(FailingTestShouldFailOneTimeWhenRepeatIsOne.count, is(1));
+ }
+
+ @Test
+ public void passingTestShouldPassOneTimeWhenRepeatIsOne() {
+ Result result = runTest(PassingTestShouldPassOneTimeWhenRepeatIsOne.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassingTestShouldPassOneTimeWhenRepeatIsOne.count, is(1));
+ }
+
+ @Test
+ public void failingTestShouldFailOneTimeWhenRepeatIsTwo() {
+ Result result = runTest(FailingTestShouldFailOneTimeWhenRepeatIsTwo.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals("Failures: " + failures, 1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString(ASSERTION_ERROR_MESSAGE));
+ assertThat(FailingTestShouldFailOneTimeWhenRepeatIsTwo.count, is(1));
+ }
+
+ @Test
+ public void passingTestShouldPassTwoTimesWhenRepeatIsTwo() {
+ Result result = runTest(PassingTestShouldPassTwoTimesWhenRepeatIsTwo.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassingTestShouldPassTwoTimesWhenRepeatIsTwo.count, is(2));
+ }
+
+ @Test
+ public void failingTestShouldFailOneTimeWhenRepeatIsThree() {
+ Result result = runTest(FailingTestShouldFailOneTimeWhenRepeatIsThree.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals("Failures: " + failures, 1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString(ASSERTION_ERROR_MESSAGE));
+ assertThat(FailingTestShouldFailOneTimeWhenRepeatIsThree.count, is(1));
+ }
+
+ @Test
+ public void passingTestShouldPassThreeTimesWhenRepeatIsThree() {
+ Result result = runTest(PassingTestShouldPassThreeTimesWhenRepeatIsThree.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassingTestShouldPassThreeTimesWhenRepeatIsThree.count, is(3));
+ }
+
+ private static Result runTest(Class<?> test) {
+ JUnitCore junitCore = new JUnitCore();
+ return junitCore.run(Request.aClass(test).getRunner());
+ }
+
+ public static class FailingTestShouldFailOneTimeWhenRepeatIsUnused {
+ protected static int count = 0;
+
+ @Rule
+ public RepeatRule repeat = new RepeatRule();
+
+ @Test
+ public void doTest() throws Exception {
+ count++;
+ fail(ASSERTION_ERROR_MESSAGE);
+ }
+ }
+
+ public static class PassingTestShouldPassOneTimeWhenRepeatIsUnused {
+ protected static int count = 0;
+
+ @Rule
+ public RepeatRule repeat = new RepeatRule();
+
+ @Test
+ public void doTest() throws Exception {
+ count++;
+ }
+ }
+
+ public static class FailingTestShouldBeSkippedWhenRepeatIsZero {
+ protected static int count = 0;
+
+ @Rule
+ public RepeatRule repeat = new RepeatRule();
+
+ @Test
+ @Repeat(0)
+ public void doTest() throws Exception {
+ count++;
+ fail(ASSERTION_ERROR_MESSAGE);
+ }
+ }
+
+ public static class PassingTestShouldBeSkippedWhenRepeatIsZero {
+ protected static int count = 0;
+
+ @Rule
+ public RepeatRule repeat = new RepeatRule();
+
+ @Test
+ @Repeat(0)
+ public void doTest() throws Exception {
+ count++;
+ }
+ }
+
+ public static class FailingTestShouldFailOneTimeWhenRepeatIsOne {
+ protected static int count = 0;
+
+ @Rule
+ public RepeatRule repeat = new RepeatRule();
+
+ @Test
+ @Repeat(1)
+ public void doTest() throws Exception {
+ count++;
+ fail(ASSERTION_ERROR_MESSAGE);
+ }
+ }
+
+ public static class PassingTestShouldPassOneTimeWhenRepeatIsOne {
+ protected static int count = 0;
+
+ @Rule
+ public RepeatRule repeat = new RepeatRule();
+
+ @Test
+ @Repeat(1)
+ public void doTest() throws Exception {
+ count++;
+ }
+ }
+
+ public static class FailingTestShouldFailOneTimeWhenRepeatIsTwo {
+ protected static int count = 0;
+
+ @Rule
+ public RepeatRule repeat = new RepeatRule();
+
+ @Test
+ @Repeat(2)
+ public void doTest() throws Exception {
+ count++;
+ fail(ASSERTION_ERROR_MESSAGE);
+ }
+ }
+
+ public static class PassingTestShouldPassTwoTimesWhenRepeatIsTwo {
+ protected static int count = 0;
+
+ @Rule
+ public RepeatRule repeat = new RepeatRule();
+
+ @Test
+ @Repeat(2)
+ public void doTest() throws Exception {
+ count++;
+ }
+ }
+
+ public static class FailingTestShouldFailOneTimeWhenRepeatIsThree {
+ protected static int count = 0;
+
+ @Rule
+ public RepeatRule repeat = new RepeatRule();
+
+ @Test
+ @Repeat(3)
+ public void doTest() throws Exception {
+ count++;
+ fail(ASSERTION_ERROR_MESSAGE);
+ }
+ }
+
+ public static class PassingTestShouldPassThreeTimesWhenRepeatIsThree {
+ protected static int count = 0;
+
+ @Rule
+ public RepeatRule repeat = new RepeatRule();
+
+ @Test
+ @Repeat(3)
+ public void doTest() throws Exception {
+ count++;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleGlobalWithErrorJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleGlobalWithErrorJUnitTest.java b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleGlobalWithErrorJUnitTest.java
new file mode 100755
index 0000000..ce473e8
--- /dev/null
+++ b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleGlobalWithErrorJUnitTest.java
@@ -0,0 +1,247 @@
+package com.gemstone.gemfire.test.junit.rules.tests;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.hamcrest.core.StringContains.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+import com.gemstone.gemfire.test.junit.Retry;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+import com.gemstone.gemfire.test.junit.rules.RetryRule;
+
+/**
+ * Unit tests for Retry JUnit Rule involving global scope (ie Rule affects all
+ * tests in the test case) with failures due to an Exception.
+ *
+ * @author Kirk Lund
+ */
+@Category(UnitTest.class)
+public class RetryRuleGlobalWithErrorJUnitTest {
+
+ @Test
+ public void zeroIsIllegal() {
+ Result result = runTest(ZeroIsIllegal.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals("Failures: " + failures, 1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(IllegalArgumentException.class)));
+ assertThat(failure.getException().getMessage(), containsString("Retry count must be greater than zero"));
+ assertThat(ZeroIsIllegal.count, is(0));
+ }
+
+ @Test
+ public void failsWithOne() {
+ Result result = runTest(FailsWithOne.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals("Failures: " + failures, 1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString(FailsWithOne.message));
+ assertThat(FailsWithOne.count, is(1));
+ }
+
+ @Test
+ public void passesWithOne() {
+ Result result = runTest(PassesWithOne.class);
+
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void passesWithUnused() {
+ Result result = runTest(PassesWhenUnused.class);
+
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void failsOnSecondAttempt() {
+ Result result = runTest(FailsOnSecondAttempt.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString(FailsOnSecondAttempt.message));
+ assertThat(FailsOnSecondAttempt.count, is(2));
+ }
+
+ @Test
+ public void passesOnSecondAttempt() {
+ Result result = runTest(PassesOnSecondAttempt.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassesOnSecondAttempt.count, is(2));
+ }
+
+ @Test
+ public void failsOnThirdAttempt() {
+ Result result = runTest(FailsOnThirdAttempt.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString(FailsOnThirdAttempt.message));
+ assertThat(FailsOnThirdAttempt.count, is(3));
+ }
+
+ @Test
+ public void passesOnThirdAttempt() {
+ Result result = runTest(PassesOnThirdAttempt.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassesOnThirdAttempt.count, is(3));
+ }
+
+ private static Result runTest(Class<?> test) {
+ JUnitCore junitCore = new JUnitCore();
+ return junitCore.run(Request.aClass(test).getRunner());
+ }
+
+ public static class ZeroIsIllegal {
+ protected static int count;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(0);
+
+ @Test
+ public void zeroIsIllegal() throws Exception {
+ count++;
+ }
+ }
+
+ public static class FailsWithOne {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(1);
+
+ @Test
+ public void failsWithOne() throws Exception {
+ count++;
+ message = "Failing " + count;
+ fail(message);
+ }
+ }
+
+ public static class PassesWithOne {
+ protected static int count;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(1);
+
+ @Test
+ public void passesWithOne() throws Exception {
+ count++;
+ }
+ }
+
+ public static class PassesWhenUnused {
+ protected static int count;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(2);
+
+ @Test
+ public void passesWithUnused() throws Exception {
+ count++;
+ }
+ }
+
+ public static class FailsOnSecondAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(2);
+
+ @Test
+ @Retry(2)
+ public void failsOnSecondAttempt() {
+ count++;
+ message = "Failing " + count;
+ fail(message);
+ }
+ }
+
+ public static class PassesOnSecondAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(2);
+
+ @Test
+ @Retry(2)
+ public void failsOnSecondAttempt() {
+ count++;
+ if (count < 2) {
+ message = "Failing " + count;
+ fail(message);
+ }
+ }
+ }
+
+ public static class FailsOnThirdAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(3);
+
+ @Test
+ @Retry(3)
+ public void failsOnThirdAttempt() {
+ count++;
+ message = "Failing " + count;
+ fail(message);
+ }
+ }
+
+ public static class PassesOnThirdAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(3);
+
+ @Test
+ public void failsOnThirdAttempt() {
+ count++;
+ if (count < 3) {
+ message = "Failing " + count;
+ fail(message);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleGlobalWithExceptionJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleGlobalWithExceptionJUnitTest.java b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleGlobalWithExceptionJUnitTest.java
new file mode 100755
index 0000000..b67880c
--- /dev/null
+++ b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleGlobalWithExceptionJUnitTest.java
@@ -0,0 +1,253 @@
+package com.gemstone.gemfire.test.junit.rules.tests;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.hamcrest.core.StringContains.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+import com.gemstone.gemfire.test.junit.Retry;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+import com.gemstone.gemfire.test.junit.rules.RetryRule;
+
+/**
+ * Unit tests for Retry JUnit Rule involving global scope (ie Rule affects all
+ * tests in the test case) with failures due to an Exception.
+ *
+ * @author Kirk Lund
+ */
+@Category(UnitTest.class)
+public class RetryRuleGlobalWithExceptionJUnitTest {
+
+ @Test
+ public void zeroIsIllegal() {
+ Result result = runTest(ZeroIsIllegal.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals("Failures: " + failures, 1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(IllegalArgumentException.class)));
+ assertThat(failure.getException().getMessage(), containsString("Retry count must be greater than zero"));
+ assertThat(ZeroIsIllegal.count, is(0));
+ }
+
+ @Test
+ public void failsWithOne() {
+ Result result = runTest(FailsWithOne.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals("Failures: " + failures, 1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(CustomException.class)));
+ assertThat(failure.getException().getMessage(), containsString(FailsWithOne.message));
+ assertThat(FailsWithOne.count, is(1));
+ }
+
+ @Test
+ public void passesWithOne() {
+ Result result = runTest(PassesWithOne.class);
+
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void passesWithUnused() {
+ Result result = runTest(PassesWhenUnused.class);
+
+ assertTrue(result.wasSuccessful());
+ }
+
+ @Test
+ public void failsOnSecondAttempt() {
+ Result result = runTest(FailsOnSecondAttempt.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(CustomException.class)));
+ assertThat(failure.getException().getMessage(), containsString(FailsOnSecondAttempt.message));
+ assertThat(FailsOnSecondAttempt.count, is(2));
+ }
+
+ @Test
+ public void passesOnSecondAttempt() {
+ Result result = runTest(PassesOnSecondAttempt.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassesOnSecondAttempt.count, is(2));
+ }
+
+ @Test
+ public void failsOnThirdAttempt() {
+ Result result = runTest(FailsOnThirdAttempt.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(CustomException.class)));
+ assertThat(failure.getException().getMessage(), containsString(FailsOnThirdAttempt.message));
+ assertThat(FailsOnThirdAttempt.count, is(3));
+ }
+
+ @Test
+ public void passesOnThirdAttempt() {
+ Result result = runTest(PassesOnThirdAttempt.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassesOnThirdAttempt.count, is(3));
+ }
+
+ private static Result runTest(Class<?> test) {
+ JUnitCore junitCore = new JUnitCore();
+ return junitCore.run(Request.aClass(test).getRunner());
+ }
+
+ public static class CustomException extends Exception {
+ private static final long serialVersionUID = 1L;
+ public CustomException(final String message) {
+ super(message);
+ }
+ }
+
+ public static class ZeroIsIllegal {
+ protected static int count;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(0);
+
+ @Test
+ public void zeroIsIllegal() throws Exception {
+ count++;
+ }
+ }
+
+ public static class FailsWithOne {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(1);
+
+ @Test
+ public void failsWithOne() throws Exception {
+ count++;
+ message = "Failing " + count;
+ throw new CustomException(message);
+ }
+ }
+
+ public static class PassesWithOne {
+ protected static int count;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(1);
+
+ @Test
+ public void passesWithOne() throws Exception {
+ count++;
+ }
+ }
+
+ public static class PassesWhenUnused {
+ protected static int count;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(2);
+
+ @Test
+ public void passesWithUnused() throws Exception {
+ count++;
+ }
+ }
+
+ public static class FailsOnSecondAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(2);
+
+ @Test
+ @Retry(2)
+ public void failsOnSecondAttempt() throws Exception {
+ count++;
+ message = "Failing " + count;
+ throw new CustomException(message);
+ }
+ }
+
+ public static class PassesOnSecondAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(2);
+
+ @Test
+ @Retry(2)
+ public void failsOnSecondAttempt() throws Exception {
+ count++;
+ if (count < 2) {
+ message = "Failing " + count;
+ throw new CustomException(message);
+ }
+ }
+ }
+
+ public static class FailsOnThirdAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(3);
+
+ @Test
+ @Retry(3)
+ public void failsOnThirdAttempt() throws Exception {
+ count++;
+ message = "Failing " + count;
+ throw new CustomException(message);
+ }
+ }
+
+ public static class PassesOnThirdAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule(3);
+
+ @Test
+ public void failsOnThirdAttempt() throws Exception {
+ count++;
+ if (count < 3) {
+ message = "Failing " + count;
+ throw new CustomException(message);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleLocalWithErrorJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleLocalWithErrorJUnitTest.java b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleLocalWithErrorJUnitTest.java
new file mode 100755
index 0000000..b06575c
--- /dev/null
+++ b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleLocalWithErrorJUnitTest.java
@@ -0,0 +1,206 @@
+package com.gemstone.gemfire.test.junit.rules.tests;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.hamcrest.core.StringContains.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+import com.gemstone.gemfire.test.junit.Retry;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+import com.gemstone.gemfire.test.junit.rules.RetryRule;
+
+/**
+ * Unit tests for Retry JUnit Rule involving local scope (ie Rule affects
+ * test methods annotated with @Retry) with failures due to an Error.
+ *
+ * @author Kirk Lund
+ */
+@Category(UnitTest.class)
+public class RetryRuleLocalWithErrorJUnitTest {
+
+ @Test
+ public void failsUnused() {
+ Result result = runTest(FailsUnused.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals("Failures: " + failures, 1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString(FailsUnused.message));
+ assertThat(FailsUnused.count, is(1));
+ }
+
+ @Test
+ public void passesUnused() {
+ Result result = runTest(PassesUnused.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassesUnused.count, is(1));
+ }
+
+ @Test
+ public void failsOnSecondAttempt() {
+ Result result = runTest(FailsOnSecondAttempt.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString(FailsOnSecondAttempt.message));
+ assertThat(FailsOnSecondAttempt.count, is(2));
+ }
+
+ @Test
+ public void passesOnSecondAttempt() {
+ Result result = runTest(PassesOnSecondAttempt.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassesOnSecondAttempt.count, is(2));
+ }
+
+ @Test
+ public void failsOnThirdAttempt() {
+ Result result = runTest(FailsOnThirdAttempt.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(AssertionError.class)));
+ assertThat(failure.getException().getMessage(), containsString(FailsOnThirdAttempt.message));
+ assertThat(FailsOnThirdAttempt.count, is(3));
+ }
+
+ @Test
+ public void passesOnThirdAttempt() {
+ Result result = runTest(PassesOnThirdAttempt.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassesOnThirdAttempt.count, is(3));
+ }
+
+ private static Result runTest(Class<?> test) {
+ JUnitCore junitCore = new JUnitCore();
+ return junitCore.run(Request.aClass(test).getRunner());
+ }
+
+ public static class FailsUnused {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule();
+
+ @Test
+ public void failsUnused() throws Exception {
+ count++;
+ message = "Failing " + count;
+ fail(message);
+ }
+ }
+
+ public static class PassesUnused {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule();
+
+ @Test
+ public void passesUnused() throws Exception {
+ count++;
+ }
+ }
+
+ public static class FailsOnSecondAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule();
+
+ @Test
+ @Retry(2)
+ public void failsOnSecondAttempt() {
+ count++;
+ message = "Failing " + count;
+ fail(message);
+ }
+ }
+
+ public static class PassesOnSecondAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule();
+
+ @Test
+ @Retry(2)
+ public void failsOnSecondAttempt() {
+ count++;
+ if (count < 2) {
+ message = "Failing " + count;
+ fail(message);
+ }
+ }
+ }
+
+ public static class FailsOnThirdAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule();
+
+ @Test
+ @Retry(3)
+ public void failsOnThirdAttempt() {
+ count++;
+
+ message = "Failing " + count;
+ fail(message);
+ }
+ }
+
+ public static class PassesOnThirdAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule();
+
+ @Test
+ @Retry(3)
+ public void failsOnThirdAttempt() {
+ count++;
+
+ if (count < 3) {
+ message = "Failing " + count;
+ fail(message);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d0c03307/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleLocalWithExceptionJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleLocalWithExceptionJUnitTest.java b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleLocalWithExceptionJUnitTest.java
new file mode 100755
index 0000000..4cff4bb
--- /dev/null
+++ b/gemfire-junit/src/test/java/com/gemstone/gemfire/test/junit/rules/tests/RetryRuleLocalWithExceptionJUnitTest.java
@@ -0,0 +1,221 @@
+package com.gemstone.gemfire.test.junit.rules.tests;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsInstanceOf.instanceOf;
+import static org.hamcrest.core.StringContains.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+
+import com.gemstone.gemfire.test.junit.Retry;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+import com.gemstone.gemfire.test.junit.rules.RetryRule;
+import com.gemstone.gemfire.test.junit.rules.tests.RetryRuleLocalWithErrorJUnitTest.FailsOnSecondAttempt;
+import com.gemstone.gemfire.test.junit.rules.tests.RetryRuleLocalWithErrorJUnitTest.FailsOnThirdAttempt;
+import com.gemstone.gemfire.test.junit.rules.tests.RetryRuleLocalWithErrorJUnitTest.FailsUnused;
+import com.gemstone.gemfire.test.junit.rules.tests.RetryRuleLocalWithErrorJUnitTest.PassesOnSecondAttempt;
+import com.gemstone.gemfire.test.junit.rules.tests.RetryRuleLocalWithErrorJUnitTest.PassesOnThirdAttempt;
+import com.gemstone.gemfire.test.junit.rules.tests.RetryRuleLocalWithErrorJUnitTest.PassesUnused;
+
+/**
+ * Unit tests for Retry JUnit Rule involving local scope (ie Rule affects
+ * test methods annotated with @Retry) with failures due to an Exception.
+ *
+ * @author Kirk Lund
+ */
+@Category(UnitTest.class)
+public class RetryRuleLocalWithExceptionJUnitTest {
+
+ @Test
+ public void failsUnused() {
+ Result result = runTest(FailsUnused.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals("Failures: " + failures, 1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(CustomException.class)));
+ assertThat(failure.getException().getMessage(), containsString(FailsUnused.message));
+ assertThat(FailsUnused.count, is(1));
+ }
+
+ @Test
+ public void passesUnused() {
+ Result result = runTest(PassesUnused.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassesUnused.count, is(1));
+ }
+
+ @Test
+ public void failsOnSecondAttempt() {
+ Result result = runTest(FailsOnSecondAttempt.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(CustomException.class)));
+ assertThat(failure.getException().getMessage(), containsString(FailsOnSecondAttempt.message));
+ assertThat(FailsOnSecondAttempt.count, is(2));
+ }
+
+ @Test
+ public void passesOnSecondAttempt() {
+ Result result = runTest(PassesOnSecondAttempt.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassesOnSecondAttempt.count, is(2));
+ }
+
+ @Test
+ public void failsOnThirdAttempt() {
+ Result result = runTest(FailsOnThirdAttempt.class);
+
+ assertFalse(result.wasSuccessful());
+
+ List<Failure> failures = result.getFailures();
+ assertEquals(1, failures.size());
+
+ Failure failure = failures.get(0);
+ assertThat(failure.getException(), is(instanceOf(CustomException.class)));
+ assertThat(failure.getException().getMessage(), containsString(FailsOnThirdAttempt.message));
+ assertThat(FailsOnThirdAttempt.count, is(3));
+ }
+
+ @Test
+ public void passesOnThirdAttempt() {
+ Result result = runTest(PassesOnThirdAttempt.class);
+
+ assertTrue(result.wasSuccessful());
+ assertThat(PassesOnThirdAttempt.count, is(3));
+ }
+
+ private static Result runTest(Class<?> test) {
+ JUnitCore junitCore = new JUnitCore();
+ return junitCore.run(Request.aClass(test).getRunner());
+ }
+
+ public static class CustomException extends Exception {
+ private static final long serialVersionUID = 1L;
+ public CustomException(final String message) {
+ super(message);
+ }
+ }
+
+ public static class FailsUnused {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule();
+
+ @Test
+ public void failsUnused() throws Exception {
+ count++;
+ message = "Failing " + count;
+ throw new CustomException(message);
+ }
+ }
+
+ public static class PassesUnused {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule();
+
+ @Test
+ public void passesUnused() throws Exception {
+ count++;
+ }
+ }
+
+ public static class FailsOnSecondAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule();
+
+ @Test
+ @Retry(2)
+ public void failsOnSecondAttempt() throws Exception {
+ count++;
+ message = "Failing " + count;
+ throw new CustomException(message);
+ }
+ }
+
+ public static class PassesOnSecondAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule();
+
+ @Test
+ @Retry(2)
+ public void failsOnSecondAttempt() throws Exception {
+ count++;
+ if (count < 2) {
+ message = "Failing " + count;
+ throw new CustomException(message);
+ }
+ }
+ }
+
+ public static class FailsOnThirdAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule();
+
+ @Test
+ @Retry(3)
+ public void failsOnThirdAttempt() throws Exception {
+ count++;
+
+ message = "Failing " + count;
+ throw new CustomException(message);
+ }
+ }
+
+ public static class PassesOnThirdAttempt {
+ protected static int count;
+ protected static String message;
+
+ @Rule
+ public RetryRule retryRule = new RetryRule();
+
+ @Test
+ @Retry(3)
+ public void failsOnThirdAttempt() throws Exception {
+ count++;
+
+ if (count < 3) {
+ message = "Failing " + count;
+ throw new CustomException(message);
+ }
+ }
+ }
+}