From 31cc48c6f70b8c24f79aa5f17f80c32f8480e2f9 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 13 Jul 2016 20:28:32 +0200 Subject: [PATCH 1/6] =?UTF-8?q?JDK9=20modules=20support=20for=20JUnit=20by?= =?UTF-8?q?=20Tom=C3=A1=C5=A1=20Zezula?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this is the combined patch or #18 which couldn't be applied via `git am` --- manual/Tasks/junit.html | 59 ++++- .../taskdefs/optional/junit/JUnitTask.java | 135 +++++++++++- .../optional/junit/JUnitTaskTest.java | 204 ++++++++++++++++++ 3 files changed, 389 insertions(+), 9 deletions(-) diff --git a/manual/Tasks/junit.html b/manual/Tasks/junit.html index 76df9ced6..9f6051217 100644 --- a/manual/Tasks/junit.html +++ b/manual/Tasks/junit.html @@ -371,6 +371,21 @@ subelement.

since Ant 1.6.

+

modulepath

+ +

The location of modules can be specified using this PATH like structure.
+The modulepath requires fork to be set to true. + +

since Ant 1.10

+ +

upgrademodulepath

+ +

The location of modules that replace upgradeable modules in the runtime image +can be specified using this PATH like structure.
+The upgrademodulepath requires fork to be set to true. + +

since Ant 1.10

+

formatter

The results of the tests can be printed in different @@ -796,7 +811,47 @@ the single <test/> will run. So only the failing test cases a The two nested formatters are for displaying (for the user) and for updating the collector class.

- - +
+    <junit fork="true"
+        jvm="${platform.java}">
+        <jvmarg value="-Xpatch:${module.name}=${build.test.classes}"/>
+        <jvmarg line="-addmods ${module.name}"/>
+        <jvmarg value="-XaddReads:${module.name}=ALL-UNNAMED"/>
+        <jvmarg value="-XaddExports:${module.name}/my.test=ALL-UNNAMED"/>
+        <classpath>
+            <pathelement path="${libs.junit}"/>
+        </classpath>
+        <modulepath>
+            <pathelement path="${modules}:${build.classes}"/>
+        </modulepath>
+        <formatter type="plain"/>
+        <test name="my.test.TestCase"/>
+    </junit>
+
+

Runs my.test.TestCase as a white-box test in the forked VM given by the platform.java property. +The junit library is a part of an unnamed module while the tested project and required modules are on the module path. The tests +do not have module-info file and are executed in the project module given by module.name property.
+The -Xpatch java option executes the tests built into ${build.test.classes} in a module given +by module.name property.
+The -addmods java option enables the tested module.
+The -XaddReads java option makes the unnamed module containing the junit readable by tested module.
+The -XaddExports java option makes the non-exported test package my.test accessible from the unnamed module containing the junit.
+

+    <junit fork="true"
+        jvm="${platform.java}">
+        <jvmarg line="-addmods ${test.module.name}"/>
+        <jvmarg value="-XaddExports:${test.module.name}/my.test=junit,ALL-UNNAMED"/>
+        <modulepath>
+            <pathelement path="${modules}:${build.classes}:${libs.junit}"/>
+        </modulepath>
+        <formatter type="plain"/>
+        <test name="my.test.TestCase"/>
+    </junit>
+
+

