1 /* 2 * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. 3 * 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 * 19 * 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. 22 */ 23 24 /** 25 * 26 * 27 * @author Adrian Colley 28 * @author Laird Dornin 29 * @author Peter Jones 30 * @author Ann Wollrath 31 * 32 * The rmi library directory contains a set of simple utiltity classes 33 * for use in rmi regression tests. 34 * 35 * NOTE: The JavaTest group has recommended that regression tests do 36 * not make use of packages. 37 */ 38 39 import java.io.File; 40 import java.io.FileInputStream; 41 import java.io.FileOutputStream; 42 import java.io.IOException; 43 import java.io.OutputStream; 44 import java.io.PrintStream; 45 import java.net.URL; 46 import java.net.MalformedURLException; 47 import java.rmi.activation.Activatable; 48 import java.rmi.activation.ActivationID; 49 import java.rmi.NoSuchObjectException; 50 import java.rmi.registry.Registry; 51 import java.rmi.Remote; 52 import java.rmi.server.UnicastRemoteObject; 53 import java.util.Enumeration; 54 import java.util.Hashtable; 55 import java.util.Properties; 56 import java.io.ByteArrayOutputStream; 57 import java.security.AccessController; 58 import java.security.PrivilegedAction; 59 60 /** 61 * Class of utility/library methods (i.e. procedures) that assist with 62 * the writing and maintainance of rmi regression tests. 63 */ 64 public class TestLibrary { 65 66 /** standard test port number for registry */ 67 public final static int REGISTRY_PORT = 2006; 68 /** port for rmid necessary: not used to actually start rmid */ 69 public final static int RMID_PORT = 1098; 70 71 static void mesg(Object mesg) { 72 System.err.println("TEST_LIBRARY: " + mesg.toString()); 73 } 74 75 /** 76 * Routines that enable rmi tests to fail in a uniformly 77 * informative fashion. 78 */ 79 public static void bomb(String message, Exception e) { 80 String testFailed = "TEST FAILED: "; 81 82 if ((message == null) && (e == null)) { 83 testFailed += " No relevant information"; 84 } else if (e == null) { 85 testFailed += message; 86 } 87 88 System.err.println(testFailed); 89 if (e != null) { 90 System.err.println("Test failed with: " + 91 e.getMessage()); 92 e.printStackTrace(System.err); 93 } 94 throw new TestFailedException(testFailed, e); 95 } 96 public static void bomb(String message) { 97 bomb(message, null); 98 } 99 public static void bomb(Exception e) { 100 bomb(null, e); 101 } 102 103 /** 104 * Property accessors 105 */ 106 private static boolean getBoolean(String name) { 107 return (new Boolean(getProperty(name, "false")).booleanValue()); 108 } 109 private static Integer getInteger(String name) { 110 int val = 0; 111 Integer value = null; 112 113 String propVal = getProperty(name, null); 114 if (propVal == null) { 115 return null; 116 } 117 118 try { 119 value = new Integer(Integer.parseInt(propVal)); 120 } catch (NumberFormatException nfe) { 121 } 122 return value; 123 } 124 public static String getProperty(String property, String defaultVal) { 125 final String prop = property; 126 final String def = defaultVal; 127 return ((String) java.security.AccessController.doPrivileged 128 (new java.security.PrivilegedAction() { 129 public Object run() { 130 return System.getProperty(prop, def); 131 } 132 })); 133 } 134 135 /** 136 * Property mutators 137 */ 138 public static void setBoolean(String property, boolean value) { 139 setProperty(property, (new Boolean(value)).toString()); 140 } 141 public static void setInteger(String property, int value) { 142 setProperty(property, Integer.toString(value)); 143 } 144 public static void setProperty(String property, String value) { 145 final String prop = property; 146 final String val = value; 147 java.security.AccessController.doPrivileged 148 (new java.security.PrivilegedAction() { 149 public Object run() { 150 System.setProperty(prop, val); 151 return null; 152 } 153 }); 154 } 155 156 /** 157 * Routines to print out a test's properties environment. 158 */ 159 public static void printEnvironment() { 160 printEnvironment(System.err); 161 } 162 public static void printEnvironment(PrintStream out) { 163 out.println("-------------------Test environment----------" + 164 "---------"); 165 166 for(Enumeration keys = System.getProperties().keys(); 167 keys.hasMoreElements();) { 168 169 String property = (String) keys.nextElement(); 170 out.println(property + " = " + getProperty(property, null)); 171 } 172 out.println("---------------------------------------------" + 173 "---------"); 174 } 175 176 /** 177 * Routine that "works-around" a limitation in jtreg. 178 * Currently it is not possible for a test to specify that the 179 * test harness should build a given source file and install the 180 * resulting class in a location that is not accessible from the 181 * test's classpath. This method enables a test to move a 182 * compiled test class file from the test's class directory into a 183 * given "codebase" directory. As a result the test can only 184 * access the class file for <code>className</code>if the test loads 185 * it from a classloader (e.g. RMIClassLoader). 186 * 187 * Tests that use this routine must have the following permissions 188 * granted to them: 189 * 190 * getProperty user.dir 191 * getProperty etc. 192 */ 193 public static URL installClassInCodebase(String className, 194 String codebase) 195 throws MalformedURLException 196 { 197 return installClassInCodebase(className, codebase, true); 198 } 199 200 public static URL installClassInCodebase(String className, 201 String codebase, 202 boolean delete) 203 throws MalformedURLException 204 { 205 /* 206 * NOTES/LIMITATIONS: The class must not be in a named package, 207 * and the codebase must be a relative path (it's created relative 208 * to the working directory). 209 */ 210 String classFileName = className + ".class"; 211 212 /* 213 * Specify the file to contain the class definition. Make sure 214 * that the codebase directory exists (underneath the working 215 * directory). 216 */ 217 File dstDir = (new File(getProperty("user.dir", "."), codebase)); 218 219 if (!dstDir.exists()) { 220 if (!dstDir.mkdir()) { 221 throw new RuntimeException( 222 "could not create codebase directory"); 223 } 224 } 225 File dstFile = new File(dstDir, classFileName); 226 227 /* 228 * Obtain the URL for the codebase. 229 */ 230 URL codebaseURL = dstDir.toURL(); 231 232 /* 233 * Specify where we will copy the class definition from, if 234 * necessary. After the test is built, the class file can be 235 * found in the "test.classes" directory. 236 */ 237 File srcDir = new File(getProperty("test.classes", ".")); 238 File srcFile = new File(srcDir, classFileName); 239 240 mesg(srcFile); 241 mesg(dstFile); 242 243 /* 244 * If the class definition is not already located at the codebase, 245 * copy it there from the test build area. 246 */ 247 if (!dstFile.exists()) { 248 if (!srcFile.exists()) { 249 throw new RuntimeException( 250 "could not find class file to install in codebase " + 251 "(try rebuilding the test): " + srcFile); 252 } 253 254 try { 255 copyFile(srcFile, dstFile); 256 } catch (IOException e) { 257 throw new RuntimeException( 258 "could not install class file in codebase"); 259 } 260 261 mesg("Installed class \"" + className + 262 "\" in codebase " + codebaseURL); 263 } 264 265 /* 266 * After the class definition is successfully installed at the 267 * codebase, delete it from the test's CLASSPATH, so that it will 268 * not be found there first before the codebase is searched. 269 */ 270 if (srcFile.exists()) { 271 if (delete && !srcFile.delete()) { 272 throw new RuntimeException( 273 "could not delete duplicate class file in CLASSPATH"); 274 } 275 } 276 277 return codebaseURL; 278 } 279 280 public static void copyFile(File srcFile, File dstFile) 281 throws IOException 282 { 283 FileInputStream src = new FileInputStream(srcFile); 284 FileOutputStream dst = new FileOutputStream(dstFile); 285 286 byte[] buf = new byte[32768]; 287 while (true) { 288 int count = src.read(buf); 289 if (count < 0) { 290 break; 291 } 292 dst.write(buf, 0, count); 293 } 294 295 dst.close(); 296 src.close(); 297 } 298 299 /** routine to unexport an object */ 300 public static void unexport(Remote obj) { 301 if (obj != null) { 302 try { 303 mesg("unexporting object..."); 304 UnicastRemoteObject.unexportObject(obj, true); 305 } catch (NoSuchObjectException munch) { 306 } catch (Exception e) { 307 e.getMessage(); 308 e.printStackTrace(); 309 } 310 } 311 } 312 313 /** 314 * Allow test framework to control the security manager set in 315 * each test. 316 * 317 * @param managerClassName The class name of the security manager 318 * to be instantiated and set if no security 319 * manager has already been set. 320 */ 321 public static void suggestSecurityManager(String managerClassName) { 322 SecurityManager manager = null; 323 324 if (System.getSecurityManager() == null) { 325 try { 326 if (managerClassName == null) { 327 managerClassName = TestParams.defaultSecurityManager; 328 } 329 manager = ((SecurityManager) Class. 330 forName(managerClassName).newInstance()); 331 } catch (ClassNotFoundException cnfe) { 332 bomb("Security manager could not be found: " + 333 managerClassName, cnfe); 334 } catch (Exception e) { 335 bomb("Error creating security manager. ", e); 336 } 337 338 System.setSecurityManager(manager); 339 } 340 } 341 342 /** 343 * Method to capture the stack trace of an exception and return it 344 * as a string. 345 */ 346 public String stackTraceToString(Exception e) { 347 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 348 PrintStream ps = new PrintStream(bos); 349 350 e.printStackTrace(ps); 351 return bos.toString(); 352 } 353 354 /** extra properties */ 355 private static Properties props; 356 357 /** 358 * Returns extra test properties. Looks for the file "../../test.props" 359 * and reads it in as a Properties file. Assuming the working directory 360 * is "<path>/JTwork/scratch", this will find "<path>/test.props". 361 */ 362 private static synchronized Properties getExtraProperties() { 363 if (props != null) { 364 return props; 365 } 366 props = new Properties(); 367 File f = new File(".." + File.separator + ".." + File.separator + 368 "test.props"); 369 if (!f.exists()) { 370 return props; 371 } 372 try { 373 FileInputStream in = new FileInputStream(f); 374 try { 375 props.load(in); 376 } finally { 377 in.close(); 378 } 379 } catch (IOException e) { 380 e.printStackTrace(); 381 throw new RuntimeException("extra property setup failed", e); 382 } 383 return props; 384 } 385 386 /** 387 * Returns an extra test property. Looks for the file "../../test.props" 388 * and reads it in as a Properties file. Assuming the working directory 389 * is "<path>/JTwork/scratch", this will find "<path>/test.props". 390 * If the property isn't found, defaultVal is returned. 391 */ 392 public static String getExtraProperty(String property, String defaultVal) { 393 return getExtraProperties().getProperty(property, defaultVal); 394 } 395 }