You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by ja...@apache.org on 2018/08/27 12:19:56 UTC

ant git commit: [junitlauncher] More fine-grained control over classpath for forked tests in junitlauncher

Repository: ant
Updated Branches:
  refs/heads/master edfeba73e -> 8590e1539


[junitlauncher] More fine-grained control over classpath for forked tests in junitlauncher

- Allows Ant runtime libraries to be excluded and thus letting the user have control over where those library jars come from
- Allows JUnit platform libraries to be excluded and thus letting the user have control over where those library jars come from

Plus added testcases to verify this feature


Project: http://git-wip-us.apache.org/repos/asf/ant/repo
Commit: http://git-wip-us.apache.org/repos/asf/ant/commit/8590e153
Tree: http://git-wip-us.apache.org/repos/asf/ant/tree/8590e153
Diff: http://git-wip-us.apache.org/repos/asf/ant/diff/8590e153

Branch: refs/heads/master
Commit: 8590e1539af7e5057d02941911c44d887ba3caca
Parents: edfeba7
Author: Jaikiran Pai <ja...@apache.org>
Authored: Mon Aug 27 17:46:12 2018 +0530
Committer: Jaikiran Pai <ja...@apache.org>
Committed: Mon Aug 27 17:48:53 2018 +0530

----------------------------------------------------------------------
 .../taskdefs/optional/junitlauncher.xml         | 46 ++++++++++++-
 .../optional/junitlauncher/ForkDefinition.java  | 18 ++++-
 .../junitlauncher/StandaloneLauncher.java       |  3 +-
 .../junitlauncher/JUnitLauncherTaskTest.java    | 71 ++++++++++++++++++++
 .../org/example/junitlauncher/Tracker.java      | 17 +++--
 5 files changed, 144 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ant/blob/8590e153/src/etc/testcases/taskdefs/optional/junitlauncher.xml
----------------------------------------------------------------------
diff --git a/src/etc/testcases/taskdefs/optional/junitlauncher.xml b/src/etc/testcases/taskdefs/optional/junitlauncher.xml
index 35b2c3f..d244213 100644
--- a/src/etc/testcases/taskdefs/optional/junitlauncher.xml
+++ b/src/etc/testcases/taskdefs/optional/junitlauncher.xml
@@ -43,7 +43,6 @@
 
     <path id="test.classpath">
         <pathelement location="${build.classes.dir}"/>
-        <path refid="junit.platform.classpath"/>
         <path refid="junit.engine.vintage.classpath"/>
         <path refid="junit.engine.jupiter.classpath"/>
     </path>
@@ -166,5 +165,50 @@
             </test>
         </junitlauncher>
     </target>
+
+    <target name="test-junit-platform-lib-excluded" depends="init">
+        <junitlauncher>
+            <classpath refid="junit.engine.jupiter.classpath"/>
+            <classpath>
+                <pathelement location="${build.classes.dir}"/>
+            </classpath>
+            <test name="org.example.junitlauncher.jupiter.JupiterSampleTest" outputdir="${output.dir}">
+                <!-- expect the test to not be launched due to CNFE on JUnit platform classes -->
+                <fork dir="${basedir}" includeJUnitPlatformLibraries="false"/>
+            </test>
+        </junitlauncher>
+    </target>
+
+    <target name="test-junit-ant-runtime-lib-excluded" depends="init">
+        <junitlauncher>
+            <classpath refid="junit.engine.jupiter.classpath"/>
+            <classpath>
+                <pathelement location="${build.classes.dir}"/>
+            </classpath>
+            <test name="org.example.junitlauncher.jupiter.JupiterSampleTest" outputdir="${output.dir}">
+                <!-- expect the test to not be launched due to CNFE on Ant runtime classes -->
+                <fork dir="${basedir}" includeAntRuntimeLibraries="false"/>
+            </test>
+        </junitlauncher>
+    </target>
+
+    <target name="test-junit-platform-lib-custom-location" depends="init">
+        <junitlauncher>
+            <classpath refid="junit.engine.jupiter.classpath"/>
+            <classpath>
+                <pathelement location="${build.classes.dir}"/>
+            </classpath>
+            <!-- we set includeJUnitPlatformLibraries=false on the fork element
+            and then explicitly specify a location of the JUnit platform libraries -->
+            <classpath refid="junit.platform.classpath"/>
+            <test name="org.example.junitlauncher.jupiter.JupiterSampleTest" outputdir="${output.dir}">
+                <listener classname="org.example.junitlauncher.Tracker"
+                          outputDir="${output.dir}"
+                          resultFile="${test-junit-platform-lib-custom-location.tracker}"
+                          if="test-junit-platform-lib-custom-location.tracker"/>
+                <fork dir="${basedir}" includeJUnitPlatformLibraries="false"/>
+            </test>
+        </junitlauncher>
+    </target>
 </project>
 

