blob: d2aa9e69b584e459a14a10392e3acbe5357fc64e [file] [log] [blame]
duke6e45e102007-12-01 00:00:00 +00001/*
2 * Copyright 1998-2003 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any 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
39import java.io.File;
40import java.io.FileInputStream;
41import java.io.FileOutputStream;
42import java.io.IOException;
43import java.io.OutputStream;
44import java.io.PrintStream;
45import java.net.URL;
46import java.net.MalformedURLException;
47import java.rmi.activation.Activatable;
48import java.rmi.activation.ActivationID;
49import java.rmi.NoSuchObjectException;
50import java.rmi.registry.Registry;
51import java.rmi.Remote;
52import java.rmi.server.UnicastRemoteObject;
53import java.util.Enumeration;
54import java.util.Hashtable;
55import java.util.Properties;
56import java.io.ByteArrayOutputStream;
57import java.security.AccessController;
58import 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 */
64public 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}