1 /* 2 * $Id$ 3 * 4 * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. 5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 * 7 * This code is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 only, as 9 * published by the Free Software Foundation. Oracle designates this 10 * particular file as subject to the "Classpath" exception as provided 11 * by Oracle in the LICENSE file that accompanied this code. 12 * 13 * This code is distributed in the hope that it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 * version 2 for more details (a copy is included in the LICENSE file that 17 * accompanied this code). 18 * 19 * You should have received a copy of the GNU General Public License version 20 * 2 along with this work; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 24 * or visit www.oracle.com if you need additional information or have any 25 * questions. 26 */ 27 package com.sun.javatest.lib; 28 29 import java.io.File; 30 import java.io.PrintWriter; 31 import com.sun.javatest.Command; 32 import com.sun.javatest.Status; 33 import com.sun.javatest.Test; 34 import com.sun.javatest.util.DirectoryClassLoader; 35 36 37 /** 38 * ExecStdTestSameJVMCmd executes a standard test (one that implements 39 * the Test interface) in the same Java Virtual Machine as the caller. 40 * 41 * It can use either a private class loader or the system class loader. 42 * A private class loader will be created if the -loadDir option is given; 43 * otherwise the system class loader will be used. A private class 44 * loader minimises the interference between tests, but you may be 45 * restricted from using private class loaders if you are running the 46 * harness inside a web browser. 47 * 48 * <p> If the the <code>-repeat</code> option is provided, then the test will be 49 * run multiple times in the same JVM. <code>Status.error()</code> will be 50 * returned (and the remainder of the iterations will not be performed) if any 51 * repetition of the test returns an error, or if the status return type changes 52 * between iterations. The returned status after each iteration will be 53 * included in the log. If this option is not given, the test will be run once. 54 * 55 * @see com.sun.javatest.lib.ExecStdTestOtherJVMCmd 56 */ 57 public class ExecStdTestSameJVMCmd extends Command 58 { 59 /** 60 * The method that that does the work of the command. 61 * @param args [-loadDir <em>dir</em>] [-saveProps] <em>executeClass</em> <em>executeArgs</em> 62 * @param log A stream to which to report messages and errors 63 * @param ref A stream to which to write reference output 64 * @return The result of the command 65 */ 66 public Status run(String[] args, PrintWriter log, PrintWriter ref) { 67 int repeat = 1; 68 String className = null; 69 String[] executeArgs = { }; 70 ClassLoader loader = getClassLoader(); 71 72 int i = 0; 73 74 for (; i < args.length && args[i].startsWith("-"); i++) { 75 if ("-loadDir".equals(args[i]) && i+1 < args.length) { 76 // -loadDir is optional; if given, a new class loader will be created 77 // to load the class to execute; if not given, the system class loader 78 // will be used. 79 loader = new DirectoryClassLoader(new File(args[++i])); 80 } else if ("-repeat".equals(args[i]) && i+1 < args.length) { 81 // -repeat is optional; if given, the test will be run that 82 // number of times (in the same JVM) 83 try { 84 if ((repeat = Integer.parseInt(args[++i])) < 1) 85 return Status.error("Unexpected number of repetitions: " + repeat); 86 } 87 catch (NumberFormatException e) { 88 return Status.error("Unrecognized number of repetitions: " + repeat); 89 } 90 } 91 } 92 93 // Next must come the executeClass 94 if (i < args.length) { 95 className = args[i]; 96 i++; 97 } else 98 return Status.failed("No executeClass specified"); 99 100 // Finally, any optional args 101 if (i < args.length) { 102 executeArgs = new String[args.length - i]; 103 System.arraycopy(args, i, executeArgs, 0, executeArgs.length); 104 } 105 106 Status status = null; 107 try { 108 Class c; 109 if (loader == null) 110 c = Class.forName(className); 111 else 112 c = loader.loadClass(className); 113 114 Status prevStatus = null; 115 for (int j = 0; j < repeat; j++) { 116 if (repeat > 1) 117 log.println("iteration: " + (j+1)); 118 119 Test t = (Test) (c.newInstance()); 120 status = t.run(executeArgs, log, ref); 121 122 if (repeat > 1) 123 log.println(" " + status); 124 125 if ((prevStatus != null) && status.getType() != prevStatus.getType()) 126 status = Status.error("Return status type changed at repetition: " + (j+1)); 127 128 if (status.isError()) 129 return status; 130 else 131 prevStatus = status; 132 } 133 } 134 catch (ClassCastException e) { 135 status = Status.failed("Can't load test: required interface not found"); 136 } 137 catch (ClassNotFoundException e) { 138 status = Status.failed("Can't load test: " + e); 139 } 140 catch (InstantiationException e) { 141 status = Status.failed("Can't instantiate test: " + e); 142 } 143 catch (IllegalAccessException e) { 144 status = Status.failed("Illegal access to test: " + e); 145 } 146 catch (VerifyError e) { 147 return Status.failed("Class verification error while trying to load test class `" + className + "': " + e); 148 } 149 catch (LinkageError e) { 150 return Status.failed("Class linking error while trying to load test class `" + className + "': " + e); 151 } 152 return status; 153 } 154 } 155