blob: 445efcec3a6a0dd94009b8c1c341210c961f5c36 [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
ksrini20a64b22008-09-24 15:07:41 -070024import java.io.BufferedReader;
25import java.io.File;
ksriniac5e02f2012-01-11 08:14:47 -080026import java.io.FileFilter;
ksrini20a64b22008-09-24 15:07:41 -070027import java.io.FileNotFoundException;
28import java.io.FileOutputStream;
ksrinif8cc5972011-04-07 12:06:32 -070029import java.io.IOException;
ksrini20a64b22008-09-24 15:07:41 -070030import java.io.InputStreamReader;
31import java.io.PrintStream;
ksrinif127cd92012-01-28 10:46:46 -080032import java.nio.charset.Charset;
ksriniac5e02f2012-01-11 08:14:47 -080033import java.nio.file.attribute.BasicFileAttributes;
ksrinif8cc5972011-04-07 12:06:32 -070034import java.nio.file.Files;
ksriniac5e02f2012-01-11 08:14:47 -080035import java.nio.file.FileVisitResult;
36import java.nio.file.SimpleFileVisitor;
ksrinif8cc5972011-04-07 12:06:32 -070037import java.nio.file.Path;
ksrini20a64b22008-09-24 15:07:41 -070038import java.util.ArrayList;
39import java.util.List;
ksrinif127cd92012-01-28 10:46:46 -080040import java.util.Locale;
ksrini20a64b22008-09-24 15:07:41 -070041import java.util.Map;
42import javax.tools.JavaCompiler;
ksriniac5e02f2012-01-11 08:14:47 -080043import javax.tools.ToolProvider;
ksrini20a64b22008-09-24 15:07:41 -070044
ksrinif8cc5972011-04-07 12:06:32 -070045import static java.nio.file.StandardCopyOption.*;
ksrinif127cd92012-01-28 10:46:46 -080046import static java.nio.file.StandardOpenOption.*;
ksrinif8cc5972011-04-07 12:06:32 -070047
ksrini20a64b22008-09-24 15:07:41 -070048/**
ksrinif8cc5972011-04-07 12:06:32 -070049 * This class provides some common utilities for the launcher tests.
ksrini20a64b22008-09-24 15:07:41 -070050 */
ksrinif127cd92012-01-28 10:46:46 -080051public class TestHelper {
ksrinieed01b82012-01-24 09:58:44 -080052 // commonly used jtreg constants
53 static final File TEST_CLASSES_DIR;
54 static final File TEST_SOURCES_DIR;
55
ksrini11e7f1b2009-11-20 11:01:32 -080056 static final String JAVAHOME = System.getProperty("java.home");
ksrini38a8aeb2012-03-29 17:49:34 -070057 static final String JAVA_BIN;
ksrini20a64b22008-09-24 15:07:41 -070058 static final boolean isSDK = JAVAHOME.endsWith("jre");
59 static final String javaCmd;
ksrinidd194042012-01-03 08:33:30 -080060 static final String javawCmd;
ksrini11e7f1b2009-11-20 11:01:32 -080061 static final String java64Cmd;
ksrini20a64b22008-09-24 15:07:41 -070062 static final String javacCmd;
63 static final JavaCompiler compiler;
64
ksrini11e7f1b2009-11-20 11:01:32 -080065 static final boolean debug = Boolean.getBoolean("TestHelper.Debug");
ksrini20a64b22008-09-24 15:07:41 -070066 static final boolean isWindows =
67 System.getProperty("os.name", "unknown").startsWith("Windows");
michaelm5ac8c152012-03-06 20:34:38 +000068 static final boolean isMacOSX =
69 System.getProperty("os.name", "unknown").startsWith("Mac");
ksrini11e7f1b2009-11-20 11:01:32 -080070 static final boolean is64Bit =
71 System.getProperty("sun.arch.data.model").equals("64");
72 static final boolean is32Bit =
73 System.getProperty("sun.arch.data.model").equals("32");
74 static final boolean isSolaris =
75 System.getProperty("os.name", "unknown").startsWith("SunOS");
76 static final boolean isLinux =
77 System.getProperty("os.name", "unknown").startsWith("Linux");
78 static final boolean isDualMode = isSolaris;
79 static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc");
80
ksrinif127cd92012-01-28 10:46:46 -080081 // make a note of the golden default locale
82 static final Locale DefaultLocale = Locale.getDefault();
83
ksriniac5e02f2012-01-11 08:14:47 -080084 static final String JAVA_FILE_EXT = ".java";
85 static final String CLASS_FILE_EXT = ".class";
86 static final String JAR_FILE_EXT = ".jar";
ksrini38a8aeb2012-03-29 17:49:34 -070087 static final String EXE_FILE_EXT = ".exe";
ksrinif127cd92012-01-28 10:46:46 -080088 static final String JLDEBUG_KEY = "_JAVA_LAUNCHER_DEBUG";
89 static final String EXPECTED_MARKER = "TRACER_MARKER:About to EXEC";
ksriniac5e02f2012-01-11 08:14:47 -080090
ksrini20a64b22008-09-24 15:07:41 -070091 static int testExitValue = 0;
92
93 static {
ksrinieed01b82012-01-24 09:58:44 -080094 String tmp = System.getProperty("test.classes", null);
95 if (tmp == null) {
96 throw new Error("property test.classes not defined ??");
97 }
98 TEST_CLASSES_DIR = new File(tmp).getAbsoluteFile();
99
100 tmp = System.getProperty("test.src", null);
101 if (tmp == null) {
102 throw new Error("property test.src not defined ??");
103 }
104 TEST_SOURCES_DIR = new File(tmp).getAbsoluteFile();
105
ksrini11e7f1b2009-11-20 11:01:32 -0800106 if (is64Bit && is32Bit) {
107 throw new RuntimeException("arch model cannot be both 32 and 64 bit");
108 }
109 if (!is64Bit && !is32Bit) {
110 throw new RuntimeException("arch model is not 32 or 64 bit ?");
111 }
ksrini20a64b22008-09-24 15:07:41 -0700112 compiler = ToolProvider.getSystemJavaCompiler();
113 File binDir = (isSDK) ? new File((new File(JAVAHOME)).getParentFile(), "bin")
114 : new File(JAVAHOME, "bin");
ksrini38a8aeb2012-03-29 17:49:34 -0700115 JAVA_BIN = binDir.getAbsolutePath();
ksrini20a64b22008-09-24 15:07:41 -0700116 File javaCmdFile = (isWindows)
117 ? new File(binDir, "java.exe")
118 : new File(binDir, "java");
119 javaCmd = javaCmdFile.getAbsolutePath();
120 if (!javaCmdFile.canExecute()) {
ksrinidd194042012-01-03 08:33:30 -0800121 throw new RuntimeException("java <" + TestHelper.javaCmd +
122 "> must exist and should be executable");
ksrini20a64b22008-09-24 15:07:41 -0700123 }
124
125 File javacCmdFile = (isWindows)
126 ? new File(binDir, "javac.exe")
127 : new File(binDir, "javac");
128 javacCmd = javacCmdFile.getAbsolutePath();
ksrinidd194042012-01-03 08:33:30 -0800129
130 if (isWindows) {
131 File javawCmdFile = new File(binDir, "javaw.exe");
132 javawCmd = javawCmdFile.getAbsolutePath();
133 if (!javawCmdFile.canExecute()) {
134 throw new RuntimeException("java <" + javawCmd +
135 "> must exist and should be executable");
136 }
137 } else {
138 javawCmd = null;
139 }
140
ksrini20a64b22008-09-24 15:07:41 -0700141 if (!javacCmdFile.canExecute()) {
ksrinidd194042012-01-03 08:33:30 -0800142 throw new RuntimeException("java <" + javacCmd +
143 "> must exist and should be executable");
ksrini20a64b22008-09-24 15:07:41 -0700144 }
ksrini11e7f1b2009-11-20 11:01:32 -0800145 if (isSolaris) {
146 File sparc64BinDir = new File(binDir,isSparc ? "sparcv9" : "amd64");
147 File java64CmdFile= new File(sparc64BinDir, "java");
148 if (java64CmdFile.exists() && java64CmdFile.canExecute()) {
149 java64Cmd = java64CmdFile.getAbsolutePath();
150 } else {
151 java64Cmd = null;
152 }
153 } else {
154 java64Cmd = null;
155 }
156 }
157
158 /*
ksrinif8cc5972011-04-07 12:06:32 -0700159 * is a dual mode available in the test jdk
160 */
161 static boolean dualModePresent() {
162 return isDualMode && java64Cmd != null;
163 }
164
165 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800166 * usually the jre/lib/arch-name is the same as os.arch, except for x86.
167 */
168 static String getJreArch() {
169 String arch = System.getProperty("os.arch");
170 return arch.equals("x86") ? "i386" : arch;
171 }
172
173 /*
ksrinif8cc5972011-04-07 12:06:32 -0700174 * get the complementary jre arch ie. if sparc then return sparcv9 and
175 * vice-versa.
176 */
177 static String getComplementaryJreArch() {
178 String arch = System.getProperty("os.arch");
179 if (arch != null) {
180 switch (arch) {
181 case "sparc":
182 return "sparcv9";
183 case "sparcv9":
184 return "sparc";
185 case "x86":
186 return "amd64";
187 case "amd64":
188 return "i386";
189 }
190 }
191 return null;
192 }
193
194 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800195 * A convenience method to create a jar with jar file name and defs
196 */
197 static void createJar(File jarName, String... mainDefs)
198 throws FileNotFoundException{
199 createJar(null, jarName, new File("Foo"), mainDefs);
ksrini20a64b22008-09-24 15:07:41 -0700200 }
201
202 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700203 * A convenience method to create a java file, compile and jar it up, using
204 * the sole class file name in the jar, as the Main-Class attribute value.
ksrini20a64b22008-09-24 15:07:41 -0700205 */
206 static void createJar(File jarName, File mainClass, String... mainDefs)
207 throws FileNotFoundException {
208 createJar(null, jarName, mainClass, mainDefs);
209 }
210
211 /*
ksrinif127cd92012-01-28 10:46:46 -0800212 * A convenience method to compile java files.
213 */
214 static void compile(String... compilerArgs) {
215 if (compiler.run(null, null, null, compilerArgs) != 0) {
216 String sarg = "";
217 for (String x : compilerArgs) {
218 sarg.concat(x + " ");
219 }
220 throw new Error("compilation failed: " + sarg);
221 }
222 }
223
224 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700225 * A generic jar file creator to create a java file, compile it
226 * and jar it up, a specific Main-Class entry name in the
227 * manifest can be specified or a null to use the sole class file name
228 * as the Main-Class attribute value.
ksrini20a64b22008-09-24 15:07:41 -0700229 */
ksrinicafaf7c2008-10-01 09:04:42 -0700230 static void createJar(String mEntry, File jarName, File mainClass,
231 String... mainDefs) throws FileNotFoundException {
ksrini20a64b22008-09-24 15:07:41 -0700232 if (jarName.exists()) {
233 jarName.delete();
234 }
ksrini37e8b502011-07-19 10:58:50 -0700235 try (PrintStream ps = new PrintStream(new FileOutputStream(mainClass + ".java"))) {
236 ps.println("public class Foo {");
237 if (mainDefs != null) {
238 for (String x : mainDefs) {
239 ps.println(x);
240 }
ksrini20a64b22008-09-24 15:07:41 -0700241 }
ksrini37e8b502011-07-19 10:58:50 -0700242 ps.println("}");
ksrini20a64b22008-09-24 15:07:41 -0700243 }
ksrini20a64b22008-09-24 15:07:41 -0700244
245 String compileArgs[] = {
246 mainClass + ".java"
247 };
248 if (compiler.run(null, null, null, compileArgs) != 0) {
249 throw new RuntimeException("compilation failed " + mainClass + ".java");
250 }
ksrinicafaf7c2008-10-01 09:04:42 -0700251 if (mEntry == null) {
ksrini20a64b22008-09-24 15:07:41 -0700252 mEntry = mainClass.getName();
253 }
254 String jarArgs[] = {
255 (debug) ? "cvfe" : "cfe",
256 jarName.getAbsolutePath(),
257 mEntry,
258 mainClass.getName() + ".class"
259 };
ksrini37e8b502011-07-19 10:58:50 -0700260 createJar(jarArgs);
261 }
262
263 static void createJar(String... args) {
ksrini20a64b22008-09-24 15:07:41 -0700264 sun.tools.jar.Main jarTool =
265 new sun.tools.jar.Main(System.out, System.err, "JarCreator");
ksrini37e8b502011-07-19 10:58:50 -0700266 if (!jarTool.run(args)) {
267 String message = "jar creation failed with command:";
268 for (String x : args) {
269 message = message.concat(" " + x);
270 }
271 throw new RuntimeException(message);
ksrini20a64b22008-09-24 15:07:41 -0700272 }
ksrini37e8b502011-07-19 10:58:50 -0700273 }
ksrini20a64b22008-09-24 15:07:41 -0700274
ksrinif8cc5972011-04-07 12:06:32 -0700275 static void copyFile(File src, File dst) throws IOException {
276 Path parent = dst.toPath().getParent();
277 if (parent != null) {
278 Files.createDirectories(parent);
279 }
280 Files.copy(src.toPath(), dst.toPath(), COPY_ATTRIBUTES, REPLACE_EXISTING);
281 }
282
ksrinif127cd92012-01-28 10:46:46 -0800283 static void createFile(File outFile, List<String> content) throws IOException {
284 Files.write(outFile.getAbsoluteFile().toPath(), content,
285 Charset.defaultCharset(), CREATE_NEW);
286 }
287
ksrinif8cc5972011-04-07 12:06:32 -0700288 static void recursiveDelete(File target) throws IOException {
289 if (!target.exists()) {
290 return;
291 }
292 Files.walkFileTree(target.toPath(), new SimpleFileVisitor<Path>() {
293 @Override
294 public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
295 try {
296 Files.deleteIfExists(dir);
297 } catch (IOException ex) {
298 System.out.println("Error: could not delete: " + dir.toString());
299 System.out.println(ex.getMessage());
300 return FileVisitResult.TERMINATE;
301 }
302 return FileVisitResult.CONTINUE;
303 }
304 @Override
305 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
306 try {
307 Files.deleteIfExists(file);
308 } catch (IOException ex) {
309 System.out.println("Error: could not delete: " + file.toString());
310 System.out.println(ex.getMessage());
311 return FileVisitResult.TERMINATE;
312 }
313 return FileVisitResult.CONTINUE;
314 }
315 });
316 }
317
ksrini11e7f1b2009-11-20 11:01:32 -0800318 static TestResult doExec(String...cmds) {
319 return doExec(null, cmds);
320 }
321
ksrini20a64b22008-09-24 15:07:41 -0700322 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700323 * A method which executes a java cmd and returns the results in a container
ksrini20a64b22008-09-24 15:07:41 -0700324 */
ksrini11e7f1b2009-11-20 11:01:32 -0800325 static TestResult doExec(Map<String, String> envToSet, String...cmds) {
ksrini20a64b22008-09-24 15:07:41 -0700326 String cmdStr = "";
327 for (String x : cmds) {
328 cmdStr = cmdStr.concat(x + " ");
329 }
330 ProcessBuilder pb = new ProcessBuilder(cmds);
331 Map<String, String> env = pb.environment();
ksrini11e7f1b2009-11-20 11:01:32 -0800332 if (envToSet != null) {
333 env.putAll(envToSet);
334 }
ksrini20a64b22008-09-24 15:07:41 -0700335 BufferedReader rdr = null;
336 try {
ksrinif8cc5972011-04-07 12:06:32 -0700337 List<String> outputList = new ArrayList<>();
ksrini20a64b22008-09-24 15:07:41 -0700338 pb.redirectErrorStream(true);
339 Process p = pb.start();
340 rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
341 String in = rdr.readLine();
342 while (in != null) {
343 outputList.add(in);
344 in = rdr.readLine();
345 }
346 p.waitFor();
347 p.destroy();
ksrinif8cc5972011-04-07 12:06:32 -0700348
349 return new TestHelper.TestResult(cmdStr, p.exitValue(), outputList,
350 env, new Throwable("current stack of the test"));
ksrini20a64b22008-09-24 15:07:41 -0700351 } catch (Exception ex) {
352 ex.printStackTrace();
353 throw new RuntimeException(ex.getMessage());
354 }
355 }
356
ksriniac5e02f2012-01-11 08:14:47 -0800357 static FileFilter createFilter(final String extension) {
358 return new FileFilter() {
359 @Override
360 public boolean accept(File pathname) {
361 String name = pathname.getName();
362 if (name.endsWith(extension)) {
363 return true;
364 }
365 return false;
366 }
367 };
368 }
369
ksrinif127cd92012-01-28 10:46:46 -0800370 static boolean isEnglishLocale() {
371 return Locale.getDefault().getLanguage().equals("en");
372 }
373
ksrini20a64b22008-09-24 15:07:41 -0700374 /*
375 * A class to encapsulate the test results and stuff, with some ease
376 * of use methods to check the test results.
377 */
378 static class TestResult {
379 StringBuilder status;
380 int exitValue;
381 List<String> testOutput;
ksrinif8cc5972011-04-07 12:06:32 -0700382 Map<String, String> env;
383 Throwable t;
ksrini20a64b22008-09-24 15:07:41 -0700384
ksrinif8cc5972011-04-07 12:06:32 -0700385 public TestResult(String str, int rv, List<String> oList,
386 Map<String, String> env, Throwable t) {
ksrini11e7f1b2009-11-20 11:01:32 -0800387 status = new StringBuilder("Executed command: " + str + "\n");
ksrini20a64b22008-09-24 15:07:41 -0700388 exitValue = rv;
389 testOutput = oList;
ksrinif8cc5972011-04-07 12:06:32 -0700390 this.env = env;
391 this.t = t;
ksrini20a64b22008-09-24 15:07:41 -0700392 }
393
ksrini11e7f1b2009-11-20 11:01:32 -0800394 void appendStatus(String x) {
395 status = status.append(" " + x + "\n");
396 }
397
ksrini20a64b22008-09-24 15:07:41 -0700398 void checkNegative() {
399 if (exitValue == 0) {
ksrini11e7f1b2009-11-20 11:01:32 -0800400 appendStatus("Error: test must not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700401 testExitValue++;
402 }
403 }
404
405 void checkPositive() {
406 if (exitValue != 0) {
ksrini11e7f1b2009-11-20 11:01:32 -0800407 appendStatus("Error: test did not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700408 testExitValue++;
409 }
410 }
411
412 boolean isOK() {
413 return exitValue == 0;
414 }
415
416 boolean isZeroOutput() {
417 if (!testOutput.isEmpty()) {
ksrini11e7f1b2009-11-20 11:01:32 -0800418 appendStatus("Error: No message from cmd please");
ksrini20a64b22008-09-24 15:07:41 -0700419 testExitValue++;
420 return false;
421 }
422 return true;
423 }
424
425 boolean isNotZeroOutput() {
426 if (testOutput.isEmpty()) {
ksrini11e7f1b2009-11-20 11:01:32 -0800427 appendStatus("Error: Missing message");
ksrini20a64b22008-09-24 15:07:41 -0700428 testExitValue++;
429 return false;
430 }
431 return true;
432 }
433
ksrini11e7f1b2009-11-20 11:01:32 -0800434 @Override
ksrini20a64b22008-09-24 15:07:41 -0700435 public String toString() {
ksrinif8cc5972011-04-07 12:06:32 -0700436 status.append("++++Begin Test Info++++\n");
437 status.append("++++Test Environment++++\n");
438 for (String x : env.keySet()) {
439 status.append(x).append("=").append(env.get(x)).append("\n");
440 }
441 status.append("++++Test Output++++\n");
ksrini11e7f1b2009-11-20 11:01:32 -0800442 for (String x : testOutput) {
443 appendStatus(x);
ksrini20a64b22008-09-24 15:07:41 -0700444 }
ksrinif8cc5972011-04-07 12:06:32 -0700445 status.append("++++Test Stack Trace++++\n");
446 status.append(t.toString());
447 for (StackTraceElement e : t.getStackTrace()) {
448 status.append(e.toString());
449 }
450 status.append("++++End of Test Info++++\n");
ksrini20a64b22008-09-24 15:07:41 -0700451 return status.toString();
452 }
453
454 boolean contains(String str) {
455 for (String x : testOutput) {
456 if (x.contains(str)) {
457 return true;
458 }
459 }
ksrini11e7f1b2009-11-20 11:01:32 -0800460 appendStatus("Error: string <" + str + "> not found");
461 testExitValue++;
462 return false;
463 }
464
465 boolean matches(String stringToMatch) {
466 for (String x : testOutput) {
467 if (x.matches(stringToMatch)) {
468 return true;
469 }
470 }
471 appendStatus("Error: string <" + stringToMatch + "> not found");
ksrini20a64b22008-09-24 15:07:41 -0700472 testExitValue++;
473 return false;
474 }
475 }
476}