http://git-wip-us.apache.org/repos/asf/ant/blob/8590e153/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ForkDefinition.java
----------------------------------------------------------------------
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ForkDefinition.java b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ForkDefinition.java
index bda3381..c5c95cc 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ForkDefinition.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ForkDefinition.java
@@ -41,7 +41,7 @@ import java.io.File;
 public class ForkDefinition {
 
     private boolean includeAntRuntimeLibraries = true;
-    private boolean includeJunitPlatformLibraries = true;
+    private boolean includeJUnitPlatformLibraries = true;
 
     private final CommandlineJava commandLineJava;
     private final Environment env = new Environment();
@@ -69,6 +69,14 @@ public class ForkDefinition {
         return this.timeout;
     }
 
+    public void setIncludeJUnitPlatformLibraries(final boolean include) {
+        this.includeJUnitPlatformLibraries = include;
+    }
+
+    public void setIncludeAntRuntimeLibraries(final boolean include) {
+        this.includeAntRuntimeLibraries = include;
+    }
+
     public Commandline.Argument createJvmArg() {
         return this.commandLineJava.createVmArgument();
     }
@@ -121,19 +129,23 @@ public class ForkDefinition {
             addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(AntMain.class));
             addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(Task.class));
             addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(JUnitLauncherTask.class));
+        } else {
+            task.log("Excluding Ant runtime libraries from forked JVM classpath", Project.MSG_DEBUG);
         }
-
-        if (this.includeJunitPlatformLibraries) {
+        if (this.includeJUnitPlatformLibraries) {
             // platform-engine
             addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(TestEngine.class));
             // platform-launcher
             addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(LauncherFactory.class));
             // platform-commons
             addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(Testable.class));
+        } else {
+            task.log("Excluding JUnit platform libraries from forked JVM classpath", Project.MSG_DEBUG);
         }
         final Path classPath = cmdLine.createClasspath(project);
         classPath.createPath().append(antRuntimeResourceSources);
 
+
         return cmdLine;
     }
 

http://git-wip-us.apache.org/repos/asf/ant/blob/8590e153/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/StandaloneLauncher.java
----------------------------------------------------------------------
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/StandaloneLauncher.java b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/StandaloneLauncher.java
index 8f43da3..69a1556 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/StandaloneLauncher.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/StandaloneLauncher.java
@@ -98,7 +98,6 @@ public class StandaloneLauncher {
                 i = i + numArgsConsumed;
             }
 
-
             launchDefinition.setTestExecutionContext(forkedExecution);
             final LauncherSupport launcherSupport = new LauncherSupport(launchDefinition);
             try {
@@ -106,8 +105,8 @@ public class StandaloneLauncher {
             } catch (Throwable t) {
                 if (launcherSupport.hasTestFailures()) {
                     System.exit(Constants.FORK_EXIT_CODE_TESTS_FAILED);
-                    throw t;
                 }
+                throw t;
             }
             if (launcherSupport.hasTestFailures()) {
                 System.exit(Constants.FORK_EXIT_CODE_TESTS_FAILED);

http://git-wip-us.apache.org/repos/asf/ant/blob/8590e153/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTaskTest.java
----------------------------------------------------------------------
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTaskTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTaskTest.java
index 8c3fbf2..cdae304 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTaskTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTaskTest.java
@@ -187,6 +187,77 @@ public class JUnitLauncherTaskTest {
                 ForkedTest.class.getName(), "testSysProp"));
     }
 
