1 /* 2 * Copyright (c) 2015, 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 24 /** 25 * @test 26 * @bug 8027634 27 * @summary Argument parsing from file 28 * @build TestHelper 29 * @run main ArgsFileTest 30 */ 31 import java.io.File; 32 import java.io.IOException; 33 import java.util.ArrayList; 34 import java.util.Arrays; 35 import java.util.Collections; 36 import java.util.HashMap; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.regex.Matcher; 40 import java.util.regex.Pattern; 41 42 public class ArgsFileTest extends TestHelper { 43 private static File testJar = null; 44 private static Map<String, String> env = new HashMap<>(); 45 46 static void init() throws IOException { 47 if (testJar != null) { 48 return; 49 } 50 testJar = new File("test.jar"); 51 StringBuilder tsrc = new StringBuilder(); 52 tsrc.append("public static void main(String... args) {\n"); 53 tsrc.append(" for (String x : args) {\n"); 54 tsrc.append(" System.out.println(x);\n"); 55 tsrc.append(" }\n"); 56 tsrc.append("}\n"); 57 createJar(testJar, new File("Foo"), tsrc.toString()); 58 59 env.put(JLDEBUG_KEY, "true"); 60 } 61 62 private File createArgFile(String fname, List<String> lines) throws IOException { 63 File argFile = new File(fname); 64 argFile.delete(); 65 createAFile(argFile, lines); 66 return argFile; 67 } 68 69 private void verifyOptions(List<String> args, TestResult tr) { 70 if (args.isEmpty()) { 71 return; 72 } 73 74 int i = 1; 75 for (String x : args) { 76 tr.matches(".*argv\\[" + i + "\\] = " + Pattern.quote(x) + ".*"); 77 i++; 78 } 79 if (! tr.testStatus) { 80 System.out.println(tr); 81 throw new RuntimeException("test fails"); 82 } 83 } 84 85 private void verifyUserArgs(List<String> args, TestResult tr, int index) { 86 if (javaCmd != TestHelper.javaCmd) { 87 tr.contains("\tFirst application arg index: 1"); 88 } else { 89 tr.contains("\tFirst application arg index: " + index); 90 91 for (String arg: args) { 92 tr.matches("^" + Pattern.quote(arg) + "$"); 93 } 94 } 95 96 if (! tr.testStatus) { 97 System.out.println(tr); 98 throw new RuntimeException("test fails"); 99 } 100 } 101 102 @Test 103 public void expandAll() throws IOException { 104 List<String> lines = new ArrayList<>(); 105 lines.add("-Xmx32m"); 106 lines.add("-Xint"); 107 File argFile1 = createArgFile("argFile1", lines); 108 lines = new ArrayList<>(); 109 lines.add("-jar"); 110 lines.add("test.jar"); 111 lines.add("uarg1 @uarg2 @@uarg3 -uarg4 uarg5"); 112 File argFile2 = createArgFile("argFile2", lines); 113 114 TestResult tr = doExec(env, javaCmd, "@argFile1", "@argFile2"); 115 116 List<String> appArgs = new ArrayList<>(); 117 appArgs.add("uarg1"); 118 appArgs.add("@uarg2"); 119 appArgs.add("@@uarg3"); 120 appArgs.add("-uarg4"); 121 appArgs.add("uarg5"); 122 123 List<String> options = new ArrayList<>(); 124 options.add("-Xmx32m"); 125 options.add("-Xint"); 126 options.add("-jar"); 127 options.add("test.jar"); 128 options.addAll(appArgs); 129 130 verifyOptions(options, tr); 131 verifyUserArgs(appArgs, tr, 5); 132 argFile1.delete(); 133 argFile2.delete(); 134 135 File cpFile = createArgFile("cpFile", Arrays.asList("-cp", "test.jar")); 136 List<String> appCmd = new ArrayList<>(); 137 appCmd.add("Foo"); 138 appCmd.addAll(appArgs); 139 File appFile = createArgFile("appFile", appCmd); 140 141 tr = doExec(env, javaCmd, "@cpFile", "@appFile"); 142 verifyOptions(Arrays.asList("-cp", "test.jar", "Foo", 143 "uarg1", "@uarg2", "@@uarg3", "-uarg4", "uarg5"), tr); 144 verifyUserArgs(appArgs, tr, 4); 145 cpFile.delete(); 146 appFile.delete(); 147 } 148 149 @Test 150 public void escapeArg() throws IOException { 151 List<String> lines = new ArrayList<>(); 152 lines.add("-Xmx32m"); 153 lines.add("-Xint"); 154 File argFile1 = createArgFile("argFile1", lines); 155 156 TestResult tr = doExec(env, javaCmd, "-cp", "@@arg", "-cp", "@", 157 "-cp", "@@@cp", "@argFile1", "@@@@Main@@@@", "-version"); 158 List<String> options = new ArrayList<>(); 159 options.add("-cp"); 160 options.add("@arg"); 161 options.add("-cp"); 162 options.add("@"); 163 options.add("-cp"); 164 options.add("@@cp"); 165 options.add("-Xmx32m"); 166 options.add("-Xint"); 167 options.add("@@@Main@@@@"); 168 options.add("-version"); 169 verifyOptions(options, tr); 170 verifyUserArgs(Collections.emptyList(), tr, options.size()); 171 argFile1.delete(); 172 } 173 174 @Test 175 public void killSwitch() throws IOException { 176 List<String> lines = new ArrayList<>(); 177 lines.add("-Xmx32m"); 178 lines.add("-Xint"); 179 File argFile1 = createArgFile("argFile1", lines); 180 lines = new ArrayList<>(); 181 lines.add("-jar"); 182 lines.add("test.jar"); 183 lines.add("uarg1 @uarg2 @@uarg3 -uarg4 uarg5"); 184 File argFile2 = createArgFile("argFile2", lines); 185 File argKill = createArgFile("argKill", 186 Collections.singletonList("--disable-@files")); 187 188 TestResult tr = doExec(env, javaCmd, "@argFile1", "--disable-@files", "@argFile2"); 189 List<String> options = new ArrayList<>(); 190 options.add("-Xmx32m"); 191 options.add("-Xint"); 192 options.add("--disable-@files"); 193 options.add("@argFile2"); 194 verifyOptions(options, tr); 195 // Main class is @argFile2 196 verifyUserArgs(Collections.emptyList(), tr, 5); 197 198 // Specify in file is same as specify inline 199 tr = doExec(env, javaCmd, "@argFile1", "@argKill", "@argFile2"); 200 verifyOptions(options, tr); 201 // Main class is @argFile2 202 verifyUserArgs(Collections.emptyList(), tr, 5); 203 204 // multiple is fine, once on is on. 205 tr = doExec(env, javaCmd, "@argKill", "@argFile1", "--disable-@files", "@argFile2"); 206 options = Arrays.asList("--disable-@files", "@argFile1", 207 "--disable-@files", "@argFile2"); 208 verifyOptions(options, tr); 209 verifyUserArgs(Collections.emptyList(), tr, 3); 210 211 // after main class, becoming an user application argument 212 tr = doExec(env, javaCmd, "@argFile2", "@argKill"); 213 options = Arrays.asList("-jar", "test.jar", "uarg1", "@uarg2", "@@uarg3", 214 "-uarg4", "uarg5", "@argKill"); 215 verifyOptions(options, tr); 216 verifyUserArgs(Arrays.asList("uarg1", "@uarg2", "@@uarg3", 217 "-uarg4", "uarg5", "@argKill"), tr, 3); 218 219 argFile1.delete(); 220 argFile2.delete(); 221 argKill.delete(); 222 } 223 224 @Test 225 public void userApplication() throws IOException { 226 List<String> lines = new ArrayList<>(); 227 lines.add("-Xmx32m"); 228 lines.add("-Xint"); 229 File vmArgs = createArgFile("vmArgs", lines); 230 File jarOpt = createArgFile("jarOpt", Arrays.asList("-jar")); 231 File cpOpt = createArgFile("cpOpt", Arrays.asList("-cp")); 232 File jarArg = createArgFile("jarArg", Arrays.asList("test.jar")); 233 File userArgs = createArgFile("userArgs", Arrays.asList("-opt", "arg", "--longopt")); 234 235 TestResult tr = doExec(env, javaCmd, 236 "@vmArgs", "@jarOpt", "test.jar", "-opt", "arg", "--longopt"); 237 verifyOptions(Arrays.asList( 238 "-Xmx32m", "-Xint", "-jar", "test.jar", "-opt", "arg", "--longopt"), tr); 239 verifyUserArgs(Arrays.asList("-opt", "arg", "--longopt"), tr, 5); 240 241 tr = doExec(env, javaCmd, "@jarOpt", "@jarArg", "@vmArgs"); 242 verifyOptions(Arrays.asList("-jar", "test.jar", "@vmArgs"), tr); 243 verifyUserArgs(Arrays.asList("@vmArgs"), tr, 3); 244 245 tr = doExec(env, javaCmd, "-cp", "@jarArg", "@vmArgs", "Foo", "@userArgs"); 246 verifyOptions(Arrays.asList("-cp", "test.jar", "-Xmx32m", "-Xint", 247 "Foo", "@userArgs"), tr); 248 verifyUserArgs(Arrays.asList("@userArgs"), tr, 6); 249 250 tr = doExec(env, javaCmd, "@cpOpt", "@jarArg", "@vmArgs", "Foo", "@userArgs"); 251 verifyOptions(Arrays.asList("-cp", "test.jar", "-Xmx32m", "-Xint", 252 "Foo", "@userArgs"), tr); 253 verifyUserArgs(Arrays.asList("@userArgs"), tr, 6); 254 255 tr = doExec(env, javaCmd, "@cpOpt", "test.jar", "@vmArgs", "Foo", "@userArgs"); 256 verifyOptions(Arrays.asList("-cp", "test.jar", "-Xmx32m", "-Xint", 257 "Foo", "@userArgs"), tr); 258 verifyUserArgs(Arrays.asList("@userArgs"), tr, 6); 259 260 vmArgs.delete(); 261 jarOpt.delete(); 262 cpOpt.delete(); 263 jarArg.delete(); 264 userArgs.delete(); 265 } 266 267 // test with missing file 268 @Test 269 public void missingFileNegativeTest() throws IOException { 270 TestResult tr = doExec(javaCmd, "@" + "missing.cmd"); 271 tr.checkNegative(); 272 tr.contains("Error: could not open `missing.cmd'"); 273 if (!tr.testStatus) { 274 System.out.println(tr); 275 throw new RuntimeException("test fails"); 276 } 277 } 278 279 public static void main(String... args) throws Exception { 280 init(); 281 ArgsFileTest a = new ArgsFileTest(); 282 a.run(args); 283 if (testExitValue > 0) { 284 System.out.println("Total of " + testExitValue + " failed"); 285 System.exit(1); 286 } else { 287 System.out.println("All tests pass"); 288 } 289 } 290 }