blob: a6628d69ee5fa6a7fdc78792eed3adca5d16b9bc [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.junit.remote;
import junit.framework.TestCase;
import java.io.File;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Properties;
/**
* Exercise the BrowserManagerServer with the serialized option turned on and
* off.
*/
public class BrowserManagerServerTest extends TestCase {
/**
* Seconds for simulated browser to hang.
*/
static final int TIMEOUT_MS = 2000;
/**
* Time to wait between keepAlive calls to all browsers.
*/
static final int PING_INTERVAL_MS = 100;
static final boolean LOG = false;
private static final String REGISTRATION_KEY = "sleep-" + (TIMEOUT_MS / 1000)
+ "-seconds";
private static Registry rmiRegistry = null;
private int portArg = Registry.REGISTRY_PORT;
private BrowserManagerServer server = null;
/**
* Run a test with the 'serialized' flag on.
*/
public void testSerializedServer() throws Exception {
BrowserManager browserManager = startBrowserManagerServer(true);
// Launch some browsers all at once.
final int NUM_BROWSERS = 4;
int tokens[] = new int[NUM_BROWSERS];
for (int i = 0; i < NUM_BROWSERS; i++) {
tokens[i] = launchBrowser(browserManager, i);
}
// Give them a chance to startup.
Thread.sleep(TIMEOUT_MS / 4);
int numQueued = server.numQueued();
int numRunning = server.numRunning();
assertEquals("Did not find the number of expected browsers queued up",
NUM_BROWSERS - 1, numQueued);
assertEquals("Expected only one running at a time for serialized.", 1,
numRunning);
outer : for (int runningBrowser = 0; runningBrowser < NUM_BROWSERS; ++runningBrowser) {
// The current browser should be dead within twice the expected timeout.
long shouldBeDeadBy = System.currentTimeMillis() + (TIMEOUT_MS * 2);
while (System.currentTimeMillis() < shouldBeDeadBy) {
assertTrue(server.numRunning() <= 1);
// Ping every alive browser.
for (int i = runningBrowser; i < NUM_BROWSERS; ++i) {
// Keep the browser alive with a margin of safety until the next ping.
try {
browserManager.keepAlive(tokens[runningBrowser], TIMEOUT_MS);
} catch (IllegalStateException ise) {
// Expected.
assertEquals("The wrong browser is dead", runningBrowser, i);
if (LOG) {
System.out.println("Browser token: " + tokens[i]
+ " exited sucessfully");
}
// Ensure it's legal to kill the dead browser.
browserManager.killBrowser(tokens[i]);
// Continue with the next active browser.
continue outer;
}
}
Thread.sleep(PING_INTERVAL_MS);
}
// Error case
fail("Browser " + runningBrowser + " failed to exit in a timely manner");
}
}
/**
* Run a test with the 'serialized' flag on.
*/
public void testUnserializedServer() throws Exception {
BrowserManager browserManager = startBrowserManagerServer(false);
// Launch some browsers all at once.
final int NUM_BROWSERS = 6;
int tokens[] = new int[NUM_BROWSERS];
for (int i = 0; i < NUM_BROWSERS; i++) {
tokens[i] = launchBrowser(browserManager, i);
}
// Give them a chance to startup.
Thread.sleep(TIMEOUT_MS / 4);
int numQueued = server.numQueued();
int numRunning = server.numRunning();
assertEquals("No queuing should occur", 0, numQueued);
assertEquals("All browers should be running", NUM_BROWSERS, numRunning);
// The current browser should be dead within twice the expected timeout.
long shouldBeDeadBy = System.currentTimeMillis() + (TIMEOUT_MS * 2);
int liveBrowsers = NUM_BROWSERS;
while (System.currentTimeMillis() < shouldBeDeadBy) {
// Ping every alive browser.
for (int i = 0; i < NUM_BROWSERS; ++i) {
if (tokens[i] == 0) {
// This one's already dead.
continue;
}
// Keep the browser alive with a margin of safety until the next ping.
try {
browserManager.keepAlive(tokens[i], TIMEOUT_MS);
} catch (IllegalStateException ise) {
// Expected.
if (LOG) {
System.out.println("Browser token: " + tokens[i]
+ " exited sucessfully");
}
// Ensure it's legal to kill the dead browser.
browserManager.killBrowser(tokens[i]);
tokens[i] = 0;
--liveBrowsers;
if (liveBrowsers == 0) {
// All done;
return;
}
}
}
Thread.sleep(PING_INTERVAL_MS);
}
// Error case
fail(liveBrowsers + " browsers failed to exit in a timely manner");
}
/**
* Start up the RMI registry and create a shell script that just sleeps for
* 'timeout' seconds.
*/
@Override
protected void setUp() throws Exception {
if (rmiRegistry == null) {
rmiRegistry = LocateRegistry.createRegistry(portArg);
}
}
/**
* Clean up temporary files.
*/
@Override
protected void tearDown() throws Exception {
// De-register the server.
if (rmiRegistry != null) {
rmiRegistry.unbind(REGISTRATION_KEY);
}
}
/**
* Start a browser task on the server.
*
* @param browserManager handle to the browser manager instance
* @param token browser ident number
*/
private int launchBrowser(BrowserManager browserManager, int token)
throws RemoteException {
return browserManager.launchNewBrowser("# client" + token, TIMEOUT_MS);
}
/**
* Starts up an instance of BrowserManagerServer.
*
* @param isSerialized true to enable the serialized mode (run one browser
* instance at a time, queue any others.)
* @return the newly created instance of BrowserManagerServer on success
*/
private BrowserManager startBrowserManagerServer(boolean isSerialized)
throws RemoteException, MalformedURLException, NotBoundException {
// Construct a launch command for relaunching the JVM out of process,
// running DummyProcess.
StringBuilder sb = new StringBuilder();
Properties properties = System.getProperties();
sb.append(properties.getProperty("java.home"));
sb.append(File.separatorChar);
sb.append("bin");
sb.append(File.separatorChar);
sb.append("java");
sb.append('\n');
sb.append("-classpath");
sb.append('\n');
sb.append(properties.getProperty("java.class.path"));
sb.append('\n');
sb.append(DummyProcess.class.getName());
server = new BrowserManagerServer(sb.toString(), isSerialized);
rmiRegistry.rebind(REGISTRATION_KEY, server);
// Server started. Now, create a client and send some commands to it
String url = "rmi://localhost/" + REGISTRATION_KEY;
BrowserManager browserManager = (BrowserManager) Naming.lookup(url);
return browserManager;
}
}