blob: 8fd7ffe0800c3300ebd78909c058a36fb71d0fae [file] [log] [blame]
ksrini20a64b22008-09-24 15:07:41 -07001/*
ksriniac5e02f2012-01-11 08:14:47 -08002 * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
ksrini20a64b22008-09-24 15:07:41 -07003 * 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 *
ohair2283b9d2010-05-25 15:58:33 -070019 * 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.
ksrini20a64b22008-09-24 15:07:41 -070022 */
23
ksrinie1a34382012-04-24 10:37:01 -070024import java.io.StringWriter;
25import java.io.PrintWriter;
ksrini20a64b22008-09-24 15:07:41 -070026import java.io.BufferedReader;
27import java.io.File;
ksriniac5e02f2012-01-11 08:14:47 -080028import java.io.FileFilter;
ksrini20a64b22008-09-24 15:07:41 -070029import java.io.FileNotFoundException;
30import java.io.FileOutputStream;
ksrinif8cc5972011-04-07 12:06:32 -070031import java.io.IOException;
ksrini20a64b22008-09-24 15:07:41 -070032import java.io.InputStreamReader;
33import java.io.PrintStream;
ksrinif127cd92012-01-28 10:46:46 -080034import java.nio.charset.Charset;
ksriniac5e02f2012-01-11 08:14:47 -080035import java.nio.file.attribute.BasicFileAttributes;
ksrinif8cc5972011-04-07 12:06:32 -070036import java.nio.file.Files;
ksriniac5e02f2012-01-11 08:14:47 -080037import java.nio.file.FileVisitResult;
38import java.nio.file.SimpleFileVisitor;
ksrinif8cc5972011-04-07 12:06:32 -070039import java.nio.file.Path;
ksrini20a64b22008-09-24 15:07:41 -070040import java.util.ArrayList;
41import java.util.List;
ksrinif127cd92012-01-28 10:46:46 -080042import java.util.Locale;
ksrini20a64b22008-09-24 15:07:41 -070043import java.util.Map;
44import javax.tools.JavaCompiler;
ksriniac5e02f2012-01-11 08:14:47 -080045import javax.tools.ToolProvider;
ksrini20a64b22008-09-24 15:07:41 -070046
ksrinif8cc5972011-04-07 12:06:32 -070047import static java.nio.file.StandardCopyOption.*;
ksrinif127cd92012-01-28 10:46:46 -080048import static java.nio.file.StandardOpenOption.*;
ksrinif8cc5972011-04-07 12:06:32 -070049
ksrini20a64b22008-09-24 15:07:41 -070050/**
ksrinif8cc5972011-04-07 12:06:32 -070051 * This class provides some common utilities for the launcher tests.
ksrini20a64b22008-09-24 15:07:41 -070052 */
ksrinif127cd92012-01-28 10:46:46 -080053public class TestHelper {
ksrinieed01b82012-01-24 09:58:44 -080054 // commonly used jtreg constants
55 static final File TEST_CLASSES_DIR;
56 static final File TEST_SOURCES_DIR;
57
ksrini11e7f1b2009-11-20 11:01:32 -080058 static final String JAVAHOME = System.getProperty("java.home");
ksrini38a8aeb2012-03-29 17:49:34 -070059 static final String JAVA_BIN;
ksrini20a64b22008-09-24 15:07:41 -070060 static final boolean isSDK = JAVAHOME.endsWith("jre");
61 static final String javaCmd;
ksrinidd194042012-01-03 08:33:30 -080062 static final String javawCmd;
ksrini11e7f1b2009-11-20 11:01:32 -080063 static final String java64Cmd;
ksrini20a64b22008-09-24 15:07:41 -070064 static final String javacCmd;
65 static final JavaCompiler compiler;
66
ksrini11e7f1b2009-11-20 11:01:32 -080067 static final boolean debug = Boolean.getBoolean("TestHelper.Debug");
ksrini20a64b22008-09-24 15:07:41 -070068 static final boolean isWindows =
69 System.getProperty("os.name", "unknown").startsWith("Windows");
michaelm5ac8c152012-03-06 20:34:38 +000070 static final boolean isMacOSX =
jmelvin75479992012-04-16 18:09:53 -040071 System.getProperty("os.name", "unknown").contains("OS X");
ksrini11e7f1b2009-11-20 11:01:32 -080072 static final boolean is64Bit =
73 System.getProperty("sun.arch.data.model").equals("64");
74 static final boolean is32Bit =
75 System.getProperty("sun.arch.data.model").equals("32");
76 static final boolean isSolaris =
77 System.getProperty("os.name", "unknown").startsWith("SunOS");
78 static final boolean isLinux =
79 System.getProperty("os.name", "unknown").startsWith("Linux");
80 static final boolean isDualMode = isSolaris;
81 static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc");
82
ksrinif127cd92012-01-28 10:46:46 -080083 // make a note of the golden default locale
84 static final Locale DefaultLocale = Locale.getDefault();
85
ksriniac5e02f2012-01-11 08:14:47 -080086 static final String JAVA_FILE_EXT = ".java";
87 static final String CLASS_FILE_EXT = ".class";
88 static final String JAR_FILE_EXT = ".jar";
ksrini38a8aeb2012-03-29 17:49:34 -070089 static final String EXE_FILE_EXT = ".exe";
ksrinif127cd92012-01-28 10:46:46 -080090 static final String JLDEBUG_KEY = "_JAVA_LAUNCHER_DEBUG";
91 static final String EXPECTED_MARKER = "TRACER_MARKER:About to EXEC";
ksrinie1a34382012-04-24 10:37:01 -070092 static final String TEST_PREFIX = "###TestError###: ";
ksriniac5e02f2012-01-11 08:14:47 -080093
ksrini20a64b22008-09-24 15:07:41 -070094 static int testExitValue = 0;
95
96 static {
ksrinieed01b82012-01-24 09:58:44 -080097 String tmp = System.getProperty("test.classes", null);
98 if (tmp == null) {
99 throw new Error("property test.classes not defined ??");
100 }
101 TEST_CLASSES_DIR = new File(tmp).getAbsoluteFile();
102
103 tmp = System.getProperty("test.src", null);
104 if (tmp == null) {
105 throw new Error("property test.src not defined ??");
106 }
107 TEST_SOURCES_DIR = new File(tmp).getAbsoluteFile();
108
ksrini11e7f1b2009-11-20 11:01:32 -0800109 if (is64Bit && is32Bit) {
110 throw new RuntimeException("arch model cannot be both 32 and 64 bit");
111 }
112 if (!is64Bit && !is32Bit) {
113 throw new RuntimeException("arch model is not 32 or 64 bit ?");
114 }
ksrini20a64b22008-09-24 15:07:41 -0700115 compiler = ToolProvider.getSystemJavaCompiler();
116 File binDir = (isSDK) ? new File((new File(JAVAHOME)).getParentFile(), "bin")
117 : new File(JAVAHOME, "bin");
ksrini38a8aeb2012-03-29 17:49:34 -0700118 JAVA_BIN = binDir.getAbsolutePath();
ksrini20a64b22008-09-24 15:07:41 -0700119 File javaCmdFile = (isWindows)
120 ? new File(binDir, "java.exe")
121 : new File(binDir, "java");
122 javaCmd = javaCmdFile.getAbsolutePath();
123 if (!javaCmdFile.canExecute()) {
ksrinidd194042012-01-03 08:33:30 -0800124 throw new RuntimeException("java <" + TestHelper.javaCmd +
125 "> must exist and should be executable");
ksrini20a64b22008-09-24 15:07:41 -0700126 }
127
128 File javacCmdFile = (isWindows)
129 ? new File(binDir, "javac.exe")
130 : new File(binDir, "javac");
131 javacCmd = javacCmdFile.getAbsolutePath();
ksrinidd194042012-01-03 08:33:30 -0800132
133 if (isWindows) {
134 File javawCmdFile = new File(binDir, "javaw.exe");
135 javawCmd = javawCmdFile.getAbsolutePath();
136 if (!javawCmdFile.canExecute()) {
137 throw new RuntimeException("java <" + javawCmd +
138 "> must exist and should be executable");
139 }
140 } else {
141 javawCmd = null;
142 }
143
ksrini20a64b22008-09-24 15:07:41 -0700144 if (!javacCmdFile.canExecute()) {
ksrinidd194042012-01-03 08:33:30 -0800145 throw new RuntimeException("java <" + javacCmd +
146 "> must exist and should be executable");
ksrini20a64b22008-09-24 15:07:41 -0700147 }
ksrini11e7f1b2009-11-20 11:01:32 -0800148 if (isSolaris) {
149 File sparc64BinDir = new File(binDir,isSparc ? "sparcv9" : "amd64");
150 File java64CmdFile= new File(sparc64BinDir, "java");
151 if (java64CmdFile.exists() && java64CmdFile.canExecute()) {
152 java64Cmd = java64CmdFile.getAbsolutePath();
153 } else {
154 java64Cmd = null;
155 }
156 } else {
157 java64Cmd = null;
158 }
159 }
160
161 /*
ksrinif8cc5972011-04-07 12:06:32 -0700162 * is a dual mode available in the test jdk
163 */
164 static boolean dualModePresent() {
165 return isDualMode && java64Cmd != null;
166 }
167
168 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800169 * usually the jre/lib/arch-name is the same as os.arch, except for x86.
170 */
171 static String getJreArch() {
172 String arch = System.getProperty("os.arch");
173 return arch.equals("x86") ? "i386" : arch;
174 }
175
176 /*
ksrinif8cc5972011-04-07 12:06:32 -0700177 * get the complementary jre arch ie. if sparc then return sparcv9 and
178 * vice-versa.
179 */
180 static String getComplementaryJreArch() {
181 String arch = System.getProperty("os.arch");
182 if (arch != null) {
183 switch (arch) {
184 case "sparc":
185 return "sparcv9";
186 case "sparcv9":
187 return "sparc";
188 case "x86":
189 return "amd64";
190 case "amd64":
191 return "i386";
192 }
193 }
194 return null;
195 }
196
197 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800198 * A convenience method to create a jar with jar file name and defs
199 */
200 static void createJar(File jarName, String... mainDefs)
201 throws FileNotFoundException{
202 createJar(null, jarName, new File("Foo"), mainDefs);
ksrini20a64b22008-09-24 15:07:41 -0700203 }
204
205 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700206 * A convenience method to create a java file, compile and jar it up, using
207 * the sole class file name in the jar, as the Main-Class attribute value.
ksrini20a64b22008-09-24 15:07:41 -0700208 */
209 static void createJar(File jarName, File mainClass, String... mainDefs)
210 throws FileNotFoundException {
211 createJar(null, jarName, mainClass, mainDefs);
212 }
213
214 /*
ksrinif127cd92012-01-28 10:46:46 -0800215 * A convenience method to compile java files.
216 */
217 static void compile(String... compilerArgs) {
218 if (compiler.run(null, null, null, compilerArgs) != 0) {
219 String sarg = "";
220 for (String x : compilerArgs) {
221 sarg.concat(x + " ");
222 }
223 throw new Error("compilation failed: " + sarg);
224 }
225 }
226
227 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700228 * A generic jar file creator to create a java file, compile it
229 * and jar it up, a specific Main-Class entry name in the
230 * manifest can be specified or a null to use the sole class file name
231 * as the Main-Class attribute value.
ksrini20a64b22008-09-24 15:07:41 -0700232 */
ksrinicafaf7c2008-10-01 09:04:42 -0700233 static void createJar(String mEntry, File jarName, File mainClass,
234 String... mainDefs) throws FileNotFoundException {
ksrini20a64b22008-09-24 15:07:41 -0700235 if (jarName.exists()) {
236 jarName.delete();
237 }
ksrini37e8b502011-07-19 10:58:50 -0700238 try (PrintStream ps = new PrintStream(new FileOutputStream(mainClass + ".java"))) {
239 ps.println("public class Foo {");
240 if (mainDefs != null) {
241 for (String x : mainDefs) {
242 ps.println(x);
243 }
ksrini20a64b22008-09-24 15:07:41 -0700244 }
ksrini37e8b502011-07-19 10:58:50 -0700245 ps.println("}");
ksrini20a64b22008-09-24 15:07:41 -0700246 }
ksrini20a64b22008-09-24 15:07:41 -0700247
248 String compileArgs[] = {
249 mainClass + ".java"
250 };
251 if (compiler.run(null, null, null, compileArgs) != 0) {
252 throw new RuntimeException("compilation failed " + mainClass + ".java");
253 }
ksrinicafaf7c2008-10-01 09:04:42 -0700254 if (mEntry == null) {
ksrini20a64b22008-09-24 15:07:41 -0700255 mEntry = mainClass.getName();
256 }
257 String jarArgs[] = {
258 (debug) ? "cvfe" : "cfe",
259 jarName.getAbsolutePath(),
260 mEntry,
261 mainClass.getName() + ".class"
262 };
ksrini37e8b502011-07-19 10:58:50 -0700263 createJar(jarArgs);
264 }
265
266 static void createJar(String... args) {
ksrini20a64b22008-09-24 15:07:41 -0700267 sun.tools.jar.Main jarTool =
268 new sun.tools.jar.Main(System.out, System.err, "JarCreator");
ksrini37e8b502011-07-19 10:58:50 -0700269 if (!jarTool.run(args)) {
270 String message = "jar creation failed with command:";
271 for (String x : args) {
272 message = message.concat(" " + x);
273 }
274 throw new RuntimeException(message);
ksrini20a64b22008-09-24 15:07:41 -0700275 }
ksrini37e8b502011-07-19 10:58:50 -0700276 }
ksrini20a64b22008-09-24 15:07:41 -0700277
ksrinif8cc5972011-04-07 12:06:32 -0700278 static void copyFile(File src, File dst) throws IOException {
279 Path parent = dst.toPath().getParent();
280 if (parent != null) {
281 Files.createDirectories(parent);
282 }
283 Files.copy(src.toPath(), dst.toPath(), COPY_ATTRIBUTES, REPLACE_EXISTING);
284 }
285
ksrinif127cd92012-01-28 10:46:46 -0800286 static void createFile(File outFile, List<String> content) throws IOException {
287 Files.write(outFile.getAbsoluteFile().toPath(), content,
288 Charset.defaultCharset(), CREATE_NEW);
289 }
290
ksrinif8cc5972011-04-07 12:06:32 -0700291 static void recursiveDelete(File target) throws IOException {
292 if (!target.exists()) {
293 return;
294 }
295 Files.walkFileTree(target.toPath(), new SimpleFileVisitor<Path>() {
296 @Override
297 public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
298 try {
299 Files.deleteIfExists(dir);
300 } catch (IOException ex) {
301 System.out.println("Error: could not delete: " + dir.toString());
302 System.out.println(ex.getMessage());
303 return FileVisitResult.TERMINATE;
304 }
305 return FileVisitResult.CONTINUE;
306 }
307 @Override
308 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
309 try {
310 Files.deleteIfExists(file);
311 } catch (IOException ex) {
312 System.out.println("Error: could not delete: " + file.toString());
313 System.out.println(ex.getMessage());
314 return FileVisitResult.TERMINATE;
315 }
316 return FileVisitResult.CONTINUE;
317 }
318 });
319 }
320
ksrini11e7f1b2009-11-20 11:01:32 -0800321 static TestResult doExec(String...cmds) {
322 return doExec(null, cmds);
323 }
324
ksrini20a64b22008-09-24 15:07:41 -0700325 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700326 * A method which executes a java cmd and returns the results in a container
ksrini20a64b22008-09-24 15:07:41 -0700327 */
ksrini11e7f1b2009-11-20 11:01:32 -0800328 static TestResult doExec(Map<String, String> envToSet, String...cmds) {
ksrini20a64b22008-09-24 15:07:41 -0700329 String cmdStr = "";
330 for (String x : cmds) {
331 cmdStr = cmdStr.concat(x + " ");
332 }
333 ProcessBuilder pb = new ProcessBuilder(cmds);
334 Map<String, String> env = pb.environment();
ksrini11e7f1b2009-11-20 11:01:32 -0800335 if (envToSet != null) {
336 env.putAll(envToSet);
337 }
ksrini20a64b22008-09-24 15:07:41 -0700338 BufferedReader rdr = null;
339 try {
ksrinif8cc5972011-04-07 12:06:32 -0700340 List<String> outputList = new ArrayList<>();
ksrini20a64b22008-09-24 15:07:41 -0700341 pb.redirectErrorStream(true);
342 Process p = pb.start();
343 rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
344 String in = rdr.readLine();
345 while (in != null) {
346 outputList.add(in);
347 in = rdr.readLine();
348 }
349 p.waitFor();
350 p.destroy();
ksrinif8cc5972011-04-07 12:06:32 -0700351
352 return new TestHelper.TestResult(cmdStr, p.exitValue(), outputList,
353 env, new Throwable("current stack of the test"));
ksrini20a64b22008-09-24 15:07:41 -0700354 } catch (Exception ex) {
355 ex.printStackTrace();
356 throw new RuntimeException(ex.getMessage());
357 }
358 }
359
ksriniac5e02f2012-01-11 08:14:47 -0800360 static FileFilter createFilter(final String extension) {
361 return new FileFilter() {
362 @Override
363 public boolean accept(File pathname) {
364 String name = pathname.getName();
365 if (name.endsWith(extension)) {
366 return true;
367 }
368 return false;
369 }
370 };
371 }
372
ksrinif127cd92012-01-28 10:46:46 -0800373 static boolean isEnglishLocale() {
374 return Locale.getDefault().getLanguage().equals("en");
375 }
376
ksrini20a64b22008-09-24 15:07:41 -0700377 /*
378 * A class to encapsulate the test results and stuff, with some ease
379 * of use methods to check the test results.
380 */
381 static class TestResult {
ksrinie1a34382012-04-24 10:37:01 -0700382 PrintWriter status;
383 StringWriter sw;
ksrini20a64b22008-09-24 15:07:41 -0700384 int exitValue;
385 List<String> testOutput;
ksrinif8cc5972011-04-07 12:06:32 -0700386 Map<String, String> env;
387 Throwable t;
ksrini20a64b22008-09-24 15:07:41 -0700388
ksrinif8cc5972011-04-07 12:06:32 -0700389 public TestResult(String str, int rv, List<String> oList,
390 Map<String, String> env, Throwable t) {
ksrinie1a34382012-04-24 10:37:01 -0700391 sw = new StringWriter();
392 status = new PrintWriter(sw);
393 status.println("Executed command: " + str + "\n");
ksrini20a64b22008-09-24 15:07:41 -0700394 exitValue = rv;
395 testOutput = oList;
ksrinif8cc5972011-04-07 12:06:32 -0700396 this.env = env;
397 this.t = t;
ksrini20a64b22008-09-24 15:07:41 -0700398 }
399
ksrinie1a34382012-04-24 10:37:01 -0700400 void appendError(String x) {
401 status.println(TEST_PREFIX + x);
402 }
403
404 void indentStatus(String x) {
405 status.println(" " + x);
ksrini11e7f1b2009-11-20 11:01:32 -0800406 }
407
ksrini20a64b22008-09-24 15:07:41 -0700408 void checkNegative() {
409 if (exitValue == 0) {
ksrinie1a34382012-04-24 10:37:01 -0700410 appendError("test must not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700411 testExitValue++;
412 }
413 }
414
415 void checkPositive() {
416 if (exitValue != 0) {
ksrinie1a34382012-04-24 10:37:01 -0700417 appendError("test did not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700418 testExitValue++;
419 }
420 }
421
422 boolean isOK() {
423 return exitValue == 0;
424 }
425
426 boolean isZeroOutput() {
427 if (!testOutput.isEmpty()) {
ksrinie1a34382012-04-24 10:37:01 -0700428 appendError("No message from cmd please");
ksrini20a64b22008-09-24 15:07:41 -0700429 testExitValue++;
430 return false;
431 }
432 return true;
433 }
434
435 boolean isNotZeroOutput() {
436 if (testOutput.isEmpty()) {
ksrinie1a34382012-04-24 10:37:01 -0700437 appendError("Missing message");
ksrini20a64b22008-09-24 15:07:41 -0700438 testExitValue++;
439 return false;
440 }
441 return true;
442 }
443
ksrini11e7f1b2009-11-20 11:01:32 -0800444 @Override
ksrini20a64b22008-09-24 15:07:41 -0700445 public String toString() {
ksrinie1a34382012-04-24 10:37:01 -0700446 status.println("++++Begin Test Info++++");
447 status.println("++++Test Environment++++");
ksrinif8cc5972011-04-07 12:06:32 -0700448 for (String x : env.keySet()) {
ksrinie1a34382012-04-24 10:37:01 -0700449 indentStatus(x + "=" + env.get(x));
ksrinif8cc5972011-04-07 12:06:32 -0700450 }
ksrinie1a34382012-04-24 10:37:01 -0700451 status.println("++++Test Output++++");
ksrini11e7f1b2009-11-20 11:01:32 -0800452 for (String x : testOutput) {
ksrinie1a34382012-04-24 10:37:01 -0700453 indentStatus(x);
ksrini20a64b22008-09-24 15:07:41 -0700454 }
ksrinie1a34382012-04-24 10:37:01 -0700455 status.println("++++Test Stack Trace++++");
456 status.println(t.toString());
ksrinif8cc5972011-04-07 12:06:32 -0700457 for (StackTraceElement e : t.getStackTrace()) {
ksrinie1a34382012-04-24 10:37:01 -0700458 indentStatus(e.toString());
ksrinif8cc5972011-04-07 12:06:32 -0700459 }
ksrinie1a34382012-04-24 10:37:01 -0700460 status.println("++++End of Test Info++++");
461 status.flush();
462 String out = sw.toString();
463 status.close();
464 return out;
ksrini20a64b22008-09-24 15:07:41 -0700465 }
466
467 boolean contains(String str) {
468 for (String x : testOutput) {
469 if (x.contains(str)) {
470 return true;
471 }
472 }
ksrinie1a34382012-04-24 10:37:01 -0700473 appendError("string <" + str + "> not found");
ksrini11e7f1b2009-11-20 11:01:32 -0800474 testExitValue++;
475 return false;
476 }
477
478 boolean matches(String stringToMatch) {
479 for (String x : testOutput) {
480 if (x.matches(stringToMatch)) {
481 return true;
482 }
483 }
ksrinie1a34382012-04-24 10:37:01 -0700484 appendError("string <" + stringToMatch + "> not found");
ksrini20a64b22008-09-24 15:07:41 -0700485 testExitValue++;
486 return false;
487 }
488 }
489}