1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package jdk.jpackage.test; 24 25 import java.io.File; 26 import java.nio.file.Files; 27 import java.nio.file.Path; 28 import java.util.ArrayList; 29 import java.util.Arrays; 30 import java.util.Collections; 31 import java.util.List; 32 33 public final class Executor extends CommandArguments<Executor> { 34 35 public Executor() { 36 saveOutputType = SaveOutputType.NONE; 37 } 38 39 public Executor setExecutable(String v) { 40 executable = v; 41 return this; 42 } 43 44 public Executor setDirectory(Path v) { 45 directory = v; 46 return this; 47 } 48 49 public Executor setExecutable(JavaTool v) { 50 return setExecutable(v.getPath().getAbsolutePath()); 51 } 52 53 public Executor saveOutput() { 54 saveOutputType = SaveOutputType.FULL; 55 return this; 56 } 57 58 public Executor saveFirstLineOfOutput() { 59 saveOutputType = SaveOutputType.FIRST_LINE; 60 return this; 61 } 62 63 public class Result { 64 65 Result(int exitCode) { 66 this.exitCode = exitCode; 67 } 68 69 public String getFirstLineOfOutput() { 70 return output.get(0).trim(); 71 } 72 73 public List<String> getOutput() { 74 return output; 75 } 76 77 public String getPrintableCommandLine() { 78 return Executor.this.getPrintableCommandLine(); 79 } 80 81 public Result assertExitCodeIs(int expectedExitCode) { 82 Test.assertEquals(expectedExitCode, exitCode, String.format( 83 "Check command %s exited with %d code", 84 getPrintableCommandLine(), expectedExitCode)); 85 return this; 86 } 87 88 public Result assertExitCodeIsZero() { 89 return assertExitCodeIs(0); 90 } 91 92 int exitCode; 93 List<String> output; 94 } 95 96 public Result execute() { 97 try { 98 return executeImpl(); 99 } catch (RuntimeException e) { 100 throw e; 101 } catch (Exception e) { 102 throw new RuntimeException(e); 103 } 104 } 105 106 private Result executeImpl() throws Exception { 107 List<String> command = new ArrayList<>(); 108 command.add(executable); 109 command.addAll(args); 110 Path outputFile = null; 111 ProcessBuilder builder = new ProcessBuilder(command); 112 StringBuilder sb = new StringBuilder(getPrintableCommandLine()); 113 if (saveOutputType != SaveOutputType.NONE) { 114 outputFile = Test.createTempFile(".out"); 115 builder.redirectErrorStream(true); 116 builder.redirectOutput(outputFile.toFile()); 117 sb.append(String.format("; redirect output to [%s]", outputFile)); 118 } 119 if (directory != null) { 120 builder.directory(directory.toFile()); 121 sb.append(String.format("; in directory [%s]", directory)); 122 } 123 124 try { 125 Test.trace("Execute " + sb.toString() + "..."); 126 Process process = builder.start(); 127 Result reply = new Result(process.waitFor()); 128 Test.trace("Done. Exit code: " + reply.exitCode); 129 if (saveOutputType == SaveOutputType.FIRST_LINE) { 130 reply.output = Arrays.asList( 131 Files.readAllLines(outputFile).stream().findFirst().get()); 132 } else if (saveOutputType == SaveOutputType.FULL) { 133 reply.output = Collections.unmodifiableList(Files.readAllLines( 134 outputFile)); 135 } 136 return reply; 137 } finally { 138 if (outputFile != null) { 139 Files.deleteIfExists(outputFile); 140 } 141 } 142 } 143 144 public String getPrintableCommandLine() { 145 return "[" + executable + "]; args(" + args.size() + ")=" + Arrays.toString( 146 args.toArray()); 147 } 148 149 private String executable; 150 private SaveOutputType saveOutputType; 151 private Path directory; 152 153 private static enum SaveOutputType { 154 NONE, FULL, FIRST_LINE 155 }; 156 }