blob: a64d97d3d0184a132a007aafc75cdcc3ba019521 [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");
ksrini11e7f1b2009-11-20 11:01:32 -080067 static final boolean is64Bit =
68 System.getProperty("sun.arch.data.model").equals("64");
69 static final boolean is32Bit =
70 System.getProperty("sun.arch.data.model").equals("32");
71 static final boolean isSolaris =
72 System.getProperty("os.name", "unknown").startsWith("SunOS");
73 static final boolean isLinux =
74 System.getProperty("os.name", "unknown").startsWith("Linux");
75 static final boolean isDualMode = isSolaris;
76 static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc");
77
ksrinif127cd92012-01-28 10:46:46 -080078 // make a note of the golden default locale
79 static final Locale DefaultLocale = Locale.getDefault();
80
ksriniac5e02f2012-01-11 08:14:47 -080081 static final String JAVA_FILE_EXT = ".java";
82 static final String CLASS_FILE_EXT = ".class";
83 static final String JAR_FILE_EXT = ".jar";
ksrinif127cd92012-01-28 10:46:46 -080084 static final String JLDEBUG_KEY = "_JAVA_LAUNCHER_DEBUG";
85 static final String EXPECTED_MARKER = "TRACER_MARKER:About to EXEC";
ksriniac5e02f2012-01-11 08:14:47 -080086
ksrini20a64b22008-09-24 15:07:41 -070087 static int testExitValue = 0;
88
89 static {
ksrinieed01b82012-01-24 09:58:44 -080090 String tmp = System.getProperty("test.classes", null);
91 if (tmp == null) {
92 throw new Error("property test.classes not defined ??");
93 }
94 TEST_CLASSES_DIR = new File(tmp).getAbsoluteFile();
95
96 tmp = System.getProperty("test.src", null);
97 if (tmp == null) {
98 throw new Error("property test.src not defined ??");
99 }
100 TEST_SOURCES_DIR = new File(tmp).getAbsoluteFile();
101
ksrini11e7f1b2009-11-20 11:01:32 -0800102 if (is64Bit && is32Bit) {
103 throw new RuntimeException("arch model cannot be both 32 and 64 bit");
104 }
105 if (!is64Bit && !is32Bit) {
106 throw new RuntimeException("arch model is not 32 or 64 bit ?");
107 }
ksrini20a64b22008-09-24 15:07:41 -0700108 compiler = ToolProvider.getSystemJavaCompiler();
109 File binDir = (isSDK) ? new File((new File(JAVAHOME)).getParentFile(), "bin")
110 : new File(JAVAHOME, "bin");
111 File javaCmdFile = (isWindows)
112 ? new File(binDir, "java.exe")
113 : new File(binDir, "java");
114 javaCmd = javaCmdFile.getAbsolutePath();
115 if (!javaCmdFile.canExecute()) {
ksrinidd194042012-01-03 08:33:30 -0800116 throw new RuntimeException("java <" + TestHelper.javaCmd +
117 "> must exist and should be executable");
ksrini20a64b22008-09-24 15:07:41 -0700118 }
119
120 File javacCmdFile = (isWindows)
121 ? new File(binDir, "javac.exe")
122 : new File(binDir, "javac");
123 javacCmd = javacCmdFile.getAbsolutePath();
ksrinidd194042012-01-03 08:33:30 -0800124
125 if (isWindows) {
126 File javawCmdFile = new File(binDir, "javaw.exe");
127 javawCmd = javawCmdFile.getAbsolutePath();
128 if (!javawCmdFile.canExecute()) {
129 throw new RuntimeException("java <" + javawCmd +
130 "> must exist and should be executable");
131 }
132 } else {
133 javawCmd = null;
134 }
135
ksrini20a64b22008-09-24 15:07:41 -0700136 if (!javacCmdFile.canExecute()) {
ksrinidd194042012-01-03 08:33:30 -0800137 throw new RuntimeException("java <" + javacCmd +
138 "> must exist and should be executable");
ksrini20a64b22008-09-24 15:07:41 -0700139 }
ksrini11e7f1b2009-11-20 11:01:32 -0800140 if (isSolaris) {
141 File sparc64BinDir = new File(binDir,isSparc ? "sparcv9" : "amd64");
142 File java64CmdFile= new File(sparc64BinDir, "java");
143 if (java64CmdFile.exists() && java64CmdFile.canExecute()) {
144 java64Cmd = java64CmdFile.getAbsolutePath();
145 } else {
146 java64Cmd = null;
147 }
148 } else {
149 java64Cmd = null;
150 }
151 }
152
153 /*
ksrinif8cc5972011-04-07 12:06:32 -0700154 * is a dual mode available in the test jdk
155 */
156 static boolean dualModePresent() {
157 return isDualMode && java64Cmd != null;
158 }
159
160 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800161 * usually the jre/lib/arch-name is the same as os.arch, except for x86.
162 */
163 static String getJreArch() {
164 String arch = System.getProperty("os.arch");
165 return arch.equals("x86") ? "i386" : arch;
166 }
167
168 /*
ksrinif8cc5972011-04-07 12:06:32 -0700169 * get the complementary jre arch ie. if sparc then return sparcv9 and
170 * vice-versa.
171 */
172 static String getComplementaryJreArch() {
173 String arch = System.getProperty("os.arch");
174 if (arch != null) {
175 switch (arch) {
176 case "sparc":
177 return "sparcv9";
178 case "sparcv9":
179 return "sparc";
180 case "x86":
181 return "amd64";
182 case "amd64":
183 return "i386";
184 }
185 }
186 return null;
187 }
188
189 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800190 * A convenience method to create a jar with jar file name and defs
191 */
192 static void createJar(File jarName, String... mainDefs)
193 throws FileNotFoundException{
194 createJar(null, jarName, new File("Foo"), mainDefs);
ksrini20a64b22008-09-24 15:07:41 -0700195 }
196
197 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700198 * A convenience method to create a java file, compile and jar it up, using
199 * the sole class file name in the jar, as the Main-Class attribute value.
ksrini20a64b22008-09-24 15:07:41 -0700200 */
201 static void createJar(File jarName, File mainClass, String... mainDefs)
202 throws FileNotFoundException {
203 createJar(null, jarName, mainClass, mainDefs);
204 }
205
206 /*
ksrinif127cd92012-01-28 10:46:46 -0800207 * A convenience method to compile java files.
208 */
209 static void compile(String... compilerArgs) {
210 if (compiler.run(null, null, null, compilerArgs) != 0) {
211 String sarg = "";
212 for (String x : compilerArgs) {
213 sarg.concat(x + " ");
214 }
215 throw new Error("compilation failed: " + sarg);
216 }
217 }
218
219 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700220 * A generic jar file creator to create a java file, compile it
221 * and jar it up, a specific Main-Class entry name in the
222 * manifest can be specified or a null to use the sole class file name
223 * as the Main-Class attribute value.
ksrini20a64b22008-09-24 15:07:41 -0700224 */
ksrinicafaf7c2008-10-01 09:04:42 -0700225 static void createJar(String mEntry, File jarName, File mainClass,
226 String... mainDefs) throws FileNotFoundException {
ksrini20a64b22008-09-24 15:07:41 -0700227 if (jarName.exists()) {
228 jarName.delete();
229 }
ksrini37e8b502011-07-19 10:58:50 -0700230 try (PrintStream ps = new PrintStream(new FileOutputStream(mainClass + ".java"))) {
231 ps.println("public class Foo {");
232 if (mainDefs != null) {
233 for (String x : mainDefs) {
234 ps.println(x);
235 }
ksrini20a64b22008-09-24 15:07:41 -0700236 }
ksrini37e8b502011-07-19 10:58:50 -0700237 ps.println("}");
ksrini20a64b22008-09-24 15:07:41 -0700238 }
ksrini20a64b22008-09-24 15:07:41 -0700239
240 String compileArgs[] = {
241 mainClass + ".java"
242 };
243 if (compiler.run(null, null, null, compileArgs) != 0) {
244 throw new RuntimeException("compilation failed " + mainClass + ".java");
245 }
ksrinicafaf7c2008-10-01 09:04:42 -0700246 if (mEntry == null) {
ksrini20a64b22008-09-24 15:07:41 -0700247 mEntry = mainClass.getName();
248 }
249 String jarArgs[] = {
250 (debug) ? "cvfe" : "cfe",
251 jarName.getAbsolutePath(),
252 mEntry,
253 mainClass.getName() + ".class"
254 };
ksrini37e8b502011-07-19 10:58:50 -0700255 createJar(jarArgs);
256 }
257
258 static void createJar(String... args) {
ksrini20a64b22008-09-24 15:07:41 -0700259 sun.tools.jar.Main jarTool =
260 new sun.tools.jar.Main(System.out, System.err, "JarCreator");
ksrini37e8b502011-07-19 10:58:50 -0700261 if (!jarTool.run(args)) {
262 String message = "jar creation failed with command:";
263 for (String x : args) {
264 message = message.concat(" " + x);
265 }
266 throw new RuntimeException(message);
ksrini20a64b22008-09-24 15:07:41 -0700267 }
ksrini37e8b502011-07-19 10:58:50 -0700268 }
ksrini20a64b22008-09-24 15:07:41 -0700269
ksrinif8cc5972011-04-07 12:06:32 -0700270 static void copyFile(File src, File dst) throws IOException {
271 Path parent = dst.toPath().getParent();
272 if (parent != null) {
273 Files.createDirectories(parent);
274 }
275 Files.copy(src.toPath(), dst.toPath(), COPY_ATTRIBUTES, REPLACE_EXISTING);
276 }
277
ksrinif127cd92012-01-28 10:46:46 -0800278 static void createFile(File outFile, List<String> content) throws IOException {
279 Files.write(outFile.getAbsoluteFile().toPath(), content,
280 Charset.defaultCharset(), CREATE_NEW);
281 }
282
ksrinif8cc5972011-04-07 12:06:32 -0700283 static void recursiveDelete(File target) throws IOException {
284 if (!target.exists()) {
285 return;
286 }
287 Files.walkFileTree(target.toPath(), new SimpleFileVisitor<Path>() {
288 @Override
289 public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
290 try {
291 Files.deleteIfExists(dir);
292 } catch (IOException ex) {
293 System.out.println("Error: could not delete: " + dir.toString());
294 System.out.println(ex.getMessage());
295 return FileVisitResult.TERMINATE;
296 }
297 return FileVisitResult.CONTINUE;
298 }
299 @Override
300 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
301 try {
302 Files.deleteIfExists(file);
303 } catch (IOException ex) {
304 System.out.println("Error: could not delete: " + file.toString());
305 System.out.println(ex.getMessage());
306 return FileVisitResult.TERMINATE;
307 }
308 return FileVisitResult.CONTINUE;
309 }
310 });
311 }
312
ksrini11e7f1b2009-11-20 11:01:32 -0800313 static TestResult doExec(String...cmds) {
314 return doExec(null, cmds);
315 }
316
ksrini20a64b22008-09-24 15:07:41 -0700317 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700318 * A method which executes a java cmd and returns the results in a container
ksrini20a64b22008-09-24 15:07:41 -0700319 */
ksrini11e7f1b2009-11-20 11:01:32 -0800320 static TestResult doExec(Map<String, String> envToSet, String...cmds) {
ksrini20a64b22008-09-24 15:07:41 -0700321 String cmdStr = "";
322 for (String x : cmds) {
323 cmdStr = cmdStr.concat(x + " ");
324 }
325 ProcessBuilder pb = new ProcessBuilder(cmds);
326 Map<String, String> env = pb.environment();
ksrini11e7f1b2009-11-20 11:01:32 -0800327 if (envToSet != null) {
328 env.putAll(envToSet);
329 }
ksrini20a64b22008-09-24 15:07:41 -0700330 BufferedReader rdr = null;
331 try {
ksrinif8cc5972011-04-07 12:06:32 -0700332 List<String> outputList = new ArrayList<>();
ksrini20a64b22008-09-24 15:07:41 -0700333 pb.redirectErrorStream(true);
334 Process p = pb.start();
335 rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
336 String in = rdr.readLine();
337 while (in != null) {
338 outputList.add(in);
339 in = rdr.readLine();
340 }
341 p.waitFor();
342 p.destroy();
ksrinif8cc5972011-04-07 12:06:32 -0700343
344 return new TestHelper.TestResult(cmdStr, p.exitValue(), outputList,
345 env, new Throwable("current stack of the test"));
ksrini20a64b22008-09-24 15:07:41 -0700346 } catch (Exception ex) {
347 ex.printStackTrace();
348 throw new RuntimeException(ex.getMessage());
349 }
350 }
351
ksriniac5e02f2012-01-11 08:14:47 -0800352 static FileFilter createFilter(final String extension) {
353 return new FileFilter() {
354 @Override
355 public boolean accept(File pathname) {
356 String name = pathname.getName();
357 if (name.endsWith(extension)) {
358 return true;
359 }
360 return false;
361 }
362 };
363 }
364
ksrinif127cd92012-01-28 10:46:46 -0800365 static boolean isEnglishLocale() {
366 return Locale.getDefault().getLanguage().equals("en");
367 }
368
ksrini20a64b22008-09-24 15:07:41 -0700369 /*
370 * A class to encapsulate the test results and stuff, with some ease
371 * of use methods to check the test results.
372 */
373 static class TestResult {
374 StringBuilder status;
375 int exitValue;
376 List<String> testOutput;
ksrinif8cc5972011-04-07 12:06:32 -0700377 Map<String, String> env;
378 Throwable t;
ksrini20a64b22008-09-24 15:07:41 -0700379
ksrinif8cc5972011-04-07 12:06:32 -0700380 public TestResult(String str, int rv, List<String> oList,
381 Map<String, String> env, Throwable t) {
ksrini11e7f1b2009-11-20 11:01:32 -0800382 status = new StringBuilder("Executed command: " + str + "\n");
ksrini20a64b22008-09-24 15:07:41 -0700383 exitValue = rv;
384 testOutput = oList;
ksrinif8cc5972011-04-07 12:06:32 -0700385 this.env = env;
386 this.t = t;
ksrini20a64b22008-09-24 15:07:41 -0700387 }
388
ksrini11e7f1b2009-11-20 11:01:32 -0800389 void appendStatus(String x) {
390 status = status.append(" " + x + "\n");
391 }
392
ksrini20a64b22008-09-24 15:07:41 -0700393 void checkNegative() {
394 if (exitValue == 0) {
ksrini11e7f1b2009-11-20 11:01:32 -0800395 appendStatus("Error: test must not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700396 testExitValue++;
397 }
398 }
399
400 void checkPositive() {
401 if (exitValue != 0) {
ksrini11e7f1b2009-11-20 11:01:32 -0800402 appendStatus("Error: test did not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700403 testExitValue++;
404 }
405 }
406
407 boolean isOK() {
408 return exitValue == 0;
409 }
410
411 boolean isZeroOutput() {
412 if (!testOutput.isEmpty()) {
ksrini11e7f1b2009-11-20 11:01:32 -0800413 appendStatus("Error: No message from cmd please");
ksrini20a64b22008-09-24 15:07:41 -0700414 testExitValue++;
415 return false;
416 }
417 return true;
418 }
419
420 boolean isNotZeroOutput() {
421 if (testOutput.isEmpty()) {
ksrini11e7f1b2009-11-20 11:01:32 -0800422 appendStatus("Error: Missing message");
ksrini20a64b22008-09-24 15:07:41 -0700423 testExitValue++;
424 return false;
425 }
426 return true;
427 }
428
ksrini11e7f1b2009-11-20 11:01:32 -0800429 @Override
ksrini20a64b22008-09-24 15:07:41 -0700430 public String toString() {
ksrinif8cc5972011-04-07 12:06:32 -0700431 status.append("++++Begin Test Info++++\n");
432 status.append("++++Test Environment++++\n");
433 for (String x : env.keySet()) {
434 status.append(x).append("=").append(env.get(x)).append("\n");
435 }
436 status.append("++++Test Output++++\n");
ksrini11e7f1b2009-11-20 11:01:32 -0800437 for (String x : testOutput) {
438 appendStatus(x);
ksrini20a64b22008-09-24 15:07:41 -0700439 }
ksrinif8cc5972011-04-07 12:06:32 -0700440 status.append("++++Test Stack Trace++++\n");
441 status.append(t.toString());
442 for (StackTraceElement e : t.getStackTrace()) {
443 status.append(e.toString());
444 }
445 status.append("++++End of Test Info++++\n");
ksrini20a64b22008-09-24 15:07:41 -0700446 return status.toString();
447 }
448
449 boolean contains(String str) {
450 for (String x : testOutput) {
451 if (x.contains(str)) {
452 return true;
453 }
454 }
ksrini11e7f1b2009-11-20 11:01:32 -0800455 appendStatus("Error: string <" + str + "> not found");
456 testExitValue++;
457 return false;
458 }
459
460 boolean matches(String stringToMatch) {
461 for (String x : testOutput) {
462 if (x.matches(stringToMatch)) {
463 return true;
464 }
465 }
466 appendStatus("Error: string <" + stringToMatch + "> not found");
ksrini20a64b22008-09-24 15:07:41 -0700467 testExitValue++;
468 return false;
469 }
470 }
471}