From db02762dc7ff784d4b68cbbdf8a86412ce87f11e Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Sun, 11 Oct 2020 17:18:57 +0200 Subject: [PATCH 01/25] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 428715884b4e..ab0d4163018c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ junit junit - 4.13.1 + 4.13.2-SNAPSHOT JUnit JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck. @@ -64,7 +64,7 @@ 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 + HEAD github From c40e88d2407b7925adc404199be5a367aab1b86c Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Sun, 11 Oct 2020 17:32:06 +0200 Subject: [PATCH 02/25] Update Version.java --- src/main/java/junit/runner/Version.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) { From 7852b90cfe1cea1e0cdaa19d490c83f0d8684b50 Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Sun, 11 Oct 2020 17:41:24 +0200 Subject: [PATCH 03/25] Document security fix in release notes --- doc/ReleaseNotes4.13.1.md | 6 ++++++ 1 file changed, 6 insertions(+) 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 From 116c1e7e203d4392c7647bce2b307635896dcd6d Mon Sep 17 00:00:00 2001 From: Olivier Blanvillain Date: Sat, 2 Jan 2021 14:53:45 +0100 Subject: [PATCH 04/25] Fix tests for floating point assertions (#1673) Since `assertEquals(1.0, 2.0, 0.0)` and `fail()` both throw AssertionFailedErrors these tests were not actually testing anything. --- .../framework/DoublePrecisionAssertTest.java | 12 ++++++++---- .../junit/tests/framework/FloatAssertTest.java | 18 +++++++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) 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); } } From 66083734d13aa67e616f3c4b429c019c5992bba0 Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Sat, 2 Jan 2021 15:41:57 +0100 Subject: [PATCH 05/25] Fix build for Java 12 and above --- pom.xml | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index ab0d4163018c..31098bfd0d25 100644 --- a/pom.xml +++ b/pom.xml @@ -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 + + + + + From b4f26d249ae9d25f3ca777908ff430d02487a20a Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Sat, 2 Jan 2021 15:09:55 +0100 Subject: [PATCH 06/25] Add GH Actions workflow --- .github/workflows/main.yml | 48 ++++++++++++++++++++++++++++++++++ .github/workflows/settings.xml | 22 ++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/settings.xml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000000..3ea3f6a0c584 --- /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] + 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/.github/workflows/settings.xml b/.github/workflows/settings.xml new file mode 100644 index 000000000000..332f39daa17b --- /dev/null +++ b/.github/workflows/settings.xml @@ -0,0 +1,22 @@ + + + + central + GCS Maven Central mirror + https://maven-central.storage-download.googleapis.com/maven2/ + google-maven-central + + + + + junit-snapshot-repo + ${env.OSSRH_USERNAME} + ${env.OSSRH_PASSWORD} + + + junit-releases-repo + ${env.OSSRH_USERNAME} + ${env.OSSRH_PASSWORD} + + + From 2bca0a42dcb09f522ceadcb97dfb8534a72d584c Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Sat, 2 Jan 2021 15:51:52 +0100 Subject: [PATCH 07/25] Delete Travis config and badge --- .travis.settings.xml | 22 -------------- .travis.yml | 69 -------------------------------------------- README.md | 2 +- 3 files changed, 1 insertion(+), 92 deletions(-) delete mode 100644 .travis.settings.xml delete mode 100644 .travis.yml diff --git a/.travis.settings.xml b/.travis.settings.xml deleted file mode 100644 index 332f39daa17b..000000000000 --- a/.travis.settings.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - central - GCS Maven Central mirror - https://maven-central.storage-download.googleapis.com/maven2/ - google-maven-central - - - - - junit-snapshot-repo - ${env.OSSRH_USERNAME} - ${env.OSSRH_PASSWORD} - - - junit-releases-repo - ${env.OSSRH_USERNAME} - ${env.OSSRH_PASSWORD} - - - 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) From 8b39600f931e341fb8a387a20b367bf88762b6a5 Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Sat, 2 Jan 2021 17:41:12 +0100 Subject: [PATCH 08/25] Update POM to reflect changed CI system --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 31098bfd0d25..b651a052bc61 100644 --- a/pom.xml +++ b/pom.xml @@ -71,8 +71,8 @@ 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 From 1254795902e56eb545e1fe696827924bc5e82b66 Mon Sep 17 00:00:00 2001 From: Kevin Cooney Date: Sat, 2 Jan 2021 14:09:07 -0800 Subject: [PATCH 09/25] Mark ThreadGroups created by FailOnTimeout as daemon groups (#1687) Mark ThreadGroup created by FailOnTimeout as a daemon group. Previously, FailOnTimeout destroyed the ThreadGroup, which could cause race conditions if the ThreadGroup was referenced by other threads. Fixes #1652 --- .../runners/statements/FailOnTimeout.java | 31 +++++------ .../runners/statements/FailOnTimeoutTest.java | 53 ++++++++++--------- 2 files changed, 41 insertions(+), 43 deletions(-) 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..e0f3c53947c7 100644 --- a/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java +++ b/src/main/java/org/junit/internal/runners/statements/FailOnTimeout.java @@ -121,28 +121,21 @@ public void evaluate() throws Throwable { CallableStatement callable = new CallableStatement(); FutureTask task = new FutureTask(callable); ThreadGroup threadGroup = new ThreadGroup("FailOnTimeoutGroup"); - 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 { + if (!threadGroup.isDaemon()) { try { - thread.join(1); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - 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. } } + Thread thread = new Thread(threadGroup, task, "Time-limited test"); + thread.setDaemon(true); + thread.start(); + callable.awaitStarted(); + Throwable throwable = getResult(task, thread); + if (throwable != null) { + throw throwable; + } } /** 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..f922169ffe3d 100644 --- a/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java +++ b/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java @@ -14,17 +14,16 @@ import static org.junit.Assert.fail; import static org.junit.internal.runners.statements.FailOnTimeout.builder; -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.atomic.AtomicReference; import org.junit.Test; import org.junit.function.ThrowingRunnable; +import org.junit.internal.runners.statements.Fail; import org.junit.runners.model.Statement; import org.junit.runners.model.TestTimedOutException; + /** * @author Asaf Ary, Stefan Birkner */ @@ -91,20 +90,24 @@ public void throwsExceptionWithTimeoutValueAndTimeUnitSet() { assertEquals(TimeUnit.MILLISECONDS, e.getTimeUnit()); } - private ThrowingRunnable evaluateWithException(final Exception exception) { + private ThrowingRunnable evaluateWithDelegate(final Statement delegate) { return new ThrowingRunnable() { public void run() throws Throwable { - statement.nextException = exception; + statement.nextStatement = delegate; statement.waitDuration = 0; failOnTimeout.evaluate(); } }; } + private ThrowingRunnable evaluateWithException(Exception exception) { + return evaluateWithDelegate(new Fail(exception)); + } + private ThrowingRunnable evaluateWithWaitDuration(final long waitDuration) { return new ThrowingRunnable() { public void run() throws Throwable { - statement.nextException = null; + statement.nextStatement = null; statement.waitDuration = waitDuration; failOnTimeout.evaluate(); } @@ -114,13 +117,13 @@ public void run() throws Throwable { private static final class TestStatement extends Statement { long waitDuration; - Exception nextException; + Statement nextStatement; @Override public void evaluate() throws Throwable { sleep(waitDuration); - if (nextException != null) { - throw nextException; + if (nextStatement != null) { + nextStatement.evaluate(); } } } @@ -210,20 +213,22 @@ 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."); + final AtomicReference innerThreadGroup = new AtomicReference(); + final AtomicReference innerThread = new AtomicReference(); + ThrowingRunnable runnable = evaluateWithDelegate(new Statement() { + @Override + public void evaluate() { + innerThread.set(currentThread()); + ThreadGroup group = currentThread().getThreadGroup(); + innerThreadGroup.set(group); + assertTrue("the 'FailOnTimeoutGroup' thread group should be a daemon thread group", group.isDaemon()); } - } - } - - private Collection subGroupsOfCurrentThread() { - ThreadGroup[] subGroups = new ThreadGroup[256]; - int numGroups = currentThread().getThreadGroup().enumerate(subGroups); - return Arrays.asList(subGroups).subList(0, numGroups); + }); + + runnable.run(); + + assertTrue("the Statement was never run", innerThread.get() != null); + innerThread.get().join(); + assertTrue("the 'FailOnTimeoutGroup' thread group should be destroyed after running the test", innerThreadGroup.get().isDestroyed()); } } From cfec8c7d242feaff0d42ff61c28993ffa537fb83 Mon Sep 17 00:00:00 2001 From: Kevin Cooney Date: Mon, 4 Jan 2021 13:35:35 -0800 Subject: [PATCH 10/25] Initial release notes for 4.13.2 (#1692) * Initial release notes for 4.13.2 Co-authored-by: Marc Philipp --- doc/ReleaseNotes4.13.2.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 doc/ReleaseNotes4.13.2.md diff --git a/doc/ReleaseNotes4.13.2.md b/doc/ReleaseNotes4.13.2.md new file mode 100644 index 000000000000..919eadff7e72 --- /dev/null +++ b/doc/ReleaseNotes4.13.2.md @@ -0,0 +1,13 @@ +## 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. From 8d9690a8be8d2c320f73b0f6074fdd8478eab0ae Mon Sep 17 00:00:00 2001 From: "Anosh D. Ullenius" Date: Wed, 27 Nov 2019 15:13:42 +0100 Subject: [PATCH 11/25] Remove commented out code --- src/test/java/junit/tests/runner/TextRunnerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); From 318e5a7861940cf0cf796bffb033e148d049b524 Mon Sep 17 00:00:00 2001 From: "Anosh D. Ullenius" Date: Wed, 27 Nov 2019 15:16:45 +0100 Subject: [PATCH 12/25] Clean up imports * Same package classes are always implicitly imported * Remove unused imports --- .../junit/experimental/results/ResultMatchers.java | 1 - .../org/junit/runners/model/FrameworkField.java | 1 - src/test/java/junit/tests/runner/ResultTest.java | 2 -- .../categories/CategoriesAndParameterizedTest.java | 2 -- .../experimental/categories/CategoryTest.java | 13 ++++++------- .../categories/CategoryValidatorTest.java | 2 -- .../junit/experimental/categories/JavadocTest.java | 12 +++++------- .../experimental/categories/MultiCategoryTest.java | 14 ++++++-------- src/test/java/org/junit/rules/RuleChainTest.java | 2 -- src/test/java/org/junit/rules/TestRuleTest.java | 4 ---- .../java/org/junit/runners/AllRunnersTests.java | 1 - .../java/org/junit/runners/RuleContainerTest.java | 2 -- .../parent/ParentRunnerClassLoaderTest.java | 12 +++++------- 13 files changed, 22 insertions(+), 46 deletions(-) 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/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/test/java/junit/tests/runner/ResultTest.java b/src/test/java/junit/tests/runner/ResultTest.java index 7a6042996268..734cf6c4ecd4 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; 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..9aa14fcf95a5 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; 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/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/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/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 { From ba3799facea95317bfd09ab802d0725b984ac2e3 Mon Sep 17 00:00:00 2001 From: "Anosh D. Ullenius" Date: Wed, 27 Nov 2019 15:38:58 +0100 Subject: [PATCH 13/25] Reordering the modifiers to comply with the JLS: * Java Language Specification --- .../junit/extensions/ActiveTestSuite.java | 2 +- src/main/java/junit/framework/Assert.java | 74 ++++++++--------- .../runner/notification/RunNotifier.java | 2 +- .../junit/validator/AnnotationsValidator.java | 2 +- .../java/junit/tests/runner/ResultTest.java | 2 +- .../experimental/categories/CategoryTest.java | 2 +- .../org/junit/rules/DisableOnDebugTest.java | 2 +- .../java/org/junit/rules/MethodRulesTest.java | 2 +- .../java/org/junit/rules/StopwatchTest.java | 2 +- .../tests/experimental/AssumptionTest.java | 4 +- .../theories/AssumingInTheoriesTest.java | 2 +- .../runner/SuccessfulWithDataPointFields.java | 2 +- .../junit3compatibility/AllTestsTest.java | 4 +- .../ForwardCompatibilityTest.java | 2 +- .../JUnit38ClassRunnerTest.java | 2 +- .../tests/junit3compatibility/OldTests.java | 2 +- .../junit3compatibility/SuiteMethodTest.java | 8 +- .../junit/tests/listening/ListenerTest.java | 2 +- .../tests/manipulation/SingleMethodTest.java | 6 +- .../tests/running/classes/EnclosedTest.java | 2 +- .../classes/ParameterizedTestTest.java | 28 +++---- .../tests/running/core/CommandLineTest.java | 4 +- .../JUnitCoreReturnsCorrectExitCodeTest.java | 4 +- .../tests/running/methods/AnnotationTest.java | 80 +++++++++---------- .../methods/ParameterizedTestMethodTest.java | 6 +- 25 files changed, 124 insertions(+), 124 deletions(-) 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/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/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/runner/ResultTest.java b/src/test/java/junit/tests/runner/ResultTest.java index 734cf6c4ecd4..8cd7ac2d657e 100644 --- a/src/test/java/junit/tests/runner/ResultTest.java +++ b/src/test/java/junit/tests/runner/ResultTest.java @@ -96,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/org/junit/experimental/categories/CategoryTest.java b/src/test/java/org/junit/experimental/categories/CategoryTest.java index 9aa14fcf95a5..6088f1d26229 100644 --- a/src/test/java/org/junit/experimental/categories/CategoryTest.java +++ b/src/test/java/org/junit/experimental/categories/CategoryTest.java @@ -411,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/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/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/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/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() { From 877750a0c8a5aff8d99e5164a1abed487d7f70cc Mon Sep 17 00:00:00 2001 From: Stefan Birkner Date: Tue, 23 Oct 2018 07:59:45 +0200 Subject: [PATCH 14/25] Extract sample test classes from StackTracesTest Follow Kevin's idea from ead2fe7ca97e4b0bc013efe0e734e39a45db213c up that sample test classes are stored in a specific container. --- .../java/org/junit/internal/Throwables.java | 5 +- .../java/junit/tests/SampleJUnit3Tests.java | 51 +++++ .../org/junit/internal/StackTracesTest.java | 210 +++--------------- .../org/junit/tests/SampleJUnit4Tests.java | 88 ++++++++ 4 files changed, 176 insertions(+), 178 deletions(-) create mode 100644 src/test/java/junit/tests/SampleJUnit3Tests.java 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/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/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/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() { From de77f666b6bcc640425dbbca559c9d62ea64a815 Mon Sep 17 00:00:00 2001 From: Kevin Cooney Date: Sat, 9 Jan 2021 20:14:02 -0800 Subject: [PATCH 15/25] Only create ThreadGroups if FailOnTimeout.lookForStuckThread is true. (#1691) This reduces the differences (where possible) when tests are run with a timeout. Creating a ThreadGroup can cause noticeable differences, for example in code that uses java.beans.ThreadGroupContext. --- doc/ReleaseNotes4.13.2.md | 17 +++++++ .../runners/statements/FailOnTimeout.java | 34 ++++++++++---- .../runners/statements/FailOnTimeoutTest.java | 45 +++++++++++++++++-- 3 files changed, 85 insertions(+), 11 deletions(-) diff --git a/doc/ReleaseNotes4.13.2.md b/doc/ReleaseNotes4.13.2.md index 919eadff7e72..3e89f62e591c 100644 --- a/doc/ReleaseNotes4.13.2.md +++ b/doc/ReleaseNotes4.13.2.md @@ -11,3 +11,20 @@ people reported problems that were caused by explicitly destroying the `ThreadGr 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)`. 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 e0f3c53947c7..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,14 +120,7 @@ public FailOnTimeout build(Statement statement) { public void evaluate() throws Throwable { CallableStatement callable = new CallableStatement(); FutureTask task = new FutureTask(callable); - ThreadGroup threadGroup = new ThreadGroup("FailOnTimeoutGroup"); - if (!threadGroup.isDaemon()) { - try { - threadGroup.setDaemon(true); - } catch (SecurityException e) { - // Swallow the exception to keep the same behavior as in JUnit 4.12. - } - } + ThreadGroup threadGroup = threadGroupForNewThread(); Thread thread = new Thread(threadGroup, task, "Time-limited test"); thread.setDaemon(true); thread.start(); @@ -138,6 +131,31 @@ public void evaluate() throws 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.setDaemon(true); + } catch (SecurityException e) { + // Swallow the exception to keep the same behavior as in JUnit 4.12. + } + } + return threadGroup; + } + /** * Wait for the test task, returning the exception thrown by the test if the * test failed, an exception indicating a timeout if the test timed out, or 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 f922169ffe3d..f1e7f79a886b 100644 --- a/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java +++ b/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java @@ -8,18 +8,23 @@ import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +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.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import org.junit.Test; import org.junit.function.ThrowingRunnable; import org.junit.internal.runners.statements.Fail; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import org.junit.runners.model.Statement; import org.junit.runners.model.TestTimedOutException; @@ -27,13 +32,29 @@ /** * @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(); - private final FailOnTimeout failOnTimeout = builder().withTimeout(TIMEOUT, MILLISECONDS).build(statement); + private final boolean lookingForStuckThread; + private final FailOnTimeout failOnTimeout; + + @Parameterized.Parameters(name = "lookingForStuckThread = {0}") + public static Iterable getParameters() { + return Arrays.asList(Boolean.TRUE, Boolean.FALSE); + } + + public FailOnTimeoutTest(Boolean lookingForStuckThread) { + this.lookingForStuckThread = lookingForStuckThread; + this.failOnTimeout = builder().withTimeout(TIMEOUT, MILLISECONDS).build(statement); + } + + private FailOnTimeout.Builder builder() { + return FailOnTimeout.builder().withLookingForStuckThread(lookingForStuckThread); + } @Test public void throwsTestTimedOutException() { @@ -212,14 +233,17 @@ private void notTheRealCauseOfTheTimeout() { } @Test - public void threadGroupNotLeaked() throws Throwable { + public void lookingForStuckThread_threadGroupNotLeaked() throws Throwable { + assumeTrue(lookingForStuckThread); final AtomicReference innerThreadGroup = new AtomicReference(); final AtomicReference innerThread = new AtomicReference(); + final ThreadGroup outerThreadGroup = currentThread().getThreadGroup(); ThrowingRunnable runnable = evaluateWithDelegate(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()); } @@ -231,4 +255,19 @@ public void evaluate() { 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 ThreadGroup outerThreadGroup = currentThread().getThreadGroup(); + ThrowingRunnable runnable = evaluateWithDelegate(new Statement() { + @Override + public void evaluate() { + ThreadGroup group = currentThread().getThreadGroup(); + assertSame("inner thread should use the same thread group", outerThreadGroup, group); + } + }); + + runnable.run(); + } } From f8ee412316b1a94d3dc35498359cc2f0ca273216 Mon Sep 17 00:00:00 2001 From: Riccardo Sirchia Date: Mon, 11 Jan 2021 06:26:40 +0100 Subject: [PATCH 16/25] Fix serialization of AssumptionViolatedException (#1654) Added serializable descriptions of values and matchers and use them in writeObject() serialization of AssumptionViolatedException. Fixes #1192 --- .../internal/AssumptionViolatedException.java | 28 +++++ .../SerializableMatcherDescription.java | 47 ++++++++ .../SerializableValueDescription.java | 38 ++++++ .../AssumptionViolatedExceptionTest.java | 112 ++++++++++++++++++ ...WithValueAndMatcherCanBeReserialized_v4_13 | Bin 0 -> 3795 bytes ...houtValueAndMatcherCanBeReserialized_v4_13 | Bin 0 -> 3638 bytes 6 files changed, 225 insertions(+) create mode 100644 src/main/java/org/junit/internal/SerializableMatcherDescription.java create mode 100644 src/main/java/org/junit/internal/SerializableValueDescription.java create mode 100644 src/test/resources/org/junit/assumptionViolatedExceptionWithValueAndMatcherCanBeReserialized_v4_13 create mode 100644 src/test/resources/org/junit/assumptionViolatedExceptionWithoutValueAndMatcherCanBeReserialized_v4_13 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/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/resources/org/junit/assumptionViolatedExceptionWithValueAndMatcherCanBeReserialized_v4_13 b/src/test/resources/org/junit/assumptionViolatedExceptionWithValueAndMatcherCanBeReserialized_v4_13 new file mode 100644 index 0000000000000000000000000000000000000000..1409545b5ab9fea37211df850ec4740292026c14 GIT binary patch literal 3795 zcmds4U2GIp6h5<*Qnpab|DWYATTp~4r9~vgYP%G&uoTi3NFni!*R^1=%*BA#<+=FXH|DCnE}aQDtV=X~dP z&YXMeE-dv0^m?LfUJ6`Wnj^j+RBO`q+;g_)Fv&|}4U4M-2!BQfpdr9aWNcS*;WFnb zgfkgvdjnR^oMTSFPcdm#xF|yBOrlo8>f$9lAxd2&TGHZ59FbgHOUPy^fYQmVqtK5|cvDOc2HH?6tN|7(2I}{6~?erCGA3d)T zd}l2XF=iNpX3Wg7Jx7i_*m;q+REylshAqg-P*5p;~h!^gNCf8Me%J>)tHiA3|f$hbdTVX;~+sJ)~;lOA=m4 z>pjXHUPj$+xs~o6Pa-S*q-JA`ZrqcwF-dpqTZk;7Gu$-G!O((~iNJNa@Xe}M;*NPt zV7})(F&j$f`X#J=Avk;$&WFvE0^FT?*6G?8BN(V= zdm153*BK_z$O)Ca+yHu*K4?aPyAlp3D9_?%f3BaRxR;j1s^t<6{wq9%C1De$jo#$E zhwmMi9Q%S@b}8_&+=#yg-!};#?X-}-i zT8_p9!Hx3?> zu#eKqY7DE?tgcMMmqyhCez4MyQFOM2 zpXpdp!JWiuL^bK6$Iu$>&pmQ)j+O>qAF$`BSJyANC`#j;W}HtmwpE$!;*h*cO-(d% zn|aTni4gBke(tP`Gmt%F(=0-x_+QWU_J8%~_3jK9MQC&Igut?RHQBp3KmxpJ6t3KU z^Zr%^V_0+{BJn;o@+WLK_@imzT}GKUA_SW!I~rGi?)l^gc5?~#T4?iezEzVq%(c-C zuR%s#YZw@ZWVYU34R0!lcr@vE3BBcXo|}y3X9_^U$NLYD?|gSYx;k%tc>Q;E)j-fy x$=q4M+ay-#>fb*9^8VHLUO_Jlu#~1Cj)Ce<_`h)N6n+x|gaso1zw%ofP=pB~L5d2Z$r3QI1S$zoB~?d9#VuUL*x4EZ>(c)bM>k_Ox8T(o^xpnP}TdOXVhVK2IxVAZGv>ZP@-gkD_@T=c- za7;H;FwbTr|MiEHhfmLc^I!#ZS7D{c;)rY5TJXhkqN(d^Tr(jr^C)6Xm5>sl2Pg^ zl0}j6k8&s^pJ2_z-zt=vTsMN6Juyn#8eY#!E3b==a-7EGYbYm$&)94qwXm7UBzc57MMH1v}p0m z#-kC>!@LA)yctRjd!9u~ZCfq;RxrnpC(s!8vlOo_v~1O|Dxq598ya3K>OIFLucL0i zzLf3*&m$ZCq-IBk?mW`4BhPr|TY{`%ZL;ZMV`KMiiV(;)$`WFex*`V4a4+yew?TS*&TXEL}d>l9NvZ-Nk63kZzw$5bREkO98|Nvh>)b~DpP3W zq)A?R5Irm&bfUmR4X1OImvM8TJU~%AN=t6l8Vx7^6`sM;uoKfpm$?$)z2ll=YY=sx z0-re!KNIVzl%L9t_?O`OHs_j^s9GbuuagZ|>qXe1Q&`hL^?=6R~?~QfD+B zAA5c$axn#D38rN=YOQiMYn`fNOX!qbS}|dq)zE_&m4=Wt3-UHmDuztUxs2dkTE13> zNMewdLzx&{SzgT406NqY;TTY(GA4*#0B4*w?-*3>B1~iir;i@5(qf?gllO$OgdhJK2Ty4@M(JfC!zy)~ zti^pdit*Jb6iv)@cvF2kqb1KU+Rb*M6vRJCA#{_`*?pVT?X}5mi zz+6>9OVr4dZPt_Q%mykSMGihU@H0VxA06&_94mNj)I8t|tN55kXJ7J~&J>ONQ#g&7 zCS45}T4VirMDESgf+OfA>^bJ@M&mw;(l}=s7mAGCO(uMtlMk7xiKcG15=fc|@e?X4 zU-NMW60?G45t_#TdZlmR>pwo-&;?Evx+R_vSP8#QjxG<71MeJ#yAR&~bFYDMJo+Xg z@qRP)=WICpqiM@ literal 0 HcmV?d00001 From 64634e1c3e357251a84278c26b73b04fc3450ea3 Mon Sep 17 00:00:00 2001 From: Kevin Cooney Date: Sat, 16 Jan 2021 19:24:40 -0800 Subject: [PATCH 17/25] Update 4.13.2 release notes to document pull 1654 --- doc/ReleaseNotes4.13.2.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/ReleaseNotes4.13.2.md b/doc/ReleaseNotes4.13.2.md index 3e89f62e591c..ba801396d1a4 100644 --- a/doc/ReleaseNotes4.13.2.md +++ b/doc/ReleaseNotes4.13.2.md @@ -28,3 +28,11 @@ behave as they did in JUnit 4.11 (and more similar to tests that do not have a t 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`). From 2db63942882d91020b46d7333285e5c94f1d1e52 Mon Sep 17 00:00:00 2001 From: Stefan Birkner Date: Sat, 2 Jan 2021 16:54:40 +0100 Subject: [PATCH 18/25] Tidy up FailOnTimeoutTest Improve readability and reusability. When I started to read the test it took me some time to understand it. The reason was the configurable statement TestStatement and the evaluateWith... methods. The refactored test uses fixed Statements when possible and uses smaller methods for wrapping FailOnTimeout with a ThrowingRunnable and for wrapping an arbitrary statement with a FailOnTimeout. It also calls FailOnTimeout#evaluate directly when possible. --- .../runners/statements/FailOnTimeoutTest.java | 267 +++++++++--------- 1 file changed, 135 insertions(+), 132 deletions(-) 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 f1e7f79a886b..20ca9cd55630 100644 --- a/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java +++ b/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java @@ -8,23 +8,24 @@ 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.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import java.util.Arrays; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import org.junit.Test; import org.junit.function.ThrowingRunnable; -import org.junit.internal.runners.statements.Fail; 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; @@ -34,176 +35,129 @@ */ @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(); - - private final boolean lookingForStuckThread; - private final FailOnTimeout failOnTimeout; - - @Parameterized.Parameters(name = "lookingForStuckThread = {0}") + @Parameters(name = "lookingForStuckThread = {0}") public static Iterable getParameters() { return Arrays.asList(Boolean.TRUE, Boolean.FALSE); } - public FailOnTimeoutTest(Boolean lookingForStuckThread) { - this.lookingForStuckThread = lookingForStuckThread; - this.failOnTimeout = builder().withTimeout(TIMEOUT, MILLISECONDS).build(statement); - } + @Parameter + public boolean lookingForStuckThread; + + @Test + public void noExceptionIsThrownWhenWrappedStatementFinishesBeforeTimeoutWithoutThrowingException() + throws Throwable { + FailOnTimeout failOnTimeout = failAfter50Ms(new FastStatement()); - private FailOnTimeout.Builder builder() { - return FailOnTimeout.builder().withLookingForStuckThread(lookingForStuckThread); + failOnTimeout.evaluate(); + + // test is successful when no exception is thrown } @Test public void throwsTestTimedOutException() { assertThrows( TestTimedOutException.class, - evaluateWithWaitDuration(DURATION_THAT_EXCEEDS_TIMEOUT)); + run(failAfter50Ms(new InfiniteLoop()))); } @Test public void throwExceptionWithNiceMessageOnTimeout() { - TestTimedOutException e = assertThrows( - TestTimedOutException.class, - evaluateWithWaitDuration(DURATION_THAT_EXCEEDS_TIMEOUT)); - assertEquals("test timed out after 100 milliseconds", e.getMessage()); + Exception e = assertThrows( + Exception.class, + run(failAfter50Ms(new InfiniteLoop()))); + 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(); + DelegateStatement statement = new DelegateStatement(); + FailOnTimeout failOnTimeout = failAfter50Ms(statement); + + statement.delegate = new FastStatement(); + failOnTimeout.evaluate(); + + statement.delegate = new InfiniteLoop(); assertThrows( TestTimedOutException.class, - evaluateWithWaitDuration(DURATION_THAT_EXCEEDS_TIMEOUT)); + run(failOnTimeout)); } @Test public void throwTimeoutExceptionOnSecondCallAlthoughFirstCallThrowsException() { - try { - evaluateWithException(new RuntimeException()).run(); - } catch (Throwable expected) { - } + DelegateStatement statement = new DelegateStatement(); + FailOnTimeout failOnTimeout = failAfter50Ms(statement); - TestTimedOutException e = assertThrows( + statement.delegate = new Fail(new AssertionError("first execution failed")); + assertThrows( + AssertionError.class, + run(failOnTimeout) + ); + + statement.delegate = new InfiniteLoop(); + 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 evaluateWithDelegate(final Statement delegate) { - return new ThrowingRunnable() { - public void run() throws Throwable { - statement.nextStatement = delegate; - statement.waitDuration = 0; - failOnTimeout.evaluate(); - } - }; - } - - private ThrowingRunnable evaluateWithException(Exception exception) { - return evaluateWithDelegate(new Fail(exception)); - } - - private ThrowingRunnable evaluateWithWaitDuration(final long waitDuration) { - return new ThrowingRunnable() { - public void run() throws Throwable { - statement.nextStatement = null; - statement.waitDuration = waitDuration; - failOnTimeout.evaluate(); - } - }; - } - - private static final class TestStatement extends Statement { - long waitDuration; - - Statement nextStatement; - - @Override - public void evaluate() throws Throwable { - sleep(waitDuration); - if (nextStatement != null) { - nextStatement.evaluate(); - } - } + run(failAfter50Ms(new InfiniteLoop()))); + assertEquals(50, e.getTimeout()); + assertEquals(MILLISECONDS, e.getTimeUnit()); } @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; - - @Override - public void evaluate() throws Throwable { - while (true) { - sleep(10); // sleep in order to enable interrupting thread - ++COUNT; - } - } + InfiniteLoop infiniteLoop = new InfiniteLoop(); + assertThrows( + TestTimedOutException.class, + run(failAfter50Ms(infiniteLoop))); + + sleep(20); // time to interrupt the thread + infiniteLoop.stillExecuting.set(false); + sleep(20); // time to increment the count + assertFalse( + "Thread has not been stopped.", + infiniteLoop.stillExecuting.get()); } @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; - } + public void stackTraceContainsRealCauseOfTimeout() { + TestTimedOutException timedOutException = assertThrows( + TestTimedOutException.class, + run(failAfter50Ms(new StuckStatement()))); + + StackTraceElement[] stackTrace = timedOutException.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; } - 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 { @@ -238,36 +192,85 @@ public void lookingForStuckThread_threadGroupNotLeaked() throws Throwable { final AtomicReference innerThreadGroup = new AtomicReference(); final AtomicReference innerThread = new AtomicReference(); final ThreadGroup outerThreadGroup = currentThread().getThreadGroup(); - ThrowingRunnable runnable = evaluateWithDelegate(new Statement() { + 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); + 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()); + assertTrue("the 'FailOnTimeoutGroup' thread group should be a daemon thread group", + group.isDaemon()); } }); - runnable.run(); + failOnTimeout.evaluate(); - assertTrue("the Statement was never run", innerThread.get() != null); + 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()); + 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(); - ThrowingRunnable runnable = evaluateWithDelegate(new Statement() { + 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); } }); - runnable.run(); + 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 DelegateStatement extends Statement { + Statement delegate; + + @Override + public void evaluate() throws Throwable { + delegate.evaluate(); + } + } + + private static class FastStatement extends Statement { + @Override + public void evaluate() throws Throwable { + } + } + + private static final class InfiniteLoop extends Statement { + final AtomicBoolean stillExecuting = new AtomicBoolean(); + + @Override + public void evaluate() throws Throwable { + while (true) { + sleep(10); // sleep in order to enable interrupting thread + stillExecuting.set(true); + } + } } } From 527f3a3d0d71ad6dc66ede6f68f6fc316904ed2a Mon Sep 17 00:00:00 2001 From: Stefan Birkner Date: Sun, 17 Jan 2021 20:22:23 +0100 Subject: [PATCH 19/25] Replace InfiniteLoop with RunForASecond RunForASecond finally stops and therefore avoids that we create background threads that run forever. --- .../runners/statements/FailOnTimeoutTest.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) 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 20ca9cd55630..25fbd52d393a 100644 --- a/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java +++ b/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java @@ -58,14 +58,14 @@ public void noExceptionIsThrownWhenWrappedStatementFinishesBeforeTimeoutWithoutT public void throwsTestTimedOutException() { assertThrows( TestTimedOutException.class, - run(failAfter50Ms(new InfiniteLoop()))); + run(failAfter50Ms(new RunForASecond()))); } @Test public void throwExceptionWithNiceMessageOnTimeout() { Exception e = assertThrows( Exception.class, - run(failAfter50Ms(new InfiniteLoop()))); + run(failAfter50Ms(new RunForASecond()))); assertEquals("test timed out after 50 milliseconds", e.getMessage()); } @@ -87,7 +87,7 @@ public void throwExceptionIfTheSecondCallToEvaluateNeedsTooMuchTime() statement.delegate = new FastStatement(); failOnTimeout.evaluate(); - statement.delegate = new InfiniteLoop(); + statement.delegate = new RunForASecond(); assertThrows( TestTimedOutException.class, run(failOnTimeout)); @@ -104,7 +104,7 @@ public void throwTimeoutExceptionOnSecondCallAlthoughFirstCallThrowsException() run(failOnTimeout) ); - statement.delegate = new InfiniteLoop(); + statement.delegate = new RunForASecond(); assertThrows( TestTimedOutException.class, run(failOnTimeout)); @@ -114,24 +114,24 @@ public void throwTimeoutExceptionOnSecondCallAlthoughFirstCallThrowsException() public void throwsExceptionWithTimeoutValueAndTimeUnitSet() { TestTimedOutException e = assertThrows( TestTimedOutException.class, - run(failAfter50Ms(new InfiniteLoop()))); + run(failAfter50Ms(new RunForASecond()))); assertEquals(50, e.getTimeout()); assertEquals(MILLISECONDS, e.getTimeUnit()); } @Test public void stopEndlessStatement() throws Throwable { - InfiniteLoop infiniteLoop = new InfiniteLoop(); + RunForASecond runForASecond = new RunForASecond(); assertThrows( TestTimedOutException.class, - run(failAfter50Ms(infiniteLoop))); + run(failAfter50Ms(runForASecond))); sleep(20); // time to interrupt the thread - infiniteLoop.stillExecuting.set(false); + runForASecond.stillExecuting.set(false); sleep(20); // time to increment the count assertFalse( "Thread has not been stopped.", - infiniteLoop.stillExecuting.get()); + runForASecond.stillExecuting.get()); } @Test @@ -262,12 +262,13 @@ public void evaluate() throws Throwable { } } - private static final class InfiniteLoop extends Statement { + private static final class RunForASecond extends Statement { final AtomicBoolean stillExecuting = new AtomicBoolean(); @Override public void evaluate() throws Throwable { - while (true) { + long timeout = currentTimeMillis() + 1000L; + while (currentTimeMillis() < timeout) { sleep(10); // sleep in order to enable interrupting thread stillExecuting.set(true); } From b83dc2e8c4ff06cf233cd347f1280bb417482985 Mon Sep 17 00:00:00 2001 From: Stefan Birkner Date: Sun, 17 Jan 2021 20:42:40 +0100 Subject: [PATCH 20/25] Better name for test that stops statement --- .../junit/internal/runners/statements/FailOnTimeoutTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 25fbd52d393a..19bb7bfc7245 100644 --- a/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java +++ b/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java @@ -120,7 +120,9 @@ public void throwsExceptionWithTimeoutValueAndTimeUnitSet() { } @Test - public void stopEndlessStatement() throws Throwable { + public void statementThatCanBeInterruptedIsStoppedAfterTimeout() throws Throwable { + // RunForASecond can be interrupted because it uses Thread.sleep which + // can be interrupted. RunForASecond runForASecond = new RunForASecond(); assertThrows( TestTimedOutException.class, From d27ad5259228e84c235dac24cd62f974ac0a8e1d Mon Sep 17 00:00:00 2001 From: Stefan Birkner Date: Wed, 20 Jan 2021 07:12:53 +0100 Subject: [PATCH 21/25] Rename DelegateStatement to DelegatingStatement --- .../internal/runners/statements/FailOnTimeoutTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 19bb7bfc7245..04b329b1fff2 100644 --- a/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java +++ b/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java @@ -81,7 +81,7 @@ public void sendUpExceptionThrownByStatement() { @Test public void throwExceptionIfTheSecondCallToEvaluateNeedsTooMuchTime() throws Throwable { - DelegateStatement statement = new DelegateStatement(); + DelegatingStatement statement = new DelegatingStatement(); FailOnTimeout failOnTimeout = failAfter50Ms(statement); statement.delegate = new FastStatement(); @@ -95,7 +95,7 @@ public void throwExceptionIfTheSecondCallToEvaluateNeedsTooMuchTime() @Test public void throwTimeoutExceptionOnSecondCallAlthoughFirstCallThrowsException() { - DelegateStatement statement = new DelegateStatement(); + DelegatingStatement statement = new DelegatingStatement(); FailOnTimeout failOnTimeout = failAfter50Ms(statement); statement.delegate = new Fail(new AssertionError("first execution failed")); @@ -249,7 +249,7 @@ public void run() throws Throwable { }; } - private static class DelegateStatement extends Statement { + private static class DelegatingStatement extends Statement { Statement delegate; @Override From e9a75f4be71a4d5a794ccd063522eea4b0f3194f Mon Sep 17 00:00:00 2001 From: Stefan Birkner Date: Wed, 20 Jan 2021 07:22:19 +0100 Subject: [PATCH 22/25] Merge test for exception type and message IMO this is conceptually one assert because the message and the exception type are strongly coupled. --- .../runners/statements/FailOnTimeoutTest.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) 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 04b329b1fff2..857708fc84b6 100644 --- a/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java +++ b/src/test/java/org/junit/internal/runners/statements/FailOnTimeoutTest.java @@ -55,16 +55,9 @@ public void noExceptionIsThrownWhenWrappedStatementFinishesBeforeTimeoutWithoutT } @Test - public void throwsTestTimedOutException() { - assertThrows( - TestTimedOutException.class, - run(failAfter50Ms(new RunForASecond()))); - } - - @Test - public void throwExceptionWithNiceMessageOnTimeout() { + public void throwsTestTimedOutExceptionWithMeaningfulMessage() { Exception e = assertThrows( - Exception.class, + TestTimedOutException.class, run(failAfter50Ms(new RunForASecond()))); assertEquals("test timed out after 50 milliseconds", e.getMessage()); } From 02aaa01b8f74c0eb496d76685ec49fddeb311087 Mon Sep 17 00:00:00 2001 From: Stefan Birkner Date: Wed, 20 Jan 2021 07:54:36 +0100 Subject: [PATCH 23/25] Improve check that thread is stopped The new code is hopefully easier to understand because it makes it explicit that it checks that the statement is stopped within a period of time that is close to the timeout. --- .../runners/statements/FailOnTimeoutTest.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) 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 857708fc84b6..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,6 +4,7 @@ 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; @@ -17,6 +18,7 @@ import static org.junit.Assume.assumeTrue; import java.util.Arrays; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @@ -114,19 +116,17 @@ public void throwsExceptionWithTimeoutValueAndTimeUnitSet() { @Test public void statementThatCanBeInterruptedIsStoppedAfterTimeout() throws Throwable { - // RunForASecond can be interrupted because it uses Thread.sleep which - // can be interrupted. + // RunForASecond can be interrupted because it checks the Thread's + // interrupted flag. RunForASecond runForASecond = new RunForASecond(); assertThrows( TestTimedOutException.class, run(failAfter50Ms(runForASecond))); - sleep(20); // time to interrupt the thread - runForASecond.stillExecuting.set(false); - sleep(20); // time to increment the count - assertFalse( - "Thread has not been stopped.", - runForASecond.stillExecuting.get()); + // 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 @@ -243,7 +243,7 @@ public void run() throws Throwable { } private static class DelegatingStatement extends Statement { - Statement delegate; + volatile Statement delegate; @Override public void evaluate() throws Throwable { @@ -258,15 +258,14 @@ public void evaluate() throws Throwable { } private static final class RunForASecond extends Statement { - final AtomicBoolean stillExecuting = new AtomicBoolean(); + final CountDownLatch finished = new CountDownLatch(1); @Override public void evaluate() throws Throwable { long timeout = currentTimeMillis() + 1000L; - while (currentTimeMillis() < timeout) { - sleep(10); // sleep in order to enable interrupting thread - stillExecuting.set(true); + while (!interrupted() && currentTimeMillis() < timeout) { } + finished.countDown(); } } } From ff57344f7171ea8b0935c4f842cacf1097266592 Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Sat, 13 Feb 2021 14:48:19 +0100 Subject: [PATCH 24/25] Add build for JDK 17-ea --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3ea3f6a0c584..65bdbaa62aa3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - java: [6, 8, 11, 15] + 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 From 05fe2a64f59127c02135be22f416e91260d6ede6 Mon Sep 17 00:00:00 2001 From: Marc Philipp Date: Sat, 13 Feb 2021 17:30:49 +0100 Subject: [PATCH 25/25] [maven-release-plugin] prepare release r4.13.2 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index b651a052bc61..38be96092f24 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ junit junit - 4.13.2-SNAPSHOT + 4.13.2 JUnit JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck. @@ -64,7 +64,7 @@ scm:git:git://github.com/junit-team/junit4.git scm:git:git@github.com:junit-team/junit4.git https://github.com/junit-team/junit4 - HEAD + r4.13.2 github