- 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"> | |||
<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> | |||
@@ -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; | |||
} | |||
@@ -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); | |||
@@ -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); | |||
@@ -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); | |||
} | |||
} |