Skip to content

Commit

Permalink
junitlauncher - timeout should apply to all tests combined when using…
Browse files Browse the repository at this point in the history
… forkMode=perTestClass
  • Loading branch information
jaikiran committed Aug 16, 2023
1 parent 2d44148 commit 89b0895
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 9 deletions.
6 changes: 5 additions & 1 deletion manual/Tasks/junitlauncher.html
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,11 @@ <h4 id="fork">fork</h4>
<td>Controls how many JVMs are launched for the forked tests. Allowed values are:
<ul class="inlinelist">
<li><code>perTestClass</code> - This mode launches each test class in a
separately forked JVM</li>
separately forked JVM. Each of these JVMs will be forked sequentially
one at a time, as and when each test class execution completes.
If any <code>timeout</code> value is specified, then that timeout applies to
the time that all tests use together, not to an individual test.
</li>
</ul>
<p><em>Since Ant 1.10.14</em></p>
</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,14 @@
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;

import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.Constants.LD_XML_ATTR_EXCLUDE_TAGS;
import static org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.Constants.LD_XML_ATTR_HALT_ON_FAILURE;
import static org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.Constants.LD_XML_ATTR_INCLUDE_TAGS;
Expand Down Expand Up @@ -82,8 +85,8 @@ public class JUnitLauncherTask extends Task {
private boolean printSummary;
private final List<TestDefinition> tests = new ArrayList<>();
private final List<ListenerDefinition> listeners = new ArrayList<>();
private List<String> includeTags = new ArrayList<>();
private List<String> excludeTags = new ArrayList<>();
private final List<String> includeTags = new ArrayList<>();
private final List<String> excludeTags = new ArrayList<>();

public JUnitLauncherTask() {
}
Expand All @@ -105,8 +108,13 @@ public void execute() throws BuildException {
launchViaReflection(new InVMLaunch(Collections.singletonList(test)));
} else {
final List<ForkedRepresentation> forkedReps = test.toForkedRepresentations();
final long timeout = forkDefinition.getTimeout(); // in millis
// compute the "end time" (if any)
final Optional<Long> deadlineNanos = timeout == -1
? Optional.empty() // no timeout
: Optional.of(System.nanoTime() + MILLISECONDS.toNanos(timeout));
for (final ForkedRepresentation forkedRep : forkedReps) {
forkTest(test, forkDefinition, forkedRep);
forkTest(test, forkDefinition, forkedRep, deadlineNanos);
}
}
}
Expand Down Expand Up @@ -244,7 +252,8 @@ private java.nio.file.Path dumpProjectProperties() throws IOException {
}

private void forkTest(final TestDefinition test, final ForkDefinition forkDefinition,
final ForkedRepresentation forkedRepresentation) {
final ForkedRepresentation forkedRepresentation,
final Optional<Long> deadlineNanos) {
// create launch command
final CommandlineJava commandlineJava = forkDefinition.generateCommandLine(this);
if (this.classPath != null) {
Expand Down Expand Up @@ -302,7 +311,7 @@ private void forkTest(final TestDefinition test, final ForkDefinition forkDefini
commandlineJava.createArgument().setValue(launchDefXmlPath.toAbsolutePath().toString());

// launch the process and wait for process to complete
final int exitCode = executeForkedTest(forkDefinition, commandlineJava);
final int exitCode = executeForkedTest(forkDefinition, commandlineJava, deadlineNanos);
switch (exitCode) {
case Constants.FORK_EXIT_CODE_SUCCESS: {
// success
Expand Down Expand Up @@ -359,11 +368,26 @@ private static String commaSeparatedListElements(final List<String> stringList)
.collect(Collectors.joining(", "));
}

private int executeForkedTest(final ForkDefinition forkDefinition, final CommandlineJava commandlineJava) {
private int executeForkedTest(final ForkDefinition forkDefinition, final CommandlineJava commandlineJava,
final Optional<Long> deadlineNanos) {
final LogOutputStream outStream = new LogOutputStream(this, Project.MSG_INFO);
final LogOutputStream errStream = new LogOutputStream(this, Project.MSG_WARN);
final ExecuteWatchdog watchdog = forkDefinition.getTimeout() > 0
? createExecuteWatchdog(forkDefinition.getTimeout()) : null;
final ExecuteWatchdog watchdog;
if (deadlineNanos.isPresent()) {
final long remainingNanos = deadlineNanos.get() - System.nanoTime();
if (remainingNanos <= 0) {
// already timed out
return Constants.FORK_EXIT_CODE_TIMED_OUT;
}
final long timeoutInMillis = NANOSECONDS.toMillis(remainingNanos);
if (timeoutInMillis == 0) {
// already timed out
return Constants.FORK_EXIT_CODE_TIMED_OUT;
}
watchdog = createExecuteWatchdog(timeoutInMillis);
} else {
watchdog = null; // no timeout specified
}
final Execute execute = new Execute(new PumpStreamHandler(outStream, errStream), watchdog);
execute.setCommandline(commandlineJava.getCommandline());
execute.setAntRun(getProject());
Expand Down

0 comments on commit 89b0895

Please sign in to comment.