[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user jaikiran closed the pull request at: https://github.com/apache/ant/pull/60 --- - To unsubscribe, e-mail: dev-unsubscr...@ant.apache.org For additional commands, e-mail: dev-h...@ant.apache.org
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user jaikiran commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r172044906 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java --- @@ -0,0 +1,508 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.FileUtils; +import org.apache.tools.ant.util.KeepAliveOutputStream; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * An Ant {@link Task} responsible for launching the JUnit platform for running tests. + * This requires a minimum of JUnit 5, since that's the version in which the JUnit platform launcher + * APIs were introduced. + * + * This task in itself doesn't run the JUnit tests, instead the sole responsibility of + * this task is to setup the JUnit platform launcher, build requests, launch those requests and then parse the + * result of the execution to present in a way that's been configured on this Ant task. + * + * + * Furthermore, this task allows users control over which classes to select for passing on to the JUnit 5 + * platform for test execution. It however, is solely the JUnit 5 platform, backed by test engines that + * decide and execute the tests. + * + * @see https://junit.org/junit5/;>JUnit 5 documentation for more details + * on how JUnit manages the platform and the test engines. + */ +public class JUnitLauncherTask extends Task { + +private Path classPath; +private boolean haltOnFailure; +private String failureProperty; +private final List tests = new ArrayList<>(); +private final List listeners = new ArrayList<>(); + +public JUnitLauncherTask() { +} + +@Override +public void execute() throws BuildException { +final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader(); +try { +final ClassLoader executionCL = createClassLoaderForTestExecution(); +Thread.currentThread().setContextClassLoader(executionCL); +final Launcher launcher = LauncherFactory.create(); +final List requests = buildTestRequests(); +for (final TestRequest testRequest : requests) { +try { +final TestDefinition test = testRequest.getOwner(); +final LauncherDiscoveryRequest request = testRequest.getDiscoveryRequest().build(); +final List testExecutionListeners = new ArrayList<>(); +// a listener that we always put at the front of list of listeners +// for this request. +final Listener firstListener = new Listener(); +// we always enroll the summary generating listener, to the request, so that we +// get to use some of the details of the summary for our further decision making +testExecutionListeners.add(firstListener); + testExecutionListeners.addAll(getListeners(testRequest, executionCL)); +final PrintStream originalSysOut = System.out; +final PrintStream originalSysErr = System.err; +try { +firstListener.switchedSysOutHandle = trySwitchSysOut(testRequest); +firstListener.switchedSysErrHandle = trySwitchSysErr(testRequest); +launcher.execute(request,
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user jaikiran commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r172044717 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/AbstractJUnitResultFormatter.java --- @@ -0,0 +1,295 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.util.FileUtils; +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.Closeable; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.Writer; +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; +import java.util.Optional; + +/** + * Contains some common behaviour that's used by our internal {@link TestResultFormatter}s + */ +abstract class AbstractJUnitResultFormatter implements TestResultFormatter { + + +protected static String NEW_LINE = System.getProperty("line.separator"); +protected Task task; + +private SysOutErrContentStore sysOutStore; +private SysOutErrContentStore sysErrStore; + +@Override +public void sysOutAvailable(final byte[] data) { +if (this.sysOutStore == null) { +this.sysOutStore = new SysOutErrContentStore(true); +} +try { +this.sysOutStore.store(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void sysErrAvailable(final byte[] data) { +if (this.sysErrStore == null) { +this.sysErrStore = new SysOutErrContentStore(false); +} +try { +this.sysErrStore.store(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void setExecutingTask(final Task task) { +this.task = task; +} + +/** + * @return Returns true if there's any stdout data, that was generated during the + * tests, is available for use. Else returns false. + */ +boolean hasSysOut() { +return this.sysOutStore != null && this.sysOutStore.hasData(); +} + +/** + * @return Returns true if there's any stderr data, that was generated during the + * tests, is available for use. Else returns false. + */ +boolean hasSysErr() { +return this.sysErrStore != null && this.sysErrStore.hasData(); +} + +/** + * @return Returns a {@link Reader} for reading any stdout data that was generated + * during the test execution. It is expected that the {@link #hasSysOut()} be first + * called to see if any such data is available and only if there is, then this method + * be called + * @throws IOException If there's any I/O problem while creating the {@link Reader} + */ +Reader getSysOutReader() throws IOException { +return this.sysOutStore.getReader(); +} + +/** + * @return Returns a {@link Reader} for reading any stderr data that was generated + * during the test execution. It is expected that the {@link #hasSysErr()} be first + * called to see if any such data is available and only if there is, then this method + * be called + * @throws IOException If there's any I/O problem while creating the {@link Reader} + */ +Reader getSysErrReader() throws IOException { +return this.sysErrStore.getReader(); +} + +/** + * Writes out any stdout data that was generated during the + * test execution. If there was no such data then this method just returns. + * + * @param writer The {@link Writer} to use. Cannot be null. + * @throws IOException If any I/O problem occurs during writing the data + */ +void writeSysOut(final Writer writer) throws IOException { +Objects.requireNonNull(writer, "Writer cannot be null"); +this.writeFrom(this.sysOutStore, writer); +} + +/** + * Writes out any stderr data that was generated during the + * test execution. If there was no such data then this
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user jaikiran commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r172044665 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/AbstractJUnitResultFormatter.java --- @@ -0,0 +1,295 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.util.FileUtils; +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.Closeable; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.Writer; +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; +import java.util.Optional; + +/** + * Contains some common behaviour that's used by our internal {@link TestResultFormatter}s + */ +abstract class AbstractJUnitResultFormatter implements TestResultFormatter { + + +protected static String NEW_LINE = System.getProperty("line.separator"); +protected Task task; + +private SysOutErrContentStore sysOutStore; +private SysOutErrContentStore sysErrStore; + +@Override +public void sysOutAvailable(final byte[] data) { +if (this.sysOutStore == null) { +this.sysOutStore = new SysOutErrContentStore(true); +} +try { +this.sysOutStore.store(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void sysErrAvailable(final byte[] data) { +if (this.sysErrStore == null) { +this.sysErrStore = new SysOutErrContentStore(false); +} +try { +this.sysErrStore.store(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void setExecutingTask(final Task task) { +this.task = task; +} + +/** + * @return Returns true if there's any stdout data, that was generated during the + * tests, is available for use. Else returns false. + */ +boolean hasSysOut() { +return this.sysOutStore != null && this.sysOutStore.hasData(); +} + +/** + * @return Returns true if there's any stderr data, that was generated during the + * tests, is available for use. Else returns false. + */ +boolean hasSysErr() { +return this.sysErrStore != null && this.sysErrStore.hasData(); +} + +/** + * @return Returns a {@link Reader} for reading any stdout data that was generated + * during the test execution. It is expected that the {@link #hasSysOut()} be first + * called to see if any such data is available and only if there is, then this method + * be called + * @throws IOException If there's any I/O problem while creating the {@link Reader} + */ +Reader getSysOutReader() throws IOException { +return this.sysOutStore.getReader(); +} + +/** + * @return Returns a {@link Reader} for reading any stderr data that was generated + * during the test execution. It is expected that the {@link #hasSysErr()} be first + * called to see if any such data is available and only if there is, then this method + * be called + * @throws IOException If there's any I/O problem while creating the {@link Reader} + */ +Reader getSysErrReader() throws IOException { +return this.sysErrStore.getReader(); +} + +/** + * Writes out any stdout data that was generated during the + * test execution. If there was no such data then this method just returns. + * + * @param writer The {@link Writer} to use. Cannot be null. + * @throws IOException If any I/O problem occurs during writing the data + */ +void writeSysOut(final Writer writer) throws IOException { +Objects.requireNonNull(writer, "Writer cannot be null"); +this.writeFrom(this.sysOutStore, writer); +} + +/** + * Writes out any stderr data that was generated during the + * test execution. If there was no such data then this
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user jaikiran commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r172044509 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/AbstractJUnitResultFormatter.java --- @@ -0,0 +1,295 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.util.FileUtils; +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.Closeable; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.Writer; +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; +import java.util.Optional; + +/** + * Contains some common behaviour that's used by our internal {@link TestResultFormatter}s + */ +abstract class AbstractJUnitResultFormatter implements TestResultFormatter { + + +protected static String NEW_LINE = System.getProperty("line.separator"); +protected Task task; + +private SysOutErrContentStore sysOutStore; +private SysOutErrContentStore sysErrStore; + +@Override +public void sysOutAvailable(final byte[] data) { +if (this.sysOutStore == null) { +this.sysOutStore = new SysOutErrContentStore(true); +} +try { +this.sysOutStore.store(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void sysErrAvailable(final byte[] data) { +if (this.sysErrStore == null) { +this.sysErrStore = new SysOutErrContentStore(false); +} +try { +this.sysErrStore.store(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void setExecutingTask(final Task task) { +this.task = task; +} + +/** + * @return Returns true if there's any stdout data, that was generated during the + * tests, is available for use. Else returns false. + */ +boolean hasSysOut() { +return this.sysOutStore != null && this.sysOutStore.hasData(); +} + +/** + * @return Returns true if there's any stderr data, that was generated during the + * tests, is available for use. Else returns false. + */ +boolean hasSysErr() { +return this.sysErrStore != null && this.sysErrStore.hasData(); +} + +/** + * @return Returns a {@link Reader} for reading any stdout data that was generated + * during the test execution. It is expected that the {@link #hasSysOut()} be first + * called to see if any such data is available and only if there is, then this method + * be called + * @throws IOException If there's any I/O problem while creating the {@link Reader} + */ +Reader getSysOutReader() throws IOException { +return this.sysOutStore.getReader(); +} + +/** + * @return Returns a {@link Reader} for reading any stderr data that was generated + * during the test execution. It is expected that the {@link #hasSysErr()} be first + * called to see if any such data is available and only if there is, then this method + * be called + * @throws IOException If there's any I/O problem while creating the {@link Reader} + */ +Reader getSysErrReader() throws IOException { +return this.sysErrStore.getReader(); +} + +/** + * Writes out any stdout data that was generated during the + * test execution. If there was no such data then this method just returns. + * + * @param writer The {@link Writer} to use. Cannot be null. + * @throws IOException If any I/O problem occurs during writing the data + */ +void writeSysOut(final Writer writer) throws IOException { +Objects.requireNonNull(writer, "Writer cannot be null"); +this.writeFrom(this.sysOutStore, writer); +} + +/** + * Writes out any stderr data that was generated during the + * test execution. If there was no such data then this
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user bodewig commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r172043964 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java --- @@ -0,0 +1,508 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.FileUtils; +import org.apache.tools.ant.util.KeepAliveOutputStream; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * An Ant {@link Task} responsible for launching the JUnit platform for running tests. + * This requires a minimum of JUnit 5, since that's the version in which the JUnit platform launcher + * APIs were introduced. + * + * This task in itself doesn't run the JUnit tests, instead the sole responsibility of + * this task is to setup the JUnit platform launcher, build requests, launch those requests and then parse the + * result of the execution to present in a way that's been configured on this Ant task. + * + * + * Furthermore, this task allows users control over which classes to select for passing on to the JUnit 5 + * platform for test execution. It however, is solely the JUnit 5 platform, backed by test engines that + * decide and execute the tests. + * + * @see https://junit.org/junit5/;>JUnit 5 documentation for more details + * on how JUnit manages the platform and the test engines. + */ +public class JUnitLauncherTask extends Task { + +private Path classPath; +private boolean haltOnFailure; +private String failureProperty; +private final List tests = new ArrayList<>(); +private final List listeners = new ArrayList<>(); + +public JUnitLauncherTask() { +} + +@Override +public void execute() throws BuildException { +final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader(); +try { +final ClassLoader executionCL = createClassLoaderForTestExecution(); +Thread.currentThread().setContextClassLoader(executionCL); +final Launcher launcher = LauncherFactory.create(); +final List requests = buildTestRequests(); +for (final TestRequest testRequest : requests) { +try { +final TestDefinition test = testRequest.getOwner(); +final LauncherDiscoveryRequest request = testRequest.getDiscoveryRequest().build(); +final List testExecutionListeners = new ArrayList<>(); +// a listener that we always put at the front of list of listeners +// for this request. +final Listener firstListener = new Listener(); +// we always enroll the summary generating listener, to the request, so that we +// get to use some of the details of the summary for our further decision making +testExecutionListeners.add(firstListener); + testExecutionListeners.addAll(getListeners(testRequest, executionCL)); +final PrintStream originalSysOut = System.out; +final PrintStream originalSysErr = System.err; +try { +firstListener.switchedSysOutHandle = trySwitchSysOut(testRequest); +firstListener.switchedSysErrHandle = trySwitchSysErr(testRequest); +launcher.execute(request,
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user bodewig commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r172043835 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/AbstractJUnitResultFormatter.java --- @@ -0,0 +1,295 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.util.FileUtils; +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.Closeable; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.Writer; +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; +import java.util.Optional; + +/** + * Contains some common behaviour that's used by our internal {@link TestResultFormatter}s + */ +abstract class AbstractJUnitResultFormatter implements TestResultFormatter { + + +protected static String NEW_LINE = System.getProperty("line.separator"); +protected Task task; + +private SysOutErrContentStore sysOutStore; +private SysOutErrContentStore sysErrStore; + +@Override +public void sysOutAvailable(final byte[] data) { +if (this.sysOutStore == null) { +this.sysOutStore = new SysOutErrContentStore(true); +} +try { +this.sysOutStore.store(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void sysErrAvailable(final byte[] data) { +if (this.sysErrStore == null) { +this.sysErrStore = new SysOutErrContentStore(false); +} +try { +this.sysErrStore.store(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void setExecutingTask(final Task task) { +this.task = task; +} + +/** + * @return Returns true if there's any stdout data, that was generated during the + * tests, is available for use. Else returns false. + */ +boolean hasSysOut() { +return this.sysOutStore != null && this.sysOutStore.hasData(); +} + +/** + * @return Returns true if there's any stderr data, that was generated during the + * tests, is available for use. Else returns false. + */ +boolean hasSysErr() { +return this.sysErrStore != null && this.sysErrStore.hasData(); +} + +/** + * @return Returns a {@link Reader} for reading any stdout data that was generated + * during the test execution. It is expected that the {@link #hasSysOut()} be first + * called to see if any such data is available and only if there is, then this method + * be called + * @throws IOException If there's any I/O problem while creating the {@link Reader} + */ +Reader getSysOutReader() throws IOException { +return this.sysOutStore.getReader(); +} + +/** + * @return Returns a {@link Reader} for reading any stderr data that was generated + * during the test execution. It is expected that the {@link #hasSysErr()} be first + * called to see if any such data is available and only if there is, then this method + * be called + * @throws IOException If there's any I/O problem while creating the {@link Reader} + */ +Reader getSysErrReader() throws IOException { +return this.sysErrStore.getReader(); +} + +/** + * Writes out any stdout data that was generated during the + * test execution. If there was no such data then this method just returns. + * + * @param writer The {@link Writer} to use. Cannot be null. + * @throws IOException If any I/O problem occurs during writing the data + */ +void writeSysOut(final Writer writer) throws IOException { +Objects.requireNonNull(writer, "Writer cannot be null"); +this.writeFrom(this.sysOutStore, writer); +} + +/** + * Writes out any stderr data that was generated during the + * test execution. If there was no such data then this
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user bodewig commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r172043778 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/AbstractJUnitResultFormatter.java --- @@ -0,0 +1,295 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.util.FileUtils; +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.Closeable; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.Writer; +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; +import java.util.Optional; + +/** + * Contains some common behaviour that's used by our internal {@link TestResultFormatter}s + */ +abstract class AbstractJUnitResultFormatter implements TestResultFormatter { + + +protected static String NEW_LINE = System.getProperty("line.separator"); +protected Task task; + +private SysOutErrContentStore sysOutStore; +private SysOutErrContentStore sysErrStore; + +@Override +public void sysOutAvailable(final byte[] data) { +if (this.sysOutStore == null) { +this.sysOutStore = new SysOutErrContentStore(true); +} +try { +this.sysOutStore.store(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void sysErrAvailable(final byte[] data) { +if (this.sysErrStore == null) { +this.sysErrStore = new SysOutErrContentStore(false); +} +try { +this.sysErrStore.store(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void setExecutingTask(final Task task) { +this.task = task; +} + +/** + * @return Returns true if there's any stdout data, that was generated during the + * tests, is available for use. Else returns false. + */ +boolean hasSysOut() { +return this.sysOutStore != null && this.sysOutStore.hasData(); +} + +/** + * @return Returns true if there's any stderr data, that was generated during the + * tests, is available for use. Else returns false. + */ +boolean hasSysErr() { +return this.sysErrStore != null && this.sysErrStore.hasData(); +} + +/** + * @return Returns a {@link Reader} for reading any stdout data that was generated + * during the test execution. It is expected that the {@link #hasSysOut()} be first + * called to see if any such data is available and only if there is, then this method + * be called + * @throws IOException If there's any I/O problem while creating the {@link Reader} + */ +Reader getSysOutReader() throws IOException { +return this.sysOutStore.getReader(); +} + +/** + * @return Returns a {@link Reader} for reading any stderr data that was generated + * during the test execution. It is expected that the {@link #hasSysErr()} be first + * called to see if any such data is available and only if there is, then this method + * be called + * @throws IOException If there's any I/O problem while creating the {@link Reader} + */ +Reader getSysErrReader() throws IOException { +return this.sysErrStore.getReader(); +} + +/** + * Writes out any stdout data that was generated during the + * test execution. If there was no such data then this method just returns. + * + * @param writer The {@link Writer} to use. Cannot be null. + * @throws IOException If any I/O problem occurs during writing the data + */ +void writeSysOut(final Writer writer) throws IOException { +Objects.requireNonNull(writer, "Writer cannot be null"); +this.writeFrom(this.sysOutStore, writer); +} + +/** + * Writes out any stderr data that was generated during the + * test execution. If there was no such data then this
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user jaikiran commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r169626791 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java --- @@ -0,0 +1,508 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.KeepAliveOutputStream; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * An Ant {@link Task} responsible for launching the JUnit platform for running tests. + * This requires a minimum of JUnit 5, since that's the version in which the JUnit platform launcher + * APIs were introduced. + * + * This task in itself doesn't run the JUnit tests, instead the sole responsibility of + * this task is to setup the JUnit platform launcher, build requests, launch those requests and then parse the + * result of the execution to present in a way that's been configured on this Ant task. + * + * + * Furthermore, this task allows users control over which classes to select for passing on to the JUnit 5 + * platform for test execution. It however, is solely the JUnit 5 platform, backed by test engines that + * decide and execute the tests. + * + * @see https://junit.org/junit5/;>JUnit 5 documentation for more details + * on how JUnit manages the platform and the test engines. + */ +public class JUnitLauncherTask extends Task { + +private Path classPath; +private boolean haltOnFailure; +private String failureProperty; +private final List tests = new ArrayList<>(); +private final List listeners = new ArrayList<>(); + +public JUnitLauncherTask() { +} + +@Override +public void execute() throws BuildException { +final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader(); +try { +final ClassLoader executionCL = createClassLoaderForTestExecution(); +Thread.currentThread().setContextClassLoader(executionCL); +final Launcher launcher = LauncherFactory.create(); +final List requests = buildTestRequests(); +for (final TestRequest testRequest : requests) { +try { +final TestDefinition test = testRequest.getOwner(); +final LauncherDiscoveryRequest request = testRequest.getDiscoveryRequest().build(); +final List testExecutionListeners = new ArrayList<>(); +// a listener that we always put at the front of list of listeners +// for this request. +final Listener firstListener = new Listener(); +// we always enroll the summary generating listener, to the request, so that we +// get to use some of the details of the summary for our further decision making +testExecutionListeners.add(firstListener); + testExecutionListeners.addAll(getListeners(testRequest, executionCL)); +final PrintStream originalSysOut = System.out; +final PrintStream originalSysErr = System.err; +try { +firstListener.switchedSysOutHandle = trySwitchSysOut(testRequest); +firstListener.switchedSysErrHandle = trySwitchSysErr(testRequest); +launcher.execute(request, testExecutionListeners.toArray(new
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user jaikiran commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r169625878 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java --- @@ -0,0 +1,508 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.KeepAliveOutputStream; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * An Ant {@link Task} responsible for launching the JUnit platform for running tests. + * This requires a minimum of JUnit 5, since that's the version in which the JUnit platform launcher + * APIs were introduced. + * + * This task in itself doesn't run the JUnit tests, instead the sole responsibility of + * this task is to setup the JUnit platform launcher, build requests, launch those requests and then parse the + * result of the execution to present in a way that's been configured on this Ant task. + * + * + * Furthermore, this task allows users control over which classes to select for passing on to the JUnit 5 + * platform for test execution. It however, is solely the JUnit 5 platform, backed by test engines that + * decide and execute the tests. + * + * @see https://junit.org/junit5/;>JUnit 5 documentation for more details + * on how JUnit manages the platform and the test engines. + */ +public class JUnitLauncherTask extends Task { + +private Path classPath; +private boolean haltOnFailure; +private String failureProperty; +private final List tests = new ArrayList<>(); +private final List listeners = new ArrayList<>(); + +public JUnitLauncherTask() { +} + +@Override +public void execute() throws BuildException { +final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader(); +try { +final ClassLoader executionCL = createClassLoaderForTestExecution(); +Thread.currentThread().setContextClassLoader(executionCL); +final Launcher launcher = LauncherFactory.create(); +final List requests = buildTestRequests(); +for (final TestRequest testRequest : requests) { +try { +final TestDefinition test = testRequest.getOwner(); +final LauncherDiscoveryRequest request = testRequest.getDiscoveryRequest().build(); +final List testExecutionListeners = new ArrayList<>(); +// a listener that we always put at the front of list of listeners +// for this request. +final Listener firstListener = new Listener(); +// we always enroll the summary generating listener, to the request, so that we +// get to use some of the details of the summary for our further decision making +testExecutionListeners.add(firstListener); + testExecutionListeners.addAll(getListeners(testRequest, executionCL)); +final PrintStream originalSysOut = System.out; +final PrintStream originalSysErr = System.err; +try { +firstListener.switchedSysOutHandle = trySwitchSysOut(testRequest); +firstListener.switchedSysErrHandle = trySwitchSysErr(testRequest); +launcher.execute(request, testExecutionListeners.toArray(new
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user jaikiran commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r169624865 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java --- @@ -0,0 +1,508 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.KeepAliveOutputStream; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * An Ant {@link Task} responsible for launching the JUnit platform for running tests. + * This requires a minimum of JUnit 5, since that's the version in which the JUnit platform launcher + * APIs were introduced. + * + * This task in itself doesn't run the JUnit tests, instead the sole responsibility of + * this task is to setup the JUnit platform launcher, build requests, launch those requests and then parse the + * result of the execution to present in a way that's been configured on this Ant task. + * + * + * Furthermore, this task allows users control over which classes to select for passing on to the JUnit 5 + * platform for test execution. It however, is solely the JUnit 5 platform, backed by test engines that + * decide and execute the tests. + * + * @see https://junit.org/junit5/;>JUnit 5 documentation for more details + * on how JUnit manages the platform and the test engines. + */ +public class JUnitLauncherTask extends Task { + +private Path classPath; +private boolean haltOnFailure; +private String failureProperty; +private final List tests = new ArrayList<>(); +private final List listeners = new ArrayList<>(); + +public JUnitLauncherTask() { +} + +@Override +public void execute() throws BuildException { +final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader(); +try { +final ClassLoader executionCL = createClassLoaderForTestExecution(); +Thread.currentThread().setContextClassLoader(executionCL); +final Launcher launcher = LauncherFactory.create(); +final List requests = buildTestRequests(); +for (final TestRequest testRequest : requests) { +try { +final TestDefinition test = testRequest.getOwner(); +final LauncherDiscoveryRequest request = testRequest.getDiscoveryRequest().build(); +final List testExecutionListeners = new ArrayList<>(); +// a listener that we always put at the front of list of listeners +// for this request. +final Listener firstListener = new Listener(); +// we always enroll the summary generating listener, to the request, so that we +// get to use some of the details of the summary for our further decision making +testExecutionListeners.add(firstListener); + testExecutionListeners.addAll(getListeners(testRequest, executionCL)); +final PrintStream originalSysOut = System.out; +final PrintStream originalSysErr = System.err; +try { +firstListener.switchedSysOutHandle = trySwitchSysOut(testRequest); +firstListener.switchedSysErrHandle = trySwitchSysErr(testRequest); +launcher.execute(request, testExecutionListeners.toArray(new
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user jaikiran commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r169624837 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java --- @@ -0,0 +1,508 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.KeepAliveOutputStream; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * An Ant {@link Task} responsible for launching the JUnit platform for running tests. + * This requires a minimum of JUnit 5, since that's the version in which the JUnit platform launcher + * APIs were introduced. + * + * This task in itself doesn't run the JUnit tests, instead the sole responsibility of + * this task is to setup the JUnit platform launcher, build requests, launch those requests and then parse the + * result of the execution to present in a way that's been configured on this Ant task. + * + * + * Furthermore, this task allows users control over which classes to select for passing on to the JUnit 5 + * platform for test execution. It however, is solely the JUnit 5 platform, backed by test engines that + * decide and execute the tests. + * + * @see https://junit.org/junit5/;>JUnit 5 documentation for more details + * on how JUnit manages the platform and the test engines. + */ +public class JUnitLauncherTask extends Task { + +private Path classPath; +private boolean haltOnFailure; +private String failureProperty; +private final List tests = new ArrayList<>(); +private final List listeners = new ArrayList<>(); + +public JUnitLauncherTask() { +} + +@Override +public void execute() throws BuildException { +final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader(); +try { +final ClassLoader executionCL = createClassLoaderForTestExecution(); +Thread.currentThread().setContextClassLoader(executionCL); +final Launcher launcher = LauncherFactory.create(); +final List requests = buildTestRequests(); +for (final TestRequest testRequest : requests) { +try { +final TestDefinition test = testRequest.getOwner(); +final LauncherDiscoveryRequest request = testRequest.getDiscoveryRequest().build(); +final List testExecutionListeners = new ArrayList<>(); +// a listener that we always put at the front of list of listeners +// for this request. +final Listener firstListener = new Listener(); +// we always enroll the summary generating listener, to the request, so that we +// get to use some of the details of the summary for our further decision making +testExecutionListeners.add(firstListener); + testExecutionListeners.addAll(getListeners(testRequest, executionCL)); +final PrintStream originalSysOut = System.out; +final PrintStream originalSysErr = System.err; +try { +firstListener.switchedSysOutHandle = trySwitchSysOut(testRequest); +firstListener.switchedSysErrHandle = trySwitchSysErr(testRequest); +launcher.execute(request, testExecutionListeners.toArray(new
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user jaikiran commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r169624475 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java --- @@ -0,0 +1,508 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.KeepAliveOutputStream; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * An Ant {@link Task} responsible for launching the JUnit platform for running tests. + * This requires a minimum of JUnit 5, since that's the version in which the JUnit platform launcher + * APIs were introduced. + * + * This task in itself doesn't run the JUnit tests, instead the sole responsibility of + * this task is to setup the JUnit platform launcher, build requests, launch those requests and then parse the + * result of the execution to present in a way that's been configured on this Ant task. + * + * + * Furthermore, this task allows users control over which classes to select for passing on to the JUnit 5 + * platform for test execution. It however, is solely the JUnit 5 platform, backed by test engines that + * decide and execute the tests. + * + * @see https://junit.org/junit5/;>JUnit 5 documentation for more details + * on how JUnit manages the platform and the test engines. + */ +public class JUnitLauncherTask extends Task { + +private Path classPath; +private boolean haltOnFailure; +private String failureProperty; +private final List tests = new ArrayList<>(); +private final List listeners = new ArrayList<>(); + +public JUnitLauncherTask() { +} + +@Override +public void execute() throws BuildException { +final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader(); +try { +final ClassLoader executionCL = createClassLoaderForTestExecution(); +Thread.currentThread().setContextClassLoader(executionCL); +final Launcher launcher = LauncherFactory.create(); +final List requests = buildTestRequests(); +for (final TestRequest testRequest : requests) { +try { +final TestDefinition test = testRequest.getOwner(); +final LauncherDiscoveryRequest request = testRequest.getDiscoveryRequest().build(); +final List testExecutionListeners = new ArrayList<>(); +// a listener that we always put at the front of list of listeners +// for this request. +final Listener firstListener = new Listener(); +// we always enroll the summary generating listener, to the request, so that we +// get to use some of the details of the summary for our further decision making +testExecutionListeners.add(firstListener); + testExecutionListeners.addAll(getListeners(testRequest, executionCL)); +final PrintStream originalSysOut = System.out; +final PrintStream originalSysErr = System.err; +try { +firstListener.switchedSysOutHandle = trySwitchSysOut(testRequest); +firstListener.switchedSysErrHandle = trySwitchSysErr(testRequest); +launcher.execute(request, testExecutionListeners.toArray(new
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user bodewig commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r169248698 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java --- @@ -0,0 +1,508 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.KeepAliveOutputStream; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * An Ant {@link Task} responsible for launching the JUnit platform for running tests. + * This requires a minimum of JUnit 5, since that's the version in which the JUnit platform launcher + * APIs were introduced. + * + * This task in itself doesn't run the JUnit tests, instead the sole responsibility of + * this task is to setup the JUnit platform launcher, build requests, launch those requests and then parse the + * result of the execution to present in a way that's been configured on this Ant task. + * + * + * Furthermore, this task allows users control over which classes to select for passing on to the JUnit 5 + * platform for test execution. It however, is solely the JUnit 5 platform, backed by test engines that + * decide and execute the tests. + * + * @see https://junit.org/junit5/;>JUnit 5 documentation for more details + * on how JUnit manages the platform and the test engines. + */ +public class JUnitLauncherTask extends Task { + +private Path classPath; +private boolean haltOnFailure; +private String failureProperty; +private final List tests = new ArrayList<>(); +private final List listeners = new ArrayList<>(); + +public JUnitLauncherTask() { +} + +@Override +public void execute() throws BuildException { +final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader(); +try { +final ClassLoader executionCL = createClassLoaderForTestExecution(); +Thread.currentThread().setContextClassLoader(executionCL); +final Launcher launcher = LauncherFactory.create(); +final List requests = buildTestRequests(); +for (final TestRequest testRequest : requests) { +try { +final TestDefinition test = testRequest.getOwner(); +final LauncherDiscoveryRequest request = testRequest.getDiscoveryRequest().build(); +final List testExecutionListeners = new ArrayList<>(); +// a listener that we always put at the front of list of listeners +// for this request. +final Listener firstListener = new Listener(); +// we always enroll the summary generating listener, to the request, so that we +// get to use some of the details of the summary for our further decision making +testExecutionListeners.add(firstListener); + testExecutionListeners.addAll(getListeners(testRequest, executionCL)); +final PrintStream originalSysOut = System.out; +final PrintStream originalSysErr = System.err; +try { +firstListener.switchedSysOutHandle = trySwitchSysOut(testRequest); +firstListener.switchedSysErrHandle = trySwitchSysErr(testRequest); +launcher.execute(request, testExecutionListeners.toArray(new
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user bodewig commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r169248048 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java --- @@ -0,0 +1,508 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.KeepAliveOutputStream; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * An Ant {@link Task} responsible for launching the JUnit platform for running tests. + * This requires a minimum of JUnit 5, since that's the version in which the JUnit platform launcher + * APIs were introduced. + * + * This task in itself doesn't run the JUnit tests, instead the sole responsibility of + * this task is to setup the JUnit platform launcher, build requests, launch those requests and then parse the + * result of the execution to present in a way that's been configured on this Ant task. + * + * + * Furthermore, this task allows users control over which classes to select for passing on to the JUnit 5 + * platform for test execution. It however, is solely the JUnit 5 platform, backed by test engines that + * decide and execute the tests. + * + * @see https://junit.org/junit5/;>JUnit 5 documentation for more details + * on how JUnit manages the platform and the test engines. + */ +public class JUnitLauncherTask extends Task { + +private Path classPath; +private boolean haltOnFailure; +private String failureProperty; +private final List tests = new ArrayList<>(); +private final List listeners = new ArrayList<>(); + +public JUnitLauncherTask() { +} + +@Override +public void execute() throws BuildException { +final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader(); +try { +final ClassLoader executionCL = createClassLoaderForTestExecution(); +Thread.currentThread().setContextClassLoader(executionCL); +final Launcher launcher = LauncherFactory.create(); +final List requests = buildTestRequests(); +for (final TestRequest testRequest : requests) { +try { +final TestDefinition test = testRequest.getOwner(); +final LauncherDiscoveryRequest request = testRequest.getDiscoveryRequest().build(); +final List testExecutionListeners = new ArrayList<>(); +// a listener that we always put at the front of list of listeners +// for this request. +final Listener firstListener = new Listener(); +// we always enroll the summary generating listener, to the request, so that we +// get to use some of the details of the summary for our further decision making +testExecutionListeners.add(firstListener); + testExecutionListeners.addAll(getListeners(testRequest, executionCL)); +final PrintStream originalSysOut = System.out; +final PrintStream originalSysErr = System.err; +try { +firstListener.switchedSysOutHandle = trySwitchSysOut(testRequest); +firstListener.switchedSysErrHandle = trySwitchSysErr(testRequest); +launcher.execute(request, testExecutionListeners.toArray(new
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user bodewig commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r169247383 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java --- @@ -0,0 +1,508 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.KeepAliveOutputStream; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * An Ant {@link Task} responsible for launching the JUnit platform for running tests. + * This requires a minimum of JUnit 5, since that's the version in which the JUnit platform launcher + * APIs were introduced. + * + * This task in itself doesn't run the JUnit tests, instead the sole responsibility of + * this task is to setup the JUnit platform launcher, build requests, launch those requests and then parse the + * result of the execution to present in a way that's been configured on this Ant task. + * + * + * Furthermore, this task allows users control over which classes to select for passing on to the JUnit 5 + * platform for test execution. It however, is solely the JUnit 5 platform, backed by test engines that + * decide and execute the tests. + * + * @see https://junit.org/junit5/;>JUnit 5 documentation for more details + * on how JUnit manages the platform and the test engines. + */ +public class JUnitLauncherTask extends Task { + +private Path classPath; +private boolean haltOnFailure; +private String failureProperty; +private final List tests = new ArrayList<>(); +private final List listeners = new ArrayList<>(); + +public JUnitLauncherTask() { +} + +@Override +public void execute() throws BuildException { +final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader(); +try { +final ClassLoader executionCL = createClassLoaderForTestExecution(); +Thread.currentThread().setContextClassLoader(executionCL); +final Launcher launcher = LauncherFactory.create(); +final List requests = buildTestRequests(); +for (final TestRequest testRequest : requests) { +try { +final TestDefinition test = testRequest.getOwner(); +final LauncherDiscoveryRequest request = testRequest.getDiscoveryRequest().build(); +final List testExecutionListeners = new ArrayList<>(); +// a listener that we always put at the front of list of listeners +// for this request. +final Listener firstListener = new Listener(); +// we always enroll the summary generating listener, to the request, so that we +// get to use some of the details of the summary for our further decision making +testExecutionListeners.add(firstListener); + testExecutionListeners.addAll(getListeners(testRequest, executionCL)); +final PrintStream originalSysOut = System.out; +final PrintStream originalSysErr = System.err; +try { +firstListener.switchedSysOutHandle = trySwitchSysOut(testRequest); +firstListener.switchedSysErrHandle = trySwitchSysErr(testRequest); +launcher.execute(request, testExecutionListeners.toArray(new
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user bodewig commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r169245116 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java --- @@ -0,0 +1,508 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.KeepAliveOutputStream; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * An Ant {@link Task} responsible for launching the JUnit platform for running tests. + * This requires a minimum of JUnit 5, since that's the version in which the JUnit platform launcher + * APIs were introduced. + * + * This task in itself doesn't run the JUnit tests, instead the sole responsibility of + * this task is to setup the JUnit platform launcher, build requests, launch those requests and then parse the + * result of the execution to present in a way that's been configured on this Ant task. + * + * + * Furthermore, this task allows users control over which classes to select for passing on to the JUnit 5 + * platform for test execution. It however, is solely the JUnit 5 platform, backed by test engines that + * decide and execute the tests. + * + * @see https://junit.org/junit5/;>JUnit 5 documentation for more details + * on how JUnit manages the platform and the test engines. + */ +public class JUnitLauncherTask extends Task { + +private Path classPath; +private boolean haltOnFailure; +private String failureProperty; +private final List tests = new ArrayList<>(); +private final List listeners = new ArrayList<>(); + +public JUnitLauncherTask() { +} + +@Override +public void execute() throws BuildException { +final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader(); +try { +final ClassLoader executionCL = createClassLoaderForTestExecution(); +Thread.currentThread().setContextClassLoader(executionCL); +final Launcher launcher = LauncherFactory.create(); +final List requests = buildTestRequests(); +for (final TestRequest testRequest : requests) { +try { +final TestDefinition test = testRequest.getOwner(); +final LauncherDiscoveryRequest request = testRequest.getDiscoveryRequest().build(); +final List testExecutionListeners = new ArrayList<>(); +// a listener that we always put at the front of list of listeners +// for this request. +final Listener firstListener = new Listener(); +// we always enroll the summary generating listener, to the request, so that we +// get to use some of the details of the summary for our further decision making +testExecutionListeners.add(firstListener); + testExecutionListeners.addAll(getListeners(testRequest, executionCL)); +final PrintStream originalSysOut = System.out; +final PrintStream originalSysErr = System.err; +try { +firstListener.switchedSysOutHandle = trySwitchSysOut(testRequest); +firstListener.switchedSysErrHandle = trySwitchSysErr(testRequest); +launcher.execute(request, testExecutionListeners.toArray(new
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user bodewig commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r169243988 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java --- @@ -0,0 +1,508 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.KeepAliveOutputStream; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.SummaryGeneratingListener; +import org.junit.platform.launcher.listeners.TestExecutionSummary; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * An Ant {@link Task} responsible for launching the JUnit platform for running tests. + * This requires a minimum of JUnit 5, since that's the version in which the JUnit platform launcher + * APIs were introduced. + * + * This task in itself doesn't run the JUnit tests, instead the sole responsibility of + * this task is to setup the JUnit platform launcher, build requests, launch those requests and then parse the + * result of the execution to present in a way that's been configured on this Ant task. + * + * + * Furthermore, this task allows users control over which classes to select for passing on to the JUnit 5 + * platform for test execution. It however, is solely the JUnit 5 platform, backed by test engines that + * decide and execute the tests. + * + * @see https://junit.org/junit5/;>JUnit 5 documentation for more details + * on how JUnit manages the platform and the test engines. + */ +public class JUnitLauncherTask extends Task { + +private Path classPath; +private boolean haltOnFailure; +private String failureProperty; +private final List tests = new ArrayList<>(); +private final List listeners = new ArrayList<>(); + +public JUnitLauncherTask() { +} + +@Override +public void execute() throws BuildException { +final ClassLoader previousClassLoader = Thread.currentThread().getContextClassLoader(); +try { +final ClassLoader executionCL = createClassLoaderForTestExecution(); +Thread.currentThread().setContextClassLoader(executionCL); +final Launcher launcher = LauncherFactory.create(); +final List requests = buildTestRequests(); +for (final TestRequest testRequest : requests) { +try { +final TestDefinition test = testRequest.getOwner(); +final LauncherDiscoveryRequest request = testRequest.getDiscoveryRequest().build(); +final List testExecutionListeners = new ArrayList<>(); +// a listener that we always put at the front of list of listeners +// for this request. +final Listener firstListener = new Listener(); +// we always enroll the summary generating listener, to the request, so that we +// get to use some of the details of the summary for our further decision making +testExecutionListeners.add(firstListener); + testExecutionListeners.addAll(getListeners(testRequest, executionCL)); +final PrintStream originalSysOut = System.out; +final PrintStream originalSysErr = System.err; +try { +firstListener.switchedSysOutHandle = trySwitchSysOut(testRequest); +firstListener.switchedSysErrHandle = trySwitchSysErr(testRequest); +launcher.execute(request, testExecutionListeners.toArray(new
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user jaikiran commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r168983237 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/AbstractJUnitResultFormatter.java --- @@ -0,0 +1,139 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; + +/** + * Contains some common behaviour that's used by our internal {@link TestResultFormatter}s + */ +abstract class AbstractJUnitResultFormatter implements TestResultFormatter { + +protected static String NEW_LINE = System.getProperty("line.separator"); +protected Path sysOutFilePath; +protected Path sysErrFilePath; +protected Task task; + +private OutputStream sysOutStream; +private OutputStream sysErrStream; + +@Override +public void sysOutAvailable(final byte[] data) { +if (this.sysOutStream == null) { +try { +this.sysOutFilePath = Files.createTempFile(null, "sysout"); +this.sysOutFilePath.toFile().deleteOnExit(); +this.sysOutStream = Files.newOutputStream(this.sysOutFilePath); +} catch (IOException e) { +handleException(e); +return; +} +} +try { +this.sysOutStream.write(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void sysErrAvailable(final byte[] data) { +if (this.sysErrStream == null) { +try { +this.sysErrFilePath = Files.createTempFile(null, "syserr"); +this.sysErrFilePath.toFile().deleteOnExit(); +this.sysErrStream = Files.newOutputStream(this.sysOutFilePath); +} catch (IOException e) { +handleException(e); +return; +} +} +try { +this.sysErrStream.write(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void setExecutingTask(final Task task) { +this.task = task; +} + +protected void writeSysOut(final Writer writer) throws IOException { +this.writeFrom(this.sysOutFilePath, writer); +} + +protected void writeSysErr(final Writer writer) throws IOException { +this.writeFrom(this.sysErrFilePath, writer); +} + +static Optional traverseAndFindTestClass(final TestPlan testPlan, final TestIdentifier testIdentifier) { +if (isTestClass(testIdentifier).isPresent()) { +return Optional.of(testIdentifier); +} +final Optional parent = testPlan.getParent(testIdentifier); +return parent.isPresent() ? traverseAndFindTestClass(testPlan, parent.get()) : Optional.empty(); +} + +static Optional isTestClass(final TestIdentifier testIdentifier) { +if (testIdentifier == null) { +return Optional.empty(); +} +final Optional source = testIdentifier.getSource(); +if (!source.isPresent()) { +return Optional.empty(); +} +final TestSource testSource = source.get(); +if (testSource instanceof ClassSource) { +return Optional.of((ClassSource) testSource); +} +return Optional.empty(); +} + +private void writeFrom(final Path path, final Writer writer) throws IOException { +final byte[] content = new byte[1024]; +int numBytes; +try (final InputStream is = Files.newInputStream(path)) { +while ((numBytes = is.read(content)) != -1) { +writer.write(new String(content, 0, numBytes)); +} +} +} + +@Override +public void close() throws IOException { +if (this.sysOutStream != null) { +try { +this.sysOutStream.close(); +} catch (Exception e) { +// ignore +}
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user jaikiran commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r168983118 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/AbstractJUnitResultFormatter.java --- @@ -0,0 +1,139 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; + +/** + * Contains some common behaviour that's used by our internal {@link TestResultFormatter}s + */ +abstract class AbstractJUnitResultFormatter implements TestResultFormatter { + +protected static String NEW_LINE = System.getProperty("line.separator"); +protected Path sysOutFilePath; +protected Path sysErrFilePath; +protected Task task; + +private OutputStream sysOutStream; +private OutputStream sysErrStream; + +@Override +public void sysOutAvailable(final byte[] data) { +if (this.sysOutStream == null) { +try { +this.sysOutFilePath = Files.createTempFile(null, "sysout"); +this.sysOutFilePath.toFile().deleteOnExit(); +this.sysOutStream = Files.newOutputStream(this.sysOutFilePath); +} catch (IOException e) { +handleException(e); +return; +} +} +try { +this.sysOutStream.write(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void sysErrAvailable(final byte[] data) { +if (this.sysErrStream == null) { +try { +this.sysErrFilePath = Files.createTempFile(null, "syserr"); +this.sysErrFilePath.toFile().deleteOnExit(); +this.sysErrStream = Files.newOutputStream(this.sysOutFilePath); --- End diff -- Indeed :) Fixed. --- - To unsubscribe, e-mail: dev-unsubscr...@ant.apache.org For additional commands, e-mail: dev-h...@ant.apache.org
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user bodewig commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r168964381 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/AbstractJUnitResultFormatter.java --- @@ -0,0 +1,139 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; + +/** + * Contains some common behaviour that's used by our internal {@link TestResultFormatter}s + */ +abstract class AbstractJUnitResultFormatter implements TestResultFormatter { + +protected static String NEW_LINE = System.getProperty("line.separator"); +protected Path sysOutFilePath; +protected Path sysErrFilePath; +protected Task task; + +private OutputStream sysOutStream; +private OutputStream sysErrStream; + +@Override +public void sysOutAvailable(final byte[] data) { +if (this.sysOutStream == null) { +try { +this.sysOutFilePath = Files.createTempFile(null, "sysout"); +this.sysOutFilePath.toFile().deleteOnExit(); +this.sysOutStream = Files.newOutputStream(this.sysOutFilePath); +} catch (IOException e) { +handleException(e); +return; +} +} +try { +this.sysOutStream.write(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void sysErrAvailable(final byte[] data) { +if (this.sysErrStream == null) { +try { +this.sysErrFilePath = Files.createTempFile(null, "syserr"); +this.sysErrFilePath.toFile().deleteOnExit(); +this.sysErrStream = Files.newOutputStream(this.sysOutFilePath); +} catch (IOException e) { +handleException(e); +return; +} +} +try { +this.sysErrStream.write(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void setExecutingTask(final Task task) { +this.task = task; +} + +protected void writeSysOut(final Writer writer) throws IOException { +this.writeFrom(this.sysOutFilePath, writer); +} + +protected void writeSysErr(final Writer writer) throws IOException { +this.writeFrom(this.sysErrFilePath, writer); +} + +static Optional traverseAndFindTestClass(final TestPlan testPlan, final TestIdentifier testIdentifier) { +if (isTestClass(testIdentifier).isPresent()) { +return Optional.of(testIdentifier); +} +final Optional parent = testPlan.getParent(testIdentifier); +return parent.isPresent() ? traverseAndFindTestClass(testPlan, parent.get()) : Optional.empty(); +} + +static Optional isTestClass(final TestIdentifier testIdentifier) { +if (testIdentifier == null) { +return Optional.empty(); +} +final Optional source = testIdentifier.getSource(); +if (!source.isPresent()) { +return Optional.empty(); +} +final TestSource testSource = source.get(); +if (testSource instanceof ClassSource) { +return Optional.of((ClassSource) testSource); +} +return Optional.empty(); +} + +private void writeFrom(final Path path, final Writer writer) throws IOException { +final byte[] content = new byte[1024]; +int numBytes; +try (final InputStream is = Files.newInputStream(path)) { +while ((numBytes = is.read(content)) != -1) { +writer.write(new String(content, 0, numBytes)); +} +} +} + +@Override +public void close() throws IOException { +if (this.sysOutStream != null) { +try { +this.sysOutStream.close(); +} catch (Exception e) { +// ignore +} +
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user bodewig commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r168964295 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/AbstractJUnitResultFormatter.java --- @@ -0,0 +1,139 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; + +/** + * Contains some common behaviour that's used by our internal {@link TestResultFormatter}s + */ +abstract class AbstractJUnitResultFormatter implements TestResultFormatter { + +protected static String NEW_LINE = System.getProperty("line.separator"); +protected Path sysOutFilePath; +protected Path sysErrFilePath; +protected Task task; + +private OutputStream sysOutStream; +private OutputStream sysErrStream; + +@Override +public void sysOutAvailable(final byte[] data) { +if (this.sysOutStream == null) { +try { +this.sysOutFilePath = Files.createTempFile(null, "sysout"); +this.sysOutFilePath.toFile().deleteOnExit(); +this.sysOutStream = Files.newOutputStream(this.sysOutFilePath); +} catch (IOException e) { +handleException(e); +return; +} +} +try { +this.sysOutStream.write(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void sysErrAvailable(final byte[] data) { +if (this.sysErrStream == null) { +try { +this.sysErrFilePath = Files.createTempFile(null, "syserr"); +this.sysErrFilePath.toFile().deleteOnExit(); +this.sysErrStream = Files.newOutputStream(this.sysOutFilePath); +} catch (IOException e) { +handleException(e); +return; +} +} +try { +this.sysErrStream.write(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void setExecutingTask(final Task task) { +this.task = task; +} + +protected void writeSysOut(final Writer writer) throws IOException { +this.writeFrom(this.sysOutFilePath, writer); +} + +protected void writeSysErr(final Writer writer) throws IOException { +this.writeFrom(this.sysErrFilePath, writer); +} + +static Optional traverseAndFindTestClass(final TestPlan testPlan, final TestIdentifier testIdentifier) { +if (isTestClass(testIdentifier).isPresent()) { +return Optional.of(testIdentifier); +} +final Optional parent = testPlan.getParent(testIdentifier); +return parent.isPresent() ? traverseAndFindTestClass(testPlan, parent.get()) : Optional.empty(); +} + +static Optional isTestClass(final TestIdentifier testIdentifier) { +if (testIdentifier == null) { +return Optional.empty(); +} +final Optional source = testIdentifier.getSource(); +if (!source.isPresent()) { +return Optional.empty(); +} +final TestSource testSource = source.get(); +if (testSource instanceof ClassSource) { +return Optional.of((ClassSource) testSource); +} +return Optional.empty(); +} + +private void writeFrom(final Path path, final Writer writer) throws IOException { +final byte[] content = new byte[1024]; +int numBytes; +try (final InputStream is = Files.newInputStream(path)) { +while ((numBytes = is.read(content)) != -1) { +writer.write(new String(content, 0, numBytes)); +} --- End diff -- I don't think this is going to work reliably. The `read` may have split a multi-byte sequence at the end of `content` and then creating a string from it is going to break. Is there any reason you want to use a stream when reading the temporary file rather than a reader? ---
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
Github user bodewig commented on a diff in the pull request: https://github.com/apache/ant/pull/60#discussion_r168963955 --- Diff: src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/AbstractJUnitResultFormatter.java --- @@ -0,0 +1,139 @@ +package org.apache.tools.ant.taskdefs.optional.junitlauncher; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.junit.platform.engine.TestSource; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; + +/** + * Contains some common behaviour that's used by our internal {@link TestResultFormatter}s + */ +abstract class AbstractJUnitResultFormatter implements TestResultFormatter { + +protected static String NEW_LINE = System.getProperty("line.separator"); +protected Path sysOutFilePath; +protected Path sysErrFilePath; +protected Task task; + +private OutputStream sysOutStream; +private OutputStream sysErrStream; + +@Override +public void sysOutAvailable(final byte[] data) { +if (this.sysOutStream == null) { +try { +this.sysOutFilePath = Files.createTempFile(null, "sysout"); +this.sysOutFilePath.toFile().deleteOnExit(); +this.sysOutStream = Files.newOutputStream(this.sysOutFilePath); +} catch (IOException e) { +handleException(e); +return; +} +} +try { +this.sysOutStream.write(data); +} catch (IOException e) { +handleException(e); +return; +} +} + +@Override +public void sysErrAvailable(final byte[] data) { +if (this.sysErrStream == null) { +try { +this.sysErrFilePath = Files.createTempFile(null, "syserr"); +this.sysErrFilePath.toFile().deleteOnExit(); +this.sysErrStream = Files.newOutputStream(this.sysOutFilePath); --- End diff -- copy-paste error, you want that to be `sysErrFilePath` :-) --- - To unsubscribe, e-mail: dev-unsubscr...@ant.apache.org For additional commands, e-mail: dev-h...@ant.apache.org
[GitHub] ant pull request #60: JUnit 5 support - A new junitlauncher task
GitHub user jaikiran opened a pull request: https://github.com/apache/ant/pull/60 JUnit 5 support - A new junitlauncher task This is the initial working version of a new `junitlauncher` task that support using JUnit 5 framework for testing, within Ant build files. The commit in this PR is the initial set of goals that I had in mind for the first release of this task. The manual for this task can be (temporarily) found at https://builds.apache.org/job/Ant-Build-Jaikiran/ws/manual/Tasks/junitlauncher.html You can merge this pull request into a Git repository by running: $ git pull https://github.com/jaikiran/ant junit5 Alternatively you can review and apply these changes as the patch at: https://github.com/apache/ant/pull/60.patch To close this pull request, make a commit to your master/trunk branch with (at least) the following in the commit message: This closes #60 commit 991bddff07b4fed1db2dc7f6b83f47557e62213b Author: Jaikiran PaiDate: 2017-12-13T13:37:41Z JUnit 5 support - A new junitlauncher task --- - To unsubscribe, e-mail: dev-unsubscr...@ant.apache.org For additional commands, e-mail: dev-h...@ant.apache.org