Adds the undocumented command line argument -externalbrowsers to
aid in running the continuous build unit tests. The comma separated
list of executable paths provided will be launched to run the
unit tests in parallel.
Patch by: zundel
Review by: scottb
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2614 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/junit/JUnitShell.java b/user/src/com/google/gwt/junit/JUnitShell.java
index 96709db..6aeddb6 100644
--- a/user/src/com/google/gwt/junit/JUnitShell.java
+++ b/user/src/com/google/gwt/junit/JUnitShell.java
@@ -286,6 +286,37 @@
}
});
+ registerHandler(new ArgHandlerString() {
+
+ @Override
+ public String getPurpose() {
+ return "Run external browsers in web mode (pass a comma separated list of executables.)";
+ }
+
+ @Override
+ public String getTag() {
+ return "-externalbrowser";
+ }
+
+ @Override
+ public String[] getTagArgs() {
+ return new String[] {"browserPaths"};
+ }
+
+ @Override
+ public boolean isUndocumented() {
+ return true;
+ }
+
+ @Override
+ public boolean setString(String str) {
+ String[] paths = str.split(",");
+ runStyle = new RunStyleExternalBrowser(JUnitShell.this, paths);
+ numClients = paths.length;
+ return runStyle != null;
+ }
+ });
+
registerHandler(new ArgHandler() {
@Override
@@ -300,7 +331,7 @@
@Override
public String getTag() {
- return "-wait";
+ return "-manual";
}
@Override
@@ -328,7 +359,7 @@
}
public void setInt(int value) {
- runStyle = new RunStyleWait(JUnitShell.this, value);
+ runStyle = new RunStyleManual(JUnitShell.this, value);
numClients = value;
}
@@ -411,7 +442,7 @@
@Override
protected boolean notDone() {
int activeClients = messageQueue.getNumClientsRetrievedCurrentTest();
- if (firstLaunch && runStyle instanceof RunStyleWait) {
+ if (firstLaunch && runStyle instanceof RunStyleManual) {
String[] newClients = messageQueue.getNewClients();
int printIndex = activeClients - newClients.length + 1;
for (String newClient : newClients) {
diff --git a/user/src/com/google/gwt/junit/RunStyleExternalBrowser.java b/user/src/com/google/gwt/junit/RunStyleExternalBrowser.java
new file mode 100644
index 0000000..e3c1eea
--- /dev/null
+++ b/user/src/com/google/gwt/junit/RunStyleExternalBrowser.java
@@ -0,0 +1,139 @@
+/*
+ * 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;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+
+/**
+ * Runs in web mode via browsers managed as an external process. This feature is
+ * experimental and is not officially supported.
+ */
+class RunStyleExternalBrowser extends RunStyle {
+
+ private static class ExternalBrowser {
+ String browserPath;
+ Process process;
+
+ public ExternalBrowser(String browserPath) {
+ this.browserPath = browserPath;
+ }
+
+ public String getPath() {
+ return browserPath;
+ }
+
+ public Process getProcess() {
+ return process;
+ }
+
+ public void setProcess(Process process) {
+ this.process = process;
+ }
+ }
+
+ private final ExternalBrowser[] externalBrowsers;
+
+ /**
+ * @param shell the containing shell
+ * @param browsers an array of path names pointing to browser executables.
+ */
+ public RunStyleExternalBrowser(JUnitShell shell, String browsers[]) {
+ super(shell);
+ synchronized (this) {
+ this.externalBrowsers = new ExternalBrowser[browsers.length];
+ for (int i = 0; i < browsers.length; ++i) {
+ externalBrowsers[i] = new ExternalBrowser(browsers[i]);
+ }
+ }
+ Runtime.getRuntime().addShutdownHook(new ShutdownCb());
+ }
+
+ @Override
+ public boolean isLocal() {
+ return false;
+ }
+
+ @Override
+ public synchronized void launchModule(String moduleName)
+ throws UnableToCompleteException {
+ String commandArray[] = new String[2];
+ // construct the URL for the browser to hit
+ commandArray[1] = "http://" + "localhost" + ":" + shell.getPort() + "/"
+ + getUrlSuffix(moduleName);
+
+ Process child = null;
+ for (ExternalBrowser browser : externalBrowsers) {
+ try {
+ commandArray[0] = browser.getPath();
+
+ child = Runtime.getRuntime().exec(commandArray);
+ if (child == null) {
+ getLogger().log(TreeLogger.ERROR,
+ "Problem exec()'ing " + commandArray[0]);
+ throw new UnableToCompleteException();
+ }
+ } catch (Exception e) {
+ getLogger().log(TreeLogger.ERROR,
+ "Error launching external browser at " + browser.getPath(), e);
+ throw new UnableToCompleteException();
+ }
+ browser.setProcess(child);
+ }
+ }
+
+ @Override
+ public boolean wasInterrupted() {
+
+ // Make sure all browsers are still running
+ for (ExternalBrowser browser : externalBrowsers) {
+ try {
+ browser.getProcess().exitValue();
+ } catch (IllegalThreadStateException e) {
+ // The process is still active, keep looking.
+ continue;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Registered as a shutdown hook to make sure that any browsers that were not
+ * finished are killed.
+ */
+ private class ShutdownCb extends Thread {
+
+ @Override
+ public void run() {
+ for (ExternalBrowser browser : externalBrowsers) {
+ try {
+ browser.getProcess().exitValue();
+ } catch (IllegalThreadStateException e) {
+ // The process is still active. Kill it.
+ browser.getProcess().destroy();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void maybeCompileModule(String moduleName)
+ throws UnableToCompleteException {
+ shell.compileForWebMode(moduleName, null);
+ }
+
+}
diff --git a/user/src/com/google/gwt/junit/RunStyleWait.java b/user/src/com/google/gwt/junit/RunStyleManual.java
similarity index 89%
rename from user/src/com/google/gwt/junit/RunStyleWait.java
rename to user/src/com/google/gwt/junit/RunStyleManual.java
index 3dd38fe..1b36d16 100644
--- a/user/src/com/google/gwt/junit/RunStyleWait.java
+++ b/user/src/com/google/gwt/junit/RunStyleManual.java
@@ -21,11 +21,11 @@
* Runs in web mode waiting for the user to contact the server with their own
* browser.
*/
-class RunStyleWait extends RunStyleRemote {
+class RunStyleManual extends RunStyleRemote {
private final int numClients;
- public RunStyleWait(JUnitShell shell, int numClients) {
+ public RunStyleManual(JUnitShell shell, int numClients) {
super(shell);
this.numClients = numClients;
}
@@ -49,7 +49,7 @@
@Override
public void maybeCompileModule(String moduleName)
throws UnableToCompleteException {
- System.out.print("Compling " + moduleName + "...");
+ System.out.print("Compiling " + moduleName + "...");
super.maybeCompileModule(moduleName);
System.out.println(" success.");
}