TestHelper.java revision 5116:d45bc4307996
1/* 2 * Copyright (c) 2008, 2012, 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 24import java.io.BufferedReader; 25import java.io.File; 26import java.io.FileFilter; 27import java.io.FileNotFoundException; 28import java.io.FileOutputStream; 29import java.io.IOException; 30import java.io.InputStreamReader; 31import java.io.PrintStream; 32import java.nio.charset.Charset; 33import java.nio.file.attribute.BasicFileAttributes; 34import java.nio.file.Files; 35import java.nio.file.FileVisitResult; 36import java.nio.file.SimpleFileVisitor; 37import java.nio.file.Path; 38import java.util.ArrayList; 39import java.util.List; 40import java.util.Locale; 41import java.util.Map; 42import javax.tools.JavaCompiler; 43import javax.tools.ToolProvider; 44 45import static java.nio.file.StandardCopyOption.*; 46import static java.nio.file.StandardOpenOption.*; 47 48/** 49 * This class provides some common utilities for the launcher tests. 50 */ 51public class TestHelper { 52 // commonly used jtreg constants 53 static final File TEST_CLASSES_DIR; 54 static final File TEST_SOURCES_DIR; 55 56 static final String JAVAHOME = System.getProperty("java.home"); 57 static final boolean isSDK = JAVAHOME.endsWith("jre"); 58 static final String javaCmd; 59 static final String javawCmd; 60 static final String java64Cmd; 61 static final String javacCmd; 62 static final JavaCompiler compiler; 63 64 static final boolean debug = Boolean.getBoolean("TestHelper.Debug"); 65 static final boolean isWindows = 66 System.getProperty("os.name", "unknown").startsWith("Windows"); 67 static final boolean isMacOSX = 68 System.getProperty("os.name", "unknown").startsWith("Mac"); 69 static final boolean is64Bit = 70 System.getProperty("sun.arch.data.model").equals("64"); 71 static final boolean is32Bit = 72 System.getProperty("sun.arch.data.model").equals("32"); 73 static final boolean isSolaris = 74 System.getProperty("os.name", "unknown").startsWith("SunOS"); 75 static final boolean isLinux = 76 System.getProperty("os.name", "unknown").startsWith("Linux"); 77 static final boolean isDualMode = isSolaris; 78 static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc"); 79 80 // make a note of the golden default locale 81 static final Locale DefaultLocale = Locale.getDefault(); 82 83 static final String JAVA_FILE_EXT = ".java"; 84 static final String CLASS_FILE_EXT = ".class"; 85 static final String JAR_FILE_EXT = ".jar"; 86 static final String JLDEBUG_KEY = "_JAVA_LAUNCHER_DEBUG"; 87 static final String EXPECTED_MARKER = "TRACER_MARKER:About to EXEC"; 88 89 static int testExitValue = 0; 90 91 static { 92 String tmp = System.getProperty("test.classes", null); 93 if (tmp == null) { 94 throw new Error("property test.classes not defined ??"); 95 } 96 TEST_CLASSES_DIR = new File(tmp).getAbsoluteFile(); 97 98 tmp = System.getProperty("test.src", null); 99 if (tmp == null) { 100 throw new Error("property test.src not defined ??"); 101 } 102 TEST_SOURCES_DIR = new File(tmp).getAbsoluteFile(); 103 104 if (is64Bit && is32Bit) { 105 throw new RuntimeException("arch model cannot be both 32 and 64 bit"); 106 } 107 if (!is64Bit && !is32Bit) { 108 throw new RuntimeException("arch model is not 32 or 64 bit ?"); 109 } 110 compiler = ToolProvider.getSystemJavaCompiler(); 111 File binDir = (isSDK) ? new File((new File(JAVAHOME)).getParentFile(), "bin") 112 : new File(JAVAHOME, "bin"); 113 File javaCmdFile = (isWindows) 114 ? new File(binDir, "java.exe") 115 : new File(binDir, "java"); 116 javaCmd = javaCmdFile.getAbsolutePath(); 117 if (!javaCmdFile.canExecute()) { 118 throw new RuntimeException("java <" + TestHelper.javaCmd + 119 "> must exist and should be executable"); 120 } 121 122 File javacCmdFile = (isWindows) 123 ? new File(binDir, "javac.exe") 124 : new File(binDir, "javac"); 125 javacCmd = javacCmdFile.getAbsolutePath(); 126 127 if (isWindows) { 128 File javawCmdFile = new File(binDir, "javaw.exe"); 129 javawCmd = javawCmdFile.getAbsolutePath(); 130 if (!javawCmdFile.canExecute()) { 131 throw new RuntimeException("java <" + javawCmd + 132 "> must exist and should be executable"); 133 } 134 } else { 135 javawCmd = null; 136 } 137 138 if (!javacCmdFile.canExecute()) { 139 throw new RuntimeException("java <" + javacCmd + 140 "> must exist and should be executable"); 141 } 142 if (isSolaris) { 143 File sparc64BinDir = new File(binDir,isSparc ? "sparcv9" : "amd64"); 144 File java64CmdFile= new File(sparc64BinDir, "java"); 145 if (java64CmdFile.exists() && java64CmdFile.canExecute()) { 146 java64Cmd = java64CmdFile.getAbsolutePath(); 147 } else { 148 java64Cmd = null; 149 } 150 } else { 151 java64Cmd = null; 152 } 153 } 154 155 /* 156 * is a dual mode available in the test jdk 157 */ 158 static boolean dualModePresent() { 159 return isDualMode && java64Cmd != null; 160 } 161 162 /* 163 * usually the jre/lib/arch-name is the same as os.arch, except for x86. 164 */ 165 static String getJreArch() { 166 String arch = System.getProperty("os.arch"); 167 return arch.equals("x86") ? "i386" : arch; 168 } 169 170 /* 171 * get the complementary jre arch ie. if sparc then return sparcv9 and 172 * vice-versa. 173 */ 174 static String getComplementaryJreArch() { 175 String arch = System.getProperty("os.arch"); 176 if (arch != null) { 177 switch (arch) { 178 case "sparc": 179 return "sparcv9"; 180 case "sparcv9": 181 return "sparc"; 182 case "x86": 183 return "amd64"; 184 case "amd64": 185 return "i386"; 186 } 187 } 188 return null; 189 } 190 191 /* 192 * A convenience method to create a jar with jar file name and defs 193 */ 194 static void createJar(File jarName, String... mainDefs) 195 throws FileNotFoundException{ 196 createJar(null, jarName, new File("Foo"), mainDefs); 197 } 198 199 /* 200 * A convenience method to create a java file, compile and jar it up, using 201 * the sole class file name in the jar, as the Main-Class attribute value. 202 */ 203 static void createJar(File jarName, File mainClass, String... mainDefs) 204 throws FileNotFoundException { 205 createJar(null, jarName, mainClass, mainDefs); 206 } 207 208 /* 209 * A convenience method to compile java files. 210 */ 211 static void compile(String... compilerArgs) { 212 if (compiler.run(null, null, null, compilerArgs) != 0) { 213 String sarg = ""; 214 for (String x : compilerArgs) { 215 sarg.concat(x + " "); 216 } 217 throw new Error("compilation failed: " + sarg); 218 } 219 } 220 221 /* 222 * A generic jar file creator to create a java file, compile it 223 * and jar it up, a specific Main-Class entry name in the 224 * manifest can be specified or a null to use the sole class file name 225 * as the Main-Class attribute value. 226 */ 227 static void createJar(String mEntry, File jarName, File mainClass, 228 String... mainDefs) throws FileNotFoundException { 229 if (jarName.exists()) { 230 jarName.delete(); 231 } 232 try (PrintStream ps = new PrintStream(new FileOutputStream(mainClass + ".java"))) { 233 ps.println("public class Foo {"); 234 if (mainDefs != null) { 235 for (String x : mainDefs) { 236 ps.println(x); 237 } 238 } 239 ps.println("}"); 240 } 241 242 String compileArgs[] = { 243 mainClass + ".java" 244 }; 245 if (compiler.run(null, null, null, compileArgs) != 0) { 246 throw new RuntimeException("compilation failed " + mainClass + ".java"); 247 } 248 if (mEntry == null) { 249 mEntry = mainClass.getName(); 250 } 251 String jarArgs[] = { 252 (debug) ? "cvfe" : "cfe", 253 jarName.getAbsolutePath(), 254 mEntry, 255 mainClass.getName() + ".class" 256 }; 257 createJar(jarArgs); 258 } 259 260 static void createJar(String... args) { 261 sun.tools.jar.Main jarTool = 262 new sun.tools.jar.Main(System.out, System.err, "JarCreator"); 263 if (!jarTool.run(args)) { 264 String message = "jar creation failed with command:"; 265 for (String x : args) { 266 message = message.concat(" " + x); 267 } 268 throw new RuntimeException(message); 269 } 270 } 271 272 static void copyFile(File src, File dst) throws IOException { 273 Path parent = dst.toPath().getParent(); 274 if (parent != null) { 275 Files.createDirectories(parent); 276 } 277 Files.copy(src.toPath(), dst.toPath(), COPY_ATTRIBUTES, REPLACE_EXISTING); 278 } 279 280 static void createFile(File outFile, List<String> content) throws IOException { 281 Files.write(outFile.getAbsoluteFile().toPath(), content, 282 Charset.defaultCharset(), CREATE_NEW); 283 } 284 285 static void recursiveDelete(File target) throws IOException { 286 if (!target.exists()) { 287 return; 288 } 289 Files.walkFileTree(target.toPath(), new SimpleFileVisitor<Path>() { 290 @Override 291 public FileVisitResult postVisitDirectory(Path dir, IOException exc) { 292 try { 293 Files.deleteIfExists(dir); 294 } catch (IOException ex) { 295 System.out.println("Error: could not delete: " + dir.toString()); 296 System.out.println(ex.getMessage()); 297 return FileVisitResult.TERMINATE; 298 } 299 return FileVisitResult.CONTINUE; 300 } 301 @Override 302 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { 303 try { 304 Files.deleteIfExists(file); 305 } catch (IOException ex) { 306 System.out.println("Error: could not delete: " + file.toString()); 307 System.out.println(ex.getMessage()); 308 return FileVisitResult.TERMINATE; 309 } 310 return FileVisitResult.CONTINUE; 311 } 312 }); 313 } 314 315 static TestResult doExec(String...cmds) { 316 return doExec(null, cmds); 317 } 318 319 /* 320 * A method which executes a java cmd and returns the results in a container 321 */ 322 static TestResult doExec(Map<String, String> envToSet, String...cmds) { 323 String cmdStr = ""; 324 for (String x : cmds) { 325 cmdStr = cmdStr.concat(x + " "); 326 } 327 ProcessBuilder pb = new ProcessBuilder(cmds); 328 Map<String, String> env = pb.environment(); 329 if (envToSet != null) { 330 env.putAll(envToSet); 331 } 332 BufferedReader rdr = null; 333 try { 334 List<String> outputList = new ArrayList<>(); 335 pb.redirectErrorStream(true); 336 Process p = pb.start(); 337 rdr = new BufferedReader(new InputStreamReader(p.getInputStream())); 338 String in = rdr.readLine(); 339 while (in != null) { 340 outputList.add(in); 341 in = rdr.readLine(); 342 } 343 p.waitFor(); 344 p.destroy(); 345 346 return new TestHelper.TestResult(cmdStr, p.exitValue(), outputList, 347 env, new Throwable("current stack of the test")); 348 } catch (Exception ex) { 349 ex.printStackTrace(); 350 throw new RuntimeException(ex.getMessage()); 351 } 352 } 353 354 static FileFilter createFilter(final String extension) { 355 return new FileFilter() { 356 @Override 357 public boolean accept(File pathname) { 358 String name = pathname.getName(); 359 if (name.endsWith(extension)) { 360 return true; 361 } 362 return false; 363 } 364 }; 365 } 366 367 static boolean isEnglishLocale() { 368 return Locale.getDefault().getLanguage().equals("en"); 369 } 370 371 /* 372 * A class to encapsulate the test results and stuff, with some ease 373 * of use methods to check the test results. 374 */ 375 static class TestResult { 376 StringBuilder status; 377 int exitValue; 378 List<String> testOutput; 379 Map<String, String> env; 380 Throwable t; 381 382 public TestResult(String str, int rv, List<String> oList, 383 Map<String, String> env, Throwable t) { 384 status = new StringBuilder("Executed command: " + str + "\n"); 385 exitValue = rv; 386 testOutput = oList; 387 this.env = env; 388 this.t = t; 389 } 390 391 void appendStatus(String x) { 392 status = status.append(" " + x + "\n"); 393 } 394 395 void checkNegative() { 396 if (exitValue == 0) { 397 appendStatus("Error: test must not return 0 exit value"); 398 testExitValue++; 399 } 400 } 401 402 void checkPositive() { 403 if (exitValue != 0) { 404 appendStatus("Error: test did not return 0 exit value"); 405 testExitValue++; 406 } 407 } 408 409 boolean isOK() { 410 return exitValue == 0; 411 } 412 413 boolean isZeroOutput() { 414 if (!testOutput.isEmpty()) { 415 appendStatus("Error: No message from cmd please"); 416 testExitValue++; 417 return false; 418 } 419 return true; 420 } 421 422 boolean isNotZeroOutput() { 423 if (testOutput.isEmpty()) { 424 appendStatus("Error: Missing message"); 425 testExitValue++; 426 return false; 427 } 428 return true; 429 } 430 431 @Override 432 public String toString() { 433 status.append("++++Begin Test Info++++\n"); 434 status.append("++++Test Environment++++\n"); 435 for (String x : env.keySet()) { 436 status.append(x).append("=").append(env.get(x)).append("\n"); 437 } 438 status.append("++++Test Output++++\n"); 439 for (String x : testOutput) { 440 appendStatus(x); 441 } 442 status.append("++++Test Stack Trace++++\n"); 443 status.append(t.toString()); 444 for (StackTraceElement e : t.getStackTrace()) { 445 status.append(e.toString()); 446 } 447 status.append("++++End of Test Info++++\n"); 448 return status.toString(); 449 } 450 451 boolean contains(String str) { 452 for (String x : testOutput) { 453 if (x.contains(str)) { 454 return true; 455 } 456 } 457 appendStatus("Error: string <" + str + "> not found"); 458 testExitValue++; 459 return false; 460 } 461 462 boolean matches(String stringToMatch) { 463 for (String x : testOutput) { 464 if (x.matches(stringToMatch)) { 465 return true; 466 } 467 } 468 appendStatus("Error: string <" + stringToMatch + "> not found"); 469 testExitValue++; 470 return false; 471 } 472 } 473} 474