blob: de8f3f7f682475c04d9739d839343e9d99e31854 [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;
ksriniac5e02f2012-01-11 08:14:47 -080032import java.nio.file.attribute.BasicFileAttributes;
ksrinif8cc5972011-04-07 12:06:32 -070033import java.nio.file.Files;
ksriniac5e02f2012-01-11 08:14:47 -080034import java.nio.file.FileVisitResult;
35import java.nio.file.SimpleFileVisitor;
ksrinif8cc5972011-04-07 12:06:32 -070036import java.nio.file.Path;
ksrini20a64b22008-09-24 15:07:41 -070037import java.util.ArrayList;
38import java.util.List;
39import java.util.Map;
40import javax.tools.JavaCompiler;
ksriniac5e02f2012-01-11 08:14:47 -080041import javax.tools.ToolProvider;
ksrini20a64b22008-09-24 15:07:41 -070042
ksrinif8cc5972011-04-07 12:06:32 -070043import static java.nio.file.StandardCopyOption.*;
44
ksrini20a64b22008-09-24 15:07:41 -070045/**
ksrinif8cc5972011-04-07 12:06:32 -070046 * This class provides some common utilities for the launcher tests.
ksrini20a64b22008-09-24 15:07:41 -070047 */
48public enum TestHelper {
49 INSTANCE;
ksrinieed01b82012-01-24 09:58:44 -080050 // commonly used jtreg constants
51 static final File TEST_CLASSES_DIR;
52 static final File TEST_SOURCES_DIR;
53
ksrini11e7f1b2009-11-20 11:01:32 -080054 static final String JAVAHOME = System.getProperty("java.home");
ksrini20a64b22008-09-24 15:07:41 -070055 static final boolean isSDK = JAVAHOME.endsWith("jre");
56 static final String javaCmd;
ksrinidd194042012-01-03 08:33:30 -080057 static final String javawCmd;
ksrini11e7f1b2009-11-20 11:01:32 -080058 static final String java64Cmd;
ksrini20a64b22008-09-24 15:07:41 -070059 static final String javacCmd;
60 static final JavaCompiler compiler;
61
ksrini11e7f1b2009-11-20 11:01:32 -080062 static final boolean debug = Boolean.getBoolean("TestHelper.Debug");
ksrini20a64b22008-09-24 15:07:41 -070063 static final boolean isWindows =
64 System.getProperty("os.name", "unknown").startsWith("Windows");
ksrini11e7f1b2009-11-20 11:01:32 -080065 static final boolean is64Bit =
66 System.getProperty("sun.arch.data.model").equals("64");
67 static final boolean is32Bit =
68 System.getProperty("sun.arch.data.model").equals("32");
69 static final boolean isSolaris =
70 System.getProperty("os.name", "unknown").startsWith("SunOS");
71 static final boolean isLinux =
72 System.getProperty("os.name", "unknown").startsWith("Linux");
73 static final boolean isDualMode = isSolaris;
74 static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc");
75
ksriniac5e02f2012-01-11 08:14:47 -080076 static final String JAVA_FILE_EXT = ".java";
77 static final String CLASS_FILE_EXT = ".class";
78 static final String JAR_FILE_EXT = ".jar";
79
ksrini20a64b22008-09-24 15:07:41 -070080 static int testExitValue = 0;
81
82 static {
ksrinieed01b82012-01-24 09:58:44 -080083 String tmp = System.getProperty("test.classes", null);
84 if (tmp == null) {
85 throw new Error("property test.classes not defined ??");
86 }
87 TEST_CLASSES_DIR = new File(tmp).getAbsoluteFile();
88
89 tmp = System.getProperty("test.src", null);
90 if (tmp == null) {
91 throw new Error("property test.src not defined ??");
92 }
93 TEST_SOURCES_DIR = new File(tmp).getAbsoluteFile();
94
ksrini11e7f1b2009-11-20 11:01:32 -080095 if (is64Bit && is32Bit) {
96 throw new RuntimeException("arch model cannot be both 32 and 64 bit");
97 }
98 if (!is64Bit && !is32Bit) {
99 throw new RuntimeException("arch model is not 32 or 64 bit ?");
100 }
ksrini20a64b22008-09-24 15:07:41 -0700101 compiler = ToolProvider.getSystemJavaCompiler();
102 File binDir = (isSDK) ? new File((new File(JAVAHOME)).getParentFile(), "bin")
103 : new File(JAVAHOME, "bin");
104 File javaCmdFile = (isWindows)
105 ? new File(binDir, "java.exe")
106 : new File(binDir, "java");
107 javaCmd = javaCmdFile.getAbsolutePath();
108 if (!javaCmdFile.canExecute()) {
ksrinidd194042012-01-03 08:33:30 -0800109 throw new RuntimeException("java <" + TestHelper.javaCmd +
110 "> must exist and should be executable");
ksrini20a64b22008-09-24 15:07:41 -0700111 }
112
113 File javacCmdFile = (isWindows)
114 ? new File(binDir, "javac.exe")
115 : new File(binDir, "javac");
116 javacCmd = javacCmdFile.getAbsolutePath();
ksrinidd194042012-01-03 08:33:30 -0800117
118 if (isWindows) {
119 File javawCmdFile = new File(binDir, "javaw.exe");
120 javawCmd = javawCmdFile.getAbsolutePath();
121 if (!javawCmdFile.canExecute()) {
122 throw new RuntimeException("java <" + javawCmd +
123 "> must exist and should be executable");
124 }
125 } else {
126 javawCmd = null;
127 }
128
ksrini20a64b22008-09-24 15:07:41 -0700129 if (!javacCmdFile.canExecute()) {
ksrinidd194042012-01-03 08:33:30 -0800130 throw new RuntimeException("java <" + javacCmd +
131 "> must exist and should be executable");
ksrini20a64b22008-09-24 15:07:41 -0700132 }
ksrini11e7f1b2009-11-20 11:01:32 -0800133 if (isSolaris) {
134 File sparc64BinDir = new File(binDir,isSparc ? "sparcv9" : "amd64");
135 File java64CmdFile= new File(sparc64BinDir, "java");
136 if (java64CmdFile.exists() && java64CmdFile.canExecute()) {
137 java64Cmd = java64CmdFile.getAbsolutePath();
138 } else {
139 java64Cmd = null;
140 }
141 } else {
142 java64Cmd = null;
143 }
144 }
145
146 /*
ksrinif8cc5972011-04-07 12:06:32 -0700147 * is a dual mode available in the test jdk
148 */
149 static boolean dualModePresent() {
150 return isDualMode && java64Cmd != null;
151 }
152
153 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800154 * usually the jre/lib/arch-name is the same as os.arch, except for x86.
155 */
156 static String getJreArch() {
157 String arch = System.getProperty("os.arch");
158 return arch.equals("x86") ? "i386" : arch;
159 }
160
161 /*
ksrinif8cc5972011-04-07 12:06:32 -0700162 * get the complementary jre arch ie. if sparc then return sparcv9 and
163 * vice-versa.
164 */
165 static String getComplementaryJreArch() {
166 String arch = System.getProperty("os.arch");
167 if (arch != null) {
168 switch (arch) {
169 case "sparc":
170 return "sparcv9";
171 case "sparcv9":
172 return "sparc";
173 case "x86":
174 return "amd64";
175 case "amd64":
176 return "i386";
177 }
178 }
179 return null;
180 }
181
182 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800183 * A convenience method to create a jar with jar file name and defs
184 */
185 static void createJar(File jarName, String... mainDefs)
186 throws FileNotFoundException{
187 createJar(null, jarName, new File("Foo"), mainDefs);
ksrini20a64b22008-09-24 15:07:41 -0700188 }
189
190 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700191 * A convenience method to create a java file, compile and jar it up, using
192 * the sole class file name in the jar, as the Main-Class attribute value.
ksrini20a64b22008-09-24 15:07:41 -0700193 */
194 static void createJar(File jarName, File mainClass, String... mainDefs)
195 throws FileNotFoundException {
196 createJar(null, jarName, mainClass, mainDefs);
197 }
198
199 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700200 * A generic jar file creator to create a java file, compile it
201 * and jar it up, a specific Main-Class entry name in the
202 * manifest can be specified or a null to use the sole class file name
203 * as the Main-Class attribute value.
ksrini20a64b22008-09-24 15:07:41 -0700204 */
ksrinicafaf7c2008-10-01 09:04:42 -0700205 static void createJar(String mEntry, File jarName, File mainClass,
206 String... mainDefs) throws FileNotFoundException {
ksrini20a64b22008-09-24 15:07:41 -0700207 if (jarName.exists()) {
208 jarName.delete();
209 }
ksrini37e8b502011-07-19 10:58:50 -0700210 try (PrintStream ps = new PrintStream(new FileOutputStream(mainClass + ".java"))) {
211 ps.println("public class Foo {");
212 if (mainDefs != null) {
213 for (String x : mainDefs) {
214 ps.println(x);
215 }
ksrini20a64b22008-09-24 15:07:41 -0700216 }
ksrini37e8b502011-07-19 10:58:50 -0700217 ps.println("}");
ksrini20a64b22008-09-24 15:07:41 -0700218 }
ksrini20a64b22008-09-24 15:07:41 -0700219
220 String compileArgs[] = {
221 mainClass + ".java"
222 };
223 if (compiler.run(null, null, null, compileArgs) != 0) {
224 throw new RuntimeException("compilation failed " + mainClass + ".java");
225 }
ksrinicafaf7c2008-10-01 09:04:42 -0700226 if (mEntry == null) {
ksrini20a64b22008-09-24 15:07:41 -0700227 mEntry = mainClass.getName();
228 }
229 String jarArgs[] = {
230 (debug) ? "cvfe" : "cfe",
231 jarName.getAbsolutePath(),
232 mEntry,
233 mainClass.getName() + ".class"
234 };
ksrini37e8b502011-07-19 10:58:50 -0700235 createJar(jarArgs);
236 }
237
238 static void createJar(String... args) {
ksrini20a64b22008-09-24 15:07:41 -0700239 sun.tools.jar.Main jarTool =
240 new sun.tools.jar.Main(System.out, System.err, "JarCreator");
ksrini37e8b502011-07-19 10:58:50 -0700241 if (!jarTool.run(args)) {
242 String message = "jar creation failed with command:";
243 for (String x : args) {
244 message = message.concat(" " + x);
245 }
246 throw new RuntimeException(message);
ksrini20a64b22008-09-24 15:07:41 -0700247 }
ksrini37e8b502011-07-19 10:58:50 -0700248 }
ksrini20a64b22008-09-24 15:07:41 -0700249
ksrinif8cc5972011-04-07 12:06:32 -0700250 static void copyFile(File src, File dst) throws IOException {
251 Path parent = dst.toPath().getParent();
252 if (parent != null) {
253 Files.createDirectories(parent);
254 }
255 Files.copy(src.toPath(), dst.toPath(), COPY_ATTRIBUTES, REPLACE_EXISTING);
256 }
257
258 static void recursiveDelete(File target) throws IOException {
259 if (!target.exists()) {
260 return;
261 }
262 Files.walkFileTree(target.toPath(), new SimpleFileVisitor<Path>() {
263 @Override
264 public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
265 try {
266 Files.deleteIfExists(dir);
267 } catch (IOException ex) {
268 System.out.println("Error: could not delete: " + dir.toString());
269 System.out.println(ex.getMessage());
270 return FileVisitResult.TERMINATE;
271 }
272 return FileVisitResult.CONTINUE;
273 }
274 @Override
275 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
276 try {
277 Files.deleteIfExists(file);
278 } catch (IOException ex) {
279 System.out.println("Error: could not delete: " + file.toString());
280 System.out.println(ex.getMessage());
281 return FileVisitResult.TERMINATE;
282 }
283 return FileVisitResult.CONTINUE;
284 }
285 });
286 }
287
ksrini11e7f1b2009-11-20 11:01:32 -0800288 static TestResult doExec(String...cmds) {
289 return doExec(null, cmds);
290 }
291
ksrini20a64b22008-09-24 15:07:41 -0700292 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700293 * A method which executes a java cmd and returns the results in a container
ksrini20a64b22008-09-24 15:07:41 -0700294 */
ksrini11e7f1b2009-11-20 11:01:32 -0800295 static TestResult doExec(Map<String, String> envToSet, String...cmds) {
ksrini20a64b22008-09-24 15:07:41 -0700296 String cmdStr = "";
297 for (String x : cmds) {
298 cmdStr = cmdStr.concat(x + " ");
299 }
300 ProcessBuilder pb = new ProcessBuilder(cmds);
301 Map<String, String> env = pb.environment();
ksrini11e7f1b2009-11-20 11:01:32 -0800302 if (envToSet != null) {
303 env.putAll(envToSet);
304 }
ksrini20a64b22008-09-24 15:07:41 -0700305 BufferedReader rdr = null;
306 try {
ksrinif8cc5972011-04-07 12:06:32 -0700307 List<String> outputList = new ArrayList<>();
ksrini20a64b22008-09-24 15:07:41 -0700308 pb.redirectErrorStream(true);
309 Process p = pb.start();
310 rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
311 String in = rdr.readLine();
312 while (in != null) {
313 outputList.add(in);
314 in = rdr.readLine();
315 }
316 p.waitFor();
317 p.destroy();
ksrinif8cc5972011-04-07 12:06:32 -0700318
319 return new TestHelper.TestResult(cmdStr, p.exitValue(), outputList,
320 env, new Throwable("current stack of the test"));
ksrini20a64b22008-09-24 15:07:41 -0700321 } catch (Exception ex) {
322 ex.printStackTrace();
323 throw new RuntimeException(ex.getMessage());
324 }
325 }
326
ksriniac5e02f2012-01-11 08:14:47 -0800327 static FileFilter createFilter(final String extension) {
328 return new FileFilter() {
329 @Override
330 public boolean accept(File pathname) {
331 String name = pathname.getName();
332 if (name.endsWith(extension)) {
333 return true;
334 }
335 return false;
336 }
337 };
338 }
339
ksrini20a64b22008-09-24 15:07:41 -0700340 /*
341 * A class to encapsulate the test results and stuff, with some ease
342 * of use methods to check the test results.
343 */
344 static class TestResult {
345 StringBuilder status;
346 int exitValue;
347 List<String> testOutput;
ksrinif8cc5972011-04-07 12:06:32 -0700348 Map<String, String> env;
349 Throwable t;
ksrini20a64b22008-09-24 15:07:41 -0700350
ksrinif8cc5972011-04-07 12:06:32 -0700351 public TestResult(String str, int rv, List<String> oList,
352 Map<String, String> env, Throwable t) {
ksrini11e7f1b2009-11-20 11:01:32 -0800353 status = new StringBuilder("Executed command: " + str + "\n");
ksrini20a64b22008-09-24 15:07:41 -0700354 exitValue = rv;
355 testOutput = oList;
ksrinif8cc5972011-04-07 12:06:32 -0700356 this.env = env;
357 this.t = t;
ksrini20a64b22008-09-24 15:07:41 -0700358 }
359
ksrini11e7f1b2009-11-20 11:01:32 -0800360 void appendStatus(String x) {
361 status = status.append(" " + x + "\n");
362 }
363
ksrini20a64b22008-09-24 15:07:41 -0700364 void checkNegative() {
365 if (exitValue == 0) {
ksrini11e7f1b2009-11-20 11:01:32 -0800366 appendStatus("Error: test must not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700367 testExitValue++;
368 }
369 }
370
371 void checkPositive() {
372 if (exitValue != 0) {
ksrini11e7f1b2009-11-20 11:01:32 -0800373 appendStatus("Error: test did not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700374 testExitValue++;
375 }
376 }
377
378 boolean isOK() {
379 return exitValue == 0;
380 }
381
382 boolean isZeroOutput() {
383 if (!testOutput.isEmpty()) {
ksrini11e7f1b2009-11-20 11:01:32 -0800384 appendStatus("Error: No message from cmd please");
ksrini20a64b22008-09-24 15:07:41 -0700385 testExitValue++;
386 return false;
387 }
388 return true;
389 }
390
391 boolean isNotZeroOutput() {
392 if (testOutput.isEmpty()) {
ksrini11e7f1b2009-11-20 11:01:32 -0800393 appendStatus("Error: Missing message");
ksrini20a64b22008-09-24 15:07:41 -0700394 testExitValue++;
395 return false;
396 }
397 return true;
398 }
399
ksrini11e7f1b2009-11-20 11:01:32 -0800400 @Override
ksrini20a64b22008-09-24 15:07:41 -0700401 public String toString() {
ksrinif8cc5972011-04-07 12:06:32 -0700402 status.append("++++Begin Test Info++++\n");
403 status.append("++++Test Environment++++\n");
404 for (String x : env.keySet()) {
405 status.append(x).append("=").append(env.get(x)).append("\n");
406 }
407 status.append("++++Test Output++++\n");
ksrini11e7f1b2009-11-20 11:01:32 -0800408 for (String x : testOutput) {
409 appendStatus(x);
ksrini20a64b22008-09-24 15:07:41 -0700410 }
ksrinif8cc5972011-04-07 12:06:32 -0700411 status.append("++++Test Stack Trace++++\n");
412 status.append(t.toString());
413 for (StackTraceElement e : t.getStackTrace()) {
414 status.append(e.toString());
415 }
416 status.append("++++End of Test Info++++\n");
ksrini20a64b22008-09-24 15:07:41 -0700417 return status.toString();
418 }
419
420 boolean contains(String str) {
421 for (String x : testOutput) {
422 if (x.contains(str)) {
423 return true;
424 }
425 }
ksrini11e7f1b2009-11-20 11:01:32 -0800426 appendStatus("Error: string <" + str + "> not found");
427 testExitValue++;
428 return false;
429 }
430
431 boolean matches(String stringToMatch) {
432 for (String x : testOutput) {
433 if (x.matches(stringToMatch)) {
434 return true;
435 }
436 }
437 appendStatus("Error: string <" + stringToMatch + "> not found");
ksrini20a64b22008-09-24 15:07:41 -0700438 testExitValue++;
439 return false;
440 }
441 }
442}