Runs my.test.TestCase as a black-box test in the forked VM given by the platform.java property. +The junit library is used as an automatic module. The tests module-info requires the tested module and junit.
+The -addmods java option enables the test module.
+The -XaddExports java option makes the non-exported test package my.test accessible from the junit module and Ant's test runner. +Another possibility is to export the test package in the tests module-info by exports my.test directive.
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java index 459bd3d5d..08ae61886 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java @@ -38,6 +38,7 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Vector; @@ -510,6 +511,26 @@ public class JUnitTask extends Task { return getCommandline().createBootclasspath(getProject()).createPath(); } + /** + * Add a path to the modulepath. + * + * @return created modulepath. + * @since 1.10 + */ + public Path createModulepath() { + return getCommandline().createModulepath(getProject()).createPath(); + } + + /** + * Add a path to the upgrademodulepath. + * + * @return created upgrademodulepath. + * @since 1.10 + */ + public Path createUpgrademodulepath() { + return getCommandline().createUpgrademodulepath(getProject()).createPath(); + } + /** * Adds an environment variable; used when forking. * @@ -749,7 +770,7 @@ public class JUnitTask extends Task { loader.loadClass("junit.framework.Test"); // sanity check } catch (final ClassNotFoundException e) { throw new BuildException( - "The for must include junit.jar " + "The or for must include junit.jar " + "if not in Ant's own classpath", e, task.getLocation()); } @@ -777,10 +798,14 @@ public class JUnitTask extends Task { if (splitJUnit) { final Path path = new Path(getProject()); path.add(antRuntimeClasses); - final Path extra = getCommandline().getClasspath(); + Path extra = getCommandline().getClasspath(); if (extra != null) { path.add(extra); } + extra = getCommandline().getModulepath(); + if (extra != null && !hasJunit(path)) { + path.add(expandModulePath(extra)); + } mirrorLoader = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return new SplitClassLoader(myLoader, path, getProject(), @@ -818,7 +843,7 @@ public class JUnitTask extends Task { @Override public void execute() throws BuildException { checkMethodLists(); - + checkModules(); setupJUnitDelegate(); final List testLists = new ArrayList(); @@ -1697,6 +1722,75 @@ public class JUnitTask extends Task { } } + /** + * Checks a validity of module specific options. + * @since 1.10 + */ + private void checkModules() { + if (hasPath(getCommandline().getModulepath()) || + hasPath(getCommandline().getUpgrademodulepath())) { + for (int i = 0, count = batchTests.size(); i < count; i++) { + if(!batchTests.elementAt(i).getFork()) { + throw new BuildException("The module path requires fork attribute to be set to true."); + } + } + for (int i = 0, count = tests.size(); i < count; i++) { + if (!tests.elementAt(i).getFork()) { + throw new BuildException("The module path requires fork attribute to be set to true."); + } + } + } + } + + /** + * Checks is a junit is on given path. + * @param path the {@link Path} to check + * @return true when given {@link Path} contains junit + * @since 1.10 + */ + private boolean hasJunit(final Path path) { + try (AntClassLoader loader = AntClassLoader.newAntClassLoader( + null, + getProject(), + path, + true)) { + try { + loader.loadClass("junit.framework.Test"); + return true; + } catch (final Exception ex) { + return false; + } + } + } + + /** + * Expands a module path to flat path of jars and root folders usable by classloader. + * @param modulePath to be expanded + * @return the expanded path + * @since 1.10 + */ + private Path expandModulePath(Path modulePath) { + final Path expanded = new Path(getProject()); + for (String path : modulePath.list()) { + final File modulePathEntry = getProject().resolveFile(path); + if (modulePathEntry.isDirectory() && !hasModuleInfo(modulePathEntry)) { + final File[] modules = modulePathEntry.listFiles((dir,name)->name.toLowerCase(Locale.ENGLISH).endsWith(".jar")); + if (modules != null) { + for (File module : modules) { + expanded.add(new Path(getProject(), String.format( + "%s%s%s", //NOI18N + path, + File.separator, + module.getName()))); + } + } + } else { + expanded.add(new Path(getProject(), path)); + } + } + return expanded; + } + /** * return an enumeration listing each test, then each batchtest * @return enumeration @@ -1892,16 +1986,23 @@ public class JUnitTask extends Task { */ private void createClassLoader() { final Path userClasspath = getCommandline().getClasspath(); - if (userClasspath != null) { + final Path userModulepath = getCommandline().getModulepath(); + if (userClasspath != null || userModulepath != null) { if (reloading || classLoader == null) { deleteClassLoader(); - final Path classpath = (Path) userClasspath.clone(); + final Path path = new Path(getProject()); + if (userClasspath != null) { + path.add((Path) userClasspath.clone()); + } + if (userModulepath != null && !hasJunit(path)) { + path.add(expandModulePath(userModulepath)); + } if (includeAntRuntime) { log("Implicitly adding " + antRuntimeClasses + " to CLASSPATH", Project.MSG_VERBOSE); - classpath.append(antRuntimeClasses); + path.append(antRuntimeClasses); } - classLoader = getProject().createClassLoader(classpath); + classLoader = getProject().createClassLoader(path); if (getClass().getClassLoader() != null && getClass().getClassLoader() != Project.class.getClassLoader()) { classLoader.setParent(getClass().getClassLoader()); @@ -2280,4 +2381,24 @@ public class JUnitTask extends Task { w.newLine(); s.println(text); } + + /** + * Checks if a path exists and is non empty. + * @param path to be checked + * @return true if the path is non null and non empty. + * @since 1.10 + */ + private static boolean hasPath(final Path path) { + return path != null && path.size() > 0; + } + + /** + * Checks if a given folder is an unpacked module. + * @param root the fodler to be checked + * @return true if the root is an unpacked module + * @since 1.10 + */ + private static boolean hasModuleInfo(final File root) { + return new File(root, "module-info.class").exists(); //NOI18N + } } diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java index 33fd3b053..f08860aaf 100644 --- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java +++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java @@ -27,18 +27,33 @@ import static org.apache.tools.ant.AntAssert.assertNotContains; import static org.apache.tools.ant.AntAssert.assertContains; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileReader; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; +import java.util.TreeSet; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; +import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildFileRule; +import org.apache.tools.ant.MagicNames; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.launcher.CommandLauncher; +import org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.ForkMode; +import org.apache.tools.ant.types.Path; import org.apache.tools.ant.util.JavaEnvUtils; +import org.apache.tools.ant.util.LoaderUtils; import org.junit.Assume; import org.junit.Before; import org.junit.Rule; @@ -395,4 +410,193 @@ public class JUnitTaskTest { } + @Test(expected = BuildException.class) + public void testModulePathNeedsFork() throws Exception { + final Project project = new Project(); + project.init(); + JUnitTask task = new JUnitTask(); + task.setProject(project); + final Path p = new Path(project); + p.setPath("modules"); + task.createModulepath().add(p); + task.addTest(new JUnitTest("org.apache.tools.ant.taskdefs.optional.junit.TestTest")); + task.execute(); + } + + @Test(expected = BuildException.class) + public void testUpgradeModulePathNeedsFork() throws Exception { + final Project project = new Project(); + project.init(); + JUnitTask task = new JUnitTask(); + task.setProject(project); + final Path p = new Path(project); + p.setPath("modules"); + task.createUpgrademodulepath().add(p); + task.addTest(new JUnitTest("org.apache.tools.ant.taskdefs.optional.junit.TestTest")); + task.execute(); + } + + @Test + public void testJunitOnCpArguments() throws Exception { + final File tmp = new File(System.getProperty("java.io.tmpdir")); //NOI18N + final File workDir = new File(tmp, String.format("%s_testJCP%d", //NOI18N + getClass().getName(), + System.currentTimeMillis()/1000)); + workDir.mkdirs(); + try { + final File modulesDir = new File(workDir,"modules"); //NOI18N + modulesDir.mkdirs(); + + final Project project = new Project(); + project.init(); + project.setBaseDir(workDir); + final MockCommandLauncher mockProcLauncher = new MockCommandLauncher(); + project.addReference( + MagicNames.ANT_VM_LAUNCHER_REF_ID, + mockProcLauncher); + JUnitTask task = new JUnitTask(); + task.setDir(workDir); + task.setFork(true); + task.setProject(project); + final File junit = LoaderUtils.getResourceSource( + JUnitTask.class.getClassLoader(), + "junit/framework/Test.class"); //NOI18N + final Path cp = new Path(project); + cp.setPath(junit.getAbsolutePath()); + task.createClasspath().add(cp); + final Path mp = new Path(project); + mp.setPath(modulesDir.getName()); + task.createModulepath().add(mp); + task.addTest(new JUnitTest("org.apache.tools.ant.taskdefs.optional.junit.TestTest")); + task.execute(); + assertNotNull(mockProcLauncher.cmd); + String resCp = null; + String resMp = null; + Set resExports = new TreeSet<>(); + for (int i = 1; i< mockProcLauncher.cmd.length; i++) { + if ("-classpath".equals(mockProcLauncher.cmd[i])) { //NOI18N + resCp = mockProcLauncher.cmd[++i]; + } else if ("-modulepath".equals(mockProcLauncher.cmd[i])) { //NOI18N + resMp = mockProcLauncher.cmd[++i]; + } else if (mockProcLauncher.cmd[i].startsWith("-XaddExports:")) { //NOI18N + resExports.add(mockProcLauncher.cmd[i]); + } else if (JUnitTestRunner.class.getName().equals(mockProcLauncher.cmd[i])) { + break; + } + } + assertTrue("No exports", resExports.isEmpty()); + assertEquals("Expected classpath", cp.toString(), resCp); + assertEquals("Expected modulepath", mp.toString(), resMp); + } finally { + delete(workDir); + } + } + + @Test + public void testJunitOnMpArguments() throws Exception { + final File tmp = new File(System.getProperty("java.io.tmpdir")); //NOI18N + final File workDir = new File(tmp, String.format("%s_testJMP%d", //NOI18N + getClass().getName(), + System.currentTimeMillis()/1000)); + workDir.mkdirs(); + try { + final File modulesDir = new File(workDir,"modules"); //NOI18N + modulesDir.mkdirs(); + + final Project project = new Project(); + project.init(); + project.setBaseDir(workDir); + final MockCommandLauncher mockProcLauncher = new MockCommandLauncher(); + project.addReference( + MagicNames.ANT_VM_LAUNCHER_REF_ID, + mockProcLauncher); + JUnitTask task = new JUnitTask(); + task.setDir(workDir); + task.setFork(true); + task.setProject(project); + final File junit = LoaderUtils.getResourceSource( + JUnitTask.class.getClassLoader(), + "junit/framework/Test.class"); //NOI18N + final Path mp = new Path(project); + mp.add(new Path(project, junit.getAbsolutePath())); + mp.add(new Path(project, modulesDir.getName())); + task.createModulepath().add(mp); + task.addTest(new JUnitTest("org.apache.tools.ant.taskdefs.optional.junit.TestTest")); //NOI18N + task.execute(); + assertNotNull(mockProcLauncher.cmd); + String resCp = null; + String resMp = null; + Set resExports = new TreeSet<>(); + for (int i = 1; i< mockProcLauncher.cmd.length; i++) { + if ("-classpath".equals(mockProcLauncher.cmd[i])) { //NOI18N + resCp = mockProcLauncher.cmd[++i]; + } else if ("-modulepath".equals(mockProcLauncher.cmd[i])) { //NOI18N + resMp = mockProcLauncher.cmd[++i]; + } else if (mockProcLauncher.cmd[i].startsWith("-XaddExports:")) { //NOI18N + resExports.add(mockProcLauncher.cmd[i]); + } else if (JUnitTestRunner.class.getName().equals(mockProcLauncher.cmd[i])) { + break; + } + } + assertTrue("No exports", resExports.isEmpty()); + assertNull("No classpath", resCp); + assertEquals("Expected modulepath", mp.toString(), resMp); + } finally { + delete(workDir); + } + } + + private void delete(File f) { + if (f.isDirectory()) { + final File[] clds = f.listFiles(); + if (clds != null) { + for (File cld : clds) { + delete(cld); + } + } + } + f.delete(); + } + + private static final class MockCommandLauncher extends CommandLauncher { + private String[] cmd; + + @Override + public Process exec(Project project, String[] cmd, String[] env, File workingDir) throws IOException { + this.cmd = Arrays.copyOf(cmd, cmd.length); + return new MockProcess(); + } + + private static class MockProcess extends Process { + + @Override + public OutputStream getOutputStream() { + return new ByteArrayOutputStream(); + } + + @Override + public InputStream getInputStream() { + return new ByteArrayInputStream(new byte[0]); + } + + @Override + public InputStream getErrorStream() { + return new ByteArrayInputStream(new byte[0]); + } + + @Override + public int waitFor() throws InterruptedException { + return exitValue(); + } + + @Override + public int exitValue() { + return 0; + } + + @Override + public void destroy() { + } + } + } } From 49e5b77cfe664bf0107f90de0a285fd3c273e864 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 13 Jul 2016 20:30:24 +0200 Subject: [PATCH 2/6] linefeeds --- .../optional/junit/JUnitTaskTest.java | 1204 ++++++++--------- 1 file changed, 602 insertions(+), 602 deletions(-) diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java index f08860aaf..5284d567c 100644 --- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java +++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java @@ -1,602 +1,602 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.tools.ant.taskdefs.optional.junit; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import static org.apache.tools.ant.AntAssert.assertNotContains; -import static org.apache.tools.ant.AntAssert.assertContains; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Arrays; -import java.util.Collections; -import java.util.Set; -import java.util.TreeSet; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathFactory; -import org.apache.tools.ant.BuildException; - -import org.apache.tools.ant.BuildFileRule; -import org.apache.tools.ant.MagicNames; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.taskdefs.launcher.CommandLauncher; -import org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.ForkMode; -import org.apache.tools.ant.types.Path; -import org.apache.tools.ant.util.JavaEnvUtils; -import org.apache.tools.ant.util.LoaderUtils; -import org.junit.Assume; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.w3c.dom.Document; -import org.w3c.dom.Node; - -public class JUnitTaskTest { - - @Rule - public BuildFileRule buildRule = new BuildFileRule(); - - /** - * The JUnit setup method. - */ - @Before - public void setUp() { - buildRule.configureProject("src/etc/testcases/taskdefs/optional/junit.xml"); - } - - @Test - public void testCrash() { - buildRule.executeTarget("crash"); - assertEquals("true", buildRule.getProject().getProperty("crashed")); - } - - @Test - public void testNoCrash() { - buildRule.executeTarget("nocrash"); - assertNull(buildRule.getProject().getProperty("crashed")); - } - - @Test - public void testTimeout() { - buildRule.executeTarget("timeout"); - assertEquals("true", buildRule.getProject().getProperty("timeout")); - } - - @Test - public void testNoTimeout() { - buildRule.executeTarget("notimeout"); - assertNull(buildRule.getProject().getProperty("timeout")); - } - - @Test - public void testNonForkedCapture() throws IOException { - buildRule.executeTarget("capture"); - assertNoPrint(buildRule.getLog(), "log"); - assertNoPrint(buildRule.getFullLog(), "debug log"); - } - - @Test - public void testForkedCapture() throws IOException { - buildRule.getProject().setProperty("fork", "true"); - testNonForkedCapture(); - // those would fail because of the way BuildFileRule captures output - assertNoPrint(buildRule.getOutput(), "output"); - assertNoPrint(buildRule.getError(), "error output"); - assertOutput(); - } - - @Test - public void testBatchTestForkOnceToDir() { - assertResultFilesExist("testBatchTestForkOnceToDir", ".xml"); - } - - /** Bugzilla Report 32973 */ - @Test - public void testBatchTestForkOnceExtension() { - assertResultFilesExist("testBatchTestForkOnceExtension", ".foo"); - } - - - /* Bugzilla Report 42984 */ - //TODO This scenario works from command line, but not from JUnit ... - // Running these steps from the junit.xml-directory work - // $ ant -f junit.xml failureRecorder.prepare - // $ ant -f junit.xml failureRecorder.runtest - // $ ant -f junit.xml failureRecorder.runtest - // $ ant -f junit.xml failureRecorder.fixing - // $ ant -f junit.xml failureRecorder.runtest - // $ ant -f junit.xml failureRecorder.runtest - // But running the JUnit testcase fails in 4th run. - @Test - public void testFailureRecorder() { - if (JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_5)) { - try { - Class clazz =Class.forName("junit.framework.JUnit4TestAdapter"); - Assume.assumeFalse("Skipping test since it fails with JUnit 4", clazz != null); - } catch (ClassNotFoundException e) { - // OK, this is JUnit3, can run test - } - } - - File testDir = new File(buildRule.getOutputDir(), "out"); - File collectorFile = new File(buildRule.getOutputDir(), - "out/FailedTests.java"); - - // ensure that there is a clean test environment - assertFalse("Test directory '" + testDir.getAbsolutePath() - + "' must not exist before the test preparation.", - testDir.exists()); - assertFalse("The collector file '" - + collectorFile.getAbsolutePath() - + "'must not exist before the test preparation.", - collectorFile.exists()); - - - // prepare the test environment - buildRule.executeTarget("failureRecorder.prepare"); - assertTrue("Test directory '" + testDir.getAbsolutePath() - + "' was not created.", testDir.exists()); - assertTrue("There should be one class.", - (new File(testDir, "A.class")).exists()); - assertFalse("The collector file '" - + collectorFile.getAbsolutePath() - + "' should not exist before the 1st run.", - collectorFile.exists()); - - - // 1st junit run: should do all tests - failing and not failing tests - buildRule.executeTarget("failureRecorder.runtest"); - assertTrue("The collector file '" + collectorFile.getAbsolutePath() - + "' should exist after the 1st run.", - collectorFile.exists()); - // the passing test cases - buildRule.executeTarget("A.test01"); - assertContains("1st run: should run A.test01", buildRule.getOutput()); - buildRule.executeTarget("B.test05"); - assertContains("1st run: should run B.test05", buildRule.getOutput()); - buildRule.executeTarget("B.test06"); - assertContains("1st run: should run B.test06", buildRule.getOutput()); - buildRule.executeTarget("C.test07"); - assertContains("1st run: should run C.test07", buildRule.getOutput()); - buildRule.executeTarget("C.test08"); - assertContains("1st run: should run C.test08", buildRule.getOutput()); - buildRule.executeTarget("C.test09"); - assertContains("1st run: should run C.test09", buildRule.getOutput()); - // the failing test cases - buildRule.executeTarget("A.test02"); - assertContains("1st run: should run A.test02", buildRule.getOutput()); - buildRule.executeTarget("A.test03"); - assertContains("1st run: should run A.test03", buildRule.getOutput()); - buildRule.executeTarget("B.test04"); - assertContains("1st run: should run B.test04", buildRule.getOutput()); - buildRule.executeTarget("D.test10"); - assertContains("1st run: should run D.test10", buildRule.getOutput()); - - - // 2nd junit run: should do only failing tests - buildRule.executeTarget("failureRecorder.runtest"); - assertTrue("The collector file '" + collectorFile.getAbsolutePath() - + "' should exist after the 2nd run.", - collectorFile.exists()); - // the passing test cases - buildRule.executeTarget("A.test01"); - assertNotContains("2nd run: should not run A.test01", buildRule.getOutput()); - buildRule.executeTarget("B.test05"); - assertNotContains("2nd run: should not run A.test05", buildRule.getOutput()); - buildRule.executeTarget("B.test06"); - assertNotContains("2nd run: should not run B.test06", buildRule.getOutput()); - buildRule.executeTarget("C.test07"); - assertNotContains("2nd run: should not run C.test07", buildRule.getOutput()); - buildRule.executeTarget("C.test08"); - assertNotContains("2nd run: should not run C.test08", buildRule.getOutput()); - buildRule.executeTarget("C.test09"); - assertNotContains("2nd run: should not run C.test09", buildRule.getOutput()); - // the failing test cases - buildRule.executeTarget("A.test02"); - assertContains("2nd run: should run A.test02", buildRule.getOutput()); - buildRule.executeTarget("A.test03"); - assertContains("2nd run: should run A.test03", buildRule.getOutput()); - buildRule.executeTarget("B.test04"); - assertContains("2nd run: should run B.test04", buildRule.getOutput()); - buildRule.executeTarget("D.test10"); - assertContains("2nd run: should run D.test10", buildRule.getOutput()); - - - // "fix" errors in class A - buildRule.executeTarget("failureRecorder.fixing"); - - // 3rd run: four running tests with two errors - buildRule.executeTarget("failureRecorder.runtest"); - assertTrue("The collector file '" + collectorFile.getAbsolutePath() - + "' should exist after the 3rd run.", - collectorFile.exists()); - buildRule.executeTarget("A.test02"); - assertContains("3rd run: should run A.test02", buildRule.getOutput()); - buildRule.executeTarget("A.test03"); - assertContains("3rd run: should run A.test03", buildRule.getOutput()); - buildRule.executeTarget("B.test04"); - assertContains("3rd run: should run B.test04", buildRule.getOutput()); - buildRule.executeTarget("D.test10"); - assertContains("3rd run: should run D.test10", buildRule.getOutput()); - - - // 4rd run: two running tests with errors - buildRule.executeTarget("failureRecorder.runtest"); - assertTrue("The collector file '" + collectorFile.getAbsolutePath() - + "' should exist after the 4th run.", - collectorFile.exists()); - //TODO: these two statements fail - //buildRule.executeTarget("A.test02");assertNotContains("4th run: should not run A.test02", buildRule.getOutput()); - //buildRule.executeTarget("A.test03");assertNotContains("4th run: should not run A.test03", buildRule.getOutput()); - buildRule.executeTarget("B.test04"); - assertContains("4th run: should run B.test04", buildRule.getOutput()); - buildRule.executeTarget("D.test10"); - assertContains("4th run: should run D.test10", buildRule.getOutput()); - - } - - @Test - public void testBatchTestForkOnceCustomFormatter() { - assertResultFilesExist("testBatchTestForkOnceCustomFormatter", "foo"); - } - - // Bugzilla Issue 45411 - @Test - public void testMultilineAssertsNoFork() { - buildRule.executeTarget("testMultilineAssertsNoFork"); - assertNotContains("messaged up", buildRule.getLog()); - assertNotContains("crashed)", buildRule.getLog()); - } - - // Bugzilla Issue 45411 - @Test - public void testMultilineAssertsFork() { - buildRule.executeTarget("testMultilineAssertsFork"); - assertNotContains("messaged up", buildRule.getLog()); - assertNotContains("crashed)", buildRule.getLog()); - } - - private void assertResultFilesExist(String target, String extension) { - buildRule.executeTarget(target); - assertResultFileExists("JUnitClassLoader", extension); - assertResultFileExists("JUnitTestRunner", extension); - assertResultFileExists("JUnitVersionHelper", extension); - } - - private void assertResultFileExists(String classNameFragment, String ext) { - assertTrue("result for " + classNameFragment + "Test" + ext + " exists", - - new File(buildRule.getOutputDir(), "TEST-org.apache.tools.ant." - + "taskdefs.optional.junit." - + classNameFragment + "Test" + ext) - .exists()); - } - - private void assertNoPrint(String result, String where) { - assertNotContains(where + " '" + result + "' must not contain print statement", - "print to System.", result); - } - - private void assertOutput() throws IOException { - FileReader inner = new FileReader(new File(buildRule.getOutputDir(), - "testlog.txt")); - BufferedReader reader = new BufferedReader(inner); - try { - String line = reader.readLine(); - assertEquals("Testsuite: org.apache.tools.ant.taskdefs.optional.junit.Printer", - line); - line = reader.readLine(); - assertNotNull(line); - assertTrue(line.startsWith("Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed:")); - line = reader.readLine(); - assertEquals("------------- Standard Output ---------------", - line); - assertPrint(reader.readLine(), "static", "out"); - assertPrint(reader.readLine(), "constructor", "out"); - assertPrint(reader.readLine(), "method", "out"); - line = reader.readLine(); - assertEquals("------------- ---------------- ---------------", - line); - line = reader.readLine(); - assertEquals("------------- Standard Error -----------------", - line); - assertPrint(reader.readLine(), "static", "err"); - assertPrint(reader.readLine(), "constructor", "err"); - assertPrint(reader.readLine(), "method", "err"); - line = reader.readLine(); - assertEquals("------------- ---------------- ---------------", - line); - line = reader.readLine(); - assertEquals("", line); - line = reader.readLine(); - assertNotNull(line); - assertTrue(line.startsWith("Testcase: testNoCrash took ")); - } finally { - inner.close(); - } - } - - private void assertPrint(String line, String from, String to) { - String search = from + " print to System." + to; - assertEquals(search, line); - } - - @Test - public void testJUnit4Skip() throws Exception { - buildRule.executeTarget("testSkippableTests"); - - DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); - Document doc = dBuilder.parse(new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit4Skippable.xml")); - - assertEquals("Incorrect number of nodes created", 8, doc.getElementsByTagName("testcase").getLength()); - - XPathFactory factory = XPathFactory.newInstance(); - XPath xpath = factory.newXPath(); - - assertEquals("Incorrect number of skipped tests in header", 4, Integer.parseInt(xpath.compile("//testsuite/@skipped").evaluate(doc))); - assertEquals("Incorrect number of error tests in header", 1, Integer.parseInt(xpath.compile("//testsuite/@errors").evaluate(doc))); - assertEquals("Incorrect number of failure tests in header", 2, Integer.parseInt(xpath.compile("//testsuite/@failures").evaluate(doc))); - assertEquals("Incorrect number of tests in header", 8, Integer.parseInt(xpath.compile("//testsuite/@tests").evaluate(doc))); - - - assertEquals("Incorrect ignore message on explicit ignored test", "Please don't ignore me!", xpath.compile("//testsuite/testcase[@name='explicitIgnoreTest']/skipped/@message").evaluate(doc)); - assertEquals("No message should be set on Ignored tests with no Ignore annotation text", 0, ((Node)xpath.compile("//testsuite/testcase[@name='explicitlyIgnoreTestNoMessage']/skipped").evaluate(doc, XPathConstants.NODE)).getAttributes().getLength()); - assertEquals("Incorrect ignore message on implicit ignored test", "This test will be ignored", xpath.compile("//testsuite/testcase[@name='implicitlyIgnoreTest']/skipped/@message").evaluate(doc)); - assertNotNull("Implicit ignore test should have an ignore element", xpath.compile("//testsuite/testcase[@name='implicitlyIgnoreTestNoMessage']/skipped").evaluate(doc, XPathConstants.NODE)); - - } - - @Test - public void testTestMethods() throws Exception { - buildRule.executeTarget("testTestMethods"); - } - - @Test - public void testNonTestsSkipped() throws Exception { - - buildRule.executeTarget("testNonTests"); - assertFalse("Test result should not exist as test was skipped - TEST-org.example.junit.NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.NonTestMissed.xml").exists()); - assertFalse("Test result should not exist as test was skipped - TEST-org.example.junit.JUnit3NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3TestMissed.xml").exists()); - assertFalse("Test result should not exist as test was skipped - TEST-org.example.junit.AbstractTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractTestMissed.xml").exists()); - assertFalse("Test result should not exist as test was skipped - TEST-org.example.junit.AbstractJUnit3TestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractJUnit3TestMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractTestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractTestNotMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractJUnit3TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractJUnit3TestNotMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.TestNotMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.JUnit3TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3TestNotMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.TestWithSuiteNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.TestWithSuiteNotMissed.xml").exists()); - - buildRule.executeTarget("testNonTestsRun"); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.NonTestMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.JUnit3NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3NonTestMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.TestNotMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.JUnit3TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3TestNotMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractTestMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractTestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractTestNotMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractJUnit3TestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractJUnit3TestMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.JUnit3NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3NonTestMissed.xml").exists()); - assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.TestWithSuiteNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.TestWithSuiteNotMissed.xml").exists()); - - - } - - @Test(expected = BuildException.class) - public void testModulePathNeedsFork() throws Exception { - final Project project = new Project(); - project.init(); - JUnitTask task = new JUnitTask(); - task.setProject(project); - final Path p = new Path(project); - p.setPath("modules"); - task.createModulepath().add(p); - task.addTest(new JUnitTest("org.apache.tools.ant.taskdefs.optional.junit.TestTest")); - task.execute(); - } - - @Test(expected = BuildException.class) - public void testUpgradeModulePathNeedsFork() throws Exception { - final Project project = new Project(); - project.init(); - JUnitTask task = new JUnitTask(); - task.setProject(project); - final Path p = new Path(project); - p.setPath("modules"); - task.createUpgrademodulepath().add(p); - task.addTest(new JUnitTest("org.apache.tools.ant.taskdefs.optional.junit.TestTest")); - task.execute(); - } - - @Test - public void testJunitOnCpArguments() throws Exception { - final File tmp = new File(System.getProperty("java.io.tmpdir")); //NOI18N - final File workDir = new File(tmp, String.format("%s_testJCP%d", //NOI18N - getClass().getName(), - System.currentTimeMillis()/1000)); - workDir.mkdirs(); - try { - final File modulesDir = new File(workDir,"modules"); //NOI18N - modulesDir.mkdirs(); - - final Project project = new Project(); - project.init(); - project.setBaseDir(workDir); - final MockCommandLauncher mockProcLauncher = new MockCommandLauncher(); - project.addReference( - MagicNames.ANT_VM_LAUNCHER_REF_ID, - mockProcLauncher); - JUnitTask task = new JUnitTask(); - task.setDir(workDir); - task.setFork(true); - task.setProject(project); - final File junit = LoaderUtils.getResourceSource( - JUnitTask.class.getClassLoader(), - "junit/framework/Test.class"); //NOI18N - final Path cp = new Path(project); - cp.setPath(junit.getAbsolutePath()); - task.createClasspath().add(cp); - final Path mp = new Path(project); - mp.setPath(modulesDir.getName()); - task.createModulepath().add(mp); - task.addTest(new JUnitTest("org.apache.tools.ant.taskdefs.optional.junit.TestTest")); - task.execute(); - assertNotNull(mockProcLauncher.cmd); - String resCp = null; - String resMp = null; - Set resExports = new TreeSet<>(); - for (int i = 1; i< mockProcLauncher.cmd.length; i++) { - if ("-classpath".equals(mockProcLauncher.cmd[i])) { //NOI18N - resCp = mockProcLauncher.cmd[++i]; - } else if ("-modulepath".equals(mockProcLauncher.cmd[i])) { //NOI18N - resMp = mockProcLauncher.cmd[++i]; - } else if (mockProcLauncher.cmd[i].startsWith("-XaddExports:")) { //NOI18N - resExports.add(mockProcLauncher.cmd[i]); - } else if (JUnitTestRunner.class.getName().equals(mockProcLauncher.cmd[i])) { - break; - } - } - assertTrue("No exports", resExports.isEmpty()); - assertEquals("Expected classpath", cp.toString(), resCp); - assertEquals("Expected modulepath", mp.toString(), resMp); - } finally { - delete(workDir); - } - } - - @Test - public void testJunitOnMpArguments() throws Exception { - final File tmp = new File(System.getProperty("java.io.tmpdir")); //NOI18N - final File workDir = new File(tmp, String.format("%s_testJMP%d", //NOI18N - getClass().getName(), - System.currentTimeMillis()/1000)); - workDir.mkdirs(); - try { - final File modulesDir = new File(workDir,"modules"); //NOI18N - modulesDir.mkdirs(); - - final Project project = new Project(); - project.init(); - project.setBaseDir(workDir); - final MockCommandLauncher mockProcLauncher = new MockCommandLauncher(); - project.addReference( - MagicNames.ANT_VM_LAUNCHER_REF_ID, - mockProcLauncher); - JUnitTask task = new JUnitTask(); - task.setDir(workDir); - task.setFork(true); - task.setProject(project); - final File junit = LoaderUtils.getResourceSource( - JUnitTask.class.getClassLoader(), - "junit/framework/Test.class"); //NOI18N - final Path mp = new Path(project); - mp.add(new Path(project, junit.getAbsolutePath())); - mp.add(new Path(project, modulesDir.getName())); - task.createModulepath().add(mp); - task.addTest(new JUnitTest("org.apache.tools.ant.taskdefs.optional.junit.TestTest")); //NOI18N - task.execute(); - assertNotNull(mockProcLauncher.cmd); - String resCp = null; - String resMp = null; - Set resExports = new TreeSet<>(); - for (int i = 1; i< mockProcLauncher.cmd.length; i++) { - if ("-classpath".equals(mockProcLauncher.cmd[i])) { //NOI18N - resCp = mockProcLauncher.cmd[++i]; - } else if ("-modulepath".equals(mockProcLauncher.cmd[i])) { //NOI18N - resMp = mockProcLauncher.cmd[++i]; - } else if (mockProcLauncher.cmd[i].startsWith("-XaddExports:")) { //NOI18N - resExports.add(mockProcLauncher.cmd[i]); - } else if (JUnitTestRunner.class.getName().equals(mockProcLauncher.cmd[i])) { - break; - } - } - assertTrue("No exports", resExports.isEmpty()); - assertNull("No classpath", resCp); - assertEquals("Expected modulepath", mp.toString(), resMp); - } finally { - delete(workDir); - } - } - - private void delete(File f) { - if (f.isDirectory()) { - final File[] clds = f.listFiles(); - if (clds != null) { - for (File cld : clds) { - delete(cld); - } - } - } - f.delete(); - } - - private static final class MockCommandLauncher extends CommandLauncher { - private String[] cmd; - - @Override - public Process exec(Project project, String[] cmd, String[] env, File workingDir) throws IOException { - this.cmd = Arrays.copyOf(cmd, cmd.length); - return new MockProcess(); - } - - private static class MockProcess extends Process { - - @Override - public OutputStream getOutputStream() { - return new ByteArrayOutputStream(); - } - - @Override - public InputStream getInputStream() { - return new ByteArrayInputStream(new byte[0]); - } - - @Override - public InputStream getErrorStream() { - return new ByteArrayInputStream(new byte[0]); - } - - @Override - public int waitFor() throws InterruptedException { - return exitValue(); - } - - @Override - public int exitValue() { - return 0; - } - - @Override - public void destroy() { - } - } - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.tools.ant.taskdefs.optional.junit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import static org.apache.tools.ant.AntAssert.assertNotContains; +import static org.apache.tools.ant.AntAssert.assertContains; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; +import java.util.TreeSet; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; +import org.apache.tools.ant.BuildException; + +import org.apache.tools.ant.BuildFileRule; +import org.apache.tools.ant.MagicNames; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.launcher.CommandLauncher; +import org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.ForkMode; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.JavaEnvUtils; +import org.apache.tools.ant.util.LoaderUtils; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +public class JUnitTaskTest { + + @Rule + public BuildFileRule buildRule = new BuildFileRule(); + + /** + * The JUnit setup method. + */ + @Before + public void setUp() { + buildRule.configureProject("src/etc/testcases/taskdefs/optional/junit.xml"); + } + + @Test + public void testCrash() { + buildRule.executeTarget("crash"); + assertEquals("true", buildRule.getProject().getProperty("crashed")); + } + + @Test + public void testNoCrash() { + buildRule.executeTarget("nocrash"); + assertNull(buildRule.getProject().getProperty("crashed")); + } + + @Test + public void testTimeout() { + buildRule.executeTarget("timeout"); + assertEquals("true", buildRule.getProject().getProperty("timeout")); + } + + @Test + public void testNoTimeout() { + buildRule.executeTarget("notimeout"); + assertNull(buildRule.getProject().getProperty("timeout")); + } + + @Test + public void testNonForkedCapture() throws IOException { + buildRule.executeTarget("capture"); + assertNoPrint(buildRule.getLog(), "log"); + assertNoPrint(buildRule.getFullLog(), "debug log"); + } + + @Test + public void testForkedCapture() throws IOException { + buildRule.getProject().setProperty("fork", "true"); + testNonForkedCapture(); + // those would fail because of the way BuildFileRule captures output + assertNoPrint(buildRule.getOutput(), "output"); + assertNoPrint(buildRule.getError(), "error output"); + assertOutput(); + } + + @Test + public void testBatchTestForkOnceToDir() { + assertResultFilesExist("testBatchTestForkOnceToDir", ".xml"); + } + + /** Bugzilla Report 32973 */ + @Test + public void testBatchTestForkOnceExtension() { + assertResultFilesExist("testBatchTestForkOnceExtension", ".foo"); + } + + + /* Bugzilla Report 42984 */ + //TODO This scenario works from command line, but not from JUnit ... + // Running these steps from the junit.xml-directory work + // $ ant -f junit.xml failureRecorder.prepare + // $ ant -f junit.xml failureRecorder.runtest + // $ ant -f junit.xml failureRecorder.runtest + // $ ant -f junit.xml failureRecorder.fixing + // $ ant -f junit.xml failureRecorder.runtest + // $ ant -f junit.xml failureRecorder.runtest + // But running the JUnit testcase fails in 4th run. + @Test + public void testFailureRecorder() { + if (JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_5)) { + try { + Class clazz =Class.forName("junit.framework.JUnit4TestAdapter"); + Assume.assumeFalse("Skipping test since it fails with JUnit 4", clazz != null); + } catch (ClassNotFoundException e) { + // OK, this is JUnit3, can run test + } + } + + File testDir = new File(buildRule.getOutputDir(), "out"); + File collectorFile = new File(buildRule.getOutputDir(), + "out/FailedTests.java"); + + // ensure that there is a clean test environment + assertFalse("Test directory '" + testDir.getAbsolutePath() + + "' must not exist before the test preparation.", + testDir.exists()); + assertFalse("The collector file '" + + collectorFile.getAbsolutePath() + + "'must not exist before the test preparation.", + collectorFile.exists()); + + + // prepare the test environment + buildRule.executeTarget("failureRecorder.prepare"); + assertTrue("Test directory '" + testDir.getAbsolutePath() + + "' was not created.", testDir.exists()); + assertTrue("There should be one class.", + (new File(testDir, "A.class")).exists()); + assertFalse("The collector file '" + + collectorFile.getAbsolutePath() + + "' should not exist before the 1st run.", + collectorFile.exists()); + + + // 1st junit run: should do all tests - failing and not failing tests + buildRule.executeTarget("failureRecorder.runtest"); + assertTrue("The collector file '" + collectorFile.getAbsolutePath() + + "' should exist after the 1st run.", + collectorFile.exists()); + // the passing test cases + buildRule.executeTarget("A.test01"); + assertContains("1st run: should run A.test01", buildRule.getOutput()); + buildRule.executeTarget("B.test05"); + assertContains("1st run: should run B.test05", buildRule.getOutput()); + buildRule.executeTarget("B.test06"); + assertContains("1st run: should run B.test06", buildRule.getOutput()); + buildRule.executeTarget("C.test07"); + assertContains("1st run: should run C.test07", buildRule.getOutput()); + buildRule.executeTarget("C.test08"); + assertContains("1st run: should run C.test08", buildRule.getOutput()); + buildRule.executeTarget("C.test09"); + assertContains("1st run: should run C.test09", buildRule.getOutput()); + // the failing test cases + buildRule.executeTarget("A.test02"); + assertContains("1st run: should run A.test02", buildRule.getOutput()); + buildRule.executeTarget("A.test03"); + assertContains("1st run: should run A.test03", buildRule.getOutput()); + buildRule.executeTarget("B.test04"); + assertContains("1st run: should run B.test04", buildRule.getOutput()); + buildRule.executeTarget("D.test10"); + assertContains("1st run: should run D.test10", buildRule.getOutput()); + + + // 2nd junit run: should do only failing tests + buildRule.executeTarget("failureRecorder.runtest"); + assertTrue("The collector file '" + collectorFile.getAbsolutePath() + + "' should exist after the 2nd run.", + collectorFile.exists()); + // the passing test cases + buildRule.executeTarget("A.test01"); + assertNotContains("2nd run: should not run A.test01", buildRule.getOutput()); + buildRule.executeTarget("B.test05"); + assertNotContains("2nd run: should not run A.test05", buildRule.getOutput()); + buildRule.executeTarget("B.test06"); + assertNotContains("2nd run: should not run B.test06", buildRule.getOutput()); + buildRule.executeTarget("C.test07"); + assertNotContains("2nd run: should not run C.test07", buildRule.getOutput()); + buildRule.executeTarget("C.test08"); + assertNotContains("2nd run: should not run C.test08", buildRule.getOutput()); + buildRule.executeTarget("C.test09"); + assertNotContains("2nd run: should not run C.test09", buildRule.getOutput()); + // the failing test cases + buildRule.executeTarget("A.test02"); + assertContains("2nd run: should run A.test02", buildRule.getOutput()); + buildRule.executeTarget("A.test03"); + assertContains("2nd run: should run A.test03", buildRule.getOutput()); + buildRule.executeTarget("B.test04"); + assertContains("2nd run: should run B.test04", buildRule.getOutput()); + buildRule.executeTarget("D.test10"); + assertContains("2nd run: should run D.test10", buildRule.getOutput()); + + + // "fix" errors in class A + buildRule.executeTarget("failureRecorder.fixing"); + + // 3rd run: four running tests with two errors + buildRule.executeTarget("failureRecorder.runtest"); + assertTrue("The collector file '" + collectorFile.getAbsolutePath() + + "' should exist after the 3rd run.", + collectorFile.exists()); + buildRule.executeTarget("A.test02"); + assertContains("3rd run: should run A.test02", buildRule.getOutput()); + buildRule.executeTarget("A.test03"); + assertContains("3rd run: should run A.test03", buildRule.getOutput()); + buildRule.executeTarget("B.test04"); + assertContains("3rd run: should run B.test04", buildRule.getOutput()); + buildRule.executeTarget("D.test10"); + assertContains("3rd run: should run D.test10", buildRule.getOutput()); + + + // 4rd run: two running tests with errors + buildRule.executeTarget("failureRecorder.runtest"); + assertTrue("The collector file '" + collectorFile.getAbsolutePath() + + "' should exist after the 4th run.", + collectorFile.exists()); + //TODO: these two statements fail + //buildRule.executeTarget("A.test02");assertNotContains("4th run: should not run A.test02", buildRule.getOutput()); + //buildRule.executeTarget("A.test03");assertNotContains("4th run: should not run A.test03", buildRule.getOutput()); + buildRule.executeTarget("B.test04"); + assertContains("4th run: should run B.test04", buildRule.getOutput()); + buildRule.executeTarget("D.test10"); + assertContains("4th run: should run D.test10", buildRule.getOutput()); + + } + + @Test + public void testBatchTestForkOnceCustomFormatter() { + assertResultFilesExist("testBatchTestForkOnceCustomFormatter", "foo"); + } + + // Bugzilla Issue 45411 + @Test + public void testMultilineAssertsNoFork() { + buildRule.executeTarget("testMultilineAssertsNoFork"); + assertNotContains("messaged up", buildRule.getLog()); + assertNotContains("crashed)", buildRule.getLog()); + } + + // Bugzilla Issue 45411 + @Test + public void testMultilineAssertsFork() { + buildRule.executeTarget("testMultilineAssertsFork"); + assertNotContains("messaged up", buildRule.getLog()); + assertNotContains("crashed)", buildRule.getLog()); + } + + private void assertResultFilesExist(String target, String extension) { + buildRule.executeTarget(target); + assertResultFileExists("JUnitClassLoader", extension); + assertResultFileExists("JUnitTestRunner", extension); + assertResultFileExists("JUnitVersionHelper", extension); + } + + private void assertResultFileExists(String classNameFragment, String ext) { + assertTrue("result for " + classNameFragment + "Test" + ext + " exists", + + new File(buildRule.getOutputDir(), "TEST-org.apache.tools.ant." + + "taskdefs.optional.junit." + + classNameFragment + "Test" + ext) + .exists()); + } + + private void assertNoPrint(String result, String where) { + assertNotContains(where + " '" + result + "' must not contain print statement", + "print to System.", result); + } + + private void assertOutput() throws IOException { + FileReader inner = new FileReader(new File(buildRule.getOutputDir(), + "testlog.txt")); + BufferedReader reader = new BufferedReader(inner); + try { + String line = reader.readLine(); + assertEquals("Testsuite: org.apache.tools.ant.taskdefs.optional.junit.Printer", + line); + line = reader.readLine(); + assertNotNull(line); + assertTrue(line.startsWith("Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed:")); + line = reader.readLine(); + assertEquals("------------- Standard Output ---------------", + line); + assertPrint(reader.readLine(), "static", "out"); + assertPrint(reader.readLine(), "constructor", "out"); + assertPrint(reader.readLine(), "method", "out"); + line = reader.readLine(); + assertEquals("------------- ---------------- ---------------", + line); + line = reader.readLine(); + assertEquals("------------- Standard Error -----------------", + line); + assertPrint(reader.readLine(), "static", "err"); + assertPrint(reader.readLine(), "constructor", "err"); + assertPrint(reader.readLine(), "method", "err"); + line = reader.readLine(); + assertEquals("------------- ---------------- ---------------", + line); + line = reader.readLine(); + assertEquals("", line); + line = reader.readLine(); + assertNotNull(line); + assertTrue(line.startsWith("Testcase: testNoCrash took ")); + } finally { + inner.close(); + } + } + + private void assertPrint(String line, String from, String to) { + String search = from + " print to System." + to; + assertEquals(search, line); + } + + @Test + public void testJUnit4Skip() throws Exception { + buildRule.executeTarget("testSkippableTests"); + + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit4Skippable.xml")); + + assertEquals("Incorrect number of nodes created", 8, doc.getElementsByTagName("testcase").getLength()); + + XPathFactory factory = XPathFactory.newInstance(); + XPath xpath = factory.newXPath(); + + assertEquals("Incorrect number of skipped tests in header", 4, Integer.parseInt(xpath.compile("//testsuite/@skipped").evaluate(doc))); + assertEquals("Incorrect number of error tests in header", 1, Integer.parseInt(xpath.compile("//testsuite/@errors").evaluate(doc))); + assertEquals("Incorrect number of failure tests in header", 2, Integer.parseInt(xpath.compile("//testsuite/@failures").evaluate(doc))); + assertEquals("Incorrect number of tests in header", 8, Integer.parseInt(xpath.compile("//testsuite/@tests").evaluate(doc))); + + + assertEquals("Incorrect ignore message on explicit ignored test", "Please don't ignore me!", xpath.compile("//testsuite/testcase[@name='explicitIgnoreTest']/skipped/@message").evaluate(doc)); + assertEquals("No message should be set on Ignored tests with no Ignore annotation text", 0, ((Node)xpath.compile("//testsuite/testcase[@name='explicitlyIgnoreTestNoMessage']/skipped").evaluate(doc, XPathConstants.NODE)).getAttributes().getLength()); + assertEquals("Incorrect ignore message on implicit ignored test", "This test will be ignored", xpath.compile("//testsuite/testcase[@name='implicitlyIgnoreTest']/skipped/@message").evaluate(doc)); + assertNotNull("Implicit ignore test should have an ignore element", xpath.compile("//testsuite/testcase[@name='implicitlyIgnoreTestNoMessage']/skipped").evaluate(doc, XPathConstants.NODE)); + + } + + @Test + public void testTestMethods() throws Exception { + buildRule.executeTarget("testTestMethods"); + } + + @Test + public void testNonTestsSkipped() throws Exception { + + buildRule.executeTarget("testNonTests"); + assertFalse("Test result should not exist as test was skipped - TEST-org.example.junit.NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.NonTestMissed.xml").exists()); + assertFalse("Test result should not exist as test was skipped - TEST-org.example.junit.JUnit3NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3TestMissed.xml").exists()); + assertFalse("Test result should not exist as test was skipped - TEST-org.example.junit.AbstractTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractTestMissed.xml").exists()); + assertFalse("Test result should not exist as test was skipped - TEST-org.example.junit.AbstractJUnit3TestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractJUnit3TestMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractTestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractTestNotMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractJUnit3TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractJUnit3TestNotMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.TestNotMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.JUnit3TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3TestNotMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.TestWithSuiteNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.TestWithSuiteNotMissed.xml").exists()); + + buildRule.executeTarget("testNonTestsRun"); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.NonTestMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.JUnit3NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3NonTestMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.TestNotMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.JUnit3TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3TestNotMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractTestMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractTestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractTestNotMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractJUnit3TestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractJUnit3TestMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.JUnit3NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3NonTestMissed.xml").exists()); + assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.TestWithSuiteNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.TestWithSuiteNotMissed.xml").exists()); + + + } + + @Test(expected = BuildException.class) + public void testModulePathNeedsFork() throws Exception { + final Project project = new Project(); + project.init(); + JUnitTask task = new JUnitTask(); + task.setProject(project); + final Path p = new Path(project); + p.setPath("modules"); + task.createModulepath().add(p); + task.addTest(new JUnitTest("org.apache.tools.ant.taskdefs.optional.junit.TestTest")); + task.execute(); + } + + @Test(expected = BuildException.class) + public void testUpgradeModulePathNeedsFork() throws Exception { + final Project project = new Project(); + project.init(); + JUnitTask task = new JUnitTask(); + task.setProject(project); + final Path p = new Path(project); + p.setPath("modules"); + task.createUpgrademodulepath().add(p); + task.addTest(new JUnitTest("org.apache.tools.ant.taskdefs.optional.junit.TestTest")); + task.execute(); + } + + @Test + public void testJunitOnCpArguments() throws Exception { + final File tmp = new File(System.getProperty("java.io.tmpdir")); //NOI18N + final File workDir = new File(tmp, String.format("%s_testJCP%d", //NOI18N + getClass().getName(), + System.currentTimeMillis()/1000)); + workDir.mkdirs(); + try { + final File modulesDir = new File(workDir,"modules"); //NOI18N + modulesDir.mkdirs(); + + final Project project = new Project(); + project.init(); + project.setBaseDir(workDir); + final MockCommandLauncher mockProcLauncher = new MockCommandLauncher(); + project.addReference( + MagicNames.ANT_VM_LAUNCHER_REF_ID, + mockProcLauncher); + JUnitTask task = new JUnitTask(); + task.setDir(workDir); + task.setFork(true); + task.setProject(project); + final File junit = LoaderUtils.getResourceSource( + JUnitTask.class.getClassLoader(), + "junit/framework/Test.class"); //NOI18N + final Path cp = new Path(project); + cp.setPath(junit.getAbsolutePath()); + task.createClasspath().add(cp); + final Path mp = new Path(project); + mp.setPath(modulesDir.getName()); + task.createModulepath().add(mp); + task.addTest(new JUnitTest("org.apache.tools.ant.taskdefs.optional.junit.TestTest")); + task.execute(); + assertNotNull(mockProcLauncher.cmd); + String resCp = null; + String resMp = null; + Set resExports = new TreeSet<>(); + for (int i = 1; i< mockProcLauncher.cmd.length; i++) { + if ("-classpath".equals(mockProcLauncher.cmd[i])) { //NOI18N + resCp = mockProcLauncher.cmd[++i]; + } else if ("-modulepath".equals(mockProcLauncher.cmd[i])) { //NOI18N + resMp = mockProcLauncher.cmd[++i]; + } else if (mockProcLauncher.cmd[i].startsWith("-XaddExports:")) { //NOI18N + resExports.add(mockProcLauncher.cmd[i]); + } else if (JUnitTestRunner.class.getName().equals(mockProcLauncher.cmd[i])) { + break; + } + } + assertTrue("No exports", resExports.isEmpty()); + assertEquals("Expected classpath", cp.toString(), resCp); + assertEquals("Expected modulepath", mp.toString(), resMp); + } finally { + delete(workDir); + } + } + + @Test + public void testJunitOnMpArguments() throws Exception { + final File tmp = new File(System.getProperty("java.io.tmpdir")); //NOI18N + final File workDir = new File(tmp, String.format("%s_testJMP%d", //NOI18N + getClass().getName(), + System.currentTimeMillis()/1000)); + workDir.mkdirs(); + try { + final File modulesDir = new File(workDir,"modules"); //NOI18N + modulesDir.mkdirs(); + + final Project project = new Project(); + project.init(); + project.setBaseDir(workDir); + final MockCommandLauncher mockProcLauncher = new MockCommandLauncher(); + project.addReference( + MagicNames.ANT_VM_LAUNCHER_REF_ID, + mockProcLauncher); + JUnitTask task = new JUnitTask(); + task.setDir(workDir); + task.setFork(true); + task.setProject(project); + final File junit = LoaderUtils.getResourceSource( + JUnitTask.class.getClassLoader(), + "junit/framework/Test.class"); //NOI18N + final Path mp = new Path(project); + mp.add(new Path(project, junit.getAbsolutePath())); + mp.add(new Path(project, modulesDir.getName())); + task.createModulepath().add(mp); + task.addTest(new JUnitTest("org.apache.tools.ant.taskdefs.optional.junit.TestTest")); //NOI18N + task.execute(); + assertNotNull(mockProcLauncher.cmd); + String resCp = null; + String resMp = null; + Set resExports = new TreeSet<>(); + for (int i = 1; i< mockProcLauncher.cmd.length; i++) { + if ("-classpath".equals(mockProcLauncher.cmd[i])) { //NOI18N + resCp = mockProcLauncher.cmd[++i]; + } else if ("-modulepath".equals(mockProcLauncher.cmd[i])) { //NOI18N + resMp = mockProcLauncher.cmd[++i]; + } else if (mockProcLauncher.cmd[i].startsWith("-XaddExports:")) { //NOI18N + resExports.add(mockProcLauncher.cmd[i]); + } else if (JUnitTestRunner.class.getName().equals(mockProcLauncher.cmd[i])) { + break; + } + } + assertTrue("No exports", resExports.isEmpty()); + assertNull("No classpath", resCp); + assertEquals("Expected modulepath", mp.toString(), resMp); + } finally { + delete(workDir); + } + } + + private void delete(File f) { + if (f.isDirectory()) { + final File[] clds = f.listFiles(); + if (clds != null) { + for (File cld : clds) { + delete(cld); + } + } + } + f.delete(); + } + + private static final class MockCommandLauncher extends CommandLauncher { + private String[] cmd; + + @Override + public Process exec(Project project, String[] cmd, String[] env, File workingDir) throws IOException { + this.cmd = Arrays.copyOf(cmd, cmd.length); + return new MockProcess(); + } + + private static class MockProcess extends Process { + + @Override + public OutputStream getOutputStream() { + return new ByteArrayOutputStream(); + } + + @Override + public InputStream getInputStream() { + return new ByteArrayInputStream(new byte[0]); + } + + @Override + public InputStream getErrorStream() { + return new ByteArrayInputStream(new byte[0]); + } + + @Override + public int waitFor() throws InterruptedException { + return exitValue(); + } + + @Override + public int exitValue() { + return 0; + } + + @Override + public void destroy() { + } + } + } +} From 3af6fcc3262d9c0b5b9d32d0c560faed06d6b1aa Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Sun, 11 Sep 2016 12:12:24 +0200 Subject: [PATCH 3/6] fix version numbers --- manual/Tasks/junit.html | 4 ++-- .../ant/taskdefs/optional/junit/JUnitTask.java | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manual/Tasks/junit.html b/manual/Tasks/junit.html index 9f6051217..9a4022e53 100644 --- a/manual/Tasks/junit.html +++ b/manual/Tasks/junit.html @@ -376,7 +376,7 @@ subelement.

The location of modules can be specified using this PATH like structure.
The modulepath requires fork to be set to true. -

since Ant 1.10

+

since Ant 1.9.8

upgrademodulepath

@@ -384,7 +384,7 @@ The modulepath requires fork to be set to true. can be specified using this PATH like structure.
The upgrademodulepath requires fork to be set to true. -

since Ant 1.10

+

since Ant 1.9.8

formatter

diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java index 08ae61886..14f9aa4a2 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java @@ -515,7 +515,7 @@ public class JUnitTask extends Task { * Add a path to the modulepath. * * @return created modulepath. - * @since 1.10 + * @since 1.9.8 */ public Path createModulepath() { return getCommandline().createModulepath(getProject()).createPath(); @@ -525,7 +525,7 @@ public class JUnitTask extends Task { * Add a path to the upgrademodulepath. * * @return created upgrademodulepath. - * @since 1.10 + * @since 1.9.8 */ public Path createUpgrademodulepath() { return getCommandline().createUpgrademodulepath(getProject()).createPath(); @@ -1724,7 +1724,7 @@ public class JUnitTask extends Task { /** * Checks a validity of module specific options. - * @since 1.10 + * @since 1.9.8 */ private void checkModules() { if (hasPath(getCommandline().getModulepath()) || @@ -1746,7 +1746,7 @@ public class JUnitTask extends Task { * Checks is a junit is on given path. * @param path the {@link Path} to check * @return true when given {@link Path} contains junit - * @since 1.10 + * @since 1.9.8 */ private boolean hasJunit(final Path path) { try (AntClassLoader loader = AntClassLoader.newAntClassLoader( @@ -1767,7 +1767,7 @@ public class JUnitTask extends Task { * Expands a module path to flat path of jars and root folders usable by classloader. * @param modulePath to be expanded * @return the expanded path - * @since 1.10 + * @since 1.9.8 */ private Path expandModulePath(Path modulePath) { final Path expanded = new Path(getProject()); @@ -2386,7 +2386,7 @@ public class JUnitTask extends Task { * Checks if a path exists and is non empty. * @param path to be checked * @return true if the path is non null and non empty. - * @since 1.10 + * @since 1.9.8 */ private static boolean hasPath(final Path path) { return path != null && path.size() > 0; @@ -2396,7 +2396,7 @@ public class JUnitTask extends Task { * Checks if a given folder is an unpacked module. * @param root the fodler to be checked * @return true if the root is an unpacked module - * @since 1.10 + * @since 1.9.8 */ private static boolean hasModuleInfo(final File root) { return new File(root, "module-info.class").exists(); //NOI18N From a4575c442c573b76a5de73135e6f1f28427cbee0 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Wed, 13 Jul 2016 20:33:16 +0200 Subject: [PATCH 4/6] record JDK9 module support for junit closes #18 --- WHATSNEW | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WHATSNEW b/WHATSNEW index 7a9e070f7..34a0c275b 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -62,6 +62,9 @@ Other changes: * now supports compression via the optional compressed attribute. Bugzilla Report 47552 + * now supports JDK9 modules + Github Pull Request #18 + * a new implementation "builtin" has been added to and is the default when running on JDK9+ since the tool itself has been removed from the JDK. From 5bbc7b6187cdb38100b3a4f9fbecb704a92bc4be Mon Sep 17 00:00:00 2001 From: Tomas Zezula Date: Fri, 9 Sep 2016 13:38:55 +0200 Subject: [PATCH 5/6] JDK9 command line options updated to JEP 293 --- manual/Tasks/junit.html | 24 +++++++++---------- .../compilers/DefaultCompilerAdapter.java | 4 ++-- .../tools/ant/types/CommandlineJava.java | 4 ++-- .../compilers/DefaultCompilerAdapterTest.java | 14 +++++------ .../optional/junit/JUnitTaskTest.java | 12 +++++----- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/manual/Tasks/junit.html b/manual/Tasks/junit.html index 9a4022e53..a6879a89b 100644 --- a/manual/Tasks/junit.html +++ b/manual/Tasks/junit.html @@ -814,10 +814,10 @@ class.
     <junit fork="true"
         jvm="${platform.java}">
-        <jvmarg value="-Xpatch:${module.name}=${build.test.classes}"/>
-        <jvmarg line="-addmods ${module.name}"/>
-        <jvmarg value="-XaddReads:${module.name}=ALL-UNNAMED"/>
-        <jvmarg value="-XaddExports:${module.name}/my.test=ALL-UNNAMED"/>
+        <jvmarg line="--patch-module ${module.name}=${build.test.classes}"/>
+        <jvmarg line="--add-modules ${module.name}"/>
+        <jvmarg line="--add-reads ${module.name}=ALL-UNNAMED"/>
+        <jvmarg line="--add-exports ${module.name}/my.test=ALL-UNNAMED"/>
         <classpath>
             <pathelement path="${libs.junit}"/>
         </classpath>
@@ -831,16 +831,16 @@ class.
 

Runs my.test.TestCase as a white-box test in the forked VM given by the platform.java property. The junit library is a part of an unnamed module while the tested project and required modules are on the module path. The tests do not have module-info file and are executed in the project module given by module.name property.
-The -Xpatch java option executes the tests built into ${build.test.classes} in a module given +The --patch-module java option executes the tests built into ${build.test.classes} in a module given by module.name property.
-The -addmods java option enables the tested module.
-The -XaddReads java option makes the unnamed module containing the junit readable by tested module.
-The -XaddExports java option makes the non-exported test package my.test accessible from the unnamed module containing the junit.
+The --add-modules java option enables the tested module.
+The --add-reads java option makes the unnamed module containing the junit readable by tested module.
+The --add-exports java option makes the non-exported test package my.test accessible from the unnamed module containing the junit.

     <junit fork="true"
         jvm="${platform.java}">
-        <jvmarg line="-addmods ${test.module.name}"/>
-        <jvmarg value="-XaddExports:${test.module.name}/my.test=junit,ALL-UNNAMED"/>
+        <jvmarg line="--add-modules ${test.module.name}"/>
+        <jvmarg line="--add-exports ${test.module.name}/my.test=junit,ALL-UNNAMED"/>
         <modulepath>
             <pathelement path="${modules}:${build.classes}:${libs.junit}"/>
         </modulepath>
@@ -850,8 +850,8 @@ The -XaddExports java option makes the non-exported test package 
 

Runs my.test.TestCase as a black-box test in the forked VM given by the platform.java property. The junit library is used as an automatic module. The tests module-info requires the tested module and junit.
-The -addmods java option enables the test module.
-The -XaddExports java option makes the non-exported test package my.test accessible from the junit module and Ant's test runner. +The --add-modules java option enables the test module.
+The --add-exports java option makes the non-exported test package my.test accessible from the junit module and Ant's test runner. Another possibility is to export the test package in the tests module-info by exports my.test directive.
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java b/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java index 5f1f1f78d..f13b3e5fa 100644 --- a/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java +++ b/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java @@ -401,12 +401,12 @@ public abstract class DefaultCompilerAdapter } final Path msp = getModulesourcepath(); if (msp.size() > 0) { - cmd.createArgument().setValue("-modulesourcepath"); + cmd.createArgument().setValue("--module-source-path"); cmd.createArgument().setPath(msp); } final Path mp = getModulepath(); if (mp.size() > 0) { - cmd.createArgument().setValue("-modulepath"); + cmd.createArgument().setValue("--module-path"); cmd.createArgument().setPath(mp); } final Path ump = getUpgrademodulepath(); diff --git a/src/main/org/apache/tools/ant/types/CommandlineJava.java b/src/main/org/apache/tools/ant/types/CommandlineJava.java index 5bf91c71f..d811633e3 100644 --- a/src/main/org/apache/tools/ant/types/CommandlineJava.java +++ b/src/main/org/apache/tools/ant/types/CommandlineJava.java @@ -520,13 +520,13 @@ public class CommandlineJava implements Cloneable { } //module path if (haveModulepath()) { - listIterator.add("-modulepath"); + listIterator.add("--module-path"); listIterator.add( modulepath.concatSystemClasspath("ignore").toString()); } //upgrade module path if (haveUpgrademodulepath()) { - listIterator.add("-upgrademodulepath"); + listIterator.add("--upgrade-module-path"); listIterator.add( upgrademodulepath.concatSystemClasspath("ignore").toString()); } diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapterTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapterTest.java index 3064876df..7ed5b3fab 100644 --- a/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapterTest.java +++ b/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapterTest.java @@ -249,13 +249,13 @@ public class DefaultCompilerAdapterTest { Assert.assertNotNull(cmd[0]); final List cmdLine = Arrays.asList(cmd[0].getCommandline()); //No modulesourcepath - assertEquals(-1, cmdLine.indexOf("-modulesourcepath")); + assertEquals(-1, cmdLine.indexOf("--module-source-path")); //The -sourcepath has to be followed by src int index = cmdLine.indexOf("-sourcepath"); Assert.assertTrue(index != -1 && index < cmdLine.size() - 1); assertEquals(src.getAbsolutePath(), cmdLine.get(index + 1)); - //The -modulepath has to be followed by modules - index = cmdLine.indexOf("-modulepath"); + //The --module-path has to be followed by modules + index = cmdLine.indexOf("--module-path"); Assert.assertTrue(index != -1 && index < cmdLine.size() - 1); assertEquals(modules.getAbsolutePath(), cmdLine.get(index + 1)); //J1.java & J2.java has to be in files list @@ -308,8 +308,8 @@ public class DefaultCompilerAdapterTest { final List cmdLine = Arrays.asList(cmd[0].getCommandline()); //No sourcepath assertEquals(-1, cmdLine.indexOf("-sourcepath")); - //The -modulesourcepath has to be followed by the pattern - int index = cmdLine.indexOf("-modulesourcepath"); + //The --module-source-path has to be followed by the pattern + int index = cmdLine.indexOf("--module-source-path"); Assert.assertTrue(index != -1 && index < cmdLine.size() - 1); String expectedModSrcPath = String.format("%s/%s", workDir.getAbsolutePath(), @@ -317,8 +317,8 @@ public class DefaultCompilerAdapterTest { .replace('/', File.separatorChar) .replace('\\', File.separatorChar); assertEquals(expectedModSrcPath, cmdLine.get(index + 1)); - //The -modulepath has to be followed by modules - index = cmdLine.indexOf("-modulepath"); + //The --module-path has to be followed by modules + index = cmdLine.indexOf("--module-path"); Assert.assertTrue(index != -1 && index < cmdLine.size() - 1); assertEquals(modules.getAbsolutePath(), cmdLine.get(index + 1)); //J1.java, J2.java & J3.java has to be in files list diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java index 5284d567c..d817cb10d 100644 --- a/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java +++ b/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java @@ -476,10 +476,10 @@ public class JUnitTaskTest { for (int i = 1; i< mockProcLauncher.cmd.length; i++) { if ("-classpath".equals(mockProcLauncher.cmd[i])) { //NOI18N resCp = mockProcLauncher.cmd[++i]; - } else if ("-modulepath".equals(mockProcLauncher.cmd[i])) { //NOI18N + } else if ("--module-path".equals(mockProcLauncher.cmd[i])) { //NOI18N resMp = mockProcLauncher.cmd[++i]; - } else if (mockProcLauncher.cmd[i].startsWith("-XaddExports:")) { //NOI18N - resExports.add(mockProcLauncher.cmd[i]); + } else if (mockProcLauncher.cmd[i].equals("--add-exports")) { //NOI18N + resExports.add(mockProcLauncher.cmd[++i]); } else if (JUnitTestRunner.class.getName().equals(mockProcLauncher.cmd[i])) { break; } @@ -530,10 +530,10 @@ public class JUnitTaskTest { for (int i = 1; i< mockProcLauncher.cmd.length; i++) { if ("-classpath".equals(mockProcLauncher.cmd[i])) { //NOI18N resCp = mockProcLauncher.cmd[++i]; - } else if ("-modulepath".equals(mockProcLauncher.cmd[i])) { //NOI18N + } else if ("--module-path".equals(mockProcLauncher.cmd[i])) { //NOI18N resMp = mockProcLauncher.cmd[++i]; - } else if (mockProcLauncher.cmd[i].startsWith("-XaddExports:")) { //NOI18N - resExports.add(mockProcLauncher.cmd[i]); + } else if (mockProcLauncher.cmd[i].equals("--add-exports")) { //NOI18N + resExports.add(mockProcLauncher.cmd[++i]); } else if (JUnitTestRunner.class.getName().equals(mockProcLauncher.cmd[i])) { break; } From bda488eafe2a5812f77acd6f0134cba5c8a32912 Mon Sep 17 00:00:00 2001 From: Tomas Zezula Date: Fri, 9 Sep 2016 19:29:25 +0200 Subject: [PATCH 6/6] Fixed forgotten -upgrademodulepath in the DefaultCompilerAdapter. --- .../tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java b/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java index f13b3e5fa..827b40206 100644 --- a/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java +++ b/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java @@ -411,7 +411,7 @@ public abstract class DefaultCompilerAdapter } final Path ump = getUpgrademodulepath(); if (ump.size() > 0) { - cmd.createArgument().setValue("-upgrademodulepath"); + cmd.createArgument().setValue("--upgrade-module-path"); cmd.createArgument().setPath(ump); } if (attributes.getNativeHeaderDir() != null) {