NIHVIVO-222 Return to stopping and starting Tomcat - stopping the webapp ran out of PermGen space no matter what I tried. Also some output formatting improvements.
This commit is contained in:
parent
c27155a696
commit
510321a192
12 changed files with 240 additions and 401 deletions
|
@ -83,10 +83,12 @@ public class CommandRunner {
|
||||||
|
|
||||||
this.returnCode = process.waitFor();
|
this.returnCode = process.waitFor();
|
||||||
|
|
||||||
outputEater.join();
|
outputEater.join(1000);
|
||||||
|
outputEater.stopRunning();
|
||||||
this.stdOut = outputEater.getContents();
|
this.stdOut = outputEater.getContents();
|
||||||
|
|
||||||
errorEater.join();
|
errorEater.join(1000);
|
||||||
|
errorEater.stopRunning();
|
||||||
this.stdErr = errorEater.getContents();
|
this.stdErr = errorEater.getContents();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new CommandRunnerException(
|
throw new CommandRunnerException(
|
||||||
|
@ -98,40 +100,6 @@ public class CommandRunner {
|
||||||
listener.subProcessStop(command);
|
listener.subProcessStop(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the command and don't wait for it to complete. {@link #stdErr} and
|
|
||||||
* {@link #stdOut} will not be set, but output from the process may be sent
|
|
||||||
* to the listener at any time.
|
|
||||||
*
|
|
||||||
* @param command
|
|
||||||
* a list containing the operating system program and its
|
|
||||||
* arguments. See
|
|
||||||
* {@link java.lang.ProcessBuilder#ProcessBuilder(List)}.
|
|
||||||
*/
|
|
||||||
public void runAsBackground(List<String> command)
|
|
||||||
throws CommandRunnerException {
|
|
||||||
listener.subProcessStartInBackground(command);
|
|
||||||
try {
|
|
||||||
ProcessBuilder builder = new ProcessBuilder(command);
|
|
||||||
|
|
||||||
if (workingDirectory != null) {
|
|
||||||
builder.directory(workingDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!environmentAdditions.isEmpty()) {
|
|
||||||
builder.environment().putAll(this.environmentAdditions);
|
|
||||||
}
|
|
||||||
|
|
||||||
Process process = builder.start();
|
|
||||||
new StreamEater(process.getInputStream(), false);
|
|
||||||
new StreamEater(process.getErrorStream(), true);
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new CommandRunnerException(
|
|
||||||
"Exception when handling sub-process:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getReturnCode() {
|
public int getReturnCode() {
|
||||||
if (returnCode == null) {
|
if (returnCode == null) {
|
||||||
throw new IllegalStateException("Return code is not available.");
|
throw new IllegalStateException("Return code is not available.");
|
||||||
|
@ -155,6 +123,7 @@ public class CommandRunner {
|
||||||
private class StreamEater extends Thread {
|
private class StreamEater extends Thread {
|
||||||
private final InputStream stream;
|
private final InputStream stream;
|
||||||
private final boolean isError;
|
private final boolean isError;
|
||||||
|
private volatile boolean running;
|
||||||
|
|
||||||
private final StringWriter contents = new StringWriter();
|
private final StringWriter contents = new StringWriter();
|
||||||
|
|
||||||
|
@ -163,14 +132,19 @@ public class CommandRunner {
|
||||||
public StreamEater(InputStream stream, boolean isError) {
|
public StreamEater(InputStream stream, boolean isError) {
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
this.isError = isError;
|
this.isError = isError;
|
||||||
|
this.running = true;
|
||||||
this.start();
|
this.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void stopRunning() {
|
||||||
|
this.running = false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
int howMany = 0;
|
int howMany = 0;
|
||||||
while (true) {
|
while (running) {
|
||||||
howMany = stream.read(buffer);
|
howMany = stream.read(buffer);
|
||||||
if (howMany > 0) {
|
if (howMany > 0) {
|
||||||
String string = new String(buffer, 0, howMany);
|
String string = new String(buffer, 0, howMany);
|
||||||
|
@ -182,7 +156,11 @@ public class CommandRunner {
|
||||||
listener.subProcessStdout(string);
|
listener.subProcessStdout(string);
|
||||||
}
|
}
|
||||||
} else if (howMany == 0) {
|
} else if (howMany == 0) {
|
||||||
Thread.yield();
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,38 +10,39 @@ import java.util.Properties;
|
||||||
* model.
|
* model.
|
||||||
*/
|
*/
|
||||||
public class ModelCleanerProperties {
|
public class ModelCleanerProperties {
|
||||||
public static final String PROP_VIVO_WEBAPP_NAME = "vivo_webapp_name";
|
|
||||||
public static final String PROP_TOMCAT_MANAGER_USERNAME = "tomcat_manager_username";
|
|
||||||
public static final String PROP_TOMCAT_MANAGER_PASSWORD = "tomcat_manager_password";
|
|
||||||
public static final String PROP_MYSQL_USERNAME = "mysql_username";
|
public static final String PROP_MYSQL_USERNAME = "mysql_username";
|
||||||
public static final String PROP_MYSQL_PASSWORD = "mysql_password";
|
public static final String PROP_MYSQL_PASSWORD = "mysql_password";
|
||||||
public static final String PROP_MYSQL_DB_NAME = "mysql_db_name";
|
public static final String PROP_MYSQL_DB_NAME = "mysql_db_name";
|
||||||
public static final String PROP_WEBAPP_DIRECTORY = "vivo_webapp_directory";
|
public static final String PROP_WEBAPP_DIRECTORY = "vivo_webapp_directory";
|
||||||
|
public static final String PROP_TOMCAT_CHECK_READY_COMMAND = "tomcat_check_ready_command";
|
||||||
|
public static final String PROP_TOMCAT_STOP_COMMAND = "tomcat_stop_command";
|
||||||
|
public static final String PROP_TOMCAT_START_COMMAND = "tomcat_start_command";
|
||||||
|
|
||||||
private final String vivoWebappName;
|
|
||||||
private final String tomcatManagerUsername;
|
|
||||||
private final String tomcatManagerPassword;
|
|
||||||
private final String mysqlUsername;
|
private final String mysqlUsername;
|
||||||
private final String mysqlPassword;
|
private final String mysqlPassword;
|
||||||
private final String mysqlDbName;
|
private final String mysqlDbName;
|
||||||
private final File webappDirectory;
|
private final File webappDirectory;
|
||||||
|
private final String tomcatCheckReadyCommand;
|
||||||
|
private final String tomcatStopCommand;
|
||||||
|
private final String tomcatStartCommand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirm that we have the expected properties, and that their values seem
|
* Confirm that we have the expected properties, and that their values seem
|
||||||
* reasonable.
|
* reasonable.
|
||||||
*/
|
*/
|
||||||
public ModelCleanerProperties(Properties props) {
|
public ModelCleanerProperties(Properties props) {
|
||||||
this.vivoWebappName = checkWebappName(props);
|
|
||||||
this.tomcatManagerUsername = getRequiredProperty(props,
|
|
||||||
PROP_TOMCAT_MANAGER_USERNAME);
|
|
||||||
this.tomcatManagerPassword = getRequiredProperty(props,
|
|
||||||
PROP_TOMCAT_MANAGER_PASSWORD);
|
|
||||||
|
|
||||||
this.mysqlUsername = getRequiredProperty(props, PROP_MYSQL_USERNAME);
|
this.mysqlUsername = getRequiredProperty(props, PROP_MYSQL_USERNAME);
|
||||||
this.mysqlPassword = getRequiredProperty(props, PROP_MYSQL_PASSWORD);
|
this.mysqlPassword = getRequiredProperty(props, PROP_MYSQL_PASSWORD);
|
||||||
this.mysqlDbName = getRequiredProperty(props, PROP_MYSQL_DB_NAME);
|
this.mysqlDbName = getRequiredProperty(props, PROP_MYSQL_DB_NAME);
|
||||||
|
|
||||||
this.webappDirectory = confirmWebappDirectory(props);
|
this.webappDirectory = confirmWebappDirectory(props);
|
||||||
|
|
||||||
|
this.tomcatCheckReadyCommand = getRequiredProperty(props,
|
||||||
|
PROP_TOMCAT_CHECK_READY_COMMAND);
|
||||||
|
this.tomcatStopCommand = getRequiredProperty(props,
|
||||||
|
PROP_TOMCAT_STOP_COMMAND);
|
||||||
|
this.tomcatStartCommand = getRequiredProperty(props,
|
||||||
|
PROP_TOMCAT_START_COMMAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMysqlUsername() {
|
public String getMysqlUsername() {
|
||||||
|
@ -60,16 +61,16 @@ public class ModelCleanerProperties {
|
||||||
return webappDirectory;
|
return webappDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getVivoWebappName() {
|
public String getTomcatCheckReadyCommand() {
|
||||||
return vivoWebappName;
|
return tomcatCheckReadyCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTomcatManagerUsername() {
|
public String getTomcatStopCommand() {
|
||||||
return tomcatManagerUsername;
|
return tomcatStopCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTomcatManagerPassword() {
|
public String getTomcatStartCommand() {
|
||||||
return tomcatManagerPassword;
|
return tomcatStartCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,22 +86,6 @@ public class ModelCleanerProperties {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The website URL must end with the webapp name.
|
|
||||||
*/
|
|
||||||
private String checkWebappName(Properties props) {
|
|
||||||
String websiteUrl = getRequiredProperty(props,
|
|
||||||
SeleniumRunnerParameters.PROP_WEBSITE_URL);
|
|
||||||
String webappName = getRequiredProperty(props, PROP_VIVO_WEBAPP_NAME);
|
|
||||||
if ((!websiteUrl.endsWith(webappName))
|
|
||||||
&& (!websiteUrl.endsWith(webappName + "/"))) {
|
|
||||||
throw new IllegalArgumentException("The " + PROP_VIVO_WEBAPP_NAME
|
|
||||||
+ " must be the last item in the "
|
|
||||||
+ SeleniumRunnerParameters.PROP_WEBSITE_URL);
|
|
||||||
}
|
|
||||||
return webappName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The dumpfile parameter must point to an existing directory.
|
* The dumpfile parameter must point to an existing directory.
|
||||||
*/
|
*/
|
||||||
|
@ -126,10 +111,7 @@ public class ModelCleanerProperties {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "\n vivoWebappName: " + vivoWebappName
|
return "\n mysqlUsername: " + mysqlUsername
|
||||||
+ "\n tomcatManagerUsername: " + tomcatManagerUsername
|
|
||||||
+ "\n tomcatManagerPassword: " + tomcatManagerPassword
|
|
||||||
+ "\n mysqlUsername: " + mysqlUsername
|
|
||||||
+ "\n mysqlPassword: " + mysqlPassword
|
+ "\n mysqlPassword: " + mysqlPassword
|
||||||
+ "\n mysqlDbName: " + mysqlDbName
|
+ "\n mysqlDbName: " + mysqlDbName
|
||||||
+ "\n webappDirectory: " + webappDirectory;
|
+ "\n webappDirectory: " + webappDirectory;
|
||||||
|
|
|
@ -65,13 +65,16 @@ public class SeleniumRunner {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
listener.runFailed(e);
|
listener.runFailed(e);
|
||||||
success = false;
|
success = false;
|
||||||
e.printStackTrace();
|
throw new FatalException(e);
|
||||||
} catch (FatalException e) {
|
} catch (FatalException e) {
|
||||||
listener.runFailed(e);
|
listener.runFailed(e);
|
||||||
success = false;
|
success = false;
|
||||||
e.printStackTrace();
|
throw e;
|
||||||
}
|
} finally {
|
||||||
listener.runStopped();
|
listener.runStopped();
|
||||||
|
outputManager.summarizeOutput(dataModel);
|
||||||
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,16 +165,19 @@ public class SeleniumRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
try {
|
try {
|
||||||
parms = new SeleniumRunnerParameters(args[0]);
|
parms = new SeleniumRunnerParameters(args[0]);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
usage("Can't read properties file: " + e.getMessage());
|
usage("Can't read properties file: " + e.getMessage());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new FatalException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
if (interactive) {
|
if (interactive) {
|
||||||
// TODO hook up the GUI.
|
// TODO hook up the GUI.
|
||||||
throw new RuntimeException("interactive mode not implemented.");
|
throw new FatalException("interactive mode not implemented. "
|
||||||
|
+ "use 'ant acceptance -Dacceptance.batch=true'");
|
||||||
} else {
|
} else {
|
||||||
File logFile = new File(parms.getOutputDirectory(),
|
File logFile = new File(parms.getOutputDirectory(),
|
||||||
LOGFILE_NAME);
|
LOGFILE_NAME);
|
||||||
|
|
|
@ -2,178 +2,159 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.util.ArrayList;
|
||||||
import java.io.IOException;
|
import java.util.List;
|
||||||
import java.io.StringReader;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.utilities.testrunner.listener.Listener;
|
import edu.cornell.mannlib.vitro.utilities.testrunner.listener.Listener;
|
||||||
import edu.cornell.mannlib.vitro.utilities.testrunner.tomcat.HttpHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start and stop the webapp, so we can clean the database.
|
* Start and stop the webapp, so we can clean the database.
|
||||||
*/
|
*/
|
||||||
public class TomcatController {
|
public class TomcatController {
|
||||||
private static final Pattern PATTERN_WEBAPP_LISTING = Pattern
|
|
||||||
.compile("/(\\w+):(\\w+):");
|
|
||||||
|
|
||||||
private final SeleniumRunnerParameters parms;
|
private final SeleniumRunnerParameters parms;
|
||||||
private final ModelCleanerProperties properties;
|
private final ModelCleanerProperties properties;
|
||||||
private final Listener listener;
|
private final Listener listener;
|
||||||
|
|
||||||
private final String tomcatBaseUrl;
|
|
||||||
private final String tomcatManagerUrl;
|
|
||||||
private final String tomcatManagerUsername;
|
|
||||||
private final String tomcatManagerPassword;
|
|
||||||
private final String webappName;
|
|
||||||
|
|
||||||
public TomcatController(SeleniumRunnerParameters parms) {
|
public TomcatController(SeleniumRunnerParameters parms) {
|
||||||
this.parms = parms;
|
this.parms = parms;
|
||||||
this.properties = parms.getModelCleanerProperties();
|
this.properties = parms.getModelCleanerProperties();
|
||||||
this.listener = parms.getListener();
|
this.listener = parms.getListener();
|
||||||
|
|
||||||
this.webappName = properties.getVivoWebappName();
|
try {
|
||||||
this.tomcatBaseUrl = figureBaseUrl();
|
|
||||||
this.tomcatManagerUrl = this.tomcatBaseUrl + "/manager";
|
|
||||||
this.tomcatManagerUsername = properties.getTomcatManagerUsername();
|
|
||||||
this.tomcatManagerPassword = properties.getTomcatManagerPassword();
|
|
||||||
|
|
||||||
checkThatTomcatIsReady();
|
checkThatTomcatIsReady();
|
||||||
|
} catch (CommandRunnerException e) {
|
||||||
|
throw new FatalException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String figureBaseUrl() {
|
|
||||||
String url = parms.getWebsiteUrl();
|
|
||||||
int end = url.lastIndexOf(webappName);
|
|
||||||
return url.substring(0, end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insure that Tomcat is running and has the ability to start and stop VIVO.
|
* Insure that Tomcat is ready and that we can start and stop VIVO.
|
||||||
*/
|
*/
|
||||||
private void checkThatTomcatIsReady() {
|
private void checkThatTomcatIsReady() throws CommandRunnerException {
|
||||||
HttpHelper hh = new HttpHelper();
|
String tomcatCheckReadyCommand = properties
|
||||||
|
.getTomcatCheckReadyCommand();
|
||||||
|
|
||||||
// Is Tomcat responding?
|
CommandRunner runner = new CommandRunner(parms);
|
||||||
if (!hh.getPage(tomcatBaseUrl)) {
|
|
||||||
throw newHttpException(hh, "Tomcat does not respond");
|
listener.webappCheckingReady(tomcatCheckReadyCommand);
|
||||||
|
runner.run(parseCommandLine(tomcatCheckReadyCommand));
|
||||||
|
|
||||||
|
int returnCode = runner.getReturnCode();
|
||||||
|
if (returnCode != 0) {
|
||||||
|
listener.webappCheckReadyFailed(returnCode);
|
||||||
|
throw new CommandRunnerException("Tomcat is not ready: code="
|
||||||
|
+ returnCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does the manager respond?
|
listener.webappCheckedReady();
|
||||||
hh.getPage(tomcatManagerUrl + "/list");
|
|
||||||
if (hh.getStatus() == 404) {
|
|
||||||
throw newHttpException(hh,
|
|
||||||
"Tomcat manager application does not respond. "
|
|
||||||
+ "Is it installed?");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do we have the correct authorization for the manager?
|
public void stopTheWebapp() throws CommandRunnerException {
|
||||||
hh.getPage(tomcatManagerUrl + "/list", tomcatManagerUsername,
|
String tomcatStopCommand = properties.getTomcatStopCommand();
|
||||||
tomcatManagerPassword);
|
|
||||||
if (hh.getStatus() != 200) {
|
|
||||||
throw newHttpException(hh, "Failed to list Tomcat applications");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is the VIVO application running?
|
CommandRunner runner = new CommandRunner(parms);
|
||||||
boolean running = isVivoRunning(hh.getResponseText());
|
|
||||||
|
|
||||||
if (running) {
|
listener.webappStopping(tomcatStopCommand);
|
||||||
stopTheWebapp();
|
runner.run(parseCommandLine(tomcatStopCommand));
|
||||||
}
|
|
||||||
|
|
||||||
// Be sure that we can start it.
|
int returnCode = runner.getReturnCode();
|
||||||
startTheWebapp();
|
if (returnCode != 0) {
|
||||||
}
|
listener.webappStopFailed(returnCode);
|
||||||
|
throw new CommandRunnerException("Failed to stop Tomcat: code="
|
||||||
/**
|
+ returnCode);
|
||||||
* Tell Tomcat to start the webapp. Check the response.
|
|
||||||
*/
|
|
||||||
public void startTheWebapp() {
|
|
||||||
String startCommand = tomcatManagerUrl + "/start?path=/" + webappName;
|
|
||||||
listener.webappStarting(startCommand);
|
|
||||||
|
|
||||||
HttpHelper hh = new HttpHelper();
|
|
||||||
hh.getPage(startCommand, tomcatManagerUsername, tomcatManagerPassword);
|
|
||||||
|
|
||||||
if ((hh.getStatus() != 200) || (!hh.getResponseText().startsWith("OK"))) {
|
|
||||||
listener.webappStartFailed(hh.getStatus());
|
|
||||||
throw newHttpException(hh, "Failed to start the webapp '"
|
|
||||||
+ webappName + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
listener.webappStarted();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tell Tomcat to stop the webapp. Check the response.
|
|
||||||
*/
|
|
||||||
public void stopTheWebapp() {
|
|
||||||
String stopCommand = tomcatManagerUrl + "/stop?path=/" + webappName;
|
|
||||||
listener.webappStopping(stopCommand);
|
|
||||||
|
|
||||||
HttpHelper hh = new HttpHelper();
|
|
||||||
hh.getPage(stopCommand, tomcatManagerUsername, tomcatManagerPassword);
|
|
||||||
|
|
||||||
if ((hh.getStatus() != 200) || (!hh.getResponseText().startsWith("OK"))) {
|
|
||||||
listener.webappStopFailed(hh.getStatus());
|
|
||||||
throw newHttpException(hh, "Failed to stop the webapp '"
|
|
||||||
+ webappName + "'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
listener.webappStopped();
|
listener.webappStopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the VIVO application listed, and is it running?
|
* Start Tomcat and wait for it to initialize.
|
||||||
*/
|
*/
|
||||||
private boolean isVivoRunning(String responseText) {
|
public void startTheWebapp() throws CommandRunnerException {
|
||||||
boolean found = false;
|
String tomcatStartCommand = properties.getTomcatStartCommand();
|
||||||
boolean running = false;
|
|
||||||
|
|
||||||
BufferedReader r = new BufferedReader(new StringReader(responseText));
|
CommandRunner runner = new CommandRunner(parms);
|
||||||
|
|
||||||
|
listener.webappStarting(tomcatStartCommand);
|
||||||
try {
|
try {
|
||||||
String line;
|
// Stupid Windows won't allow us to start Tomcat as an independent
|
||||||
while (null != (line = r.readLine())) {
|
// process (except if its installed as a service).
|
||||||
Matcher m = PATTERN_WEBAPP_LISTING.matcher(line);
|
runner.run(parseCommandLine(tomcatStartCommand));
|
||||||
if (m.find()) {
|
} catch (CommandRunnerException e) {
|
||||||
if (this.webappName.equals(m.group(1))) {
|
throw new FatalException(e);
|
||||||
found = true;
|
|
||||||
if ("running".equals(m.group(2))) {
|
|
||||||
running = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Can't happen when reading from a string.
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
int returnCode = runner.getReturnCode();
|
||||||
throw new FatalException("Webapp '" + this.webappName
|
if (returnCode != 0) {
|
||||||
+ "' not found in Tomcat's list of webapps: \n"
|
listener.webappStartFailed(returnCode);
|
||||||
+ responseText);
|
throw new CommandRunnerException("Failed to start Tomcat: code="
|
||||||
|
+ returnCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return running;
|
listener.webappStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a {@link FatalException} that contains a bunch of info from the
|
* A command line must be broken into separate arguments, where arguments
|
||||||
* {@link HttpHelper}.
|
* are delimited by blanks unless the blank (and the argument) is enclosed
|
||||||
|
* in quotes.
|
||||||
*/
|
*/
|
||||||
private FatalException newHttpException(HttpHelper hh, String text) {
|
static List<String> parseCommandLine(String commandLine) {
|
||||||
return new FatalException(text + " status is " + hh.getStatus()
|
List<String> pieces = new ArrayList<String>();
|
||||||
+ ", response text is '" + hh.getResponseText() + "'");
|
StringBuilder piece = null;
|
||||||
|
boolean inDelimiter = true;
|
||||||
|
boolean inQuotes = false;
|
||||||
|
for (int i = 0; i < commandLine.length(); i++) {
|
||||||
|
char thisChar = commandLine.charAt(i);
|
||||||
|
if ((thisChar == ' ') && !inQuotes) {
|
||||||
|
if (inDelimiter) {
|
||||||
|
// No effect.
|
||||||
|
} else {
|
||||||
|
inDelimiter = true;
|
||||||
|
pieces.add(piece.toString());
|
||||||
|
}
|
||||||
|
} else if (thisChar == '"') {
|
||||||
|
// Quotes are not carried into the parsed strings.
|
||||||
|
inQuotes = !inQuotes;
|
||||||
|
} else { // Not a blank or a quote.
|
||||||
|
if (inDelimiter) {
|
||||||
|
inDelimiter = false;
|
||||||
|
piece = new StringBuilder();
|
||||||
|
}
|
||||||
|
piece.append(thisChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is an implied delimiter at the end of the command line.
|
||||||
|
if (!inDelimiter) {
|
||||||
|
pieces.add(piece.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quotes must appear in pairs
|
||||||
|
if (inQuotes) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Command line contains mismatched quotes: " + commandLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pieces;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The run is finished. Do we need to do anything?
|
* The run is finished. Do we need to do anything?
|
||||||
*/
|
*/
|
||||||
public void cleanup() {
|
public void cleanup() {
|
||||||
// Leave the webapp running.
|
// Don't need to do anything.
|
||||||
|
|
||||||
|
// If we've been starting and stopping Tomcat,
|
||||||
|
// stop it one more time.
|
||||||
|
if (parms.isCleanModel()) {
|
||||||
|
try {
|
||||||
|
stopTheWebapp();
|
||||||
|
} catch (CommandRunnerException e) {
|
||||||
|
throw new FatalException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,6 @@ public interface Listener {
|
||||||
|
|
||||||
void webappStopFailed(int returnCode);
|
void webappStopFailed(int returnCode);
|
||||||
|
|
||||||
void webappWaitingForStop(int tomcatStopDelay);
|
|
||||||
|
|
||||||
void webappStopped();
|
void webappStopped();
|
||||||
|
|
||||||
void dropDatabaseStarting(String statement);
|
void dropDatabaseStarting(String statement);
|
||||||
|
@ -49,12 +47,16 @@ public interface Listener {
|
||||||
|
|
||||||
void loadDatabaseComplete();
|
void loadDatabaseComplete();
|
||||||
|
|
||||||
void webappStarting(String tomcatStartCommand);
|
void webappCheckingReady(String command);
|
||||||
|
|
||||||
|
void webappCheckReadyFailed(int returnCode);
|
||||||
|
|
||||||
|
void webappCheckedReady();
|
||||||
|
|
||||||
|
void webappStarting(String command);
|
||||||
|
|
||||||
void webappStartFailed(int returnCode);
|
void webappStartFailed(int returnCode);
|
||||||
|
|
||||||
void webappWaitingForStart(int tomcatStartDelay);
|
|
||||||
|
|
||||||
void webappStarted();
|
void webappStarted();
|
||||||
|
|
||||||
void subProcessStart(List<String> command);
|
void subProcessStart(List<String> command);
|
||||||
|
|
|
@ -88,8 +88,23 @@ public class LoggingListener implements Listener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void webappStopping(String tomcatStopCommand) {
|
public void webappCheckingReady(String command) {
|
||||||
log("Stopping tomcat: " + tomcatStopCommand);
|
log("Checking if Tomcat is ready: " + command);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void webappCheckReadyFailed(int returnCode) {
|
||||||
|
log("Tomcat is not ready: " + returnCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void webappCheckedReady() {
|
||||||
|
log("Checked that Tomcat is ready.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void webappStopping(String command) {
|
||||||
|
log("Stopping tomcat: " + command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -97,11 +112,6 @@ public class LoggingListener implements Listener {
|
||||||
log("Failed to stop tomcat; return code was " + returnCode);
|
log("Failed to stop tomcat; return code was " + returnCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void webappWaitingForStop(int tomcatStopDelay) {
|
|
||||||
log("Waiting " + tomcatStopDelay + " seconds for tomcat to stop.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void webappStopped() {
|
public void webappStopped() {
|
||||||
log("Tomcat stopped.");
|
log("Tomcat stopped.");
|
||||||
|
@ -147,11 +157,6 @@ public class LoggingListener implements Listener {
|
||||||
log("Failed to start tomcat; return code was " + returnCode);
|
log("Failed to start tomcat; return code was " + returnCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void webappWaitingForStart(int tomcatStartDelay) {
|
|
||||||
log("Waiting " + tomcatStartDelay + " seconds for tomcat to start.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void webappStarted() {
|
public void webappStarted() {
|
||||||
log("Tomcat started.");
|
log("Tomcat started.");
|
||||||
|
|
|
@ -99,13 +99,6 @@ public class MulticastListener implements Listener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void webappWaitingForStop(int tomcatStopDelay) {
|
|
||||||
for (Listener l : listeners) {
|
|
||||||
l.webappWaitingForStop(tomcatStopDelay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void webappStopped() {
|
public void webappStopped() {
|
||||||
for (Listener l : listeners) {
|
for (Listener l : listeners) {
|
||||||
|
@ -155,6 +148,27 @@ public class MulticastListener implements Listener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void webappCheckingReady(String command) {
|
||||||
|
for (Listener l : listeners) {
|
||||||
|
l.webappCheckingReady(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void webappCheckReadyFailed(int returnCode) {
|
||||||
|
for (Listener l : listeners) {
|
||||||
|
l.webappCheckReadyFailed(returnCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void webappCheckedReady() {
|
||||||
|
for (Listener l : listeners) {
|
||||||
|
l.webappCheckedReady();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void webappStarting(String tomcatStartCommand) {
|
public void webappStarting(String tomcatStartCommand) {
|
||||||
for (Listener l : listeners) {
|
for (Listener l : listeners) {
|
||||||
|
@ -169,13 +183,6 @@ public class MulticastListener implements Listener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void webappWaitingForStart(int tomcatStartDelay) {
|
|
||||||
for (Listener l : listeners) {
|
|
||||||
l.webappWaitingForStart(tomcatStartDelay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void webappStarted() {
|
public void webappStarted() {
|
||||||
for (Listener l : listeners) {
|
for (Listener l : listeners) {
|
||||||
|
|
|
@ -205,6 +205,18 @@ public class OutputDataListener implements Listener {
|
||||||
public void cleanOutputStop(File outputDirectory) {
|
public void cleanOutputStop(File outputDirectory) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void webappCheckingReady(String command) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void webappCheckReadyFailed(int returnCode) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void webappCheckedReady() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void webappStopping(String tomcatStopCommand) {
|
public void webappStopping(String tomcatStopCommand) {
|
||||||
}
|
}
|
||||||
|
@ -213,10 +225,6 @@ public class OutputDataListener implements Listener {
|
||||||
public void webappStopFailed(int returnCode) {
|
public void webappStopFailed(int returnCode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void webappWaitingForStop(int tomcatStopDelay) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void webappStopped() {
|
public void webappStopped() {
|
||||||
}
|
}
|
||||||
|
@ -253,10 +261,6 @@ public class OutputDataListener implements Listener {
|
||||||
public void webappStartFailed(int returnCode) {
|
public void webappStartFailed(int returnCode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void webappWaitingForStart(int tomcatStartDelay) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void webappStarted() {
|
public void webappStarted() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ public class OutputManager {
|
||||||
* output file.
|
* output file.
|
||||||
*/
|
*/
|
||||||
public void summarizeOutput(DataModel dataModel) {
|
public void summarizeOutput(DataModel dataModel) {
|
||||||
|
try {
|
||||||
LogStats log = LogStats.parse(parms.getLogFile());
|
LogStats log = LogStats.parse(parms.getLogFile());
|
||||||
|
|
||||||
List<SuiteResults> suiteResults = new ArrayList<SuiteResults>();
|
List<SuiteResults> suiteResults = new ArrayList<SuiteResults>();
|
||||||
|
@ -80,6 +81,11 @@ public class OutputManager {
|
||||||
|
|
||||||
OutputSummaryFormatter formatter = new OutputSummaryFormatter(parms);
|
OutputSummaryFormatter formatter = new OutputSummaryFormatter(parms);
|
||||||
formatter.format(log, dataModel);
|
formatter.format(log, dataModel);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// It must be impossible to throw an exception from here, so just
|
||||||
|
// print it to sysout.
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class HtmlFileFilter implements FileFilter {
|
private static class HtmlFileFilter implements FileFilter {
|
||||||
|
|
|
@ -271,7 +271,7 @@ public class OutputSummaryFormatter {
|
||||||
|
|
||||||
w.println(" <div class=section>Ignored</div>");
|
w.println(" <div class=section>Ignored</div>");
|
||||||
w.println();
|
w.println();
|
||||||
w.println(" <table cellspacing=\"0\">");
|
w.println(" <table class=\"ignored\" cellspacing=\"0\">");
|
||||||
w.println(" <tr><th>Suite name</th><th>Test name</th>"
|
w.println(" <tr><th>Suite name</th><th>Test name</th>"
|
||||||
+ "<th>Reason for ignoring</th></tr>\n");
|
+ "<th>Reason for ignoring</th></tr>\n");
|
||||||
if (ignoredTests.isEmpty()) {
|
if (ignoredTests.isEmpty()) {
|
||||||
|
@ -297,7 +297,7 @@ public class OutputSummaryFormatter {
|
||||||
|
|
||||||
private void writeFooter(PrintWriter w) {
|
private void writeFooter(PrintWriter w) {
|
||||||
w.println(" <div class=section>Log</div>");
|
w.println(" <div class=section>Log</div>");
|
||||||
w.println(" <pre>");
|
w.println(" <pre class=\"log\">");
|
||||||
|
|
||||||
Reader reader = null;
|
Reader reader = null;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -104,3 +104,12 @@ table.condensed div.test div.tReason{
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
padding: 3px 3px 3px 10px;
|
padding: 3px 3px 3px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table.ignored td {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.log {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
|
@ -1,141 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.utilities.testrunner.tomcat;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
|
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
|
||||||
import org.apache.commons.httpclient.HttpMethod;
|
|
||||||
import org.apache.commons.httpclient.UsernamePasswordCredentials;
|
|
||||||
import org.apache.commons.httpclient.auth.AuthScope;
|
|
||||||
import org.apache.commons.httpclient.auth.BasicScheme;
|
|
||||||
import org.apache.commons.httpclient.cookie.CookiePolicy;
|
|
||||||
import org.apache.commons.httpclient.methods.GetMethod;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.utilities.testrunner.FileHelper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO
|
|
||||||
*/
|
|
||||||
public class HttpHelper {
|
|
||||||
private String responseText;
|
|
||||||
private int status = -1;
|
|
||||||
private Throwable exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the page at the specified URL, and set the response text and status.
|
|
||||||
*/
|
|
||||||
public boolean getPage(String url) {
|
|
||||||
this.responseText = null;
|
|
||||||
this.status = -1;
|
|
||||||
this.exception = null;
|
|
||||||
|
|
||||||
HttpClient httpClient = new HttpClient();
|
|
||||||
HttpMethod method = new GetMethod(url);
|
|
||||||
Reader reader = null;
|
|
||||||
try {
|
|
||||||
method.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
|
|
||||||
method.getParams().setSoTimeout(60000);
|
|
||||||
|
|
||||||
httpClient.executeMethod(method);
|
|
||||||
|
|
||||||
this.status = method.getStatusCode();
|
|
||||||
|
|
||||||
reader = new InputStreamReader(method.getResponseBodyAsStream(),
|
|
||||||
Charset.forName("UTF-8"));
|
|
||||||
this.responseText = FileHelper.readAll(reader);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
this.exception = e;
|
|
||||||
return false;
|
|
||||||
} finally {
|
|
||||||
method.releaseConnection();
|
|
||||||
if (reader != null) {
|
|
||||||
try {
|
|
||||||
reader.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the page at the specified URL, performing authentication with the
|
|
||||||
* specified username and password, and set the response text and status.
|
|
||||||
*/
|
|
||||||
public boolean getPage(String url, String username, String password) {
|
|
||||||
responseText = null;
|
|
||||||
status = -1;
|
|
||||||
this.exception = null;
|
|
||||||
|
|
||||||
HttpClient httpClient = new HttpClient();
|
|
||||||
httpClient.getState().setCredentials(new AuthScope(null, -1, null, "basic"),
|
|
||||||
new UsernamePasswordCredentials(username, password));
|
|
||||||
|
|
||||||
HttpMethod method = new GetMethod(url);
|
|
||||||
|
|
||||||
Reader reader = null;
|
|
||||||
try {
|
|
||||||
method.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
|
|
||||||
method.getParams().setSoTimeout(60000);
|
|
||||||
|
|
||||||
httpClient.executeMethod(method);
|
|
||||||
|
|
||||||
this.status = method.getStatusCode();
|
|
||||||
|
|
||||||
reader = new InputStreamReader(method.getResponseBodyAsStream(),
|
|
||||||
Charset.forName("UTF-8"));
|
|
||||||
responseText = FileHelper.readAll(reader);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
this.exception = e;
|
|
||||||
return false;
|
|
||||||
} finally {
|
|
||||||
method.releaseConnection();
|
|
||||||
if (reader != null) {
|
|
||||||
try {
|
|
||||||
reader.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getResponseText() {
|
|
||||||
return responseText;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Throwable getException() {
|
|
||||||
return exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HttpHelperException extends Exception {
|
|
||||||
|
|
||||||
public HttpHelperException() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHelperException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHelperException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpHelperException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue