diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000000..65bdbaa62aa3 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,48 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + branches: + - '*' + +jobs: + + build-and-verify: + name: Build and verify (JDK ${{ matrix.java }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + java: [6, 8, 11, 15, 17-ea] + steps: + - uses: actions/checkout@v2 + - name: Download Maven # Download with default JDK because OpenJDK 6 does not support TLS 1.2 + run: ./mvnw --version + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + - name: Build and verify + run: ./mvnw verify javadoc:javadoc site:site --batch-mode --errors --settings .github/workflows/settings.xml + + publish-snapshots: + name: Publish snapshot artifacts + if: github.event_name == 'push' && github.repository == 'junit-team/junit4' && github.ref == 'refs/heads/main' + needs: build-and-verify + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Download Maven # Download with default JDK because OpenJDK 6 does not support TLS 1.2 + run: ./mvnw --version + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: 6 + - name: Publish snapshot artifacts + env: + OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} + OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + run: ./mvnw deploy --batch-mode --errors --activate-profiles generate-docs --settings .github/workflows/settings.xml diff --git a/.travis.settings.xml b/.github/workflows/settings.xml similarity index 100% rename from .travis.settings.xml rename to .github/workflows/settings.xml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5b1744397f29..000000000000 --- a/.travis.yml +++ /dev/null @@ -1,69 +0,0 @@ -dist: trusty - -language: java - -script: ./mvnw verify javadoc:javadoc site:site - -install: -- ./mvnw --version - -stages: - - test - - name: deploy - if: (branch = main) AND (NOT type IN (pull_request)) - -jobs: - include: - - name: Java 6 - env: JDK=openjdk6 - addons: - apt: - packages: - - openjdk-6-jdk - install: - # Download dependencies with JDK 8 because Mave Central supports - # TLS 1.2 only but OpenJDK 6 does not. - - export ORIGINAL_JAVA_HOME=$JAVA_HOME - - jdk_switcher use oraclejdk8 - - ./mvnw test -DskipTests - # Delete all files created with JDK 8 - - ./mvnw clean - # Restore desired JDK - - export JAVA_HOME=$ORIGINAL_JAVA_HOME - - jdk_switcher use openjdk6 - - ./mvnw --version - - name: Java 7 - jdk: openjdk7 - - name: Java 8 - jdk: oraclejdk8 - - name: Java 9 - jdk: oraclejdk9 - - name: Java 10 - jdk: openjdk10 - - name: Java 11 - jdk: openjdk11 - - stage: deploy - name: "Publish snapshot artifacts" - addons: - apt: - packages: - - openjdk-6-jdk - install: - # Download dependencies with JDK 8 because Mave Central supports - # TLS 1.2 only but OpenJDK 6 does not. - - export ORIGINAL_JAVA_HOME=$JAVA_HOME - - jdk_switcher use oraclejdk8 - - ./mvnw test -DskipTests - # Delete all files created with JDK 8 - - ./mvnw clean - # Restore desired JDK - - export JAVA_HOME=$ORIGINAL_JAVA_HOME - - jdk_switcher use openjdk6 - - ./mvnw --version - env: - - JDK=openjdk6 - # OSSRH_USERNAME - - secure: griGZYDtqDMRUaYex/uAnpkWIQ/yodM6IOn4G8izWKpyGLeCxyXBG0FDcVo81xRq/9mMevj2idyW/xNP/HAQ45G4pyJUk/vTSMkNslzVjr7OBEtQQCN8XahSaOO0l0CJ5lzA6LdwWg7uDaf9znqZ0slt81u0S1NJmUZyYeUEim0= - # OSSRH_PASSWORD - - secure: EM7Z2M09HvLJXYJaeD/YmeF5A6tqavG2tBBeDcFZ7C6k0AI/wApe882pEMMoUG06xufKfSlt7WFJxoyU3M+fPOpeK5qZpJQxsHWnNJwbcbKzqMpM9mDsgIL9rtAvm9MuIIbIY2spiT0Cx3sHdh5qofaJHPL/u8Or5L9tE8FV1ew= - script: ./mvnw deploy --batch-mode --activate-profiles generate-docs --settings .travis.settings.xml diff --git a/README.md b/README.md index f73f89ca5ed0..739347df5078 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,4 @@ For more information, please visit: * [Download and Install guide](https://github.com/junit-team/junit4/wiki/Download-and-Install) * [Getting Started](https://github.com/junit-team/junit4/wiki/Getting-started) -[![Build Status](https://travis-ci.org/junit-team/junit4.svg?branch=main)](https://travis-ci.org/junit-team/junit4) +[![CI Status](https://github.com/junit-team/junit4/workflows/CI/badge.svg)](https://github.com/junit-team/junit4/actions) diff --git a/doc/ReleaseNotes4.13.1.md b/doc/ReleaseNotes4.13.1.md index ab44490622c6..0305102d27f4 100644 --- a/doc/ReleaseNotes4.13.1.md +++ b/doc/ReleaseNotes4.13.1.md @@ -1,5 +1,11 @@ ## Summary of changes in version 4.13.1 +# Rules + +### Security fix: `TemporaryFolder` now limits access to temporary folders on Java 1.7 or later + +A local information disclosure vulnerability in `TemporaryFolder` has been fixed. See the published [security advisory](https://github.com/junit-team/junit4/security/advisories/GHSA-269g-pwp5-87pp) for details. + # Test Runners ### [Pull request #1669:](https://github.com/junit-team/junit/pull/1669) Make `FrameworkField` constructor public diff --git a/doc/ReleaseNotes4.13.2.md b/doc/ReleaseNotes4.13.2.md new file mode 100644 index 000000000000..ba801396d1a4 --- /dev/null +++ b/doc/ReleaseNotes4.13.2.md @@ -0,0 +1,38 @@ +## Summary of changes in version 4.13.2 + +# Rules + +### [Pull request #1687:](https://github.com/junit-team/junit/pull/1687) Mark ThreadGroups created by FailOnTimeout as daemon groups + +In JUnit 4.13 ([pull request #1517](https://github.com/junit-team/junit4/pull/1517)) an attempt was +made to fix leakage of the `ThreadGroup` instances created when a test is run with a timeout. That +change explicitly destroyed the `ThreadGroup` that was created for the time-limited test. Numerous +people reported problems that were caused by explicitly destroying the `ThreadGroup`. + +In this change, the code was updated to call `ThreadGroup.setDaemon(true)` instead of destroying the +ThreadGroup. + +### [Pull request $1691:](https://github.com/junit-team/junit/pull/1691) Only create ThreadGroups if FailOnTimeout.lookForStuckThread is true. + +In JUnit 4.12 ([pull request #742](https://github.com/junit-team/junit4/pull/742)) the `Timeout` +Rule was updated to optionally display the stacktrace of the thread that appears to be stuck +(enabled on an opt-in basis by passing `true` to `Timeout.Builder.lookForStuckThread(boolean)`). +When that change was made, time-limited tests were changed to start the new thread in a new +`ThreadGroup`, even if the test did not call `lookForStuckThread()`. This subtle change in +behavior resulted in visible behavior changes to some tests (for example, tests of code that uses +`java.beans.ThreadGroupContext`). + +In this change, the code is updated to only create a new `ThreadGroup` if the caller calls +`Timeout.Builder.lookForStuckThread(true)`. Tests with timeouts that do not make this call will +behave as they did in JUnit 4.11 (and more similar to tests that do not have a timeout). This +unfortunately could result in visible changes of tests written or updated since the 4.12 +release. If this change adversely affects your tests, you can create the `Timeout` rule via the +builder and call `Timeout.Builder.lookForStuckThread(true)`. + +# Exceptions + +### [Pull request #1654:](https://github.com/junit-team/junit/pull/1654) Fix for issue #1192: NotSerializableException with AssumptionViolatedException + +This change fixes an issue where `AssumptionViolatedException` instances could not be serialized +if they were created with a constructor that takes in an `org.hamcrest.Matcher` instance (these +constructors are used if you use one of the `assumeThat()` methods in `org.junit.Assume`). diff --git a/pom.xml b/pom.xml index 428715884b4e..38be96092f24 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ junit junit - 4.13.1 + 4.13.2 JUnit JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck. @@ -64,15 +64,15 @@ scm:git:git://github.com/junit-team/junit4.git scm:git:git@github.com:junit-team/junit4.git https://github.com/junit-team/junit4 - r4.13.1 + r4.13.2 github https://github.com/junit-team/junit4/issues - travis - https://travis-ci.org/junit-team/junit4 + github + https://github.com/junit-team/junit4/actions https://github.com/junit-team/junit4/wiki/Download-and-Install @@ -96,6 +96,9 @@ 1.5 2.19.1 1.3 + 1.4 + 2.6 + 2.10.3 ISO-8859-1 67893CC4 @@ -147,7 +150,7 @@ the project, requires only release versions of dependencies of other artifacts. --> maven-enforcer-plugin - 1.4 + ${enforcerPluginVersion} enforce-versions @@ -286,7 +289,7 @@ in jar archive target/junit-*-javadoc.jar. --> maven-javadoc-plugin - 2.10.3 + ${javadocPluginVersion} ${basedir}/src/main/javadoc/stylesheet.css protected @@ -345,7 +348,7 @@ maven-jar-plugin - 2.6 + ${jarPluginVersion} false @@ -408,7 +411,7 @@ maven-javadoc-plugin - 2.10.3 + ${javadocPluginVersion} javadoc/latest ${basedir}/src/main/javadoc/stylesheet.css @@ -556,7 +559,7 @@ java9 - [1.9,) + [1.9,12) @@ -583,5 +586,48 @@ + + java12 + + [12,) + + + + 1.7 + 3.0.0-M3 + 3.2.0 + 3.2.0 + + + + + maven-javadoc-plugin + + 1.7 + false + + + + maven-compiler-plugin + + + -Xdoclint:none + + + + + + + + + maven-javadoc-plugin + + 1.7 + false + + + + + diff --git a/src/main/java/junit/extensions/ActiveTestSuite.java b/src/main/java/junit/extensions/ActiveTestSuite.java index 95c5e2e71062..6f0f99dad04e 100644 --- a/src/main/java/junit/extensions/ActiveTestSuite.java +++ b/src/main/java/junit/extensions/ActiveTestSuite.java @@ -63,7 +63,7 @@ synchronized void waitUntilFinished() { } } - synchronized public void runFinished() { + public synchronized void runFinished() { fActiveTestDeathCount++; notifyAll(); } diff --git a/src/main/java/junit/framework/Assert.java b/src/main/java/junit/framework/Assert.java index d10cdb4247b6..43482a16b6f2 100644 --- a/src/main/java/junit/framework/Assert.java +++ b/src/main/java/junit/framework/Assert.java @@ -17,7 +17,7 @@ protected Assert() { * Asserts that a condition is true. If it isn't it throws * an AssertionFailedError with the given message. */ - static public void assertTrue(String message, boolean condition) { + public static void assertTrue(String message, boolean condition) { if (!condition) { fail(message); } @@ -27,7 +27,7 @@ static public void assertTrue(String message, boolean condition) { * Asserts that a condition is true. If it isn't it throws * an AssertionFailedError. */ - static public void assertTrue(boolean condition) { + public static void assertTrue(boolean condition) { assertTrue(null, condition); } @@ -35,7 +35,7 @@ static public void assertTrue(boolean condition) { * Asserts that a condition is false. If it isn't it throws * an AssertionFailedError with the given message. */ - static public void assertFalse(String message, boolean condition) { + public static void assertFalse(String message, boolean condition) { assertTrue(message, !condition); } @@ -43,14 +43,14 @@ static public void assertFalse(String message, boolean condition) { * Asserts that a condition is false. If it isn't it throws * an AssertionFailedError. */ - static public void assertFalse(boolean condition) { + public static void assertFalse(boolean condition) { assertFalse(null, condition); } /** * Fails a test with the given message. */ - static public void fail(String message) { + public static void fail(String message) { if (message == null) { throw new AssertionFailedError(); } @@ -60,7 +60,7 @@ static public void fail(String message) { /** * Fails a test with no message. */ - static public void fail() { + public static void fail() { fail(null); } @@ -68,7 +68,7 @@ static public void fail() { * Asserts that two objects are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - static public void assertEquals(String message, Object expected, Object actual) { + public static void assertEquals(String message, Object expected, Object actual) { if (expected == null && actual == null) { return; } @@ -82,14 +82,14 @@ static public void assertEquals(String message, Object expected, Object actual) * Asserts that two objects are equal. If they are not * an AssertionFailedError is thrown. */ - static public void assertEquals(Object expected, Object actual) { + public static void assertEquals(Object expected, Object actual) { assertEquals(null, expected, actual); } /** * Asserts that two Strings are equal. */ - static public void assertEquals(String message, String expected, String actual) { + public static void assertEquals(String message, String expected, String actual) { if (expected == null && actual == null) { return; } @@ -103,7 +103,7 @@ static public void assertEquals(String message, String expected, String actual) /** * Asserts that two Strings are equal. */ - static public void assertEquals(String expected, String actual) { + public static void assertEquals(String expected, String actual) { assertEquals(null, expected, actual); } @@ -112,7 +112,7 @@ static public void assertEquals(String expected, String actual) { * an AssertionFailedError is thrown with the given message. If the expected * value is infinity then the delta value is ignored. */ - static public void assertEquals(String message, double expected, double actual, double delta) { + public static void assertEquals(String message, double expected, double actual, double delta) { if (Double.compare(expected, actual) == 0) { return; } @@ -125,7 +125,7 @@ static public void assertEquals(String message, double expected, double actual, * Asserts that two doubles are equal concerning a delta. If the expected * value is infinity then the delta value is ignored. */ - static public void assertEquals(double expected, double actual, double delta) { + public static void assertEquals(double expected, double actual, double delta) { assertEquals(null, expected, actual, delta); } @@ -134,7 +134,7 @@ static public void assertEquals(double expected, double actual, double delta) { * are not an AssertionFailedError is thrown with the given message. If the * expected value is infinity then the delta value is ignored. */ - static public void assertEquals(String message, float expected, float actual, float delta) { + public static void assertEquals(String message, float expected, float actual, float delta) { if (Float.compare(expected, actual) == 0) { return; } @@ -147,7 +147,7 @@ static public void assertEquals(String message, float expected, float actual, fl * Asserts that two floats are equal concerning a delta. If the expected * value is infinity then the delta value is ignored. */ - static public void assertEquals(float expected, float actual, float delta) { + public static void assertEquals(float expected, float actual, float delta) { assertEquals(null, expected, actual, delta); } @@ -155,14 +155,14 @@ static public void assertEquals(float expected, float actual, float delta) { * Asserts that two longs are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - static public void assertEquals(String message, long expected, long actual) { + public static void assertEquals(String message, long expected, long actual) { assertEquals(message, Long.valueOf(expected), Long.valueOf(actual)); } /** * Asserts that two longs are equal. */ - static public void assertEquals(long expected, long actual) { + public static void assertEquals(long expected, long actual) { assertEquals(null, expected, actual); } @@ -170,14 +170,14 @@ static public void assertEquals(long expected, long actual) { * Asserts that two booleans are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - static public void assertEquals(String message, boolean expected, boolean actual) { + public static void assertEquals(String message, boolean expected, boolean actual) { assertEquals(message, Boolean.valueOf(expected), Boolean.valueOf(actual)); } /** * Asserts that two booleans are equal. */ - static public void assertEquals(boolean expected, boolean actual) { + public static void assertEquals(boolean expected, boolean actual) { assertEquals(null, expected, actual); } @@ -185,14 +185,14 @@ static public void assertEquals(boolean expected, boolean actual) { * Asserts that two bytes are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - static public void assertEquals(String message, byte expected, byte actual) { + public static void assertEquals(String message, byte expected, byte actual) { assertEquals(message, Byte.valueOf(expected), Byte.valueOf(actual)); } /** * Asserts that two bytes are equal. */ - static public void assertEquals(byte expected, byte actual) { + public static void assertEquals(byte expected, byte actual) { assertEquals(null, expected, actual); } @@ -200,14 +200,14 @@ static public void assertEquals(byte expected, byte actual) { * Asserts that two chars are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - static public void assertEquals(String message, char expected, char actual) { + public static void assertEquals(String message, char expected, char actual) { assertEquals(message, Character.valueOf(expected), Character.valueOf(actual)); } /** * Asserts that two chars are equal. */ - static public void assertEquals(char expected, char actual) { + public static void assertEquals(char expected, char actual) { assertEquals(null, expected, actual); } @@ -215,14 +215,14 @@ static public void assertEquals(char expected, char actual) { * Asserts that two shorts are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - static public void assertEquals(String message, short expected, short actual) { + public static void assertEquals(String message, short expected, short actual) { assertEquals(message, Short.valueOf(expected), Short.valueOf(actual)); } /** * Asserts that two shorts are equal. */ - static public void assertEquals(short expected, short actual) { + public static void assertEquals(short expected, short actual) { assertEquals(null, expected, actual); } @@ -230,21 +230,21 @@ static public void assertEquals(short expected, short actual) { * Asserts that two ints are equal. If they are not * an AssertionFailedError is thrown with the given message. */ - static public void assertEquals(String message, int expected, int actual) { + public static void assertEquals(String message, int expected, int actual) { assertEquals(message, Integer.valueOf(expected), Integer.valueOf(actual)); } /** * Asserts that two ints are equal. */ - static public void assertEquals(int expected, int actual) { + public static void assertEquals(int expected, int actual) { assertEquals(null, expected, actual); } /** * Asserts that an object isn't null. */ - static public void assertNotNull(Object object) { + public static void assertNotNull(Object object) { assertNotNull(null, object); } @@ -252,7 +252,7 @@ static public void assertNotNull(Object object) { * Asserts that an object isn't null. If it is * an AssertionFailedError is thrown with the given message. */ - static public void assertNotNull(String message, Object object) { + public static void assertNotNull(String message, Object object) { assertTrue(message, object != null); } @@ -263,7 +263,7 @@ static public void assertNotNull(String message, Object object) { * * @param object Object to check or null */ - static public void assertNull(Object object) { + public static void assertNull(Object object) { if (object != null) { assertNull("Expected: but was: " + object.toString(), object); } @@ -273,7 +273,7 @@ static public void assertNull(Object object) { * Asserts that an object is null. If it is not * an AssertionFailedError is thrown with the given message. */ - static public void assertNull(String message, Object object) { + public static void assertNull(String message, Object object) { assertTrue(message, object == null); } @@ -281,7 +281,7 @@ static public void assertNull(String message, Object object) { * Asserts that two objects refer to the same object. If they are not * an AssertionFailedError is thrown with the given message. */ - static public void assertSame(String message, Object expected, Object actual) { + public static void assertSame(String message, Object expected, Object actual) { if (expected == actual) { return; } @@ -292,7 +292,7 @@ static public void assertSame(String message, Object expected, Object actual) { * Asserts that two objects refer to the same object. If they are not * the same an AssertionFailedError is thrown. */ - static public void assertSame(Object expected, Object actual) { + public static void assertSame(Object expected, Object actual) { assertSame(null, expected, actual); } @@ -301,7 +301,7 @@ static public void assertSame(Object expected, Object actual) { * refer to the same object an AssertionFailedError is thrown with the * given message. */ - static public void assertNotSame(String message, Object expected, Object actual) { + public static void assertNotSame(String message, Object expected, Object actual) { if (expected == actual) { failSame(message); } @@ -311,21 +311,21 @@ static public void assertNotSame(String message, Object expected, Object actual) * Asserts that two objects do not refer to the same object. If they do * refer to the same object an AssertionFailedError is thrown. */ - static public void assertNotSame(Object expected, Object actual) { + public static void assertNotSame(Object expected, Object actual) { assertNotSame(null, expected, actual); } - static public void failSame(String message) { + public static void failSame(String message) { String formatted = (message != null) ? message + " " : ""; fail(formatted + "expected not same"); } - static public void failNotSame(String message, Object expected, Object actual) { + public static void failNotSame(String message, Object expected, Object actual) { String formatted = (message != null) ? message + " " : ""; fail(formatted + "expected same:<" + expected + "> was not:<" + actual + ">"); } - static public void failNotEquals(String message, Object expected, Object actual) { + public static void failNotEquals(String message, Object expected, Object actual) { fail(format(message, expected, actual)); } diff --git a/src/main/java/junit/runner/Version.java b/src/main/java/junit/runner/Version.java index 9f263840e40f..bb12a70a95aa 100644 --- a/src/main/java/junit/runner/Version.java +++ b/src/main/java/junit/runner/Version.java @@ -9,7 +9,7 @@ private Version() { } public static String id() { - return "4.13.1-SNAPSHOT"; + return "4.13.2-SNAPSHOT"; } public static void main(String[] args) { diff --git a/src/main/java/org/junit/experimental/results/ResultMatchers.java b/src/main/java/org/junit/experimental/results/ResultMatchers.java index e111093150c1..92f2e6b0482c 100644 --- a/src/main/java/org/junit/experimental/results/ResultMatchers.java +++ b/src/main/java/org/junit/experimental/results/ResultMatchers.java @@ -4,7 +4,6 @@ import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; -import org.junit.runner.notification.Failure; /** * Matchers on a PrintableResult, to enable JUnit self-tests. diff --git a/src/main/java/org/junit/internal/AssumptionViolatedException.java b/src/main/java/org/junit/internal/AssumptionViolatedException.java index 15c27af1b279..0e79b562f5f2 100644 --- a/src/main/java/org/junit/internal/AssumptionViolatedException.java +++ b/src/main/java/org/junit/internal/AssumptionViolatedException.java @@ -1,5 +1,8 @@ package org.junit.internal; +import java.io.IOException; +import java.io.ObjectOutputStream; + import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.SelfDescribing; @@ -108,4 +111,29 @@ public void describeTo(Description description) { } } } + + /** + * Override default Java object serialization to correctly deal with potentially unserializable matchers or values. + * By not implementing readObject, we assure ourselves of backwards compatibility and compatibility with the + * standard way of Java serialization. + * + * @param objectOutputStream The outputStream to write our representation to + * @throws IOException When serialization fails + */ + private void writeObject(ObjectOutputStream objectOutputStream) throws IOException { + ObjectOutputStream.PutField putField = objectOutputStream.putFields(); + putField.put("fAssumption", fAssumption); + putField.put("fValueMatcher", fValueMatcher); + + // We have to wrap the matcher into a serializable form. + putField.put("fMatcher", SerializableMatcherDescription.asSerializableMatcher(fMatcher)); + + // We have to wrap the value inside a non-String class (instead of serializing the String value directly) as + // A Description will handle a String and non-String object differently (1st is surrounded by '"' while the + // latter will be surrounded by '<' '>'. Wrapping it makes sure that the description of a serialized and + // non-serialized instance produce the exact same description + putField.put("fValue", SerializableValueDescription.asSerializableValue(fValue)); + + objectOutputStream.writeFields(); + } } diff --git a/src/main/java/org/junit/internal/SerializableMatcherDescription.java b/src/main/java/org/junit/internal/SerializableMatcherDescription.java new file mode 100644 index 000000000000..e0365572001c --- /dev/null +++ b/src/main/java/org/junit/internal/SerializableMatcherDescription.java @@ -0,0 +1,47 @@ +package org.junit.internal; + +import java.io.Serializable; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.StringDescription; + +/** + * This class exists solely to provide a serializable description of a matcher to be serialized as a field in + * {@link AssumptionViolatedException}. Being a {@link Throwable}, it is required to be {@link Serializable}, but most + * implementations of {@link Matcher} are not. This class works around that limitation as + * {@link AssumptionViolatedException} only every uses the description of the {@link Matcher}, while still retaining + * backwards compatibility with classes compiled against its class signature before 4.14 and/or deserialization of + * previously serialized instances. + */ +class SerializableMatcherDescription extends BaseMatcher implements Serializable { + + private final String matcherDescription; + + private SerializableMatcherDescription(Matcher matcher) { + matcherDescription = StringDescription.asString(matcher); + } + + public boolean matches(Object o) { + throw new UnsupportedOperationException("This Matcher implementation only captures the description"); + } + + public void describeTo(Description description) { + description.appendText(matcherDescription); + } + + /** + * Factory method that checks to see if the matcher is already serializable. + * @param matcher the matcher to make serializable + * @return The provided matcher if it is null or already serializable, + * the SerializableMatcherDescription representation of it if it is not. + */ + static Matcher asSerializableMatcher(Matcher matcher) { + if (matcher == null || matcher instanceof Serializable) { + return matcher; + } else { + return new SerializableMatcherDescription(matcher); + } + } +} diff --git a/src/main/java/org/junit/internal/SerializableValueDescription.java b/src/main/java/org/junit/internal/SerializableValueDescription.java new file mode 100644 index 000000000000..4d055d7a4019 --- /dev/null +++ b/src/main/java/org/junit/internal/SerializableValueDescription.java @@ -0,0 +1,38 @@ +package org.junit.internal; + +import java.io.Serializable; + +/** + * This class exists solely to provide a serializable description of a value to be serialized as a field in + * {@link AssumptionViolatedException}. Being a {@link Throwable}, it is required to be {@link Serializable}, but a + * value of type Object provides no guarantee to be serializable. This class works around that limitation as + * {@link AssumptionViolatedException} only every uses the string representation of the value, while still retaining + * backwards compatibility with classes compiled against its class signature before 4.14 and/or deserialization of + * previously serialized instances. + */ +class SerializableValueDescription implements Serializable { + private final String value; + + private SerializableValueDescription(Object value) { + this.value = String.valueOf(value); + } + + /** + * Factory method that checks to see if the value is already serializable. + * @param value the value to make serializable + * @return The provided value if it is null or already serializable, + * the SerializableValueDescription representation of it if it is not. + */ + static Object asSerializableValue(Object value) { + if (value == null || value instanceof Serializable) { + return value; + } else { + return new SerializableValueDescription(value); + } + } + + @Override + public String toString() { + return value; + } +} diff --git a/src/main/java/org/junit/internal/Throwables.java b/src/main/java/org/junit/internal/Throwables.java index 67d6b2bc06ec..3f0f7a33b051 100644 --- a/src/main/java/org/junit/internal/Throwables.java +++ b/src/main/java/org/junit/internal/Throwables.java @@ -232,7 +232,10 @@ public final State processStackTraceElement(StackTraceElement element) { "org.junit.runners.", "org.junit.experimental.runners.", "org.junit.internal.", - "junit.", + "junit.extensions", + "junit.framework", + "junit.runner", + "junit.textui", }; private static final String[] TEST_FRAMEWORK_TEST_METHOD_NAME_PREFIXES = { diff --git a/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java b/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java index 94c12e6e9770..9362cc168965 100644 --- a/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java +++ b/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java @@ -120,29 +120,40 @@ public FailOnTimeout build(Statement statement) { public void evaluate() throws Throwable { CallableStatement callable = new CallableStatement(); FutureTask task = new FutureTask(callable); - ThreadGroup threadGroup = new ThreadGroup("FailOnTimeoutGroup"); + ThreadGroup threadGroup = threadGroupForNewThread(); Thread thread = new Thread(threadGroup, task, "Time-limited test"); - try { - thread.setDaemon(true); - thread.start(); - callable.awaitStarted(); - Throwable throwable = getResult(task, thread); - if (throwable != null) { - throw throwable; - } - } finally { - try { - thread.join(1); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + thread.setDaemon(true); + thread.start(); + callable.awaitStarted(); + Throwable throwable = getResult(task, thread); + if (throwable != null) { + throw throwable; + } + } + + private ThreadGroup threadGroupForNewThread() { + if (!lookForStuckThread) { + // Use the default ThreadGroup (usually the one from the current + // thread). + return null; + } + + // Create the thread in a new ThreadGroup, so if the time-limited thread + // becomes stuck, getStuckThread() can find the thread likely to be the + // culprit. + ThreadGroup threadGroup = new ThreadGroup("FailOnTimeoutGroup"); + if (!threadGroup.isDaemon()) { + // Mark the new ThreadGroup as a daemon thread group, so it will be + // destroyed after the time-limited thread completes. By ensuring the + // ThreadGroup is destroyed, any data associated with the ThreadGroup + // (ex: via java.beans.ThreadGroupContext) is destroyed. try { - threadGroup.destroy(); - } catch (IllegalThreadStateException e) { - // If a thread from the group is still alive, the ThreadGroup cannot be destroyed. - // Swallow the exception to keep the same behavior prior to this change. + threadGroup.setDaemon(true); + } catch (SecurityException e) { + // Swallow the exception to keep the same behavior as in JUnit 4.12. } } + return threadGroup; } /** diff --git a/src/main/java/org/junit/runner/notification/RunNotifier.java b/src/main/java/org/junit/runner/notification/RunNotifier.java index 8b686cdf287a..752fa3bdf6ac 100644 --- a/src/main/java/org/junit/runner/notification/RunNotifier.java +++ b/src/main/java/org/junit/runner/notification/RunNotifier.java @@ -78,7 +78,7 @@ void run() { fireTestFailures(safeListeners, failures); } - abstract protected void notifyListener(RunListener each) throws Exception; + protected abstract void notifyListener(RunListener each) throws Exception; } /** diff --git a/src/main/java/org/junit/runners/model/FrameworkField.java b/src/main/java/org/junit/runners/model/FrameworkField.java index 1f8a101418fb..ea2b16f8c4ae 100644 --- a/src/main/java/org/junit/runners/model/FrameworkField.java +++ b/src/main/java/org/junit/runners/model/FrameworkField.java @@ -2,7 +2,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Field; -import java.util.List; import org.junit.runners.BlockJUnit4ClassRunner; diff --git a/src/main/java/org/junit/validator/AnnotationsValidator.java b/src/main/java/org/junit/validator/AnnotationsValidator.java index 44d99d2a2f8d..d8b58404f9a5 100644 --- a/src/main/java/org/junit/validator/AnnotationsValidator.java +++ b/src/main/java/org/junit/validator/AnnotationsValidator.java @@ -40,7 +40,7 @@ public List validateTestClass(TestClass testClass) { return validationErrors; } - private static abstract class AnnotatableValidator { + private abstract static class AnnotatableValidator { private static final AnnotationValidatorFactory ANNOTATION_VALIDATOR_FACTORY = new AnnotationValidatorFactory(); abstract Iterable getAnnotatablesForTestClass(TestClass testClass); diff --git a/src/test/java/junit/tests/SampleJUnit3Tests.java b/src/test/java/junit/tests/SampleJUnit3Tests.java new file mode 100644 index 000000000000..46f996b3da3a --- /dev/null +++ b/src/test/java/junit/tests/SampleJUnit3Tests.java @@ -0,0 +1,51 @@ +package junit.tests; + +import junit.framework.TestCase; + +/** + * Container for sample JUnit3-style tests used in integration tests. + */ +public class SampleJUnit3Tests { + + public static class TestWithOneThrowingTestMethod extends TestCase { + + public void testAlwaysThrows() { + new FakeClassUnderTest().throwsExceptionWithoutCause(); + } + } + + public static class TestWithThrowingSetUpMethod extends TestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + new FakeClassUnderTest().throwsExceptionWithoutCause(); + } + + public void testAlwaysPasses() { + } + } + + private static class FakeClassUnderTest { + + public void throwsExceptionWithCause() { + doThrowExceptionWithCause(); + } + + public void throwsExceptionWithoutCause() { + doThrowExceptionWithoutCause(); + } + + private void doThrowExceptionWithCause() { + try { + throwsExceptionWithoutCause(); + } catch (Exception e) { + throw new RuntimeException("outer", e); + } + } + + private void doThrowExceptionWithoutCause() { + throw new RuntimeException("cause"); + } + } +} diff --git a/src/test/java/junit/tests/framework/DoublePrecisionAssertTest.java b/src/test/java/junit/tests/framework/DoublePrecisionAssertTest.java index 439cc983dd00..f4161091ec14 100644 --- a/src/test/java/junit/tests/framework/DoublePrecisionAssertTest.java +++ b/src/test/java/junit/tests/framework/DoublePrecisionAssertTest.java @@ -11,17 +11,19 @@ public class DoublePrecisionAssertTest extends TestCase { public void testAssertEqualsNaNFails() { try { assertEquals(1.234, Double.NaN, 0.0); - fail(); } catch (AssertionFailedError e) { + return; } + fail(); } public void testAssertNaNEqualsFails() { try { assertEquals(Double.NaN, 1.234, 0.0); - fail(); } catch (AssertionFailedError e) { + return; } + fail(); } public void testAssertNaNEqualsNaN() { @@ -31,17 +33,19 @@ public void testAssertNaNEqualsNaN() { public void testAssertPosInfinityNotEqualsNegInfinity() { try { assertEquals(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 0.0); - fail(); } catch (AssertionFailedError e) { + return; } + fail(); } public void testAssertPosInfinityNotEquals() { try { assertEquals(Double.POSITIVE_INFINITY, 1.23, 0.0); - fail(); } catch (AssertionFailedError e) { + return; } + fail(); } public void testAssertPosInfinityEqualsInfinity() { diff --git a/src/test/java/junit/tests/framework/FloatAssertTest.java b/src/test/java/junit/tests/framework/FloatAssertTest.java index d390f0b19cf2..aeae9443d80d 100644 --- a/src/test/java/junit/tests/framework/FloatAssertTest.java +++ b/src/test/java/junit/tests/framework/FloatAssertTest.java @@ -11,17 +11,19 @@ public class FloatAssertTest extends TestCase { public void testAssertEqualsNaNFails() { try { assertEquals(1.234f, Float.NaN, 0.0); - fail(); } catch (AssertionFailedError e) { + return; } + fail(); } public void testAssertNaNEqualsFails() { try { assertEquals(Float.NaN, 1.234f, 0.0); - fail(); } catch (AssertionFailedError e) { + return; } + fail(); } public void testAssertNaNEqualsNaN() { @@ -31,17 +33,19 @@ public void testAssertNaNEqualsNaN() { public void testAssertPosInfinityNotEqualsNegInfinity() { try { assertEquals(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, 0.0); - fail(); } catch (AssertionFailedError e) { + return; } + fail(); } public void testAssertPosInfinityNotEquals() { try { assertEquals(Float.POSITIVE_INFINITY, 1.23f, 0.0); - fail(); } catch (AssertionFailedError e) { + return; } + fail(); } public void testAssertPosInfinityEqualsInfinity() { @@ -53,11 +57,7 @@ public void testAssertNegInfinityEqualsInfinity() { } public void testAllInfinities() { - try { - assertEquals(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY); - fail(); - } catch (AssertionFailedError e) { - } + assertEquals(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY); } } diff --git a/src/test/java/junit/tests/runner/ResultTest.java b/src/test/java/junit/tests/runner/ResultTest.java index 7a6042996268..8cd7ac2d657e 100644 --- a/src/test/java/junit/tests/runner/ResultTest.java +++ b/src/test/java/junit/tests/runner/ResultTest.java @@ -2,8 +2,6 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; @@ -98,7 +96,7 @@ private void assertResultReserializable(Result result, SerializationFormat resou fromStream, resourceSerializationFormat); } - static public class AssumptionFailedTest { + public static class AssumptionFailedTest { @Test public void assumptionFailed() throws Exception { org.junit.Assume.assumeTrue(false); diff --git a/src/test/java/junit/tests/runner/TextRunnerTest.java b/src/test/java/junit/tests/runner/TextRunnerTest.java index c74acc21335a..44e16fd599d0 100644 --- a/src/test/java/junit/tests/runner/TextRunnerTest.java +++ b/src/test/java/junit/tests/runner/TextRunnerTest.java @@ -32,7 +32,7 @@ void execTest(String testClass, boolean success) throws Exception { Process p = Runtime.getRuntime().exec(cmd); InputStream i = p.getInputStream(); while ((i.read()) != -1) - ; //System.out.write(b); + ; assertTrue((p.waitFor() == 0) == success); if (success) { assertTrue(p.exitValue() == 0); diff --git a/src/test/java/org/junit/AssumptionViolatedExceptionTest.java b/src/test/java/org/junit/AssumptionViolatedExceptionTest.java index 574cdb13059d..f5dbfcb9813b 100644 --- a/src/test/java/org/junit/AssumptionViolatedExceptionTest.java +++ b/src/test/java/org/junit/AssumptionViolatedExceptionTest.java @@ -4,12 +4,27 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsNot.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assume.assumeThat; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.StringDescription; import org.junit.experimental.theories.DataPoint; import org.junit.experimental.theories.Theories; import org.junit.experimental.theories.Theory; +import org.junit.rules.TestName; import org.junit.runner.RunWith; @RunWith(Theories.class) @@ -23,6 +38,14 @@ public class AssumptionViolatedExceptionTest { @DataPoint public static Matcher NULL = null; + @Rule + public TestName name = new TestName(); + + private static final String MESSAGE = "Assumption message"; + private static Matcher SERIALIZABLE_IS_THREE = new SerializableIsThreeMatcher(); + private static final UnserializableClass UNSERIALIZABLE_VALUE = new UnserializableClass(); + private static final Matcher UNSERIALIZABLE_MATCHER = not(is(UNSERIALIZABLE_VALUE)); + @Theory public void toStringReportsMatcher(Integer actual, Matcher matcher) { assumeThat(matcher, notNullValue()); @@ -92,4 +115,93 @@ public void canSetCauseWithInstanceCreatedWithExplicitThrowableConstructor() { AssumptionViolatedException e = new AssumptionViolatedException("invalid number", cause); assertThat(e.getCause(), is(cause)); } + + @Test + public void assumptionViolatedExceptionWithoutValueAndMatcherCanBeReserialized_v4_13() + throws IOException, ClassNotFoundException { + assertReserializable(new AssumptionViolatedException(MESSAGE)); + } + + @Test + public void assumptionViolatedExceptionWithValueAndMatcherCanBeReserialized_v4_13() + throws IOException, ClassNotFoundException { + assertReserializable(new AssumptionViolatedException(MESSAGE, TWO, SERIALIZABLE_IS_THREE)); + } + + @Test + public void unserializableValueAndMatcherCanBeSerialized() throws IOException, ClassNotFoundException { + AssumptionViolatedException exception = new AssumptionViolatedException(MESSAGE, + UNSERIALIZABLE_VALUE, UNSERIALIZABLE_MATCHER); + + assertCanBeSerialized(exception); + } + + @Test + public void nullValueAndMatcherCanBeSerialized() throws IOException, ClassNotFoundException { + AssumptionViolatedException exception = new AssumptionViolatedException(MESSAGE); + + assertCanBeSerialized(exception); + } + + @Test + public void serializableValueAndMatcherCanBeSerialized() throws IOException, ClassNotFoundException { + AssumptionViolatedException exception = new AssumptionViolatedException(MESSAGE, + TWO, SERIALIZABLE_IS_THREE); + + assertCanBeSerialized(exception); + } + + private void assertCanBeSerialized(AssumptionViolatedException exception) + throws IOException, ClassNotFoundException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(exception); + + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bais); + AssumptionViolatedException fromStream = (AssumptionViolatedException) ois.readObject(); + + assertSerializedCorrectly(exception, fromStream); + } + + private void assertReserializable(AssumptionViolatedException expected) + throws IOException, ClassNotFoundException { + String resourceName = name.getMethodName(); + InputStream resource = getClass().getResourceAsStream(resourceName); + assertNotNull("Could not read resource " + resourceName, resource); + ObjectInputStream objectInputStream = new ObjectInputStream(resource); + AssumptionViolatedException fromStream = (AssumptionViolatedException) objectInputStream.readObject(); + + assertSerializedCorrectly(expected, fromStream); + } + + private void assertSerializedCorrectly( + AssumptionViolatedException expected, AssumptionViolatedException fromStream) { + assertNotNull(fromStream); + + // Exceptions don't implement equals() so we need to compare field by field + assertEquals("message", expected.getMessage(), fromStream.getMessage()); + assertEquals("description", StringDescription.asString(expected), StringDescription.asString(fromStream)); + // We don't check the stackTrace as that will be influenced by how the test was started + // (e.g. by maven or directly from IDE) + // We also don't check the cause as that should already be serialized correctly by the superclass + } + + private static class SerializableIsThreeMatcher extends BaseMatcher implements Serializable { + + public boolean matches(Object item) { + return IS_THREE.matches(item); + } + + public void describeTo(Description description) { + IS_THREE.describeTo(description); + } + } + + private static class UnserializableClass { + @Override + public String toString() { + return "I'm not serializable"; + } + } } diff --git a/src/test/java/org/junit/experimental/categories/CategoriesAndParameterizedTest.java b/src/test/java/org/junit/experimental/categories/CategoriesAndParameterizedTest.java index 68e842bb53e9..3d792225d179 100644 --- a/src/test/java/org/junit/experimental/categories/CategoriesAndParameterizedTest.java +++ b/src/test/java/org/junit/experimental/categories/CategoriesAndParameterizedTest.java @@ -6,9 +6,7 @@ import org.junit.Assert; import org.junit.Test; -import org.junit.experimental.categories.Categories; import org.junit.experimental.categories.Categories.IncludeCategory; -import org.junit.experimental.categories.Category; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.RunWith; diff --git a/src/test/java/org/junit/experimental/categories/CategoryTest.java b/src/test/java/org/junit/experimental/categories/CategoryTest.java index 59242b447cfa..6088f1d26229 100644 --- a/src/test/java/org/junit/experimental/categories/CategoryTest.java +++ b/src/test/java/org/junit/experimental/categories/CategoryTest.java @@ -1,28 +1,27 @@ package org.junit.experimental.categories; +import static java.lang.String.format; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.AnyOf.anyOf; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.experimental.results.PrintableResult.testResult; -import static org.junit.experimental.results.ResultMatchers.isSuccessful; import static org.junit.experimental.results.ResultMatchers.failureCountIs; -import static org.hamcrest.core.AnyOf.anyOf; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.IsEqual.equalTo; -import static java.lang.String.format; +import static org.junit.experimental.results.ResultMatchers.isSuccessful; import java.util.Collections; import java.util.HashSet; import java.util.Set; + import org.junit.Ignore; import org.junit.Test; -import org.junit.experimental.categories.Categories; import org.junit.experimental.categories.Categories.CategoryFilter; import org.junit.experimental.categories.Categories.ExcludeCategory; import org.junit.experimental.categories.Categories.IncludeCategory; -import org.junit.experimental.categories.Category; import org.junit.runner.JUnitCore; import org.junit.runner.Request; import org.junit.runner.Result; @@ -412,7 +411,7 @@ public void classesCanBeCategories() { } @Category(SlowTests.class) - public static abstract class Ancestor{} + public abstract static class Ancestor{} public static class Inherited extends Ancestor { @Test diff --git a/src/test/java/org/junit/experimental/categories/CategoryValidatorTest.java b/src/test/java/org/junit/experimental/categories/CategoryValidatorTest.java index 654622f594bf..6d7c22ec31dd 100644 --- a/src/test/java/org/junit/experimental/categories/CategoryValidatorTest.java +++ b/src/test/java/org/junit/experimental/categories/CategoryValidatorTest.java @@ -10,8 +10,6 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.experimental.categories.CategoryValidator; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.TestClass; diff --git a/src/test/java/org/junit/experimental/categories/JavadocTest.java b/src/test/java/org/junit/experimental/categories/JavadocTest.java index 65fa430f9dbb..fc0df7248bbd 100644 --- a/src/test/java/org/junit/experimental/categories/JavadocTest.java +++ b/src/test/java/org/junit/experimental/categories/JavadocTest.java @@ -1,18 +1,16 @@ package org.junit.experimental.categories; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + import org.junit.Test; -import org.junit.experimental.categories.Categories; -import org.junit.experimental.categories.Category; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.RunWith; import org.junit.runners.Suite; -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - /** * @author tibor17 * @version 4.12 diff --git a/src/test/java/org/junit/experimental/categories/MultiCategoryTest.java b/src/test/java/org/junit/experimental/categories/MultiCategoryTest.java index c7169aca120a..68a580cdead7 100644 --- a/src/test/java/org/junit/experimental/categories/MultiCategoryTest.java +++ b/src/test/java/org/junit/experimental/categories/MultiCategoryTest.java @@ -1,19 +1,17 @@ package org.junit.experimental.categories; -import org.junit.Test; -import org.junit.experimental.categories.Categories; -import org.junit.experimental.categories.Category; -import org.junit.runner.JUnitCore; -import org.junit.runner.Result; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; +import org.junit.Test; +import org.junit.runner.JUnitCore; +import org.junit.runner.Result; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + /** * @author tibor17 * @version 4.12 diff --git a/src/test/java/org/junit/internal/StackTracesTest.java b/src/test/java/org/junit/internal/StackTracesTest.java index 748d86a5f9e8..5c0e8a1603a8 100644 --- a/src/test/java/org/junit/internal/StackTracesTest.java +++ b/src/test/java/org/junit/internal/StackTracesTest.java @@ -6,7 +6,6 @@ import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; -import java.lang.reflect.Method; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -14,25 +13,19 @@ import java.util.concurrent.Future; import java.util.regex.Pattern; -import junit.framework.TestCase; +import junit.tests.SampleJUnit3Tests; import org.hamcrest.CoreMatchers; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.StringDescription; import org.hamcrest.TypeSafeMatcher; import org.junit.AfterClass; -import org.junit.Before; import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.MethodRule; -import org.junit.rules.TestRule; import org.junit.runner.JUnitCore; import org.junit.runner.Result; import org.junit.runner.notification.Failure; -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.Statement; +import org.junit.tests.SampleJUnit4Tests.*; public class StackTracesTest { private static final String EOL = System.getProperty("line.separator", "\n"); @@ -58,9 +51,9 @@ public void getTrimmedStackForJUnit4TestFailingInTestMethod() { assertHasTrimmedTrace(failure, message("java.lang.RuntimeException: cause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.doThrowExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.throwsExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$TestWithOneThrowingTestMethod.alwaysThrows")); + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"), + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithoutCause"), + at("org.junit.tests.SampleJUnit4Tests$TestWithOneThrowingTestMethod.alwaysThrows")); assertNotEquals(failure.getTrace(), failure.getTrimmedTrace()); } @@ -73,14 +66,14 @@ public void getTrimmedStackForJUnit4TestFailingInTestMethodWithCause() { assertHasTrimmedTrace(failure, message("java.lang.RuntimeException: outer"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.doThrowExceptionWithCause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.throwsExceptionWithCause"), - at("org.junit.internal.StackTracesTest$TestWithOneThrowingTestMethodWithCause.alwaysThrows"), + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithCause"), + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithCause"), + at("org.junit.tests.SampleJUnit4Tests$TestWithOneThrowingTestMethodWithCause.alwaysThrows"), framesTrimmed(), message("Caused by: java.lang.RuntimeException: cause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.doThrowExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.throwsExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.doThrowExceptionWithCause"), + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"), + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithoutCause"), + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithCause"), framesInCommon()); assertNotEquals(failure.getTrace(), failure.getTrimmedTrace()); } @@ -94,39 +87,39 @@ public void getTrimmedStackForJUnit4TestFailingInBeforeMethod() { assertHasTrimmedTrace(failure, message("java.lang.RuntimeException: cause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.doThrowExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.throwsExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$TestWithThrowingBeforeMethod.alwaysThrows")); + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"), + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithoutCause"), + at("org.junit.tests.SampleJUnit4Tests$TestWithThrowingBeforeMethod.alwaysThrows")); assertNotEquals(failure.getTrace(), failure.getTrimmedTrace()); } @Test public void getTrimmedStackForJUnit3TestFailingInTestMethod() { - Result result = runTest(JUnit3TestWithOneThrowingTestMethod.class); + Result result = runTest(SampleJUnit3Tests.TestWithOneThrowingTestMethod.class); assertEquals("Should run the test", 1, result.getRunCount()); assertEquals("One test should fail", 1, result.getFailureCount()); Failure failure = result.getFailures().get(0); assertHasTrimmedTrace(failure, message("java.lang.RuntimeException: cause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.doThrowExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.throwsExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$JUnit3TestWithOneThrowingTestMethod.testAlwaysThrows")); + at("junit.tests.SampleJUnit3Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"), + at("junit.tests.SampleJUnit3Tests$FakeClassUnderTest.throwsExceptionWithoutCause"), + at("junit.tests.SampleJUnit3Tests$TestWithOneThrowingTestMethod.testAlwaysThrows")); assertNotEquals(failure.getTrace(), failure.getTrimmedTrace()); } @Test public void getTrimmedStackForJUnit3TestFailingInSetupMethod() { - Result result = runTest(JUnit3TestWithThrowingSetUpMethod.class); + Result result = runTest(SampleJUnit3Tests.TestWithThrowingSetUpMethod.class); assertEquals("Should run the test", 1, result.getRunCount()); assertEquals("One test should fail", 1, result.getFailureCount()); Failure failure = result.getFailures().get(0); assertHasTrimmedTrace(failure, message("java.lang.RuntimeException: cause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.doThrowExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.throwsExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$JUnit3TestWithThrowingSetUpMethod.setUp")); + at("junit.tests.SampleJUnit3Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"), + at("junit.tests.SampleJUnit3Tests$FakeClassUnderTest.throwsExceptionWithoutCause"), + at("junit.tests.SampleJUnit3Tests$TestWithThrowingSetUpMethod.setUp")); assertNotEquals(failure.getTrace(), failure.getTrimmedTrace()); } @@ -139,9 +132,9 @@ public void getTrimmedStackForJUnit4TestFailingInTestRule() { assertHasTrimmedTrace(failure, message("java.lang.RuntimeException: cause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.doThrowExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.throwsExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$ThrowingTestRule.apply")); + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"), + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithoutCause"), + at("org.junit.tests.SampleJUnit4Tests$ThrowingTestRule.apply")); assertNotEquals(failure.getTrace(), failure.getTrimmedTrace()); } @@ -154,9 +147,9 @@ public void getTrimmedStackForJUnit4TestFailingInClassRule() { assertHasTrimmedTrace(failure, message("java.lang.RuntimeException: cause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.doThrowExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.throwsExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$ThrowingTestRule.apply")); + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"), + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithoutCause"), + at("org.junit.tests.SampleJUnit4Tests$ThrowingTestRule.apply")); assertNotEquals(failure.getTrace(), failure.getTrimmedTrace()); } @@ -169,9 +162,9 @@ public void getTrimmedStackForJUnit4TestFailingInMethodRule() { assertHasTrimmedTrace(failure, message("java.lang.RuntimeException: cause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.doThrowExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$FakeClassUnderTest.throwsExceptionWithoutCause"), - at("org.junit.internal.StackTracesTest$ThrowingMethodRule.apply")); + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.doThrowExceptionWithoutCause"), + at("org.junit.tests.SampleJUnit4Tests$FakeClassUnderTest.throwsExceptionWithoutCause"), + at("org.junit.tests.SampleJUnit4Tests$ThrowingMethodRule.apply")); assertNotEquals(failure.getTrace(), failure.getTrimmedTrace()); } @@ -185,9 +178,9 @@ public void getTrimmedStackWithSuppressedExceptions() { assertHasTrimmedTrace(failure, message("java.lang.RuntimeException: error"), - at("org.junit.internal.StackTracesTest$TestWithSuppressedException.alwaysThrows"), + at("org.junit.tests.SampleJUnit4Tests$TestWithSuppressedException.alwaysThrows"), message("\tSuppressed: java.lang.RuntimeException: suppressed"), - at("org.junit.internal.StackTracesTest$TestWithSuppressedException.alwaysThrows"), + at("org.junit.tests.SampleJUnit4Tests$TestWithSuppressedException.alwaysThrows"), framesInCommon()); assertNotEquals(failure.getTrace(), failure.getTrimmedTrace()); } @@ -336,141 +329,4 @@ private static void assertHasTrimmedTrace(Failure failure, StringMatcher... matc fail("Missing line in trimmed trace: " + description.toString()); } } - - public static class TestWithOneThrowingTestMethod { - - @Test - public void alwaysThrows() { - new FakeClassUnderTest().throwsExceptionWithoutCause(); - } - } - - public static class JUnit3TestWithOneThrowingTestMethod extends TestCase { - - public void testAlwaysThrows() { - new FakeClassUnderTest().throwsExceptionWithoutCause(); - } - } - - public static class TestWithOneThrowingTestMethodWithCause { - - @Test - public void alwaysThrows() { - new FakeClassUnderTest().throwsExceptionWithCause(); - } - } - - public static class TestWithThrowingBeforeMethod { - - @Before - public void alwaysThrows() { - new FakeClassUnderTest().throwsExceptionWithoutCause(); - } - - @Test - public void alwaysPasses() { - } - } - - public static class JUnit3TestWithThrowingSetUpMethod extends TestCase { - - @Override - protected void setUp() throws Exception { - super.setUp(); - new FakeClassUnderTest().throwsExceptionWithoutCause(); - } - - public void testAlwaysPasses() { - } - } - - public static class ThrowingTestRule implements TestRule { - - public Statement apply( - Statement base, org.junit.runner.Description description) { - new FakeClassUnderTest().throwsExceptionWithoutCause(); - return base; - } - } - - public static class TestWithThrowingTestRule { - - @Rule - public final TestRule rule = new ThrowingTestRule(); - - @Test - public void alwaysPasses() { - } - } - - public static class TestWithThrowingClassRule { - - @ClassRule - public static final TestRule rule = new ThrowingTestRule(); - - @Test - public void alwaysPasses() { - } - } - - public static class ThrowingMethodRule implements MethodRule { - - public Statement apply( - Statement base, FrameworkMethod method, Object target) { - new FakeClassUnderTest().throwsExceptionWithoutCause(); - return base; - } - } - - public static class TestWithThrowingMethodRule { - - @Rule - public final ThrowingMethodRule rule = new ThrowingMethodRule(); - - @Test - public void alwaysPasses() { - } - } - - private static class FakeClassUnderTest { - - public void throwsExceptionWithCause() { - doThrowExceptionWithCause(); - } - - public void throwsExceptionWithoutCause() { - doThrowExceptionWithoutCause(); - } - - private void doThrowExceptionWithCause() { - try { - throwsExceptionWithoutCause(); - } catch (Exception e) { - throw new RuntimeException("outer", e); - } - } - - private void doThrowExceptionWithoutCause() { - throw new RuntimeException("cause"); - } - } - - public static class TestWithSuppressedException { - static final Method addSuppressed = initAddSuppressed(); - - static Method initAddSuppressed() { - try { - return Throwable.class.getMethod("addSuppressed", Throwable.class); - } catch (Throwable e) { - return null; - } - } - - @Test - public void alwaysThrows() throws Exception { - final RuntimeException exception = new RuntimeException("error"); - addSuppressed.invoke(exception, new RuntimeException("suppressed")); - throw exception; - } - } } diff --git a/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java b/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java index 00c3f0b98276..8bf7823f30af 100644 --- a/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java +++ b/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java @@ -4,182 +4,155 @@ import static java.lang.Math.atan; import static java.lang.System.currentTimeMillis; import static java.lang.Thread.currentThread; +import static java.lang.Thread.interrupted; import static java.lang.Thread.sleep; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.internal.runners.statements.FailOnTimeout.builder; +import static org.junit.Assume.assumeFalse; +import static org.junit.Assume.assumeTrue; import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import org.junit.Test; import org.junit.function.ThrowingRunnable; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; import org.junit.runners.model.Statement; import org.junit.runners.model.TestTimedOutException; + /** * @author Asaf Ary, Stefan Birkner */ +@RunWith(Parameterized.class) public class FailOnTimeoutTest { - private static final long TIMEOUT = 100; - private static final long DURATION_THAT_EXCEEDS_TIMEOUT = 60 * 60 * 1000; //1 hour - private final TestStatement statement = new TestStatement(); + @Parameters(name = "lookingForStuckThread = {0}") + public static Iterable getParameters() { + return Arrays.asList(Boolean.TRUE, Boolean.FALSE); + } - private final FailOnTimeout failOnTimeout = builder().withTimeout(TIMEOUT, MILLISECONDS).build(statement); + @Parameter + public boolean lookingForStuckThread; @Test - public void throwsTestTimedOutException() { - assertThrows( - TestTimedOutException.class, - evaluateWithWaitDuration(DURATION_THAT_EXCEEDS_TIMEOUT)); + public void noExceptionIsThrownWhenWrappedStatementFinishesBeforeTimeoutWithoutThrowingException() + throws Throwable { + FailOnTimeout failOnTimeout = failAfter50Ms(new FastStatement()); + + failOnTimeout.evaluate(); + + // test is successful when no exception is thrown } @Test - public void throwExceptionWithNiceMessageOnTimeout() { - TestTimedOutException e = assertThrows( + public void throwsTestTimedOutExceptionWithMeaningfulMessage() { + Exception e = assertThrows( TestTimedOutException.class, - evaluateWithWaitDuration(DURATION_THAT_EXCEEDS_TIMEOUT)); - assertEquals("test timed out after 100 milliseconds", e.getMessage()); + run(failAfter50Ms(new RunForASecond()))); + assertEquals("test timed out after 50 milliseconds", e.getMessage()); } @Test public void sendUpExceptionThrownByStatement() { - RuntimeException exception = new RuntimeException(); - RuntimeException e = assertThrows( - RuntimeException.class, - evaluateWithException(exception)); + Exception exception = new RuntimeException(); + Exception e = assertThrows( + Exception.class, + run(failAfter50Ms(new Fail(exception)))); assertSame(exception, e); } @Test public void throwExceptionIfTheSecondCallToEvaluateNeedsTooMuchTime() throws Throwable { - evaluateWithWaitDuration(0).run(); + DelegatingStatement statement = new DelegatingStatement(); + FailOnTimeout failOnTimeout = failAfter50Ms(statement); + + statement.delegate = new FastStatement(); + failOnTimeout.evaluate(); + + statement.delegate = new RunForASecond(); assertThrows( TestTimedOutException.class, - evaluateWithWaitDuration(DURATION_THAT_EXCEEDS_TIMEOUT)); + run(failOnTimeout)); } @Test public void throwTimeoutExceptionOnSecondCallAlthoughFirstCallThrowsException() { - try { - evaluateWithException(new RuntimeException()).run(); - } catch (Throwable expected) { - } + DelegatingStatement statement = new DelegatingStatement(); + FailOnTimeout failOnTimeout = failAfter50Ms(statement); - TestTimedOutException e = assertThrows( + statement.delegate = new Fail(new AssertionError("first execution failed")); + assertThrows( + AssertionError.class, + run(failOnTimeout) + ); + + statement.delegate = new RunForASecond(); + assertThrows( TestTimedOutException.class, - evaluateWithWaitDuration(DURATION_THAT_EXCEEDS_TIMEOUT)); - assertEquals("test timed out after 100 milliseconds", e.getMessage()); + run(failOnTimeout)); } @Test public void throwsExceptionWithTimeoutValueAndTimeUnitSet() { TestTimedOutException e = assertThrows( TestTimedOutException.class, - evaluateWithWaitDuration(DURATION_THAT_EXCEEDS_TIMEOUT)); - assertEquals(TIMEOUT, e.getTimeout()); - assertEquals(TimeUnit.MILLISECONDS, e.getTimeUnit()); - } - - private ThrowingRunnable evaluateWithException(final Exception exception) { - return new ThrowingRunnable() { - public void run() throws Throwable { - statement.nextException = exception; - statement.waitDuration = 0; - failOnTimeout.evaluate(); - } - }; - } - - private ThrowingRunnable evaluateWithWaitDuration(final long waitDuration) { - return new ThrowingRunnable() { - public void run() throws Throwable { - statement.nextException = null; - statement.waitDuration = waitDuration; - failOnTimeout.evaluate(); - } - }; + run(failAfter50Ms(new RunForASecond()))); + assertEquals(50, e.getTimeout()); + assertEquals(MILLISECONDS, e.getTimeUnit()); } - private static final class TestStatement extends Statement { - long waitDuration; - - Exception nextException; + @Test + public void statementThatCanBeInterruptedIsStoppedAfterTimeout() throws Throwable { + // RunForASecond can be interrupted because it checks the Thread's + // interrupted flag. + RunForASecond runForASecond = new RunForASecond(); + assertThrows( + TestTimedOutException.class, + run(failAfter50Ms(runForASecond))); - @Override - public void evaluate() throws Throwable { - sleep(waitDuration); - if (nextException != null) { - throw nextException; - } - } + // Thread is explicitly stopped if it finishes faster than its + // pre-defined execution time of one second. + boolean stopped = runForASecond.finished.await(50, MILLISECONDS); + assertTrue("Thread has not been stopped.", stopped); } @Test - public void stopEndlessStatement() throws Throwable { - InfiniteLoopStatement infiniteLoop = new InfiniteLoopStatement(); - FailOnTimeout infiniteLoopTimeout = builder().withTimeout(TIMEOUT, MILLISECONDS).build(infiniteLoop); - try { - infiniteLoopTimeout.evaluate(); - } catch (Exception timeoutException) { - sleep(20); // time to interrupt the thread - int firstCount = InfiniteLoopStatement.COUNT; - sleep(20); // time to increment the count - assertTrue("Thread has not been stopped.", - firstCount == InfiniteLoopStatement.COUNT); - } - } - - private static final class InfiniteLoopStatement extends Statement { - private static int COUNT = 0; + public void stackTraceContainsRealCauseOfTimeout() { + TestTimedOutException timedOutException = assertThrows( + TestTimedOutException.class, + run(failAfter50Ms(new StuckStatement()))); - @Override - public void evaluate() throws Throwable { - while (true) { - sleep(10); // sleep in order to enable interrupting thread - ++COUNT; + StackTraceElement[] stackTrace = timedOutException.getStackTrace(); + boolean stackTraceContainsTheRealCauseOfTheTimeout = false; + boolean stackTraceContainsOtherThanTheRealCauseOfTheTimeout = false; + for (StackTraceElement element : stackTrace) { + String methodName = element.getMethodName(); + if ("theRealCauseOfTheTimeout".equals(methodName)) { + stackTraceContainsTheRealCauseOfTheTimeout = true; } - } - } - - @Test - public void stackTraceContainsRealCauseOfTimeout() throws Throwable { - StuckStatement stuck = new StuckStatement(); - FailOnTimeout stuckTimeout = builder().withTimeout(TIMEOUT, MILLISECONDS).build(stuck); - try { - stuckTimeout.evaluate(); - // We must not get here, we expect a timeout exception - fail("Expected timeout exception"); - } catch (Exception timeoutException) { - StackTraceElement[] stackTrace = timeoutException.getStackTrace(); - boolean stackTraceContainsTheRealCauseOfTheTimeout = false; - boolean stackTraceContainsOtherThanTheRealCauseOfTheTimeout = false; - for (StackTraceElement element : stackTrace) { - String methodName = element.getMethodName(); - if ("theRealCauseOfTheTimeout".equals(methodName)) { - stackTraceContainsTheRealCauseOfTheTimeout = true; - } - if ("notTheRealCauseOfTheTimeout".equals(methodName)) { - stackTraceContainsOtherThanTheRealCauseOfTheTimeout = true; - } + if ("notTheRealCauseOfTheTimeout".equals(methodName)) { + stackTraceContainsOtherThanTheRealCauseOfTheTimeout = true; } - assertTrue( - "Stack trace does not contain the real cause of the timeout", - stackTraceContainsTheRealCauseOfTheTimeout); - assertFalse( - "Stack trace contains other than the real cause of the timeout, which can be very misleading", - stackTraceContainsOtherThanTheRealCauseOfTheTimeout); } + assertTrue( + "Stack trace does not contain the real cause of the timeout", + stackTraceContainsTheRealCauseOfTheTimeout); + assertFalse( + "Stack trace contains other than the real cause of the timeout, which can be very misleading", + stackTraceContainsOtherThanTheRealCauseOfTheTimeout); } private static final class StuckStatement extends Statement { @@ -209,21 +182,90 @@ private void notTheRealCauseOfTheTimeout() { } @Test - public void threadGroupNotLeaked() throws Throwable { - Collection groupsBeforeSet = subGroupsOfCurrentThread(); - - evaluateWithWaitDuration(0); - - for (ThreadGroup group: subGroupsOfCurrentThread()) { - if (!groupsBeforeSet.contains(group) && "FailOnTimeoutGroup".equals(group.getName())) { - fail("A 'FailOnTimeoutGroup' thread group remains referenced after the test execution."); + public void lookingForStuckThread_threadGroupNotLeaked() throws Throwable { + assumeTrue(lookingForStuckThread); + final AtomicReference innerThreadGroup = new AtomicReference(); + final AtomicReference innerThread = new AtomicReference(); + final ThreadGroup outerThreadGroup = currentThread().getThreadGroup(); + FailOnTimeout failOnTimeout = failAfter50Ms(new Statement() { + @Override + public void evaluate() { + innerThread.set(currentThread()); + ThreadGroup group = currentThread().getThreadGroup(); + assertNotSame("inner thread should use a different thread group", + outerThreadGroup, group); + innerThreadGroup.set(group); + assertTrue("the 'FailOnTimeoutGroup' thread group should be a daemon thread group", + group.isDaemon()); + } + }); + + failOnTimeout.evaluate(); + + assertNotNull("the Statement was never run", innerThread.get()); + innerThread.get().join(); + assertTrue("the 'FailOnTimeoutGroup' thread group should be destroyed after running the test", + innerThreadGroup.get().isDestroyed()); + } + + @Test + public void notLookingForStuckThread_usesSameThreadGroup() throws Throwable { + assumeFalse(lookingForStuckThread); + final AtomicBoolean statementWasExecuted = new AtomicBoolean(); + final ThreadGroup outerThreadGroup = currentThread().getThreadGroup(); + FailOnTimeout failOnTimeout = failAfter50Ms(new Statement() { + @Override + public void evaluate() { + statementWasExecuted.set(true); + ThreadGroup group = currentThread().getThreadGroup(); + assertSame("inner thread should use the same thread group", outerThreadGroup, group); + } + }); + + failOnTimeout.evaluate(); + + assertTrue("the Statement was never run", statementWasExecuted.get()); + } + + private FailOnTimeout failAfter50Ms(Statement statement) { + return FailOnTimeout.builder() + .withTimeout(50, MILLISECONDS) + .withLookingForStuckThread(lookingForStuckThread) + .build(statement); + } + + private ThrowingRunnable run(final FailOnTimeout failOnTimeout) { + return new ThrowingRunnable() { + public void run() throws Throwable { + failOnTimeout.evaluate(); } + }; + } + + private static class DelegatingStatement extends Statement { + volatile Statement delegate; + + @Override + public void evaluate() throws Throwable { + delegate.evaluate(); + } + } + + private static class FastStatement extends Statement { + @Override + public void evaluate() throws Throwable { } } - - private Collection subGroupsOfCurrentThread() { - ThreadGroup[] subGroups = new ThreadGroup[256]; - int numGroups = currentThread().getThreadGroup().enumerate(subGroups); - return Arrays.asList(subGroups).subList(0, numGroups); + + private static final class RunForASecond extends Statement { + final CountDownLatch finished = new CountDownLatch(1); + + @Override + public void evaluate() throws Throwable { + long timeout = currentTimeMillis() + 1000L; + while (!interrupted() && currentTimeMillis() < timeout) { + } + finished.countDown(); + } } } diff --git a/src/test/java/org/junit/rules/DisableOnDebugTest.java b/src/test/java/org/junit/rules/DisableOnDebugTest.java index d61db9e528db..8bf6b9deeee4 100644 --- a/src/test/java/org/junit/rules/DisableOnDebugTest.java +++ b/src/test/java/org/junit/rules/DisableOnDebugTest.java @@ -48,7 +48,7 @@ public void evaluate() throws Throwable { } - public static abstract class AbstractDisableOnDebugTest { + public abstract static class AbstractDisableOnDebugTest { @Rule public TestRule failOnExecution; diff --git a/src/test/java/org/junit/rules/MethodRulesTest.java b/src/test/java/org/junit/rules/MethodRulesTest.java index 93eb68468d28..6c59f7edab3c 100644 --- a/src/test/java/org/junit/rules/MethodRulesTest.java +++ b/src/test/java/org/junit/rules/MethodRulesTest.java @@ -44,7 +44,7 @@ public void nothing() { } } - static abstract class NonPublicExampleTest { + abstract static class NonPublicExampleTest { @Rule public MethodRule example = new TestMethodRule(); diff --git a/src/test/java/org/junit/rules/RuleChainTest.java b/src/test/java/org/junit/rules/RuleChainTest.java index 914b6a9088c5..54daf8dc59a7 100644 --- a/src/test/java/org/junit/rules/RuleChainTest.java +++ b/src/test/java/org/junit/rules/RuleChainTest.java @@ -10,8 +10,6 @@ import static org.junit.experimental.results.PrintableResult.testResult; import static org.junit.rules.RuleChain.outerRule; -import java.io.PrintWriter; -import java.io.StringWriter; import java.util.ArrayList; import java.util.List; diff --git a/src/test/java/org/junit/rules/StopwatchTest.java b/src/test/java/org/junit/rules/StopwatchTest.java index 69fbcb03ec68..5941eb9b1bb1 100644 --- a/src/test/java/org/junit/rules/StopwatchTest.java +++ b/src/test/java/org/junit/rules/StopwatchTest.java @@ -49,7 +49,7 @@ private static class Record { } } - public static abstract class AbstractStopwatchTest { + public abstract static class AbstractStopwatchTest { /** * Fake implementation of {@link Stopwatch.Clock} that increments the time diff --git a/src/test/java/org/junit/rules/TestRuleTest.java b/src/test/java/org/junit/rules/TestRuleTest.java index 23d4bfbc8ff4..cc6db7d9eb34 100644 --- a/src/test/java/org/junit/rules/TestRuleTest.java +++ b/src/test/java/org/junit/rules/TestRuleTest.java @@ -1,11 +1,9 @@ package org.junit.rules; -import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import static org.junit.experimental.results.PrintableResult.testResult; import static org.junit.experimental.results.ResultMatchers.hasSingleFailureContaining; import static org.junit.experimental.results.ResultMatchers.isSuccessful; @@ -14,11 +12,9 @@ import java.util.List; import org.junit.After; -import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.junit.internal.AssumptionViolatedException; import org.junit.runner.Description; import org.junit.runner.JUnitCore; import org.junit.runner.Result; diff --git a/src/test/java/org/junit/runners/AllRunnersTests.java b/src/test/java/org/junit/runners/AllRunnersTests.java index a51072c054a6..5464fb27f9ac 100644 --- a/src/test/java/org/junit/runners/AllRunnersTests.java +++ b/src/test/java/org/junit/runners/AllRunnersTests.java @@ -1,7 +1,6 @@ package org.junit.runners; import org.junit.runner.RunWith; -import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; import org.junit.runners.model.AllModelTests; import org.junit.runners.parameterized.AllParameterizedTests; diff --git a/src/test/java/org/junit/runners/RuleContainerTest.java b/src/test/java/org/junit/runners/RuleContainerTest.java index 714d0dfdf660..8c6649c5022f 100644 --- a/src/test/java/org/junit/runners/RuleContainerTest.java +++ b/src/test/java/org/junit/runners/RuleContainerTest.java @@ -2,8 +2,6 @@ import static org.junit.Assert.assertEquals; -import java.util.Arrays; - import org.junit.Test; import org.junit.rules.MethodRule; import org.junit.rules.TestRule; diff --git a/src/test/java/org/junit/tests/SampleJUnit4Tests.java b/src/test/java/org/junit/tests/SampleJUnit4Tests.java index c42026f2f79f..739f17bc679a 100644 --- a/src/test/java/org/junit/tests/SampleJUnit4Tests.java +++ b/src/test/java/org/junit/tests/SampleJUnit4Tests.java @@ -1,6 +1,15 @@ package org.junit.tests; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.MethodRule; +import org.junit.rules.TestRule; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.Statement; + +import java.lang.reflect.Method; /** * Container for sample JUnit4-style tests used in integration tests. @@ -23,6 +32,85 @@ public void alwaysThrows() { } } + public static class TestWithThrowingBeforeMethod { + + @Before + public void alwaysThrows() { + new FakeClassUnderTest().throwsExceptionWithoutCause(); + } + + @Test + public void alwaysPasses() { + } + } + + public static class ThrowingTestRule implements TestRule { + + public Statement apply( + Statement base, org.junit.runner.Description description) { + new FakeClassUnderTest().throwsExceptionWithoutCause(); + return base; + } + } + + public static class TestWithThrowingTestRule { + + @Rule + public final TestRule rule = new ThrowingTestRule(); + + @Test + public void alwaysPasses() { + } + } + + public static class TestWithThrowingClassRule { + + @ClassRule + public static final TestRule rule = new ThrowingTestRule(); + + @Test + public void alwaysPasses() { + } + } + + public static class ThrowingMethodRule implements MethodRule { + + public Statement apply( + Statement base, FrameworkMethod method, Object target) { + new FakeClassUnderTest().throwsExceptionWithoutCause(); + return base; + } + } + + public static class TestWithThrowingMethodRule { + + @Rule + public final ThrowingMethodRule rule = new ThrowingMethodRule(); + + @Test + public void alwaysPasses() { + } + } + + public static class TestWithSuppressedException { + public static final Method addSuppressed = initAddSuppressed(); + + static Method initAddSuppressed() { + try { + return Throwable.class.getMethod("addSuppressed", Throwable.class); + } catch (Throwable e) { + return null; + } + } + + @Test + public void alwaysThrows() throws Exception { + final RuntimeException exception = new RuntimeException("error"); + addSuppressed.invoke(exception, new RuntimeException("suppressed")); + throw exception; + } + } + private static class FakeClassUnderTest { public void throwsExceptionWithCause() { diff --git a/src/test/java/org/junit/tests/experimental/AssumptionTest.java b/src/test/java/org/junit/tests/experimental/AssumptionTest.java index 45e94b026edc..e011619cf679 100644 --- a/src/test/java/org/junit/tests/experimental/AssumptionTest.java +++ b/src/test/java/org/junit/tests/experimental/AssumptionTest.java @@ -237,8 +237,8 @@ public void assumeWithExpectedExceptionShouldThrowAssumptionViolatedException() assertThat(result.getAssumptionFailureCount(), is(1)); } - final static String message = "Some random message string."; - final static Throwable e = new Throwable(); + static final String message = "Some random message string."; + static final Throwable e = new Throwable(); /** * @see AssumptionTest#assumptionsWithMessage() diff --git a/src/test/java/org/junit/tests/experimental/theories/AssumingInTheoriesTest.java b/src/test/java/org/junit/tests/experimental/theories/AssumingInTheoriesTest.java index 758e6fbe2b2d..099b50fe14c4 100644 --- a/src/test/java/org/junit/tests/experimental/theories/AssumingInTheoriesTest.java +++ b/src/test/java/org/junit/tests/experimental/theories/AssumingInTheoriesTest.java @@ -31,7 +31,7 @@ public void theoryMeansOnlyAssumeShouldFail() throws InitializationError { public static class TheoryWithNoUnassumedParameters { @DataPoint - public final static boolean FALSE = false; + public static final boolean FALSE = false; @Theory public void theoryWithNoUnassumedParameters(boolean value) { diff --git a/src/test/java/org/junit/tests/experimental/theories/runner/SuccessfulWithDataPointFields.java b/src/test/java/org/junit/tests/experimental/theories/runner/SuccessfulWithDataPointFields.java index 2b5d587be21c..80cfd897642d 100644 --- a/src/test/java/org/junit/tests/experimental/theories/runner/SuccessfulWithDataPointFields.java +++ b/src/test/java/org/junit/tests/experimental/theories/runner/SuccessfulWithDataPointFields.java @@ -195,7 +195,7 @@ public static void calledTwice() { } @RunWith(Theories.class) - static public class StaticPublicNonDataPoints { + public static class StaticPublicNonDataPoints { // DataPoint which passes the test @DataPoint public static int ZERO = 0; diff --git a/src/test/java/org/junit/tests/junit3compatibility/AllTestsTest.java b/src/test/java/org/junit/tests/junit3compatibility/AllTestsTest.java index 99468128907a..3f4a7f40435c 100644 --- a/src/test/java/org/junit/tests/junit3compatibility/AllTestsTest.java +++ b/src/test/java/org/junit/tests/junit3compatibility/AllTestsTest.java @@ -24,7 +24,7 @@ public void testSomething() { @RunWith(AllTests.class) public static class All { - static public junit.framework.Test suite() { + public static junit.framework.Test suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(OneTest.class); return suite; @@ -60,7 +60,7 @@ public void testSomething() { @RunWith(AllTests.class) public static class AllJUnit4 { - static public junit.framework.Test suite() { + public static junit.framework.Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new JUnit4TestAdapter(JUnit4Test.class)); return suite; diff --git a/src/test/java/org/junit/tests/junit3compatibility/ForwardCompatibilityTest.java b/src/test/java/org/junit/tests/junit3compatibility/ForwardCompatibilityTest.java index 34673e9fbd1b..79539d1497b4 100644 --- a/src/test/java/org/junit/tests/junit3compatibility/ForwardCompatibilityTest.java +++ b/src/test/java/org/junit/tests/junit3compatibility/ForwardCompatibilityTest.java @@ -19,7 +19,7 @@ public class ForwardCompatibilityTest extends TestCase { static String fLog; - static public class NewTest { + public static class NewTest { @Before public void before() { fLog += "before "; diff --git a/src/test/java/org/junit/tests/junit3compatibility/JUnit38ClassRunnerTest.java b/src/test/java/org/junit/tests/junit3compatibility/JUnit38ClassRunnerTest.java index b7a1c515e3f2..429bde6910e7 100644 --- a/src/test/java/org/junit/tests/junit3compatibility/JUnit38ClassRunnerTest.java +++ b/src/test/java/org/junit/tests/junit3compatibility/JUnit38ClassRunnerTest.java @@ -53,7 +53,7 @@ public void canUnadaptAnAdapter() { static int count; - static public class OneTest extends TestCase { + public static class OneTest extends TestCase { public void testOne() { } } diff --git a/src/test/java/org/junit/tests/junit3compatibility/OldTests.java b/src/test/java/org/junit/tests/junit3compatibility/OldTests.java index e8b3ab8eca32..bee32f50b84d 100644 --- a/src/test/java/org/junit/tests/junit3compatibility/OldTests.java +++ b/src/test/java/org/junit/tests/junit3compatibility/OldTests.java @@ -6,7 +6,7 @@ @RunWith(AllTests.class) public class OldTests { - static public Test suite() { + public static Test suite() { return junit.tests.AllTests.suite(); } } diff --git a/src/test/java/org/junit/tests/junit3compatibility/SuiteMethodTest.java b/src/test/java/org/junit/tests/junit3compatibility/SuiteMethodTest.java index edc9eac2b0c4..55c1cd119afe 100644 --- a/src/test/java/org/junit/tests/junit3compatibility/SuiteMethodTest.java +++ b/src/test/java/org/junit/tests/junit3compatibility/SuiteMethodTest.java @@ -18,7 +18,7 @@ public class SuiteMethodTest { public static boolean wasRun; - static public class OldTest extends TestCase { + public static class OldTest extends TestCase { public OldTest(String name) { super(name); } @@ -41,7 +41,7 @@ public void makeSureSuiteIsCalled() { assertTrue(wasRun); } - static public class NewTest { + public static class NewTest { @Test public void sample() { wasRun = true; @@ -81,7 +81,7 @@ public void descriptionAndRunNotificationsAreConsistent() { assertEquals(0, description.getChildren().size()); } - static public class NewTestSuiteFails { + public static class NewTestSuiteFails { @Test public void sample() { wasRun = true; @@ -101,7 +101,7 @@ public void suiteIsUsedWithJUnit4Classes() { assertFalse(wasRun); } - static public class NewTestSuiteNotUsed { + public static class NewTestSuiteNotUsed { private static boolean wasIgnoredRun; @Test diff --git a/src/test/java/org/junit/tests/listening/ListenerTest.java b/src/test/java/org/junit/tests/listening/ListenerTest.java index c76581a0d5c6..b3003394797b 100644 --- a/src/test/java/org/junit/tests/listening/ListenerTest.java +++ b/src/test/java/org/junit/tests/listening/ListenerTest.java @@ -8,7 +8,7 @@ import org.junit.runner.notification.RunListener; public class ListenerTest { - static private String log; + private static String log; public static class OneTest { @Test diff --git a/src/test/java/org/junit/tests/manipulation/SingleMethodTest.java b/src/test/java/org/junit/tests/manipulation/SingleMethodTest.java index cf62c98e4d79..a15340708fab 100644 --- a/src/test/java/org/junit/tests/manipulation/SingleMethodTest.java +++ b/src/test/java/org/junit/tests/manipulation/SingleMethodTest.java @@ -27,7 +27,7 @@ public class SingleMethodTest { public static int count; - static public class OneTimeSetup { + public static class OneTimeSetup { @BeforeClass public static void once() { count++; @@ -53,7 +53,7 @@ public void oneTimeSetup() throws Exception { } @RunWith(Parameterized.class) - static public class ParameterizedOneTimeSetup { + public static class ParameterizedOneTimeSetup { @Parameters public static List params() { return Arrays.asList(new Object[]{1}, new Object[]{2}); @@ -78,7 +78,7 @@ public void parameterizedFilterToSingleMethod() throws Exception { } @RunWith(Parameterized.class) - static public class ParameterizedOneTimeBeforeClass { + public static class ParameterizedOneTimeBeforeClass { @Parameters public static List params() { return Arrays.asList(new Object[]{1}, new Object[]{2}); diff --git a/src/test/java/org/junit/tests/running/classes/EnclosedTest.java b/src/test/java/org/junit/tests/running/classes/EnclosedTest.java index 9f71deadaf18..9a8165a4c73e 100644 --- a/src/test/java/org/junit/tests/running/classes/EnclosedTest.java +++ b/src/test/java/org/junit/tests/running/classes/EnclosedTest.java @@ -30,7 +30,7 @@ public void b() {} @Test public void c() {} } - abstract public static class C { + public abstract static class C { @Test public void a() {} } } diff --git a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java index 14fb825df5bc..6288dbc4af43 100644 --- a/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java +++ b/src/test/java/org/junit/tests/running/classes/ParameterizedTestTest.java @@ -168,7 +168,7 @@ public void providesDataByAnnotatedFields() { } @RunWith(Parameterized.class) - static public class BadIndexForAnnotatedFieldTest { + public static class BadIndexForAnnotatedFieldTest { @Parameters public static Collection data() { return Arrays.asList(new Object[][]{{0}}); @@ -200,7 +200,7 @@ public void failureOnInitialization() { } @RunWith(Parameterized.class) - static public class BadNumberOfAnnotatedFieldTest { + public static class BadNumberOfAnnotatedFieldTest { @Parameters public static Collection data() { return Arrays.asList(new Object[][]{{0, 0}}); @@ -232,7 +232,7 @@ public void numberOfFieldsAndParametersShouldMatch() { private static String fLog; @RunWith(Parameterized.class) - static public class BeforeAndAfter { + public static class BeforeAndAfter { @BeforeClass public static void before() { fLog += "before "; @@ -487,7 +487,7 @@ public void beforeParamAndAfterParamValidationNumberOfParameters() { } @RunWith(Parameterized.class) - static public class EmptyTest { + public static class EmptyTest { @BeforeClass public static void before() { fLog += "before "; @@ -506,7 +506,7 @@ public void validateClassCatchesNoParameters() { } @RunWith(Parameterized.class) - static public class IncorrectTest { + public static class IncorrectTest { @Test public int test() { return 0; @@ -525,7 +525,7 @@ public void failuresAddedForBadTestMethod() throws Exception { } @RunWith(Parameterized.class) - static public class ProtectedParametersTest { + public static class ProtectedParametersTest { @Parameters protected static Collection data() { return Collections.emptyList(); @@ -544,7 +544,7 @@ public void meaningfulFailureWhenParametersNotPublic() { } @RunWith(Parameterized.class) - static public class ParametersNotIterable { + public static class ParametersNotIterable { @Parameters public static String data() { return "foo"; @@ -563,7 +563,7 @@ public void meaningfulFailureWhenParametersAreNotAnIterable() { } @RunWith(Parameterized.class) - static public class PrivateConstructor { + public static class PrivateConstructor { private PrivateConstructor(int x) { } @@ -613,7 +613,7 @@ public void runsEveryTestOfArray() { } @RunWith(Parameterized.class) - static public class SingleArgumentTestWithArray { + public static class SingleArgumentTestWithArray { @Parameters public static Object[] data() { return new Object[] { "first test", "second test" }; @@ -634,7 +634,7 @@ public void runsForEverySingleArgumentOfArray() { } @RunWith(Parameterized.class) - static public class SingleArgumentTestWithIterable { + public static class SingleArgumentTestWithIterable { private static final AtomicBoolean dataCalled = new AtomicBoolean(false); @Parameters @@ -677,7 +677,7 @@ public void runsForEverySingleArgumentOfIterable() { } @RunWith(Parameterized.class) - static public class SingleArgumentTestWithCollection { + public static class SingleArgumentTestWithCollection { @Parameters public static Iterable data() { return Collections.unmodifiableCollection(asList("first test", "second test")); @@ -699,7 +699,7 @@ public void runsForEverySingleArgumentOfCollection() { } - static public class ExceptionThrowingRunnerFactory implements + public static class ExceptionThrowingRunnerFactory implements ParametersRunnerFactory { public Runner createRunnerForTestWithParameters(TestWithParameters test) throws InitializationError { @@ -710,7 +710,7 @@ public Runner createRunnerForTestWithParameters(TestWithParameters test) @RunWith(Parameterized.class) @UseParametersRunnerFactory(ExceptionThrowingRunnerFactory.class) - static public class TestWithUseParametersRunnerFactoryAnnotation { + public static class TestWithUseParametersRunnerFactoryAnnotation { @Parameters public static Iterable data() { return asList("single test"); @@ -739,7 +739,7 @@ private void assertTestCreatesSingleFailureWithMessage(Class test, String mes @RunWith(Parameterized.class) @UseParametersRunnerFactory(ExceptionThrowingRunnerFactory.class) - public static abstract class UseParameterizedFactoryAbstractTest { + public abstract static class UseParameterizedFactoryAbstractTest { @Parameters public static Iterable data() { return asList("single test"); diff --git a/src/test/java/org/junit/tests/running/classes/parent/ParentRunnerClassLoaderTest.java b/src/test/java/org/junit/tests/running/classes/parent/ParentRunnerClassLoaderTest.java index bb6ba14e4c44..16443368d7dc 100644 --- a/src/test/java/org/junit/tests/running/classes/parent/ParentRunnerClassLoaderTest.java +++ b/src/test/java/org/junit/tests/running/classes/parent/ParentRunnerClassLoaderTest.java @@ -1,5 +1,10 @@ package org.junit.tests.running.classes.parent; +import static org.junit.Assert.assertEquals; + +import java.lang.reflect.Field; +import java.net.URL; +import java.net.URLClassLoader; import org.junit.Test; import org.junit.runner.Description; @@ -9,13 +14,6 @@ import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; -import java.lang.reflect.Field; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.List; - -import static org.junit.Assert.assertEquals; - public class ParentRunnerClassLoaderTest { @Test public void testClassRuleAccessToClassInAnotherClassLoader() throws Exception { diff --git a/src/test/java/org/junit/tests/running/core/CommandLineTest.java b/src/test/java/org/junit/tests/running/core/CommandLineTest.java index f72b3e916075..37f065902884 100644 --- a/src/test/java/org/junit/tests/running/core/CommandLineTest.java +++ b/src/test/java/org/junit/tests/running/core/CommandLineTest.java @@ -28,7 +28,7 @@ public void after() { System.setOut(oldOut); } - static public class Example { + public static class Example { @Test public void test() { testWasRun = true; @@ -55,7 +55,7 @@ public void runAClass() { private static int fCount; - static public class Count { + public static class Count { @Test public void increment() { fCount++; diff --git a/src/test/java/org/junit/tests/running/core/JUnitCoreReturnsCorrectExitCodeTest.java b/src/test/java/org/junit/tests/running/core/JUnitCoreReturnsCorrectExitCodeTest.java index 21e13ddb7c6f..64af301ae93e 100644 --- a/src/test/java/org/junit/tests/running/core/JUnitCoreReturnsCorrectExitCodeTest.java +++ b/src/test/java/org/junit/tests/running/core/JUnitCoreReturnsCorrectExitCodeTest.java @@ -8,7 +8,7 @@ public class JUnitCoreReturnsCorrectExitCodeTest { - static public class Fail { + public static class Fail { @Test public void kaboom() { fail(); @@ -25,7 +25,7 @@ public void missingClassCausesExitCodeOf1() throws Exception { runClass("Foo", 1); } - static public class Succeed { + public static class Succeed { @Test public void peacefulSilence() { } diff --git a/src/test/java/org/junit/tests/running/methods/AnnotationTest.java b/src/test/java/org/junit/tests/running/methods/AnnotationTest.java index 593cdb1c27a6..002517891012 100644 --- a/src/test/java/org/junit/tests/running/methods/AnnotationTest.java +++ b/src/test/java/org/junit/tests/running/methods/AnnotationTest.java @@ -34,7 +34,7 @@ public void setUp() { run = false; } - static public class SimpleTest { + public static class SimpleTest { @Test public void success() { run = true; @@ -48,7 +48,7 @@ public void testAnnotatedMethod() throws Exception { } @RunWith(JUnit4.class) - static public class SimpleTestWithFutureProofExplicitRunner { + public static class SimpleTestWithFutureProofExplicitRunner { @Test public void success() { run = true; @@ -61,7 +61,7 @@ public void testAnnotatedMethodWithFutureProofExplicitRunner() throws Exception assertTrue(run); } - static public class SetupTest { + public static class SetupTest { @Before public void before() { run = true; @@ -78,7 +78,7 @@ public void testSetup() throws Exception { assertTrue(run); } - static public class TeardownTest { + public static class TeardownTest { @After public void after() { run = true; @@ -95,7 +95,7 @@ public void testTeardown() throws Exception { assertTrue(run); } - static public class FailureTest { + public static class FailureTest { @Test public void error() throws Exception { org.junit.Assert.fail(); @@ -110,7 +110,7 @@ public void testRunFailure() throws Exception { assertEquals(AssertionError.class, result.getFailures().get(0).getException().getClass()); } - static public class SetupFailureTest { + public static class SetupFailureTest { @Before public void before() { throw new Error(); @@ -131,7 +131,7 @@ public void testSetupFailure() throws Exception { assertFalse(run); } - static public class TeardownFailureTest { + public static class TeardownFailureTest { @After public void after() { throw new Error(); @@ -150,7 +150,7 @@ public void testTeardownFailure() throws Exception { assertEquals(Error.class, runner.getFailures().get(0).getException().getClass()); } - static public class TestAndTeardownFailureTest { + public static class TestAndTeardownFailureTest { @After public void after() { throw new Error("hereAfter"); @@ -170,7 +170,7 @@ public void testTestAndTeardownFailure() throws Exception { assertThat(runner.getFailures().toString(), allOf(containsString("hereAfter"), containsString("inTest"))); } - static public class TeardownAfterFailureTest { + public static class TeardownAfterFailureTest { @After public void after() { run = true; @@ -191,7 +191,7 @@ public void testTeardownAfterFailure() throws Exception { static int count; static Collection tests; - static public class TwoTests { + public static class TwoTests { @Test public void one() { count++; @@ -214,7 +214,7 @@ public void testTwoTests() throws Exception { assertEquals(2, tests.size()); } - static public class OldTest extends TestCase { + public static class OldTest extends TestCase { public void test() { run = true; } @@ -226,7 +226,7 @@ public void testOldTest() throws Exception { assertTrue(run); } - static public class OldSuiteTest extends TestCase { + public static class OldSuiteTest extends TestCase { public void testOne() { run = true; } @@ -239,7 +239,7 @@ public void testOldSuiteTest() throws Exception { assertTrue(run); } - static public class ExceptionTest { + public static class ExceptionTest { @Test(expected = Error.class) public void expectedException() { throw new Error(); @@ -252,7 +252,7 @@ public void testException() throws Exception { assertEquals(0, result.getFailureCount()); } - static public class NoExceptionTest { + public static class NoExceptionTest { @Test(expected = Error.class) public void expectedException() { } @@ -265,7 +265,7 @@ public void testExceptionNotThrown() throws Exception { assertEquals("Expected exception: java.lang.Error", result.getFailures().get(0).getMessage()); } - static public class OneTimeSetup { + public static class OneTimeSetup { @BeforeClass public static void once() { count++; @@ -287,7 +287,7 @@ public void testOneTimeSetup() throws Exception { assertEquals(1, count); } - static public class OneTimeTeardown { + public static class OneTimeTeardown { @AfterClass public static void once() { count++; @@ -345,7 +345,7 @@ public void testOrder() throws Exception { assertEquals("beforeClass before test after afterClass ", log); } - static public class NonStaticOneTimeSetup { + public static class NonStaticOneTimeSetup { @BeforeClass public void once() { } @@ -361,7 +361,7 @@ public void testNonStaticOneTimeSetup() throws Exception { assertEquals(1, result.getFailureCount()); } - static public class ErrorInBeforeClass { + public static class ErrorInBeforeClass { @BeforeClass public static void before() throws Exception { throw new Exception(); @@ -383,7 +383,7 @@ public void testErrorInBeforeClass() throws Exception { assertEquals(ErrorInBeforeClass.class.getName(), description.getDisplayName()); } - static public class ErrorInAfterClass { + public static class ErrorInAfterClass { @Test public void test() { run = true; @@ -405,12 +405,12 @@ public void testErrorInAfterClass() throws Exception { static class SuperInheritance { @BeforeClass - static public void beforeClassSuper() { + public static void beforeClassSuper() { log += "Before class super "; } @AfterClass - static public void afterClassSuper() { + public static void afterClassSuper() { log += "After class super "; } @@ -425,14 +425,14 @@ public void afterSuper() { } } - static public class SubInheritance extends SuperInheritance { + public static class SubInheritance extends SuperInheritance { @BeforeClass - static public void beforeClassSub() { + public static void beforeClassSub() { log += "Before class sub "; } @AfterClass - static public void afterClassSub() { + public static void afterClassSub() { log += "After class sub "; } @@ -459,7 +459,7 @@ public void testOrderingOfInheritance() throws Exception { assertEquals("Before class super Before class sub Before super Before sub Test After sub After super After class sub After class super ", log); } - static public abstract class SuperShadowing { + public abstract static class SuperShadowing { @Rule public TestRule rule() { @@ -487,7 +487,7 @@ public void after() { } } - static public class SubShadowing extends SuperShadowing { + public static class SubShadowing extends SuperShadowing { @Override @Rule @@ -545,7 +545,7 @@ public void testShadowing() throws Exception { log); } - static public abstract class SuperStaticMethodShadowing { + public abstract static class SuperStaticMethodShadowing { @ClassRule public static TestRule rule() { @@ -563,7 +563,7 @@ protected void after() { } } - static public class SubStaticMethodShadowing extends SuperStaticMethodShadowing { + public static class SubStaticMethodShadowing extends SuperStaticMethodShadowing { @ClassRule public static TestRule rule() { @@ -596,7 +596,7 @@ public void testStaticMethodsCanBeTreatedAsShadowed() throws Exception { log); } - static public abstract class SuperFieldShadowing { + public abstract static class SuperFieldShadowing { @Rule public final TestRule rule = new ExternalResource() { @@ -612,7 +612,7 @@ protected void after() { }; } - static public class SubFieldShadowing extends SuperFieldShadowing { + public static class SubFieldShadowing extends SuperFieldShadowing { @Rule public final TestRule rule = new ExternalResource() { @@ -643,7 +643,7 @@ public void testFieldsShadowFieldsFromParent() throws Exception { log); } - static public abstract class SuperStaticFieldShadowing { + public abstract static class SuperStaticFieldShadowing { @ClassRule public static TestRule rule = new ExternalResource() { @@ -659,7 +659,7 @@ protected void after() { }; } - static public class SubStaticFieldShadowing extends SuperStaticFieldShadowing { + public static class SubStaticFieldShadowing extends SuperStaticFieldShadowing { @ClassRule public static TestRule rule = new ExternalResource() { @@ -690,7 +690,7 @@ public void testStaticFieldsCanBeTreatedAsShadowed() throws Exception { log); } - static public class SuperTest { + public static class SuperTest { @Test public void one() { log += "Super"; @@ -702,7 +702,7 @@ public void two() { } } - static public class SubTest extends SuperTest { + public static class SubTest extends SuperTest { @Override @Test public void one() { @@ -720,7 +720,7 @@ public void testTestInheritance() throws Exception { assertFalse(log.contains("Super")); } - static public class RunAllAfters { + public static class RunAllAfters { @Before public void good() { } @@ -753,7 +753,7 @@ public void testRunAllAfters() { assertTrue(log.contains("two")); } - static public class RunAllAftersRegardless { + public static class RunAllAftersRegardless { @Test public void empty() { } @@ -780,7 +780,7 @@ public void testRunAllAftersRegardless() { assertEquals(2, result.getFailureCount()); } - static public class RunAllAfterClasses { + public static class RunAllAfterClasses { @Before public void good() { } @@ -813,19 +813,19 @@ public void testRunAllAfterClasses() { assertTrue(log.contains("two")); } - static public class RunAllAfterClassesRegardless { + public static class RunAllAfterClassesRegardless { @Test public void empty() { } @AfterClass - static public void one() { + public static void one() { log += "one"; throw new Error(); } @AfterClass - static public void two() { + public static void two() { log += "two"; throw new Error(); } diff --git a/src/test/java/org/junit/tests/running/methods/ParameterizedTestMethodTest.java b/src/test/java/org/junit/tests/running/methods/ParameterizedTestMethodTest.java index e2442a5b4513..4e249581af73 100644 --- a/src/test/java/org/junit/tests/running/methods/ParameterizedTestMethodTest.java +++ b/src/test/java/org/junit/tests/running/methods/ParameterizedTestMethodTest.java @@ -136,19 +136,19 @@ public void fineT() { private Class fClass; private int fErrorCount; - static public class SuperWrong { + public static class SuperWrong { @Test void notPublic() { } } - static public class SubWrong extends SuperWrong { + public static class SubWrong extends SuperWrong { @Test public void justFine() { } } - static public class SubShadows extends SuperWrong { + public static class SubShadows extends SuperWrong { @Override @Test public void notPublic() { diff --git a/src/test/resources/org/junit/assumptionViolatedExceptionWithValueAndMatcherCanBeReserialized_v4_13 b/src/test/resources/org/junit/assumptionViolatedExceptionWithValueAndMatcherCanBeReserialized_v4_13 new file mode 100644 index 000000000000..1409545b5ab9 Binary files /dev/null and b/src/test/resources/org/junit/assumptionViolatedExceptionWithValueAndMatcherCanBeReserialized_v4_13 differ diff --git a/src/test/resources/org/junit/assumptionViolatedExceptionWithoutValueAndMatcherCanBeReserialized_v4_13 b/src/test/resources/org/junit/assumptionViolatedExceptionWithoutValueAndMatcherCanBeReserialized_v4_13 new file mode 100644 index 000000000000..199c36d05588 Binary files /dev/null and b/src/test/resources/org/junit/assumptionViolatedExceptionWithoutValueAndMatcherCanBeReserialized_v4_13 differ