- 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 featuremaster
@@ -43,7 +43,6 @@ | |||||
<path id="test.classpath"> | <path id="test.classpath"> | ||||
<pathelement location="${build.classes.dir}"/> | <pathelement location="${build.classes.dir}"/> | ||||
<path refid="junit.platform.classpath"/> | |||||
<path refid="junit.engine.vintage.classpath"/> | <path refid="junit.engine.vintage.classpath"/> | ||||
<path refid="junit.engine.jupiter.classpath"/> | <path refid="junit.engine.jupiter.classpath"/> | ||||
</path> | </path> | ||||
@@ -166,5 +165,50 @@ | |||||
</test> | </test> | ||||
</junitlauncher> | </junitlauncher> | ||||
</target> | </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> | </project> | ||||
@@ -41,7 +41,7 @@ import java.io.File; | |||||
public class ForkDefinition { | public class ForkDefinition { | ||||
private boolean includeAntRuntimeLibraries = true; | private boolean includeAntRuntimeLibraries = true; | ||||
private boolean includeJunitPlatformLibraries = true; | |||||
private boolean includeJUnitPlatformLibraries = true; | |||||
private final CommandlineJava commandLineJava; | private final CommandlineJava commandLineJava; | ||||
private final Environment env = new Environment(); | private final Environment env = new Environment(); | ||||
@@ -69,6 +69,14 @@ public class ForkDefinition { | |||||
return this.timeout; | 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() { | public Commandline.Argument createJvmArg() { | ||||
return this.commandLineJava.createVmArgument(); | return this.commandLineJava.createVmArgument(); | ||||
} | } | ||||
@@ -121,19 +129,23 @@ public class ForkDefinition { | |||||
addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(AntMain.class)); | addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(AntMain.class)); | ||||
addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(Task.class)); | addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(Task.class)); | ||||
addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(JUnitLauncherTask.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 | // platform-engine | ||||
addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(TestEngine.class)); | addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(TestEngine.class)); | ||||
// platform-launcher | // platform-launcher | ||||
addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(LauncherFactory.class)); | addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(LauncherFactory.class)); | ||||
// platform-commons | // platform-commons | ||||
addAntRuntimeResourceSource(antRuntimeResourceSources, task, toResourceName(Testable.class)); | 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); | final Path classPath = cmdLine.createClasspath(project); | ||||
classPath.createPath().append(antRuntimeResourceSources); | classPath.createPath().append(antRuntimeResourceSources); | ||||
return cmdLine; | return cmdLine; | ||||
} | } | ||||
@@ -98,7 +98,6 @@ public class StandaloneLauncher { | |||||
i = i + numArgsConsumed; | i = i + numArgsConsumed; | ||||
} | } | ||||
launchDefinition.setTestExecutionContext(forkedExecution); | launchDefinition.setTestExecutionContext(forkedExecution); | ||||
final LauncherSupport launcherSupport = new LauncherSupport(launchDefinition); | final LauncherSupport launcherSupport = new LauncherSupport(launchDefinition); | ||||
try { | try { | ||||
@@ -106,8 +105,8 @@ public class StandaloneLauncher { | |||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
if (launcherSupport.hasTestFailures()) { | if (launcherSupport.hasTestFailures()) { | ||||
System.exit(Constants.FORK_EXIT_CODE_TESTS_FAILED); | System.exit(Constants.FORK_EXIT_CODE_TESTS_FAILED); | ||||
throw t; | |||||
} | } | ||||
throw t; | |||||
} | } | ||||
if (launcherSupport.hasTestFailures()) { | if (launcherSupport.hasTestFailures()) { | ||||
System.exit(Constants.FORK_EXIT_CODE_TESTS_FAILED); | System.exit(Constants.FORK_EXIT_CODE_TESTS_FAILED); | ||||
@@ -187,6 +187,77 @@ public class JUnitLauncherTaskTest { | |||||
ForkedTest.class.getName(), "testSysProp")); | 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) { | private Path setupTrackerProperty(final String targetName) { | ||||
final String filename = targetName + "-tracker.txt"; | final String filename = targetName + "-tracker.txt"; | ||||
buildRule.getProject().setProperty(targetName + ".tracker", filename); | buildRule.getProject().setProperty(targetName + ".tracker", filename); | ||||
@@ -110,27 +110,34 @@ public class Tracker implements TestResultFormatter { | |||||
} | } | ||||
public static boolean wasTestRun(final Path trackerFile, final String className) throws IOException { | 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); | return lines.contains(PREFIX_TEST_CLASS_STARTED + className); | ||||
} | } | ||||
public static boolean wasTestRun(final Path trackerFile, final String className, final String methodName) throws IOException { | 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); | return lines.contains(PREFIX_TEST_METHOD_STARTED + className + "#" + methodName); | ||||
} | } | ||||
public static boolean verifyFailed(final Path trackerFile, final String className, final String methodName) throws IOException { | 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); | 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 { | 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); | 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 { | 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); | 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); | |||||
} | |||||
} | } |