+    /**
+     * Tests that in a forked mode execution of tests, when the {@code includeJUnitPlatformLibraries} attribute
+     * is set to false, then the execution of such tests fails with a classloading error for the JUnit platform
+     * classes
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testExcludeJUnitPlatformLibs() throws Exception {
+        final String targetName = "test-junit-platform-lib-excluded";
+        try {
+            buildRule.executeTarget(targetName);
+            Assert.fail(targetName + " was expected to fail since JUnit platform libraries " +
+                    "weren't included in the classpath of the forked JVM");
+        } catch (BuildException be) {
+            // expect a ClassNotFoundException for a JUnit platform class
+            final String cnfeMessage = ClassNotFoundException.class.getName() + ": org.junit.platform";
+            if (!buildRule.getFullLog().contains(cnfeMessage)) {
+                throw be;
+            }
+        }
+        final String exlusionLogMsg = "Excluding JUnit platform libraries";
+        Assert.assertTrue("JUnit platform libraries weren't excluded from classpath", buildRule.getFullLog().contains(exlusionLogMsg));
+    }
+
+    /**
+     * Tests that in a forked mode execution of tests, when the {@code includeAntRuntimeLibraries} attribute
+     * is set to false, then the execution of such tests fails with a classloading error for the Ant runtime
+     * classes
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testExcludeAntRuntimeLibs() throws Exception {
+        final String targetName = "test-junit-ant-runtime-lib-excluded";
+        try {
+            buildRule.executeTarget(targetName);
+            Assert.fail(targetName + " was expected to fail since JUnit platform libraries " +
+                    "weren't included in the classpath of the forked JVM");
+        } catch (BuildException be) {
+            // expect a Error due to missing main class (which is part of Ant runtime libraries
+            // that we excluded)
+            final String missingMainClass = "Could not find or load main class " + StandaloneLauncher.class.getName();
+            if (!buildRule.getFullLog().contains(missingMainClass)) {
+                throw be;
+            }
+        }
+        final String exlusionLogMsg = "Excluding Ant runtime libraries";
+        Assert.assertTrue("Ant runtime libraries weren't excluded from classpath", buildRule.getFullLog().contains(exlusionLogMsg));
+    }
+
+
+    /**
+     * Tests that in a forked mode execution, with {@code includeJUnitPlatformLibraries} attribute set to false
+     * and with the test classpath explicitly including JUnit platform library jars, the tests are executed successfully
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testJUnitPlatformLibsCustomLocation() throws Exception {
+        final String targetName = "test-junit-platform-lib-custom-location";
+        final Path trackerFile = setupTrackerProperty(targetName);
+        buildRule.executeTarget(targetName);
+        final String exlusionLogMsg = "Excluding JUnit platform libraries";
+        Assert.assertTrue("JUnit platform libraries weren't excluded from classpath", buildRule.getFullLog().contains(exlusionLogMsg));
+        Assert.assertTrue("JupiterSampleTest#testSucceeds was expected to succeed", verifySuccess(trackerFile,
+                JupiterSampleTest.class.getName(), "testSucceeds"));
+        Assert.assertTrue("JupiterSampleTest#testFails was expected to succeed", verifyFailed(trackerFile,
+                JupiterSampleTest.class.getName(), "testFails"));
+    }
+
     private Path setupTrackerProperty(final String targetName) {
         final String filename = targetName + "-tracker.txt";
         buildRule.getProject().setProperty(targetName + ".tracker", filename);

http://git-wip-us.apache.org/repos/asf/ant/blob/8590e153/src/tests/junit/org/example/junitlauncher/Tracker.java
----------------------------------------------------------------------
diff --git a/src/tests/junit/org/example/junitlauncher/Tracker.java b/src/tests/junit/org/example/junitlauncher/Tracker.java
index 8ef89b2..28ba1e6 100644
--- a/src/tests/junit/org/example/junitlauncher/Tracker.java
+++ b/src/tests/junit/org/example/junitlauncher/Tracker.java
@@ -110,27 +110,34 @@ public class Tracker implements TestResultFormatter {
     }
 
     public static boolean wasTestRun(final Path trackerFile, final String className) throws IOException {
-        final List<String> lines = Files.readAllLines(trackerFile);
+        final List<String> lines = readTrackerFile(trackerFile);
         return lines.contains(PREFIX_TEST_CLASS_STARTED + className);
     }
 
     public static boolean wasTestRun(final Path trackerFile, final String className, final String methodName) throws IOException {
-        final List<String> lines = Files.readAllLines(trackerFile);
+        final List<String> lines = readTrackerFile(trackerFile);
         return lines.contains(PREFIX_TEST_METHOD_STARTED + className + "#" + methodName);
     }
 
     public static boolean verifyFailed(final Path trackerFile, final String className, final String methodName) throws IOException {
-        final List<String> lines = Files.readAllLines(trackerFile);
+        final List<String> lines = readTrackerFile(trackerFile);
         return lines.contains(TestExecutionResult.Status.FAILED + ":test-method:" + className + "#" + methodName);
     }
 
     public static boolean verifySuccess(final Path trackerFile, final String className, final String methodName) throws IOException {
-        final List<String> lines = Files.readAllLines(trackerFile);
+        final List<String> lines = readTrackerFile(trackerFile);
         return lines.contains(TestExecutionResult.Status.SUCCESSFUL + ":test-method:" + className + "#" + methodName);
     }
 
     public static boolean verifySkipped(final Path trackerFile, final String className, final String methodName) throws IOException {
-        final List<String> lines = Files.readAllLines(trackerFile);
+        final List<String> lines = readTrackerFile(trackerFile);
         return lines.contains(PREFIX_TEST_METHOD_SKIPPED + className + "#" + methodName);
     }
+
+    private static List<String> readTrackerFile(final Path trackerFile) throws IOException {
+        if (!Files.isRegularFile(trackerFile)) {
+            throw new RuntimeException(trackerFile + " is either missing or not a file");
+        }
+        return Files.readAllLines(trackerFile);
+    }
 }