7144861: speed up RMI activation tests
Reviewed-by: alanb, smarks, dholmes, dmocek
--- a/jdk/test/java/rmi/activation/checkusage/CheckUsage.java Fri May 11 12:53:03 2012 -0700
+++ b/jdk/test/java/rmi/activation/checkusage/CheckUsage.java Fri May 11 14:13:29 2012 -0700
@@ -53,12 +53,9 @@
rmidVM.start();
// wait for registry exit
+ int rmidVMExitStatus = rmidVM.getVM().waitFor();
System.err.println("rmid exited with status: " +
- rmidVM.getVM().waitFor());
- try {
- Thread.sleep(7000);
- } catch (InterruptedException ie) {
- }
+ rmidVMExitStatus);
String usage = new String(berr.toByteArray());
--- a/jdk/test/java/rmi/testlibrary/ActivationLibrary.java Fri May 11 12:53:03 2012 -0700
+++ b/jdk/test/java/rmi/testlibrary/ActivationLibrary.java Fri May 11 14:13:29 2012 -0700
@@ -63,19 +63,30 @@
*/
public static void deactivate(Remote remote,
ActivationID id) {
- for (int i = 0; i < 5; i ++) {
+ // We do as much as 50 deactivation trials, each separated by
+ // at least 100 milliseconds sleep time (max sleep time of 5 secs).
+ final long deactivateSleepTime = 100;
+ for (int i = 0; i < 50; i ++) {
try {
if (Activatable.inactive(id) == true) {
mesg("inactive successful");
return;
} else {
- Thread.sleep(1000);
+ mesg("inactive trial failed. Sleeping " +
+ deactivateSleepTime +
+ " milliseconds before next trial");
+ Thread.sleep(deactivateSleepTime);
}
} catch (InterruptedException e) {
- continue;
+ Thread.currentThread().interrupt();
+ mesg("Thread interrupted while trying to deactivate activatable. Exiting deactivation");
+ return;
} catch (Exception e) {
try {
// forcibly unexport the object
+ mesg("Unexpected exception. Have to forcibly unexport the object." +
+ " Exception was :");
+ e.printStackTrace();
Activatable.unexportObject(remote, true);
} catch (NoSuchObjectException ex) {
}
@@ -99,37 +110,61 @@
* activation system.
*/
public static boolean rmidRunning(int port) {
- int allowedNotReady = 10;
+ int allowedNotReady = 50;
int connectionRefusedExceptions = 0;
- for (int i = 0; i < 15 ; i++) {
+ /* We wait as much as a total of 7.5 secs trying to see Rmid running.
+ * We do this by pausing steps of 100 milliseconds (so up to 75 steps),
+ * right after trying to lookup and find RMID running in the other vm.
+ */
+ final long rmidWaitingStepTime = 100;
+ for (int i = 0; i <= 74; i++) {
try {
- Thread.sleep(500);
LocateRegistry.getRegistry(port).lookup(SYSTEM_NAME);
+ mesg("Activation System available after " +
+ (i * rmidWaitingStepTime) + " milliseconds");
return true;
} catch (java.rmi.ConnectException e) {
+ mesg("Remote connection refused after " +
+ (i * rmidWaitingStepTime) + " milliseconds");
+
// ignore connect exceptions until we decide rmid is not up
-
if ((connectionRefusedExceptions ++) >= allowedNotReady) {
return false;
}
+ } catch (java.rmi.NoSuchObjectException nsoe) {
+ /* Activation System still unavailable.
+ * Ignore this since we are just waiting for its availibility.
+ * Just signal unavailibility.
+ */
+ mesg("Activation System still unavailable after more than " +
+ (i * rmidWaitingStepTime) + " milliseconds");
+
} catch (NotBoundException e) {
-
return false;
} catch (Exception e) {
- // print out other types of exceptions as an FYI.
- // test should not fail as rmid is likely to be in an
- // undetermined state at this point.
-
+ /* print out other types of exceptions as an FYI.
+ * test should not fail as rmid is likely to be in an
+ * undetermined state at this point.
+ */
mesg("caught an exception trying to" +
" start rmid, last exception was: " +
e.getMessage());
e.printStackTrace();
}
+
+ // Waiting for another 100 milliseconds.
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ mesg("Thread interrupted while checking if Activation System is running. Exiting check");
+ return false;
+ }
}
return false;
}
--- a/jdk/test/java/rmi/testlibrary/JavaVM.java Fri May 11 12:53:03 2012 -0700
+++ b/jdk/test/java/rmi/testlibrary/JavaVM.java Fri May 11 14:13:29 2012 -0700
@@ -36,7 +36,6 @@
*/
public class JavaVM {
- // need to
protected Process vm = null;
private String classname = "";
@@ -46,6 +45,10 @@
private OutputStream errorStream = System.err;
private String policyFileName = null;
+ // This is used to shorten waiting time at startup.
+ private volatile boolean started = false;
+ private boolean forcesOutput = true; // default behavior
+
private static void mesg(Object mesg) {
System.err.println("JAVAVM: " + mesg.toString());
}
@@ -79,6 +82,25 @@
this.errorStream = err;
}
+ /* This constructor will instantiate a JavaVM object for which caller
+ * can ask for forcing initial version output on child vm process
+ * (if forcesVersionOutput is true), or letting the started vm behave freely
+ * (when forcesVersionOutput is false).
+ */
+ public JavaVM(String classname,
+ String options, String args,
+ OutputStream out, OutputStream err,
+ boolean forcesVersionOutput) {
+ this(classname, options, args, out, err);
+ this.forcesOutput = forcesVersionOutput;
+ }
+
+
+ public void setStarted() {
+ started = true;
+ }
+
+ // Prepends passed opts array to current options
public void addOptions(String[] opts) {
String newOpts = "";
for (int i = 0 ; i < opts.length ; i ++) {
@@ -87,6 +109,8 @@
newOpts += " ";
options = newOpts + options;
}
+
+ // Prepends passed arguments array to current args
public void addArguments(String[] arguments) {
String newArgs = "";
for (int i = 0 ; i < arguments.length ; i ++) {
@@ -127,6 +151,18 @@
addOptions(new String[] { getCodeCoverageOptions() });
+ /*
+ * If forcesOutput is true :
+ * We force the new starting vm to output something so that we can know
+ * when it is effectively started by redirecting standard output through
+ * the next StreamPipe call (the vm is considered started when a first
+ * output has been streamed out).
+ * We do this by prepnding a "-showversion" option in the command line.
+ */
+ if (forcesOutput) {
+ addOptions(new String[] {"-showversion"});
+ }
+
StringTokenizer optionsTokenizer = new StringTokenizer(options);
StringTokenizer argsTokenizer = new StringTokenizer(args);
int optionsCount = optionsTokenizer.countTokens();
@@ -150,15 +186,43 @@
vm = Runtime.getRuntime().exec(javaCommand);
/* output from the execed process may optionally be captured. */
- StreamPipe.plugTogether(vm.getInputStream(), this.outputStream);
- StreamPipe.plugTogether(vm.getErrorStream(), this.errorStream);
+ StreamPipe.plugTogether(this, vm.getInputStream(), this.outputStream);
+ StreamPipe.plugTogether(this, vm.getErrorStream(), this.errorStream);
try {
- Thread.sleep(2000);
- } catch (Exception ignore) {
+ if (forcesOutput) {
+ // Wait distant vm to start, by using waiting time slices of 100 ms.
+ // Wait at most for 2secs, after it considers the vm to be started.
+ final long vmStartSleepTime = 100;
+ final int maxTrials = 20;
+ int numTrials = 0;
+ while (!started && numTrials < maxTrials) {
+ numTrials++;
+ Thread.sleep(vmStartSleepTime);
+ }
+
+ // Outputs running status of distant vm
+ String message =
+ "after " + (numTrials * vmStartSleepTime) + " milliseconds";
+ if (started) {
+ mesg("distant vm process running, " + message);
+ }
+ else {
+ mesg("unknown running status of distant vm process, " + message);
+ }
+ }
+ else {
+ // Since we have no way to know if the distant vm is started,
+ // we just consider the vm to be started after a 2secs waiting time.
+ Thread.sleep(2000);
+ mesg("distant vm considered to be started after a waiting time of 2 secs");
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ mesg("Thread interrupted while checking if distant vm is started. Giving up check.");
+ mesg("Distant vm state unknown");
+ return;
}
-
- mesg("finished starting vm.");
}
public void destroy() {
--- a/jdk/test/java/rmi/testlibrary/RMID.java Fri May 11 12:53:03 2012 -0700
+++ b/jdk/test/java/rmi/testlibrary/RMID.java Fri May 11 14:13:29 2012 -0700
@@ -218,20 +218,30 @@
} catch (NumberFormatException ignore) {}
waitTime = waitTime * slopFactor;
- // give rmid time to come up
+ // We check several times (as many as provides passed waitTime) to
+ // see if Rmid is currently running. Waiting steps last 100 msecs.
+ final long rmidStartSleepTime = 100;
do {
+ // Sleeping for another rmidStartSleepTime time slice.
try {
- Thread.sleep(Math.min(waitTime, 10000));
+ Thread.sleep(Math.min(waitTime, rmidStartSleepTime));
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
+ mesg("Thread interrupted while checking for start of Activation System. Giving up check.");
+ mesg("Activation System state unknown");
+ return;
}
- waitTime -= 10000;
+ waitTime -= rmidStartSleepTime;
- // is rmid present?
+ // Checking if rmid is present
if (ActivationLibrary.rmidRunning(port)) {
mesg("finished starting rmid.");
return;
}
+ else {
+ mesg("rmid still not started");
+ }
+
} while (waitTime > 0);
TestLibrary.bomb("start rmid failed... giving up", null);
}
@@ -264,6 +274,8 @@
port +
"/java.rmi.activation.ActivationSystem");
mesg("obtained a reference to the activation system");
+ } catch (RemoteException re) {
+ mesg("could not contact registry while trying to shutdown activation system");
} catch (java.net.MalformedURLException mue) {
}
@@ -272,19 +284,14 @@
}
system.shutdown();
+ } catch (RemoteException re) {
+ mesg("shutting down the activation daemon failed");
} catch (Exception e) {
mesg("caught exception trying to shutdown rmid");
mesg(e.getMessage());
e.printStackTrace();
}
- try {
- // wait for the shutdown to happen
- Thread.sleep(5000);
- } catch (InterruptedException ie) {
- Thread.currentThread().interrupt();
- }
-
mesg("testlibrary finished shutting down rmid");
}
@@ -301,18 +308,47 @@
if (vm != null) {
try {
- // destroy rmid if it is still running...
- try {
- vm.exitValue();
- mesg("rmid exited on shutdown request");
- } catch (IllegalThreadStateException illegal) {
- mesg("Had to destroy RMID's process " +
- "using Process.destroy()");
+ /* Waiting for distant RMID process to shutdown.
+ * Waiting is bounded at a hardcoded max of 60 secs (1 min).
+ * Waiting by steps of 200 msecs, thus at most 300 such attempts
+ * for termination of distant RMID process. If process is not
+ * known to be terminated properly after that time,
+ * we give up for a gracefull termination, and thus go for
+ * forcibly destroying the process.
+ */
+ boolean vmEnded = false;
+ int waitingTrials = 0;
+ final int maxTrials = 300;
+ final long vmProcessEndWaitInterval = 200;
+ int vmExitValue;
+ do {
+ try {
+ Thread.sleep(vmProcessEndWaitInterval);
+ waitingTrials++;
+ vmExitValue = vm.exitValue();
+ mesg("rmid exited on shutdown request");
+ vmEnded = true;
+ } catch (IllegalThreadStateException illegal) {
+ mesg("RMID's process still not terminated after more than " +
+ (waitingTrials * vmProcessEndWaitInterval) + " milliseconds");
+ }
+ }
+ while (!vmEnded &&
+ (waitingTrials < maxTrials));
+
+ if (waitingTrials >= maxTrials) {
+ mesg("RMID's process still not terminated after more than " +
+ (waitingTrials * vmProcessEndWaitInterval) + " milliseconds." +
+ "Givinp up gracefull termination...");
+ mesg("destroying RMID's process using Process.destroy()");
super.destroy();
}
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ mesg("Thread interrupted while checking for termination of distant rmid vm. Giving up check.");
} catch (Exception e) {
- mesg("caught exception trying to destroy rmid: " +
+ mesg("caught unexpected exception trying to destroy rmid: " +
e.getMessage());
e.printStackTrace();
}
--- a/jdk/test/java/rmi/testlibrary/StreamPipe.java Fri May 11 12:53:03 2012 -0700
+++ b/jdk/test/java/rmi/testlibrary/StreamPipe.java Fri May 11 14:13:29 2012 -0700
@@ -35,46 +35,89 @@
private InputStream in;
private OutputStream out;
private String preamble;
+ private JavaVM javaVM;
private static Object lock = new Object();
private static int count = 0;
- public StreamPipe(InputStream in, OutputStream out, String name) {
+
+ /* StreamPipe constructor : should only be called by plugTogether() method !!
+ * If passed vm is not null :
+ * - This is StreamPipe usage when streams to pipe come from a given
+ * vm (JavaVM) process (the vm process must be started with a prefixed
+ * "-showversion" option to be able to determine as soon as possible when
+ * the vm process is started through the redirection of the streams).
+ * There must be a close connection between the StreamPipe instance and
+ * the JavaVM object on which a start() call has been done.
+ * run() method will flag distant JavaVM as started.
+ * If passed vm is null :
+ * - We don't have control on the process which we want to redirect the passed
+ * streams.
+ * run() method will ignore distant process.
+ */
+ private StreamPipe(JavaVM vm, InputStream in, OutputStream out, String name) {
super(name);
this.in = in;
this.out = out;
this.preamble = "# ";
+ this.javaVM = vm;
}
+ // Install redirection of passed InputStream and OutputStream from passed JavaVM
+ // to this vm standard output and input streams.
+ public static void plugTogether(JavaVM vm, InputStream in, OutputStream out) {
+ String name = null;
+
+ synchronized (lock) {
+ name = "TestLibrary: StreamPipe-" + (count ++ );
+ }
+
+ Thread pipe = new StreamPipe(vm, in, out, name);
+ pipe.setDaemon(true);
+ pipe.start();
+ }
+
+ /* Redirects the InputStream and OutputStream passed by caller to this
+ * vm standard output and input streams.
+ * (we just have to use fully parametered plugTogether() call with a null
+ * JavaVM input to do this).
+ */
+ public static void plugTogether(InputStream in, OutputStream out) {
+ plugTogether(null, in, out);
+ }
+
+ // Starts redirection of streams.
public void run() {
BufferedReader r = new BufferedReader(new InputStreamReader(in), 1);
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(out));
byte[] buf = new byte[256];
- boolean bol = true; // beginning-of-line
- int count;
try {
String line;
- while ((line = r.readLine()) != null) {
+
+ /* This is to check that the distant vm has started,
+ * if such a vm has been provided at construction :
+ * - As soon as we can read something from r BufferedReader,
+ * that means the distant vm is already started.
+ * Thus we signal associated JavaVM object that it is now started.
+ */
+ if (((line = r.readLine()) != null) &&
+ (javaVM != null)) {
+ javaVM.setStarted();
+ }
+
+ // Redirects r on w.
+ while (line != null) {
w.write(preamble);
w.write(line);
w.newLine();
w.flush();
+ line = r.readLine();
}
+
} catch (IOException e) {
System.err.println("*** IOException in StreamPipe.run:");
e.printStackTrace();
}
}
- public static void plugTogether(InputStream in, OutputStream out) {
- String name = null;
-
- synchronized (lock) {
- name = "TestLibrary: StreamPipe-" + (count ++ );
- }
-
- Thread pipe = new StreamPipe(in, out, name);
- pipe.setDaemon(true);
- pipe.start();
- }
}
--- a/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java Fri May 11 12:53:03 2012 -0700
+++ b/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java Fri May 11 14:13:29 2012 -0700
@@ -60,9 +60,12 @@
File.separatorChar + "logging.properties";
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream err = new ByteArrayOutputStream();
+
+ // We instantiate a JavaVM that should not produce any console output
+ // (neither on standard output, nor on standard err streams).
JavaVM vm = new JavaVM(DoRMIStuff.class.getName(),
"-Djava.util.logging.config.file=" + loggingPropertiesFile,
- "", out, err);
+ "", out, err, false);
vm.start();
vm.getVM().waitFor();