37 */
38
39 import java.io.ByteArrayOutputStream;
40 import java.io.File;
41 import java.io.FileInputStream;
42 import java.io.FileOutputStream;
43 import java.io.IOException;
44 import java.io.PrintStream;
45 import java.net.MalformedURLException;
46 import java.net.ServerSocket;
47 import java.net.URL;
48 import java.rmi.NoSuchObjectException;
49 import java.rmi.Remote;
50 import java.rmi.RemoteException;
51 import java.rmi.registry.LocateRegistry;
52 import java.rmi.registry.Registry;
53 import java.rmi.server.RemoteRef;
54 import java.rmi.server.UnicastRemoteObject;
55 import java.util.Enumeration;
56 import java.util.Properties;
57 import sun.rmi.registry.RegistryImpl;
58 import sun.rmi.server.UnicastServerRef;
59 import sun.rmi.transport.Endpoint;
60 import sun.rmi.transport.LiveRef;
61 import sun.rmi.transport.tcp.TCPEndpoint;
62
63 /**
64 * Class of utility/library methods (i.e. procedures) that assist with
65 * the writing and maintainance of rmi regression tests.
66 */
67 public class TestLibrary {
68 /**
69 * IMPORTANT!
70 *
71 * RMI tests are run concurrently and port conflicts result when a single
72 * port number is used by multiple tests. When needing a port, use
73 * getUnusedRandomPort() wherever possible. If getUnusedRandomPort() cannot
74 * be used, reserve and specify a port to use for your test here. This
75 * will ensure there are no port conflicts amongst the RMI tests. The
76 * port numbers specified here may also be specified in the respective
77 * tests. Do not change the reserved port numbers here without also
78 * changing the port numbers in the respective tests.
79 *
80 * When needing an instance of the RMIRegistry, use
81 * createRegistryOnUnusedPort wherever possible to prevent port conflicts.
82 *
83 * Reserved port range: FIXED_PORT_MIN to FIXED_PORT_MAX (inclusive) for
84 * tests which cannot use a random port. If new fixed ports are added below
85 * FIXED_PORT_MIN or above FIXED_PORT_MAX, then adjust
86 * FIXED_PORT_MIN/MAX appropriately.
87 */
88 public final static int FIXED_PORT_MIN = 64001;
89 public final static int FIXED_PORT_MAX = 64010;
90 public final static int RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT = 64001;
91 public final static int RMIDVIAINHERITEDCHANNEL_REGISTRY_PORT = 64002;
92 public final static int INHERITEDCHANNELNOTSERVERSOCKET_ACTIVATION_PORT = 64003;
93 public final static int INHERITEDCHANNELNOTSERVERSOCKET_REGISTRY_PORT = 64004;
94 public final static int READTEST_REGISTRY_PORT = 64005;
95
96 static void mesg(Object mesg) {
97 System.err.println("TEST_LIBRARY: " + mesg.toString());
98 }
99
100 /**
101 * Routines that enable rmi tests to fail in a uniformly
102 * informative fashion.
103 */
104 public static void bomb(String message, Exception e) {
105 String testFailed = "TEST FAILED: ";
106
107 if ((message == null) && (e == null)) {
108 testFailed += " No relevant information";
109 } else if (e == null) {
110 testFailed += message;
111 }
112
113 System.err.println(testFailed);
114 if (e != null) {
115 System.err.println("Test failed with: " +
116 e.getMessage());
117 e.printStackTrace(System.err);
118 }
119 throw new TestFailedException(testFailed, e);
120 }
121 public static void bomb(String message) {
122 bomb(message, null);
123 }
124 public static void bomb(Exception e) {
125 bomb(null, e);
126 }
127
128 /**
129 * Property accessors
130 */
131 private static boolean getBoolean(String name) {
132 return (new Boolean(getProperty(name, "false")).booleanValue());
133 }
134 private static Integer getInteger(String name) {
135 int val = 0;
136 Integer value = null;
137
138 String propVal = getProperty(name, null);
139 if (propVal == null) {
140 return null;
141 }
142
143 try {
144 value = new Integer(Integer.parseInt(propVal));
145 } catch (NumberFormatException nfe) {
146 }
147 return value;
148 }
149 public static String getProperty(String property, String defaultVal) {
150 final String prop = property;
151 final String def = defaultVal;
152 return ((String) java.security.AccessController.doPrivileged
153 (new java.security.PrivilegedAction() {
154 public Object run() {
155 return System.getProperty(prop, def);
156 }
157 }));
158 }
159
160 /**
161 * Property mutators
162 */
163 public static void setBoolean(String property, boolean value) {
164 setProperty(property, (new Boolean(value)).toString());
165 }
166 public static void setInteger(String property, int value) {
167 setProperty(property, Integer.toString(value));
168 }
169 public static void setProperty(String property, String value) {
170 final String prop = property;
171 final String val = value;
172 java.security.AccessController.doPrivileged
173 (new java.security.PrivilegedAction() {
174 public Object run() {
175 System.setProperty(prop, val);
176 return null;
177 }
178 });
179 }
180
181 /**
182 * Routines to print out a test's properties environment.
183 */
184 public static void printEnvironment() {
185 printEnvironment(System.err);
186 }
187 public static void printEnvironment(PrintStream out) {
188 out.println("-------------------Test environment----------" +
189 "---------");
190
191 for(Enumeration keys = System.getProperties().keys();
192 keys.hasMoreElements();) {
193
194 String property = (String) keys.nextElement();
195 out.println(property + " = " + getProperty(property, null));
196 }
197 out.println("---------------------------------------------" +
198 "---------");
199 }
200
201 /**
202 * Routine that "works-around" a limitation in jtreg.
203 * Currently it is not possible for a test to specify that the
204 * test harness should build a given source file and install the
205 * resulting class in a location that is not accessible from the
206 * test's classpath. This method enables a test to move a
207 * compiled test class file from the test's class directory into a
208 * given "codebase" directory. As a result the test can only
209 * access the class file for <code>className</code>if the test loads
210 * it from a classloader (e.g. RMIClassLoader).
211 *
235 String classFileName = className + ".class";
236
237 /*
238 * Specify the file to contain the class definition. Make sure
239 * that the codebase directory exists (underneath the working
240 * directory).
241 */
242 File dstDir = (new File(getProperty("user.dir", "."), codebase));
243
244 if (!dstDir.exists()) {
245 if (!dstDir.mkdir()) {
246 throw new RuntimeException(
247 "could not create codebase directory");
248 }
249 }
250 File dstFile = new File(dstDir, classFileName);
251
252 /*
253 * Obtain the URL for the codebase.
254 */
255 URL codebaseURL = dstDir.toURL();
256
257 /*
258 * Specify where we will copy the class definition from, if
259 * necessary. After the test is built, the class file can be
260 * found in the "test.classes" directory.
261 */
262 File srcDir = new File(getProperty("test.classes", "."));
263 File srcFile = new File(srcDir, classFileName);
264
265 mesg(srcFile);
266 mesg(dstFile);
267
268 /*
269 * If the class definition is not already located at the codebase,
270 * copy it there from the test build area.
271 */
272 if (!dstFile.exists()) {
273 if (!srcFile.exists()) {
274 throw new RuntimeException(
275 "could not find class file to install in codebase " +
390 Endpoint endpoint = liveRef.getChannel().getEndpoint();
391 TCPEndpoint tcpEndpoint = (TCPEndpoint) endpoint;
392 port = tcpEndpoint.getPort();
393 } catch (Exception ex) {
394 throw new RuntimeException("Error getting registry port.", ex);
395 }
396
397 return port;
398 }
399
400 /**
401 * Returns an unused random port number which is not a reserved port. Will
402 * try up to 10 times to get a random port before giving up and throwing a
403 * RuntimeException.
404 *
405 * @return an unused random port number.
406 * @throws RuntimeException if there was a problem getting a port.
407 */
408 public static int getUnusedRandomPort() {
409 int numTries = 0;
410 int unusedRandomPort = FIXED_PORT_MIN;
411 Exception ex = null;
412
413 while (numTries++ < 10) {
414 ex = null; //reset
415
416 try (ServerSocket ss = new ServerSocket(0)) {
417 unusedRandomPort = ss.getLocalPort();
418 } catch (Exception e) {
419 ex = e;
420 }
421
422 if (!isReservedPort(unusedRandomPort)) {
423 return unusedRandomPort;
424 }
425 }
426
427 // If we're here, then either an exception was thrown or the port is
428 // a reserved port.
429 throw new RuntimeException("Error getting unused random port.", ex);
430 }
431
432 /**
433 * Determines if a port is one of the reserved port numbers.
434 *
435 * @param port the port to test.
436 * @return {@code true} if the port is a reserved port, otherwise
437 * {@code false}.
438 */
439 public static boolean isReservedPort(int port) {
440 return ((port >= FIXED_PORT_MIN) && (port <= FIXED_PORT_MAX) ||
441 (port == 1099));
442 }
443
444 /**
445 * Method to capture the stack trace of an exception and return it
446 * as a string.
447 */
448 public String stackTraceToString(Exception e) {
449 ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
37 */
38
39 import java.io.ByteArrayOutputStream;
40 import java.io.File;
41 import java.io.FileInputStream;
42 import java.io.FileOutputStream;
43 import java.io.IOException;
44 import java.io.PrintStream;
45 import java.net.MalformedURLException;
46 import java.net.ServerSocket;
47 import java.net.URL;
48 import java.rmi.NoSuchObjectException;
49 import java.rmi.Remote;
50 import java.rmi.RemoteException;
51 import java.rmi.registry.LocateRegistry;
52 import java.rmi.registry.Registry;
53 import java.rmi.server.RemoteRef;
54 import java.rmi.server.UnicastRemoteObject;
55 import java.util.Enumeration;
56 import java.util.Properties;
57
58 import sun.rmi.registry.RegistryImpl;
59 import sun.rmi.server.UnicastServerRef;
60 import sun.rmi.transport.Endpoint;
61 import sun.rmi.transport.LiveRef;
62 import sun.rmi.transport.tcp.TCPEndpoint;
63
64 /**
65 * Class of utility/library methods (i.e. procedures) that assist with
66 * the writing and maintainance of rmi regression tests.
67 */
68 public class TestLibrary {
69 /**
70 * IMPORTANT!
71 *
72 * RMI tests are run concurrently and port conflicts result when a single
73 * port number is used by multiple tests. When needing a port, use
74 * getUnusedRandomPort() wherever possible. If getUnusedRandomPort() cannot
75 * be used, reserve and specify a port to use for your test here. This
76 * will ensure there are no port conflicts amongst the RMI tests. The
77 * port numbers specified here may also be specified in the respective
78 * tests. Do not change the reserved port numbers here without also
79 * changing the port numbers in the respective tests.
80 *
81 * When needing an instance of the RMIRegistry, use
82 * createRegistryOnUnusedPort wherever possible to prevent port conflicts.
83 *
84 * Reserved port range: FIXED_PORT_MIN to FIXED_PORT_MAX (inclusive) for
85 * tests which cannot use a random port. If new fixed ports are added below
86 * FIXED_PORT_MIN or above FIXED_PORT_MAX, then adjust
87 * FIXED_PORT_MIN/MAX appropriately.
88 */
89 public final static int FIXED_PORT_MIN = 64001;
90 public final static int FIXED_PORT_MAX = 64010;
91 public final static int RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT = 64001;
92 public final static int RMIDVIAINHERITEDCHANNEL_REGISTRY_PORT = 64002;
93 public final static int INHERITEDCHANNELNOTSERVERSOCKET_ACTIVATION_PORT = 64003;
94 public final static int INHERITEDCHANNELNOTSERVERSOCKET_REGISTRY_PORT = 64004;
95 public final static int READTEST_REGISTRY_PORT = 64005;
96 private final static int MAX_SERVER_SOCKET_TRIES = 10;
97
98 static void mesg(Object mesg) {
99 System.err.println("TEST_LIBRARY: " + mesg.toString());
100 }
101
102 /**
103 * Routines that enable rmi tests to fail in a uniformly
104 * informative fashion.
105 */
106 public static void bomb(String message, Exception e) {
107 String testFailed = "TEST FAILED: ";
108
109 if ((message == null) && (e == null)) {
110 testFailed += " No relevant information";
111 } else if (e == null) {
112 testFailed += message;
113 }
114
115 System.err.println(testFailed);
116 if (e != null) {
117 System.err.println("Test failed with: " +
118 e.getMessage());
119 e.printStackTrace(System.err);
120 }
121 throw new TestFailedException(testFailed, e);
122 }
123 public static void bomb(String message) {
124 bomb(message, null);
125 }
126 public static void bomb(Exception e) {
127 bomb(null, e);
128 }
129
130 public static String getProperty(String property, String defaultVal) {
131 final String prop = property;
132 final String def = defaultVal;
133 return ((String) java.security.AccessController.doPrivileged
134 (new java.security.PrivilegedAction<String>() {
135 public String run() {
136 return System.getProperty(prop, def);
137 }
138 }));
139 }
140
141 /**
142 * Property mutators
143 */
144 public static void setBoolean(String property, boolean value) {
145 setProperty(property, (new Boolean(value)).toString());
146 }
147 public static void setInteger(String property, int value) {
148 setProperty(property, Integer.toString(value));
149 }
150 public static void setProperty(String property, String value) {
151 final String prop = property;
152 final String val = value;
153 java.security.AccessController.doPrivileged
154 (new java.security.PrivilegedAction<Void>() {
155 public Void run() {
156 System.setProperty(prop, val);
157 return null;
158 }
159 });
160 }
161
162 /**
163 * Routines to print out a test's properties environment.
164 */
165 public static void printEnvironment() {
166 printEnvironment(System.err);
167 }
168 public static void printEnvironment(PrintStream out) {
169 out.println("-------------------Test environment----------" +
170 "---------");
171
172 for(Enumeration<?> keys = System.getProperties().keys();
173 keys.hasMoreElements();) {
174
175 String property = (String) keys.nextElement();
176 out.println(property + " = " + getProperty(property, null));
177 }
178 out.println("---------------------------------------------" +
179 "---------");
180 }
181
182 /**
183 * Routine that "works-around" a limitation in jtreg.
184 * Currently it is not possible for a test to specify that the
185 * test harness should build a given source file and install the
186 * resulting class in a location that is not accessible from the
187 * test's classpath. This method enables a test to move a
188 * compiled test class file from the test's class directory into a
189 * given "codebase" directory. As a result the test can only
190 * access the class file for <code>className</code>if the test loads
191 * it from a classloader (e.g. RMIClassLoader).
192 *
216 String classFileName = className + ".class";
217
218 /*
219 * Specify the file to contain the class definition. Make sure
220 * that the codebase directory exists (underneath the working
221 * directory).
222 */
223 File dstDir = (new File(getProperty("user.dir", "."), codebase));
224
225 if (!dstDir.exists()) {
226 if (!dstDir.mkdir()) {
227 throw new RuntimeException(
228 "could not create codebase directory");
229 }
230 }
231 File dstFile = new File(dstDir, classFileName);
232
233 /*
234 * Obtain the URL for the codebase.
235 */
236 URL codebaseURL = dstDir.toURI().toURL();
237
238 /*
239 * Specify where we will copy the class definition from, if
240 * necessary. After the test is built, the class file can be
241 * found in the "test.classes" directory.
242 */
243 File srcDir = new File(getProperty("test.classes", "."));
244 File srcFile = new File(srcDir, classFileName);
245
246 mesg(srcFile);
247 mesg(dstFile);
248
249 /*
250 * If the class definition is not already located at the codebase,
251 * copy it there from the test build area.
252 */
253 if (!dstFile.exists()) {
254 if (!srcFile.exists()) {
255 throw new RuntimeException(
256 "could not find class file to install in codebase " +
371 Endpoint endpoint = liveRef.getChannel().getEndpoint();
372 TCPEndpoint tcpEndpoint = (TCPEndpoint) endpoint;
373 port = tcpEndpoint.getPort();
374 } catch (Exception ex) {
375 throw new RuntimeException("Error getting registry port.", ex);
376 }
377
378 return port;
379 }
380
381 /**
382 * Returns an unused random port number which is not a reserved port. Will
383 * try up to 10 times to get a random port before giving up and throwing a
384 * RuntimeException.
385 *
386 * @return an unused random port number.
387 * @throws RuntimeException if there was a problem getting a port.
388 */
389 public static int getUnusedRandomPort() {
390 int numTries = 0;
391 int unusedRandomPort = -1;
392 IOException ex = null;
393
394 while (numTries++ < MAX_SERVER_SOCKET_TRIES) {
395 ex = null; //reset
396
397 try (ServerSocket ss = new ServerSocket(0)) {
398 unusedRandomPort = ss.getLocalPort();
399 } catch (IOException e) {
400 ex = e;
401 // temporarily print stack trace here until we find out why
402 // tests are failing.
403 System.err.println("TestLibrary.getUnusedRandomPort() caught "
404 + "exception on iteration " + numTries
405 + (numTries==MAX_SERVER_SOCKET_TRIES ? " (the final try)."
406 : "."));
407 ex.printStackTrace();
408 }
409
410 if (unusedRandomPort >= 0) {
411 if (isReservedPort(unusedRandomPort)) {
412 System.out.println("INFO: On try # " + numTries
413 + (numTries==MAX_SERVER_SOCKET_TRIES ? ", the final try, ": ",")
414 + " ServerSocket(0) returned the reserved port "
415 + unusedRandomPort
416 + " in TestLibrary.getUnusedRandomPort() ");
417 } else {
418 return unusedRandomPort;
419 }
420 }
421 }
422
423 // If we're here, then either an exception was thrown or the port is
424 // a reserved port.
425 if (ex==null) {
426 throw new RuntimeException("Error getting unused random port. The"
427 +" last port returned by ServerSocket(0) was a reserved port");
428 } else {
429 throw new RuntimeException("Error getting unused random port.", ex);
430 }
431 }
432
433 /**
434 * Determines if a port is one of the reserved port numbers.
435 *
436 * @param port the port to test.
437 * @return {@code true} if the port is a reserved port, otherwise
438 * {@code false}.
439 */
440 public static boolean isReservedPort(int port) {
441 return ((port >= FIXED_PORT_MIN) && (port <= FIXED_PORT_MAX) ||
442 (port == 1099));
443 }
444
445 /**
446 * Method to capture the stack trace of an exception and return it
447 * as a string.
448 */
449 public String stackTraceToString(Exception e) {
450 ByteArrayOutputStream bos = new ByteArrayOutputStream();
|