blob: 2c4dedd82773f5844a2591d93ddaabf476cd459b [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");
ksrini20a64b22008-09-24 15:07:41 -070057 static final boolean isSDK = JAVAHOME.endsWith("jre");
58 static final String javaCmd;
ksrinidd194042012-01-03 08:33:30 -080059 static final String javawCmd;
ksrini11e7f1b2009-11-20 11:01:32 -080060 static final String java64Cmd;
ksrini20a64b22008-09-24 15:07:41 -070061 static final String javacCmd;
62 static final JavaCompiler compiler;
63
ksrini11e7f1b2009-11-20 11:01:32 -080064 static final boolean debug = Boolean.getBoolean("TestHelper.Debug");
ksrini20a64b22008-09-24 15:07:41 -070065 static final boolean isWindows =
66 System.getProperty("os.name", "unknown").startsWith("Windows");
michaelm5ac8c152012-03-06 20:34:38 +000067 static final boolean isMacOSX =
68 System.getProperty("os.name", "unknown").startsWith("Mac");
ksrini11e7f1b2009-11-20 11:01:32 -080069 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
ksrinif127cd92012-01-28 10:46:46 -080080 // make a note of the golden default locale
81 static final Locale DefaultLocale = Locale.getDefault();
82
ksriniac5e02f2012-01-11 08:14:47 -080083 static final String JAVA_FILE_EXT = ".java";
84 static final String CLASS_FILE_EXT = ".class";
85 static final String JAR_FILE_EXT = ".jar";
ksrinif127cd92012-01-28 10:46:46 -080086 static final String JLDEBUG_KEY = "_JAVA_LAUNCHER_DEBUG";
87 static final String EXPECTED_MARKER = "TRACER_MARKER:About to EXEC";
ksriniac5e02f2012-01-11 08:14:47 -080088
ksrini20a64b22008-09-24 15:07:41 -070089 static int testExitValue = 0;
90
91 static {
ksrinieed01b82012-01-24 09:58:44 -080092 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
ksrini11e7f1b2009-11-20 11:01:32 -0800104 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 }
ksrini20a64b22008-09-24 15:07:41 -0700110 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()) {
ksrinidd194042012-01-03 08:33:30 -0800118 throw new RuntimeException("java <" + TestHelper.javaCmd +
119 "> must exist and should be executable");
ksrini20a64b22008-09-24 15:07:41 -0700120 }
121
122 File javacCmdFile = (isWindows)
123 ? new File(binDir, "javac.exe")
124 : new File(binDir, "javac");
125 javacCmd = javacCmdFile.getAbsolutePath();
ksrinidd194042012-01-03 08:33:30 -0800126
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
ksrini20a64b22008-09-24 15:07:41 -0700138 if (!javacCmdFile.canExecute()) {
ksrinidd194042012-01-03 08:33:30 -0800139 throw new RuntimeException("java <" + javacCmd +
140 "> must exist and should be executable");
ksrini20a64b22008-09-24 15:07:41 -0700141 }
ksrini11e7f1b2009-11-20 11:01:32 -0800142 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 /*
ksrinif8cc5972011-04-07 12:06:32 -0700156 * is a dual mode available in the test jdk
157 */
158 static boolean dualModePresent() {
159 return isDualMode && java64Cmd != null;
160 }
161
162 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800163 * 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 /*
ksrinif8cc5972011-04-07 12:06:32 -0700171 * 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 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800192 * 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);
ksrini20a64b22008-09-24 15:07:41 -0700197 }
198
199 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700200 * 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.
ksrini20a64b22008-09-24 15:07:41 -0700202 */
203 static void createJar(File jarName, File mainClass, String... mainDefs)
204 throws FileNotFoundException {
205 createJar(null, jarName, mainClass, mainDefs);
206 }
207
208 /*
ksrinif127cd92012-01-28 10:46:46 -0800209 * 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 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700222 * 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.
ksrini20a64b22008-09-24 15:07:41 -0700226 */
ksrinicafaf7c2008-10-01 09:04:42 -0700227 static void createJar(String mEntry, File jarName, File mainClass,
228 String... mainDefs) throws FileNotFoundException {
ksrini20a64b22008-09-24 15:07:41 -0700229 if (jarName.exists()) {
230 jarName.delete();
231 }
ksrini37e8b502011-07-19 10:58:50 -0700232 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 }
ksrini20a64b22008-09-24 15:07:41 -0700238 }
ksrini37e8b502011-07-19 10:58:50 -0700239 ps.println("}");
ksrini20a64b22008-09-24 15:07:41 -0700240 }
ksrini20a64b22008-09-24 15:07:41 -0700241
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 }
ksrinicafaf7c2008-10-01 09:04:42 -0700248 if (mEntry == null) {
ksrini20a64b22008-09-24 15:07:41 -0700249 mEntry = mainClass.getName();
250 }
251 String jarArgs[] = {
252 (debug) ? "cvfe" : "cfe",
253 jarName.getAbsolutePath(),
254 mEntry,
255 mainClass.getName() + ".class"
256 };
ksrini37e8b502011-07-19 10:58:50 -0700257 createJar(jarArgs);
258 }
259
260 static void createJar(String... args) {
ksrini20a64b22008-09-24 15:07:41 -0700261 sun.tools.jar.Main jarTool =
262 new sun.tools.jar.Main(System.out, System.err, "JarCreator");
ksrini37e8b502011-07-19 10:58:50 -0700263 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);
ksrini20a64b22008-09-24 15:07:41 -0700269 }
ksrini37e8b502011-07-19 10:58:50 -0700270 }
ksrini20a64b22008-09-24 15:07:41 -0700271
ksrinif8cc5972011-04-07 12:06:32 -0700272 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
ksrinif127cd92012-01-28 10:46:46 -0800280 static void createFile(File outFile, List<String> content) throws IOException {
281 Files.write(outFile.getAbsoluteFile().toPath(), content,
282 Charset.defaultCharset(), CREATE_NEW);
283 }
284
ksrinif8cc5972011-04-07 12:06:32 -0700285 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
ksrini11e7f1b2009-11-20 11:01:32 -0800315 static TestResult doExec(String...cmds) {
316 return doExec(null, cmds);
317 }
318
ksrini20a64b22008-09-24 15:07:41 -0700319 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700320 * A method which executes a java cmd and returns the results in a container
ksrini20a64b22008-09-24 15:07:41 -0700321 */
ksrini11e7f1b2009-11-20 11:01:32 -0800322 static TestResult doExec(Map<String, String> envToSet, String...cmds) {
ksrini20a64b22008-09-24 15:07:41 -0700323 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();
ksrini11e7f1b2009-11-20 11:01:32 -0800329 if (envToSet != null) {
330 env.putAll(envToSet);
331 }
ksrini20a64b22008-09-24 15:07:41 -0700332 BufferedReader rdr = null;
333 try {
ksrinif8cc5972011-04-07 12:06:32 -0700334 List<String> outputList = new ArrayList<>();
ksrini20a64b22008-09-24 15:07:41 -0700335 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();
ksrinif8cc5972011-04-07 12:06:32 -0700345
346 return new TestHelper.TestResult(cmdStr, p.exitValue(), outputList,
347 env, new Throwable("current stack of the test"));
ksrini20a64b22008-09-24 15:07:41 -0700348 } catch (Exception ex) {
349 ex.printStackTrace();
350 throw new RuntimeException(ex.getMessage());
351 }
352 }
353
ksriniac5e02f2012-01-11 08:14:47 -0800354 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
ksrinif127cd92012-01-28 10:46:46 -0800367 static boolean isEnglishLocale() {
368 return Locale.getDefault().getLanguage().equals("en");
369 }
370
ksrini20a64b22008-09-24 15:07:41 -0700371 /*
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;
ksrinif8cc5972011-04-07 12:06:32 -0700379 Map<String, String> env;
380 Throwable t;
ksrini20a64b22008-09-24 15:07:41 -0700381
ksrinif8cc5972011-04-07 12:06:32 -0700382 public TestResult(String str, int rv, List<String> oList,
383 Map<String, String> env, Throwable t) {
ksrini11e7f1b2009-11-20 11:01:32 -0800384 status = new StringBuilder("Executed command: " + str + "\n");
ksrini20a64b22008-09-24 15:07:41 -0700385 exitValue = rv;
386 testOutput = oList;
ksrinif8cc5972011-04-07 12:06:32 -0700387 this.env = env;
388 this.t = t;
ksrini20a64b22008-09-24 15:07:41 -0700389 }
390
ksrini11e7f1b2009-11-20 11:01:32 -0800391 void appendStatus(String x) {
392 status = status.append(" " + x + "\n");
393 }
394
ksrini20a64b22008-09-24 15:07:41 -0700395 void checkNegative() {
396 if (exitValue == 0) {
ksrini11e7f1b2009-11-20 11:01:32 -0800397 appendStatus("Error: test must not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700398 testExitValue++;
399 }
400 }
401
402 void checkPositive() {
403 if (exitValue != 0) {
ksrini11e7f1b2009-11-20 11:01:32 -0800404 appendStatus("Error: test did not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700405 testExitValue++;
406 }
407 }
408
409 boolean isOK() {
410 return exitValue == 0;
411 }
412
413 boolean isZeroOutput() {
414 if (!testOutput.isEmpty()) {
ksrini11e7f1b2009-11-20 11:01:32 -0800415 appendStatus("Error: No message from cmd please");
ksrini20a64b22008-09-24 15:07:41 -0700416 testExitValue++;
417 return false;
418 }
419 return true;
420 }
421
422 boolean isNotZeroOutput() {
423 if (testOutput.isEmpty()) {
ksrini11e7f1b2009-11-20 11:01:32 -0800424 appendStatus("Error: Missing message");
ksrini20a64b22008-09-24 15:07:41 -0700425 testExitValue++;
426 return false;
427 }
428 return true;
429 }
430
ksrini11e7f1b2009-11-20 11:01:32 -0800431 @Override
ksrini20a64b22008-09-24 15:07:41 -0700432 public String toString() {
ksrinif8cc5972011-04-07 12:06:32 -0700433 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");
ksrini11e7f1b2009-11-20 11:01:32 -0800439 for (String x : testOutput) {
440 appendStatus(x);
ksrini20a64b22008-09-24 15:07:41 -0700441 }
ksrinif8cc5972011-04-07 12:06:32 -0700442 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");
ksrini20a64b22008-09-24 15:07:41 -0700448 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 }
ksrini11e7f1b2009-11-20 11:01:32 -0800457 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");
ksrini20a64b22008-09-24 15:07:41 -0700469 testExitValue++;
470 return false;
471 }
472 }
473}