--- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java Mon Sep 30 15:59:50 2019 -0400
+++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java Mon Sep 30 19:11:19 2019 -0400
@@ -22,28 +22,37 @@
*/
package jdk.jpackage.test;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.nio.file.Files;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.StringReader;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
-import java.util.regex.Matcher;
+import java.util.Set;
import java.util.regex.Pattern;
import java.util.spi.ToolProvider;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import jdk.jpackage.test.Functional.ThrowingSupplier;
public final class Executor extends CommandArguments<Executor> {
public Executor() {
- saveOutputType = SaveOutputType.NONE;
+ saveOutputType = new HashSet<>(Set.of(SaveOutputType.NONE));
}
public Executor setExecutable(String v) {
+ return setExecutable(Path.of(v));
+ }
+
+ public Executor setExecutable(Path v) {
executable = v;
if (executable != null) {
toolProvider = null;
@@ -53,6 +62,7 @@
public Executor setToolProvider(ToolProvider v) {
toolProvider = v;
+ filterOutJcovOutput = true;
if (toolProvider != null) {
executable = null;
}
@@ -65,21 +75,72 @@
}
public Executor setExecutable(JavaTool v) {
- return setExecutable(v.getPath().getAbsolutePath());
+ filterOutJcovOutput = true;
+ return setExecutable(v.getPath());
}
+ /**
+ * Configures this instance to save full output that command will produce.
+ * This function is mutual exclusive with
+ * saveFirstLineOfOutput() function.
+ *
+ * @return this
+ */
public Executor saveOutput() {
- saveOutputType = SaveOutputType.FULL;
+ saveOutputType.remove(SaveOutputType.FIRST_LINE);
+ saveOutputType.add(SaveOutputType.FULL);
return this;
}
- public Executor saveFirstLineOfOutput() {
- saveOutputType = SaveOutputType.FIRST_LINE;
+ /**
+ * Configures how to save output that command will produce. If
+ * <code>v</code> is <code>true</code>, the function call is equivalent to
+ * <code>saveOutput()</code> call. If <code>v</code> is <code>false</code>,
+ * the function will result in not preserving command output.
+ *
+ * @return this
+ */
+ public Executor saveOutput(boolean v) {
+ if (v) {
+ saveOutput();
+ } else {
+ saveOutputType.remove(SaveOutputType.FIRST_LINE);
+ saveOutputType.remove(SaveOutputType.FULL);
+ }
return this;
}
- public Executor dumpOtput() {
- saveOutputType = SaveOutputType.DUMP;
+ /**
+ * Configures this instance to save only the first line out output that
+ * command will produce. This function is mutual exclusive with
+ * saveOutput() function.
+ *
+ * @return this
+ */
+ public Executor saveFirstLineOfOutput() {
+ saveOutputType.add(SaveOutputType.FIRST_LINE);
+ saveOutputType.remove(SaveOutputType.FULL);
+ return this;
+ }
+
+ /**
+ * Configures this instance to dump all output that command will produce to
+ * System.out and System.err. Can be used together with saveOutput() and
+ * saveFirstLineOfOutput() to save command output and also copy it in the
+ * default output streams.
+ *
+ * @return this
+ */
+ public Executor dumpOutput() {
+ return dumpOutput(true);
+ }
+
+ public Executor dumpOutput(boolean v) {
+ if (v) {
+ saveOutputType.add(SaveOutputType.DUMP);
+ } else {
+ saveOutputType.remove(SaveOutputType.DUMP);
+ }
return this;
}
@@ -102,7 +163,7 @@
}
public Result assertExitCodeIs(int expectedExitCode) {
- Test.assertEquals(expectedExitCode, exitCode, String.format(
+ TKit.assertEquals(expectedExitCode, exitCode, String.format(
"Check command %s exited with %d code",
getPrintableCommandLine(), expectedExitCode));
return this;
@@ -117,21 +178,17 @@
}
public Result execute() {
- if (toolProvider != null) {
- return runToolProvider();
- }
+ return ThrowingSupplier.toSupplier(() -> {
+ if (toolProvider != null) {
+ return runToolProvider();
+ }
- try {
if (executable != null) {
return runExecutable();
}
- } catch (RuntimeException e) {
- throw e;
- } catch (IOException | InterruptedException e) {
- throw new RuntimeException(e);
- }
- throw new IllegalStateException("No command to execute");
+ throw new IllegalStateException("No command to execute");
+ }).get();
}
public String executeAndGetFirstLineOfOutput() {
@@ -142,69 +199,119 @@
return saveOutput().execute().assertExitCodeIsZero().getOutput();
}
+ private boolean withSavedOutput() {
+ return saveOutputType.contains(SaveOutputType.FULL) || saveOutputType.contains(
+ SaveOutputType.FIRST_LINE);
+ }
+
private Result runExecutable() throws IOException, InterruptedException {
List<String> command = new ArrayList<>();
- command.add(executable);
+ command.add(executable.toString());
command.addAll(args);
- Path outputFile = null;
ProcessBuilder builder = new ProcessBuilder(command);
StringBuilder sb = new StringBuilder(getPrintableCommandLine());
- if (saveOutputType != SaveOutputType.NONE) {
+ if (withSavedOutput()) {
builder.redirectErrorStream(true);
-
- if (saveOutputType == SaveOutputType.DUMP) {
- builder.inheritIO();
- sb.append("; redirect output to stdout");
- } else {
- outputFile = Test.createTempFile(".out");
- builder.redirectOutput(outputFile.toFile());
- sb.append(String.format("; redirect output to [%s]", outputFile));
- }
+ sb.append("; save output");
+ } else if (saveOutputType.contains(SaveOutputType.DUMP)) {
+ builder.inheritIO();
+ sb.append("; inherit I/O");
}
if (directory != null) {
builder.directory(directory.toFile());
sb.append(String.format("; in directory [%s]", directory));
}
- try {
- Test.trace("Execute " + sb.toString() + "...");
- Process process = builder.start();
- Result reply = new Result(process.waitFor());
- Test.trace("Done. Exit code: " + reply.exitCode);
- if (saveOutputType == SaveOutputType.FIRST_LINE) {
- // If the command produced no ouput, save null in 'result.output' list.
- reply.output = Arrays.asList(
- Files.readAllLines(outputFile).stream().findFirst().orElse(
- null));
- } else if (saveOutputType == SaveOutputType.FULL) {
- reply.output = Collections.unmodifiableList(Files.readAllLines(
- outputFile));
- }
- return reply;
- } finally {
- if (outputFile != null) {
- Files.deleteIfExists(outputFile);
+ TKit.trace("Execute " + sb.toString() + "...");
+ Process process = builder.start();
+
+ List<String> outputLines = null;
+ if (withSavedOutput()) {
+ try (BufferedReader outReader = new BufferedReader(
+ new InputStreamReader(process.getInputStream()))) {
+ if (saveOutputType.contains(SaveOutputType.DUMP) || saveOutputType.contains(
+ SaveOutputType.FULL)) {
+ outputLines = outReader.lines().collect(Collectors.toList());
+ } else {
+ outputLines = Arrays.asList(
+ outReader.lines().findFirst().orElse(null));
+ }
+ } finally {
+ if (saveOutputType.contains(SaveOutputType.DUMP) && outputLines != null) {
+ outputLines.stream().forEach(System.out::println);
+ if (saveOutputType.contains(SaveOutputType.FIRST_LINE)) {
+ // Pick the first line of saved output if there is one
+ for (String line: outputLines) {
+ outputLines = List.of(line);
+ break;
+ }
+ }
+ }
}
}
+
+ Result reply = new Result(process.waitFor());
+ TKit.trace("Done. Exit code: " + reply.exitCode);
+
+ if (outputLines != null) {
+ reply.output = Collections.unmodifiableList(outputLines);
+ }
+ return reply;
+ }
+
+ private Result runToolProvider(PrintStream out, PrintStream err) {
+ TKit.trace("Execute " + getPrintableCommandLine() + "...");
+ Result reply = new Result(toolProvider.run(out, err, args.toArray(
+ String[]::new)));
+ TKit.trace("Done. Exit code: " + reply.exitCode);
+ return reply;
}
- private Result runToolProvider() {
- StringWriter writer = new StringWriter();
- PrintWriter pw = new PrintWriter(writer);
+
+ private Result runToolProvider() throws IOException {
+ if (!withSavedOutput()) {
+ if (saveOutputType.contains(SaveOutputType.DUMP)) {
+ return runToolProvider(System.out, System.err);
+ }
- Test.trace("Execute " + getPrintableCommandLine() + "...");
- Result reply = new Result(toolProvider.run(pw, pw, args.toArray(
- String[]::new)));
- Test.trace("Done. Exit code: " + reply.exitCode);
+ PrintStream nullPrintStream = new PrintStream(new OutputStream() {
+ @Override
+ public void write(int b) {
+ // Nop
+ }
+ });
+ return runToolProvider(nullPrintStream, nullPrintStream);
+ }
- List lines = List.of(writer.toString().split("\\R", -1));
+ try (ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(buf)) {
+ Result reply = runToolProvider(ps, ps);
+ ps.flush();
+ try (BufferedReader bufReader = new BufferedReader(new StringReader(
+ buf.toString()))) {
+ if (saveOutputType.contains(SaveOutputType.FIRST_LINE)) {
+ String firstLine = filterJcovOutput(bufReader.lines()).findFirst().orElse(
+ null);
+ if (firstLine != null) {
+ reply.output = List.of(firstLine);
+ }
+ } else if (saveOutputType.contains(SaveOutputType.FULL)) {
+ reply.output = filterJcovOutput(bufReader.lines()).collect(
+ Collectors.toUnmodifiableList());
+ }
- if (saveOutputType == SaveOutputType.FIRST_LINE) {
- reply.output = Stream.of(lines).findFirst().get();
- } else if (saveOutputType == SaveOutputType.FULL) {
- reply.output = Collections.unmodifiableList(lines);
+ if (saveOutputType.contains(SaveOutputType.DUMP)) {
+ Stream<String> lines;
+ if (saveOutputType.contains(SaveOutputType.FULL)) {
+ lines = reply.output.stream();
+ } else {
+ lines = bufReader.lines();
+ }
+ lines.forEach(System.out::println);
+ }
+ }
+ return reply;
}
- return reply;
}
public String getPrintableCommandLine() {
@@ -216,7 +323,7 @@
format = "tool provider " + format;
exec = toolProvider.name();
} else {
- exec = executable;
+ exec = executable.toString();
}
return String.format(format, printCommandLine(exec, args),
@@ -232,10 +339,18 @@
Collectors.joining(" "));
}
+ private Stream<String> filterJcovOutput(Stream<String> lines) {
+ if (filterOutJcovOutput) {
+ return lines.filter(line -> !line.startsWith("Picked up"));
+ }
+ return lines;
+ }
+
private ToolProvider toolProvider;
- private String executable;
- private SaveOutputType saveOutputType;
+ private Path executable;
+ private Set<SaveOutputType> saveOutputType;
private Path directory;
+ private boolean filterOutJcovOutput;
private static enum SaveOutputType {
NONE, FULL, FIRST_LINE, DUMP