blob: f2997368d9c3070017cc494f4dfce80cc8cce91c [file] [log] [blame]
ksrini20a64b22008-09-24 15:07:41 -07001/*
katleman7d8178b2011-05-25 13:32:36 -07002 * Copyright (c) 2008, 2011, 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
ksrinif8cc5972011-04-07 12:06:32 -070024import java.nio.file.attribute.BasicFileAttributes;
25import java.nio.file.FileVisitResult;
26import java.nio.file.SimpleFileVisitor;
ksrini20a64b22008-09-24 15:07:41 -070027import javax.tools.ToolProvider;
28import java.io.BufferedReader;
29import java.io.File;
30import java.io.FileNotFoundException;
31import java.io.FileOutputStream;
ksrinif8cc5972011-04-07 12:06:32 -070032import java.io.IOException;
ksrini20a64b22008-09-24 15:07:41 -070033import java.io.InputStreamReader;
34import java.io.PrintStream;
ksrinif8cc5972011-04-07 12:06:32 -070035import java.nio.file.Files;
36import 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;
41
ksrinif8cc5972011-04-07 12:06:32 -070042import static java.nio.file.StandardCopyOption.*;
43
ksrini20a64b22008-09-24 15:07:41 -070044/**
ksrinif8cc5972011-04-07 12:06:32 -070045 * This class provides some common utilities for the launcher tests.
ksrini20a64b22008-09-24 15:07:41 -070046 */
47public enum TestHelper {
48 INSTANCE;
ksrini11e7f1b2009-11-20 11:01:32 -080049 static final String JAVAHOME = System.getProperty("java.home");
ksrini20a64b22008-09-24 15:07:41 -070050 static final boolean isSDK = JAVAHOME.endsWith("jre");
51 static final String javaCmd;
ksrini11e7f1b2009-11-20 11:01:32 -080052 static final String java64Cmd;
ksrini20a64b22008-09-24 15:07:41 -070053 static final String javacCmd;
54 static final JavaCompiler compiler;
55
ksrini11e7f1b2009-11-20 11:01:32 -080056 static final boolean debug = Boolean.getBoolean("TestHelper.Debug");
ksrini20a64b22008-09-24 15:07:41 -070057 static final boolean isWindows =
58 System.getProperty("os.name", "unknown").startsWith("Windows");
ksrini11e7f1b2009-11-20 11:01:32 -080059 static final boolean is64Bit =
60 System.getProperty("sun.arch.data.model").equals("64");
61 static final boolean is32Bit =
62 System.getProperty("sun.arch.data.model").equals("32");
63 static final boolean isSolaris =
64 System.getProperty("os.name", "unknown").startsWith("SunOS");
65 static final boolean isLinux =
66 System.getProperty("os.name", "unknown").startsWith("Linux");
67 static final boolean isDualMode = isSolaris;
68 static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc");
69
ksrini20a64b22008-09-24 15:07:41 -070070 static int testExitValue = 0;
71
72 static {
ksrini11e7f1b2009-11-20 11:01:32 -080073 if (is64Bit && is32Bit) {
74 throw new RuntimeException("arch model cannot be both 32 and 64 bit");
75 }
76 if (!is64Bit && !is32Bit) {
77 throw new RuntimeException("arch model is not 32 or 64 bit ?");
78 }
ksrini20a64b22008-09-24 15:07:41 -070079 compiler = ToolProvider.getSystemJavaCompiler();
80 File binDir = (isSDK) ? new File((new File(JAVAHOME)).getParentFile(), "bin")
81 : new File(JAVAHOME, "bin");
82 File javaCmdFile = (isWindows)
83 ? new File(binDir, "java.exe")
84 : new File(binDir, "java");
85 javaCmd = javaCmdFile.getAbsolutePath();
86 if (!javaCmdFile.canExecute()) {
87 throw new RuntimeException("java <" + TestHelper.javaCmd + "> must exist");
88 }
89
90 File javacCmdFile = (isWindows)
91 ? new File(binDir, "javac.exe")
92 : new File(binDir, "javac");
93 javacCmd = javacCmdFile.getAbsolutePath();
94 if (!javacCmdFile.canExecute()) {
95 throw new RuntimeException("java <" + javacCmd + "> must exist");
96 }
ksrini11e7f1b2009-11-20 11:01:32 -080097 if (isSolaris) {
98 File sparc64BinDir = new File(binDir,isSparc ? "sparcv9" : "amd64");
99 File java64CmdFile= new File(sparc64BinDir, "java");
100 if (java64CmdFile.exists() && java64CmdFile.canExecute()) {
101 java64Cmd = java64CmdFile.getAbsolutePath();
102 } else {
103 java64Cmd = null;
104 }
105 } else {
106 java64Cmd = null;
107 }
108 }
109
110 /*
ksrinif8cc5972011-04-07 12:06:32 -0700111 * is a dual mode available in the test jdk
112 */
113 static boolean dualModePresent() {
114 return isDualMode && java64Cmd != null;
115 }
116
117 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800118 * usually the jre/lib/arch-name is the same as os.arch, except for x86.
119 */
120 static String getJreArch() {
121 String arch = System.getProperty("os.arch");
122 return arch.equals("x86") ? "i386" : arch;
123 }
124
125 /*
ksrinif8cc5972011-04-07 12:06:32 -0700126 * get the complementary jre arch ie. if sparc then return sparcv9 and
127 * vice-versa.
128 */
129 static String getComplementaryJreArch() {
130 String arch = System.getProperty("os.arch");
131 if (arch != null) {
132 switch (arch) {
133 case "sparc":
134 return "sparcv9";
135 case "sparcv9":
136 return "sparc";
137 case "x86":
138 return "amd64";
139 case "amd64":
140 return "i386";
141 }
142 }
143 return null;
144 }
145
146 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800147 * A convenience method to create a jar with jar file name and defs
148 */
149 static void createJar(File jarName, String... mainDefs)
150 throws FileNotFoundException{
151 createJar(null, jarName, new File("Foo"), mainDefs);
ksrini20a64b22008-09-24 15:07:41 -0700152 }
153
154 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700155 * A convenience method to create a java file, compile and jar it up, using
156 * the sole class file name in the jar, as the Main-Class attribute value.
ksrini20a64b22008-09-24 15:07:41 -0700157 */
158 static void createJar(File jarName, File mainClass, String... mainDefs)
159 throws FileNotFoundException {
160 createJar(null, jarName, mainClass, mainDefs);
161 }
162
163 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700164 * A generic jar file creator to create a java file, compile it
165 * and jar it up, a specific Main-Class entry name in the
166 * manifest can be specified or a null to use the sole class file name
167 * as the Main-Class attribute value.
ksrini20a64b22008-09-24 15:07:41 -0700168 */
ksrinicafaf7c2008-10-01 09:04:42 -0700169 static void createJar(String mEntry, File jarName, File mainClass,
170 String... mainDefs) throws FileNotFoundException {
ksrini20a64b22008-09-24 15:07:41 -0700171 if (jarName.exists()) {
172 jarName.delete();
173 }
ksrini37e8b502011-07-19 10:58:50 -0700174 try (PrintStream ps = new PrintStream(new FileOutputStream(mainClass + ".java"))) {
175 ps.println("public class Foo {");
176 if (mainDefs != null) {
177 for (String x : mainDefs) {
178 ps.println(x);
179 }
ksrini20a64b22008-09-24 15:07:41 -0700180 }
ksrini37e8b502011-07-19 10:58:50 -0700181 ps.println("}");
ksrini20a64b22008-09-24 15:07:41 -0700182 }
ksrini20a64b22008-09-24 15:07:41 -0700183
184 String compileArgs[] = {
185 mainClass + ".java"
186 };
187 if (compiler.run(null, null, null, compileArgs) != 0) {
188 throw new RuntimeException("compilation failed " + mainClass + ".java");
189 }
ksrinicafaf7c2008-10-01 09:04:42 -0700190 if (mEntry == null) {
ksrini20a64b22008-09-24 15:07:41 -0700191 mEntry = mainClass.getName();
192 }
193 String jarArgs[] = {
194 (debug) ? "cvfe" : "cfe",
195 jarName.getAbsolutePath(),
196 mEntry,
197 mainClass.getName() + ".class"
198 };
ksrini37e8b502011-07-19 10:58:50 -0700199 createJar(jarArgs);
200 }
201
202 static void createJar(String... args) {
ksrini20a64b22008-09-24 15:07:41 -0700203 sun.tools.jar.Main jarTool =
204 new sun.tools.jar.Main(System.out, System.err, "JarCreator");
ksrini37e8b502011-07-19 10:58:50 -0700205 if (!jarTool.run(args)) {
206 String message = "jar creation failed with command:";
207 for (String x : args) {
208 message = message.concat(" " + x);
209 }
210 throw new RuntimeException(message);
ksrini20a64b22008-09-24 15:07:41 -0700211 }
ksrini37e8b502011-07-19 10:58:50 -0700212 }
ksrini20a64b22008-09-24 15:07:41 -0700213
ksrinif8cc5972011-04-07 12:06:32 -0700214 static void copyFile(File src, File dst) throws IOException {
215 Path parent = dst.toPath().getParent();
216 if (parent != null) {
217 Files.createDirectories(parent);
218 }
219 Files.copy(src.toPath(), dst.toPath(), COPY_ATTRIBUTES, REPLACE_EXISTING);
220 }
221
222 static void recursiveDelete(File target) throws IOException {
223 if (!target.exists()) {
224 return;
225 }
226 Files.walkFileTree(target.toPath(), new SimpleFileVisitor<Path>() {
227 @Override
228 public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
229 try {
230 Files.deleteIfExists(dir);
231 } catch (IOException ex) {
232 System.out.println("Error: could not delete: " + dir.toString());
233 System.out.println(ex.getMessage());
234 return FileVisitResult.TERMINATE;
235 }
236 return FileVisitResult.CONTINUE;
237 }
238 @Override
239 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
240 try {
241 Files.deleteIfExists(file);
242 } catch (IOException ex) {
243 System.out.println("Error: could not delete: " + file.toString());
244 System.out.println(ex.getMessage());
245 return FileVisitResult.TERMINATE;
246 }
247 return FileVisitResult.CONTINUE;
248 }
249 });
250 }
251
ksrini11e7f1b2009-11-20 11:01:32 -0800252 static TestResult doExec(String...cmds) {
253 return doExec(null, cmds);
254 }
255
ksrini20a64b22008-09-24 15:07:41 -0700256 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700257 * A method which executes a java cmd and returns the results in a container
ksrini20a64b22008-09-24 15:07:41 -0700258 */
ksrini11e7f1b2009-11-20 11:01:32 -0800259 static TestResult doExec(Map<String, String> envToSet, String...cmds) {
ksrini20a64b22008-09-24 15:07:41 -0700260 String cmdStr = "";
261 for (String x : cmds) {
262 cmdStr = cmdStr.concat(x + " ");
263 }
264 ProcessBuilder pb = new ProcessBuilder(cmds);
265 Map<String, String> env = pb.environment();
ksrini11e7f1b2009-11-20 11:01:32 -0800266 if (envToSet != null) {
267 env.putAll(envToSet);
268 }
ksrini20a64b22008-09-24 15:07:41 -0700269 BufferedReader rdr = null;
270 try {
ksrinif8cc5972011-04-07 12:06:32 -0700271 List<String> outputList = new ArrayList<>();
ksrini20a64b22008-09-24 15:07:41 -0700272 pb.redirectErrorStream(true);
273 Process p = pb.start();
274 rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
275 String in = rdr.readLine();
276 while (in != null) {
277 outputList.add(in);
278 in = rdr.readLine();
279 }
280 p.waitFor();
281 p.destroy();
ksrinif8cc5972011-04-07 12:06:32 -0700282
283 return new TestHelper.TestResult(cmdStr, p.exitValue(), outputList,
284 env, new Throwable("current stack of the test"));
ksrini20a64b22008-09-24 15:07:41 -0700285 } catch (Exception ex) {
286 ex.printStackTrace();
287 throw new RuntimeException(ex.getMessage());
288 }
289 }
290
291 /*
292 * A class to encapsulate the test results and stuff, with some ease
293 * of use methods to check the test results.
294 */
295 static class TestResult {
296 StringBuilder status;
297 int exitValue;
298 List<String> testOutput;
ksrinif8cc5972011-04-07 12:06:32 -0700299 Map<String, String> env;
300 Throwable t;
ksrini20a64b22008-09-24 15:07:41 -0700301
ksrinif8cc5972011-04-07 12:06:32 -0700302 public TestResult(String str, int rv, List<String> oList,
303 Map<String, String> env, Throwable t) {
ksrini11e7f1b2009-11-20 11:01:32 -0800304 status = new StringBuilder("Executed command: " + str + "\n");
ksrini20a64b22008-09-24 15:07:41 -0700305 exitValue = rv;
306 testOutput = oList;
ksrinif8cc5972011-04-07 12:06:32 -0700307 this.env = env;
308 this.t = t;
ksrini20a64b22008-09-24 15:07:41 -0700309 }
310
ksrini11e7f1b2009-11-20 11:01:32 -0800311 void appendStatus(String x) {
312 status = status.append(" " + x + "\n");
313 }
314
ksrini20a64b22008-09-24 15:07:41 -0700315 void checkNegative() {
316 if (exitValue == 0) {
ksrini11e7f1b2009-11-20 11:01:32 -0800317 appendStatus("Error: test must not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700318 testExitValue++;
319 }
320 }
321
322 void checkPositive() {
323 if (exitValue != 0) {
ksrini11e7f1b2009-11-20 11:01:32 -0800324 appendStatus("Error: test did not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700325 testExitValue++;
326 }
327 }
328
329 boolean isOK() {
330 return exitValue == 0;
331 }
332
333 boolean isZeroOutput() {
334 if (!testOutput.isEmpty()) {
ksrini11e7f1b2009-11-20 11:01:32 -0800335 appendStatus("Error: No message from cmd please");
ksrini20a64b22008-09-24 15:07:41 -0700336 testExitValue++;
337 return false;
338 }
339 return true;
340 }
341
342 boolean isNotZeroOutput() {
343 if (testOutput.isEmpty()) {
ksrini11e7f1b2009-11-20 11:01:32 -0800344 appendStatus("Error: Missing message");
ksrini20a64b22008-09-24 15:07:41 -0700345 testExitValue++;
346 return false;
347 }
348 return true;
349 }
350
ksrini11e7f1b2009-11-20 11:01:32 -0800351 @Override
ksrini20a64b22008-09-24 15:07:41 -0700352 public String toString() {
ksrinif8cc5972011-04-07 12:06:32 -0700353 status.append("++++Begin Test Info++++\n");
354 status.append("++++Test Environment++++\n");
355 for (String x : env.keySet()) {
356 status.append(x).append("=").append(env.get(x)).append("\n");
357 }
358 status.append("++++Test Output++++\n");
ksrini11e7f1b2009-11-20 11:01:32 -0800359 for (String x : testOutput) {
360 appendStatus(x);
ksrini20a64b22008-09-24 15:07:41 -0700361 }
ksrinif8cc5972011-04-07 12:06:32 -0700362 status.append("++++Test Stack Trace++++\n");
363 status.append(t.toString());
364 for (StackTraceElement e : t.getStackTrace()) {
365 status.append(e.toString());
366 }
367 status.append("++++End of Test Info++++\n");
ksrini20a64b22008-09-24 15:07:41 -0700368 return status.toString();
369 }
370
371 boolean contains(String str) {
372 for (String x : testOutput) {
373 if (x.contains(str)) {
374 return true;
375 }
376 }
ksrini11e7f1b2009-11-20 11:01:32 -0800377 appendStatus("Error: string <" + str + "> not found");
378 testExitValue++;
379 return false;
380 }
381
382 boolean matches(String stringToMatch) {
383 for (String x : testOutput) {
384 if (x.matches(stringToMatch)) {
385 return true;
386 }
387 }
388 appendStatus("Error: string <" + stringToMatch + "> not found");
ksrini20a64b22008-09-24 15:07:41 -0700389 testExitValue++;
390 return false;
391 }
392 }
393}