blob: c0f1119554ca554150a3d210414564e4eb562bfc [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;
ksrini11e7f1b2009-11-20 11:01:32 -080050 static final String JAVAHOME = System.getProperty("java.home");
ksrini20a64b22008-09-24 15:07:41 -070051 static final boolean isSDK = JAVAHOME.endsWith("jre");
52 static final String javaCmd;
ksrinidd194042012-01-03 08:33:30 -080053 static final String javawCmd;
ksrini11e7f1b2009-11-20 11:01:32 -080054 static final String java64Cmd;
ksrini20a64b22008-09-24 15:07:41 -070055 static final String javacCmd;
56 static final JavaCompiler compiler;
57
ksrini11e7f1b2009-11-20 11:01:32 -080058 static final boolean debug = Boolean.getBoolean("TestHelper.Debug");
ksrini20a64b22008-09-24 15:07:41 -070059 static final boolean isWindows =
60 System.getProperty("os.name", "unknown").startsWith("Windows");
ksrini11e7f1b2009-11-20 11:01:32 -080061 static final boolean is64Bit =
62 System.getProperty("sun.arch.data.model").equals("64");
63 static final boolean is32Bit =
64 System.getProperty("sun.arch.data.model").equals("32");
65 static final boolean isSolaris =
66 System.getProperty("os.name", "unknown").startsWith("SunOS");
67 static final boolean isLinux =
68 System.getProperty("os.name", "unknown").startsWith("Linux");
69 static final boolean isDualMode = isSolaris;
70 static final boolean isSparc = System.getProperty("os.arch").startsWith("sparc");
71
ksriniac5e02f2012-01-11 08:14:47 -080072 static final String JAVA_FILE_EXT = ".java";
73 static final String CLASS_FILE_EXT = ".class";
74 static final String JAR_FILE_EXT = ".jar";
75
ksrini20a64b22008-09-24 15:07:41 -070076 static int testExitValue = 0;
77
78 static {
ksrini11e7f1b2009-11-20 11:01:32 -080079 if (is64Bit && is32Bit) {
80 throw new RuntimeException("arch model cannot be both 32 and 64 bit");
81 }
82 if (!is64Bit && !is32Bit) {
83 throw new RuntimeException("arch model is not 32 or 64 bit ?");
84 }
ksrini20a64b22008-09-24 15:07:41 -070085 compiler = ToolProvider.getSystemJavaCompiler();
86 File binDir = (isSDK) ? new File((new File(JAVAHOME)).getParentFile(), "bin")
87 : new File(JAVAHOME, "bin");
88 File javaCmdFile = (isWindows)
89 ? new File(binDir, "java.exe")
90 : new File(binDir, "java");
91 javaCmd = javaCmdFile.getAbsolutePath();
92 if (!javaCmdFile.canExecute()) {
ksrinidd194042012-01-03 08:33:30 -080093 throw new RuntimeException("java <" + TestHelper.javaCmd +
94 "> must exist and should be executable");
ksrini20a64b22008-09-24 15:07:41 -070095 }
96
97 File javacCmdFile = (isWindows)
98 ? new File(binDir, "javac.exe")
99 : new File(binDir, "javac");
100 javacCmd = javacCmdFile.getAbsolutePath();
ksrinidd194042012-01-03 08:33:30 -0800101
102 if (isWindows) {
103 File javawCmdFile = new File(binDir, "javaw.exe");
104 javawCmd = javawCmdFile.getAbsolutePath();
105 if (!javawCmdFile.canExecute()) {
106 throw new RuntimeException("java <" + javawCmd +
107 "> must exist and should be executable");
108 }
109 } else {
110 javawCmd = null;
111 }
112
ksrini20a64b22008-09-24 15:07:41 -0700113 if (!javacCmdFile.canExecute()) {
ksrinidd194042012-01-03 08:33:30 -0800114 throw new RuntimeException("java <" + javacCmd +
115 "> must exist and should be executable");
ksrini20a64b22008-09-24 15:07:41 -0700116 }
ksrini11e7f1b2009-11-20 11:01:32 -0800117 if (isSolaris) {
118 File sparc64BinDir = new File(binDir,isSparc ? "sparcv9" : "amd64");
119 File java64CmdFile= new File(sparc64BinDir, "java");
120 if (java64CmdFile.exists() && java64CmdFile.canExecute()) {
121 java64Cmd = java64CmdFile.getAbsolutePath();
122 } else {
123 java64Cmd = null;
124 }
125 } else {
126 java64Cmd = null;
127 }
128 }
129
130 /*
ksrinif8cc5972011-04-07 12:06:32 -0700131 * is a dual mode available in the test jdk
132 */
133 static boolean dualModePresent() {
134 return isDualMode && java64Cmd != null;
135 }
136
137 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800138 * usually the jre/lib/arch-name is the same as os.arch, except for x86.
139 */
140 static String getJreArch() {
141 String arch = System.getProperty("os.arch");
142 return arch.equals("x86") ? "i386" : arch;
143 }
144
145 /*
ksrinif8cc5972011-04-07 12:06:32 -0700146 * get the complementary jre arch ie. if sparc then return sparcv9 and
147 * vice-versa.
148 */
149 static String getComplementaryJreArch() {
150 String arch = System.getProperty("os.arch");
151 if (arch != null) {
152 switch (arch) {
153 case "sparc":
154 return "sparcv9";
155 case "sparcv9":
156 return "sparc";
157 case "x86":
158 return "amd64";
159 case "amd64":
160 return "i386";
161 }
162 }
163 return null;
164 }
165
166 /*
ksrini11e7f1b2009-11-20 11:01:32 -0800167 * A convenience method to create a jar with jar file name and defs
168 */
169 static void createJar(File jarName, String... mainDefs)
170 throws FileNotFoundException{
171 createJar(null, jarName, new File("Foo"), mainDefs);
ksrini20a64b22008-09-24 15:07:41 -0700172 }
173
174 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700175 * A convenience method to create a java file, compile and jar it up, using
176 * the sole class file name in the jar, as the Main-Class attribute value.
ksrini20a64b22008-09-24 15:07:41 -0700177 */
178 static void createJar(File jarName, File mainClass, String... mainDefs)
179 throws FileNotFoundException {
180 createJar(null, jarName, mainClass, mainDefs);
181 }
182
183 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700184 * A generic jar file creator to create a java file, compile it
185 * and jar it up, a specific Main-Class entry name in the
186 * manifest can be specified or a null to use the sole class file name
187 * as the Main-Class attribute value.
ksrini20a64b22008-09-24 15:07:41 -0700188 */
ksrinicafaf7c2008-10-01 09:04:42 -0700189 static void createJar(String mEntry, File jarName, File mainClass,
190 String... mainDefs) throws FileNotFoundException {
ksrini20a64b22008-09-24 15:07:41 -0700191 if (jarName.exists()) {
192 jarName.delete();
193 }
ksrini37e8b502011-07-19 10:58:50 -0700194 try (PrintStream ps = new PrintStream(new FileOutputStream(mainClass + ".java"))) {
195 ps.println("public class Foo {");
196 if (mainDefs != null) {
197 for (String x : mainDefs) {
198 ps.println(x);
199 }
ksrini20a64b22008-09-24 15:07:41 -0700200 }
ksrini37e8b502011-07-19 10:58:50 -0700201 ps.println("}");
ksrini20a64b22008-09-24 15:07:41 -0700202 }
ksrini20a64b22008-09-24 15:07:41 -0700203
204 String compileArgs[] = {
205 mainClass + ".java"
206 };
207 if (compiler.run(null, null, null, compileArgs) != 0) {
208 throw new RuntimeException("compilation failed " + mainClass + ".java");
209 }
ksrinicafaf7c2008-10-01 09:04:42 -0700210 if (mEntry == null) {
ksrini20a64b22008-09-24 15:07:41 -0700211 mEntry = mainClass.getName();
212 }
213 String jarArgs[] = {
214 (debug) ? "cvfe" : "cfe",
215 jarName.getAbsolutePath(),
216 mEntry,
217 mainClass.getName() + ".class"
218 };
ksrini37e8b502011-07-19 10:58:50 -0700219 createJar(jarArgs);
220 }
221
222 static void createJar(String... args) {
ksrini20a64b22008-09-24 15:07:41 -0700223 sun.tools.jar.Main jarTool =
224 new sun.tools.jar.Main(System.out, System.err, "JarCreator");
ksrini37e8b502011-07-19 10:58:50 -0700225 if (!jarTool.run(args)) {
226 String message = "jar creation failed with command:";
227 for (String x : args) {
228 message = message.concat(" " + x);
229 }
230 throw new RuntimeException(message);
ksrini20a64b22008-09-24 15:07:41 -0700231 }
ksrini37e8b502011-07-19 10:58:50 -0700232 }
ksrini20a64b22008-09-24 15:07:41 -0700233
ksrinif8cc5972011-04-07 12:06:32 -0700234 static void copyFile(File src, File dst) throws IOException {
235 Path parent = dst.toPath().getParent();
236 if (parent != null) {
237 Files.createDirectories(parent);
238 }
239 Files.copy(src.toPath(), dst.toPath(), COPY_ATTRIBUTES, REPLACE_EXISTING);
240 }
241
242 static void recursiveDelete(File target) throws IOException {
243 if (!target.exists()) {
244 return;
245 }
246 Files.walkFileTree(target.toPath(), new SimpleFileVisitor<Path>() {
247 @Override
248 public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
249 try {
250 Files.deleteIfExists(dir);
251 } catch (IOException ex) {
252 System.out.println("Error: could not delete: " + dir.toString());
253 System.out.println(ex.getMessage());
254 return FileVisitResult.TERMINATE;
255 }
256 return FileVisitResult.CONTINUE;
257 }
258 @Override
259 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
260 try {
261 Files.deleteIfExists(file);
262 } catch (IOException ex) {
263 System.out.println("Error: could not delete: " + file.toString());
264 System.out.println(ex.getMessage());
265 return FileVisitResult.TERMINATE;
266 }
267 return FileVisitResult.CONTINUE;
268 }
269 });
270 }
271
ksrini11e7f1b2009-11-20 11:01:32 -0800272 static TestResult doExec(String...cmds) {
273 return doExec(null, cmds);
274 }
275
ksrini20a64b22008-09-24 15:07:41 -0700276 /*
ksrinicafaf7c2008-10-01 09:04:42 -0700277 * A method which executes a java cmd and returns the results in a container
ksrini20a64b22008-09-24 15:07:41 -0700278 */
ksrini11e7f1b2009-11-20 11:01:32 -0800279 static TestResult doExec(Map<String, String> envToSet, String...cmds) {
ksrini20a64b22008-09-24 15:07:41 -0700280 String cmdStr = "";
281 for (String x : cmds) {
282 cmdStr = cmdStr.concat(x + " ");
283 }
284 ProcessBuilder pb = new ProcessBuilder(cmds);
285 Map<String, String> env = pb.environment();
ksrini11e7f1b2009-11-20 11:01:32 -0800286 if (envToSet != null) {
287 env.putAll(envToSet);
288 }
ksrini20a64b22008-09-24 15:07:41 -0700289 BufferedReader rdr = null;
290 try {
ksrinif8cc5972011-04-07 12:06:32 -0700291 List<String> outputList = new ArrayList<>();
ksrini20a64b22008-09-24 15:07:41 -0700292 pb.redirectErrorStream(true);
293 Process p = pb.start();
294 rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
295 String in = rdr.readLine();
296 while (in != null) {
297 outputList.add(in);
298 in = rdr.readLine();
299 }
300 p.waitFor();
301 p.destroy();
ksrinif8cc5972011-04-07 12:06:32 -0700302
303 return new TestHelper.TestResult(cmdStr, p.exitValue(), outputList,
304 env, new Throwable("current stack of the test"));
ksrini20a64b22008-09-24 15:07:41 -0700305 } catch (Exception ex) {
306 ex.printStackTrace();
307 throw new RuntimeException(ex.getMessage());
308 }
309 }
310
ksriniac5e02f2012-01-11 08:14:47 -0800311 static FileFilter createFilter(final String extension) {
312 return new FileFilter() {
313 @Override
314 public boolean accept(File pathname) {
315 String name = pathname.getName();
316 if (name.endsWith(extension)) {
317 return true;
318 }
319 return false;
320 }
321 };
322 }
323
ksrini20a64b22008-09-24 15:07:41 -0700324 /*
325 * A class to encapsulate the test results and stuff, with some ease
326 * of use methods to check the test results.
327 */
328 static class TestResult {
329 StringBuilder status;
330 int exitValue;
331 List<String> testOutput;
ksrinif8cc5972011-04-07 12:06:32 -0700332 Map<String, String> env;
333 Throwable t;
ksrini20a64b22008-09-24 15:07:41 -0700334
ksrinif8cc5972011-04-07 12:06:32 -0700335 public TestResult(String str, int rv, List<String> oList,
336 Map<String, String> env, Throwable t) {
ksrini11e7f1b2009-11-20 11:01:32 -0800337 status = new StringBuilder("Executed command: " + str + "\n");
ksrini20a64b22008-09-24 15:07:41 -0700338 exitValue = rv;
339 testOutput = oList;
ksrinif8cc5972011-04-07 12:06:32 -0700340 this.env = env;
341 this.t = t;
ksrini20a64b22008-09-24 15:07:41 -0700342 }
343
ksrini11e7f1b2009-11-20 11:01:32 -0800344 void appendStatus(String x) {
345 status = status.append(" " + x + "\n");
346 }
347
ksrini20a64b22008-09-24 15:07:41 -0700348 void checkNegative() {
349 if (exitValue == 0) {
ksrini11e7f1b2009-11-20 11:01:32 -0800350 appendStatus("Error: test must not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700351 testExitValue++;
352 }
353 }
354
355 void checkPositive() {
356 if (exitValue != 0) {
ksrini11e7f1b2009-11-20 11:01:32 -0800357 appendStatus("Error: test did not return 0 exit value");
ksrini20a64b22008-09-24 15:07:41 -0700358 testExitValue++;
359 }
360 }
361
362 boolean isOK() {
363 return exitValue == 0;
364 }
365
366 boolean isZeroOutput() {
367 if (!testOutput.isEmpty()) {
ksrini11e7f1b2009-11-20 11:01:32 -0800368 appendStatus("Error: No message from cmd please");
ksrini20a64b22008-09-24 15:07:41 -0700369 testExitValue++;
370 return false;
371 }
372 return true;
373 }
374
375 boolean isNotZeroOutput() {
376 if (testOutput.isEmpty()) {
ksrini11e7f1b2009-11-20 11:01:32 -0800377 appendStatus("Error: Missing message");
ksrini20a64b22008-09-24 15:07:41 -0700378 testExitValue++;
379 return false;
380 }
381 return true;
382 }
383
ksrini11e7f1b2009-11-20 11:01:32 -0800384 @Override
ksrini20a64b22008-09-24 15:07:41 -0700385 public String toString() {
ksrinif8cc5972011-04-07 12:06:32 -0700386 status.append("++++Begin Test Info++++\n");
387 status.append("++++Test Environment++++\n");
388 for (String x : env.keySet()) {
389 status.append(x).append("=").append(env.get(x)).append("\n");
390 }
391 status.append("++++Test Output++++\n");
ksrini11e7f1b2009-11-20 11:01:32 -0800392 for (String x : testOutput) {
393 appendStatus(x);
ksrini20a64b22008-09-24 15:07:41 -0700394 }
ksrinif8cc5972011-04-07 12:06:32 -0700395 status.append("++++Test Stack Trace++++\n");
396 status.append(t.toString());
397 for (StackTraceElement e : t.getStackTrace()) {
398 status.append(e.toString());
399 }
400 status.append("++++End of Test Info++++\n");
ksrini20a64b22008-09-24 15:07:41 -0700401 return status.toString();
402 }
403
404 boolean contains(String str) {
405 for (String x : testOutput) {
406 if (x.contains(str)) {
407 return true;
408 }
409 }
ksrini11e7f1b2009-11-20 11:01:32 -0800410 appendStatus("Error: string <" + str + "> not found");
411 testExitValue++;
412 return false;
413 }
414
415 boolean matches(String stringToMatch) {
416 for (String x : testOutput) {
417 if (x.matches(stringToMatch)) {
418 return true;
419 }
420 }
421 appendStatus("Error: string <" + stringToMatch + "> not found");
ksrini20a64b22008-09-24 15:07:41 -0700422 testExitValue++;
423 return false;
424 }
425 }
426}