NIHVIVO-222 Use the OWL file of the test user model instead of a MySQL dump.
Embed the OWL file in the source, so we don't need to configure it. Break out a separate TomcatController class.
This commit is contained in:
parent
60444bb7f8
commit
99c70b5d66
7 changed files with 294 additions and 161 deletions
|
@ -193,6 +193,10 @@ public class Listener {
|
||||||
log("Upload cleaning stopped: " + uploadDirectory.getPath());
|
log("Upload cleaning stopped: " + uploadDirectory.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void logWarning(String message) {
|
||||||
|
log("WARNING: " + message);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Helper methods
|
// Helper methods
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -11,14 +13,18 @@ import java.util.List;
|
||||||
* test suite.
|
* test suite.
|
||||||
*/
|
*/
|
||||||
public class ModelCleaner {
|
public class ModelCleaner {
|
||||||
|
public static final String TEST_USER_ONTOLOGY_FILENAME = "test-user-model.owl";
|
||||||
private final ModelCleanerProperties properties;
|
private final ModelCleanerProperties properties;
|
||||||
|
private final TomcatController tomcatController;
|
||||||
private final CommandRunner runner;
|
private final CommandRunner runner;
|
||||||
private final Listener listener;
|
private final Listener listener;
|
||||||
|
|
||||||
public ModelCleaner(SeleniumRunnerParameters parms) {
|
public ModelCleaner(SeleniumRunnerParameters parms,
|
||||||
|
TomcatController tomcatController) {
|
||||||
this.properties = parms.getModelCleanerProperties();
|
this.properties = parms.getModelCleanerProperties();
|
||||||
this.listener = parms.getListener();
|
this.listener = parms.getListener();
|
||||||
this.runner = new CommandRunner(parms);
|
this.runner = new CommandRunner(parms);
|
||||||
|
this.tomcatController = tomcatController;
|
||||||
|
|
||||||
sanityCheck();
|
sanityCheck();
|
||||||
}
|
}
|
||||||
|
@ -42,42 +48,39 @@ public class ModelCleaner {
|
||||||
* if a problem occurs in a sub-process.
|
* if a problem occurs in a sub-process.
|
||||||
*/
|
*/
|
||||||
public void clean() throws CommandRunnerException {
|
public void clean() throws CommandRunnerException {
|
||||||
stopTheWebapp();
|
tomcatController.stopTheWebapp();
|
||||||
dropDatabase();
|
insertTheUserFile();
|
||||||
createAndLoadDatabase();
|
recreateTheDatabase();
|
||||||
startTheWebapp();
|
tomcatController.startTheWebapp();
|
||||||
|
removeTheUserFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop Tomcat and wait the prescribed number of seconds for it to clean up.
|
* Copy the test data ontology file into the auth area, so we get our
|
||||||
|
* pre-defined admin user.
|
||||||
*/
|
*/
|
||||||
public void stopTheWebapp() throws CommandRunnerException {
|
private void insertTheUserFile() {
|
||||||
String tomcatStopCommand = properties.getTomcatStopCommand();
|
InputStream userOntologyStream = this.getClass().getResourceAsStream(
|
||||||
int tomcatStopDelay = properties.getTomcatStopDelay();
|
TEST_USER_ONTOLOGY_FILENAME);
|
||||||
|
if (userOntologyStream == null) {
|
||||||
listener.webappStopping(tomcatStopCommand);
|
throw new FatalException(
|
||||||
runner.run(parseCommandLine(tomcatStopCommand));
|
"Couldn't find the Test User Ontology file: '"
|
||||||
|
+ TEST_USER_ONTOLOGY_FILENAME + "'");
|
||||||
int returnCode = runner.getReturnCode();
|
|
||||||
if (returnCode != 0) {
|
|
||||||
listener.webappStopFailed(returnCode);
|
|
||||||
// Throw no exception - this can happen if Tomcat isn't running.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
listener.webappWaitingForStop(tomcatStopDelay);
|
File userOntologyTarget = figureUserOntologyTarget();
|
||||||
try {
|
try {
|
||||||
Thread.sleep(tomcatStopDelay * 1000L);
|
FileHelper.copy(userOntologyStream, userOntologyTarget);
|
||||||
} catch (InterruptedException e) {
|
userOntologyStream.close();
|
||||||
// Just continue.
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
listener.webappStopped();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the database.
|
* Drop the database and create it again, empty.
|
||||||
*/
|
*/
|
||||||
private void dropDatabase() {
|
private void recreateTheDatabase() {
|
||||||
String mysqlStatement = "drop database " + properties.getMysqlDbName()
|
String mysqlStatement = "drop database " + properties.getMysqlDbName()
|
||||||
+ "; create database " + properties.getMysqlDbName()
|
+ "; create database " + properties.getMysqlDbName()
|
||||||
+ " character set utf8;";
|
+ " character set utf8;";
|
||||||
|
@ -96,54 +99,15 @@ public class ModelCleaner {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rebuild the database.
|
* Remove the test data ontology file, so we leave no trace.
|
||||||
*/
|
*/
|
||||||
private void createAndLoadDatabase() {
|
private void removeTheUserFile() {
|
||||||
String mysqlStatement = "source "
|
File userOntologyTarget = figureUserOntologyTarget();
|
||||||
+ convertBackslashes(properties.getMysqlDumpfile()) + ";";
|
userOntologyTarget.delete();
|
||||||
|
if (userOntologyTarget.exists()) {
|
||||||
listener.loadDatabaseStarting(mysqlStatement);
|
listener.logWarning("Failed to delete the test data ontology "
|
||||||
executeMysqlStatement(mysqlStatement);
|
+ "file: '" + TEST_USER_ONTOLOGY_FILENAME + "'");
|
||||||
|
|
||||||
int returnCode = runner.getReturnCode();
|
|
||||||
if (returnCode != 0) {
|
|
||||||
listener.loadDatabaseFailed(returnCode);
|
|
||||||
throw new FatalException("loadDatabase() failed: return code="
|
|
||||||
+ returnCode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
listener.loadDatabaseComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start Tomcat and wait for it to initialize.
|
|
||||||
*/
|
|
||||||
private void startTheWebapp() {
|
|
||||||
String tomcatStartCommand = properties.getTomcatStartCommand();
|
|
||||||
int tomcatStartDelay = properties.getTomcatStartDelay();
|
|
||||||
|
|
||||||
listener.webappStarting(tomcatStartCommand);
|
|
||||||
try {
|
|
||||||
runner.runAsBackground(parseCommandLine(tomcatStartCommand));
|
|
||||||
} catch (CommandRunnerException e) {
|
|
||||||
throw new FatalException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
int returnCode = runner.getReturnCode();
|
|
||||||
if (returnCode != 0) {
|
|
||||||
listener.webappStartFailed(returnCode);
|
|
||||||
throw new FatalException("startTheWebapp() failed: return code="
|
|
||||||
+ returnCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
listener.webappWaitingForStart(tomcatStartDelay);
|
|
||||||
try {
|
|
||||||
Thread.sleep(tomcatStartDelay * 1000L);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// Just continue.
|
|
||||||
}
|
|
||||||
|
|
||||||
listener.webappStarted();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -166,48 +130,23 @@ public class ModelCleaner {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A command line must be broken into separate arguments, where arguments
|
* Figure out where the test data ontology file should go. C:\Program
|
||||||
* are delimited by blanks unless the blank (and the argument) is enclosed
|
* Files\Apache Software Foundation\Tomcat
|
||||||
* in quotes.
|
* 6.0\webapps\vivo\WEB-INF\ontologies\auth
|
||||||
*/
|
*/
|
||||||
static List<String> parseCommandLine(String commandLine) {
|
private File figureUserOntologyTarget() {
|
||||||
List<String> pieces = new ArrayList<String>();
|
File webappDirectory = properties.getWebappDirectory();
|
||||||
StringBuilder piece = null;
|
File authDirectory = new File(webappDirectory,
|
||||||
boolean inDelimiter = true;
|
"WEB-INF/ontologies/auth");
|
||||||
boolean inQuotes = false;
|
|
||||||
for (int i = 0; i < commandLine.length(); i++) {
|
if (!authDirectory.exists()) {
|
||||||
char thisChar = commandLine.charAt(i);
|
throw new FatalException("Target directory for the test data "
|
||||||
if ((thisChar == ' ') && !inQuotes) {
|
+ "ontology file doesn't exist. Webapp directory is '"
|
||||||
if (inDelimiter) {
|
+ webappDirectory + "', target directory is '"
|
||||||
// No effect.
|
+ authDirectory + "'");
|
||||||
} 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.
|
return new File(authDirectory, TEST_USER_ONTOLOGY_FILENAME);
|
||||||
if (!inDelimiter) {
|
|
||||||
pieces.add(piece.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quotes must appear in pairs
|
|
||||||
if (inQuotes) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Command line contains mismatched quotes: " + commandLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pieces;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static String convertBackslashes(File file) {
|
static String convertBackslashes(File file) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class ModelCleanerProperties {
|
||||||
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_MYSQL_DUMPFILE = "mysql_dumpfile";
|
public static final String PROP_WEBAPP_DIRECTORY = "vivo_webapp_directory";
|
||||||
|
|
||||||
private final String tomcatStartCommand;
|
private final String tomcatStartCommand;
|
||||||
private final int tomcatStartDelay;
|
private final int tomcatStartDelay;
|
||||||
|
@ -26,7 +26,7 @@ public class ModelCleanerProperties {
|
||||||
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 mysqlDumpfile;
|
private final File webappDirectory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirm that we have the expected properties, and that their values seem
|
* Confirm that we have the expected properties, and that their values seem
|
||||||
|
@ -47,7 +47,7 @@ public class ModelCleanerProperties {
|
||||||
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.mysqlDumpfile = confirmDumpfile(props);
|
this.webappDirectory = confirmWebappDirectory(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTomcatStartCommand() {
|
public String getTomcatStartCommand() {
|
||||||
|
@ -78,8 +78,8 @@ public class ModelCleanerProperties {
|
||||||
return mysqlDbName;
|
return mysqlDbName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getMysqlDumpfile() {
|
public File getWebappDirectory() {
|
||||||
return mysqlDumpfile;
|
return webappDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -106,33 +106,38 @@ public class ModelCleanerProperties {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The dumpfile parameter must point to an existing file.
|
* The dumpfile parameter must point to an existing directory.
|
||||||
*/
|
*/
|
||||||
private File confirmDumpfile(Properties props) {
|
private File confirmWebappDirectory(Properties props) {
|
||||||
String filename = getRequiredProperty(props, PROP_MYSQL_DUMPFILE);
|
String filename = getRequiredProperty(props, PROP_WEBAPP_DIRECTORY);
|
||||||
File dumpfile = new File(filename);
|
File webappDirectory = new File(filename);
|
||||||
if (!dumpfile.exists()) {
|
if (!webappDirectory.exists()) {
|
||||||
throw new IllegalArgumentException("Invalid value for '"
|
throw new IllegalArgumentException("Invalid value for '"
|
||||||
+ PROP_MYSQL_DUMPFILE + "': file '" + filename
|
+ PROP_WEBAPP_DIRECTORY + "': directory '" + filename
|
||||||
+ "' does not exist.");
|
+ "' does not exist.");
|
||||||
}
|
}
|
||||||
if (!dumpfile.isFile()) {
|
if (!webappDirectory.isDirectory()) {
|
||||||
throw new IllegalArgumentException("Invalid value for '"
|
throw new IllegalArgumentException("Invalid value for '"
|
||||||
+ PROP_MYSQL_DUMPFILE + "': '" + filename
|
+ PROP_WEBAPP_DIRECTORY + "': '" + filename
|
||||||
+ "' is not a file.");
|
+ "' is not a directory.");
|
||||||
}
|
}
|
||||||
if (!dumpfile.canRead()) {
|
if (!webappDirectory.canWrite()) {
|
||||||
throw new IllegalArgumentException("Invalid value for '"
|
throw new IllegalArgumentException("Invalid value for '"
|
||||||
+ PROP_MYSQL_DUMPFILE + "': file '" + filename
|
+ PROP_WEBAPP_DIRECTORY + "': directory '" + filename
|
||||||
+ "' is not readable.");
|
+ "' is not writeable.");
|
||||||
}
|
}
|
||||||
return dumpfile;
|
return webappDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "\n tomcatStartCommand: " + tomcatStartCommand
|
return "\n tomcatStartCommand: " + tomcatStartCommand
|
||||||
+ "\n tomcatStartDelay: " + tomcatStartDelay
|
+ "\n tomcatStartDelay: " + tomcatStartDelay
|
||||||
+ "\n tomcatStopCommand: " + tomcatStopCommand
|
+ "\n tomcatStopCommand: " + tomcatStopCommand
|
||||||
+ "\n tomcatStopDelay: " + tomcatStopDelay;
|
+ "\n tomcatStopDelay: " + tomcatStopDelay
|
||||||
|
+ "\n mysqlUsername: " + mysqlUsername
|
||||||
|
+ "\n mysqlPassword: " + mysqlPassword
|
||||||
|
+ "\n mysqlDbName: " + mysqlDbName
|
||||||
|
+ "\n webappDirectory: " + webappDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ public class SeleniumRunner {
|
||||||
private final SeleniumRunnerParameters parms;
|
private final SeleniumRunnerParameters parms;
|
||||||
private final Listener listener;
|
private final Listener listener;
|
||||||
private final UploadAreaCleaner uploadCleaner;
|
private final UploadAreaCleaner uploadCleaner;
|
||||||
|
private final TomcatController tomcatController;
|
||||||
private final ModelCleaner modelCleaner;
|
private final ModelCleaner modelCleaner;
|
||||||
private final SuiteRunner suiteRunner;
|
private final SuiteRunner suiteRunner;
|
||||||
private final OutputManager outputManager;
|
private final OutputManager outputManager;
|
||||||
|
@ -25,16 +26,45 @@ public class SeleniumRunner {
|
||||||
this.parms = parms;
|
this.parms = parms;
|
||||||
this.listener = parms.getListener();
|
this.listener = parms.getListener();
|
||||||
this.uploadCleaner = new UploadAreaCleaner(parms);
|
this.uploadCleaner = new UploadAreaCleaner(parms);
|
||||||
this.modelCleaner = new ModelCleaner(parms);
|
this.tomcatController = new TomcatController(parms);
|
||||||
|
this.modelCleaner = new ModelCleaner(parms, this.tomcatController);
|
||||||
this.suiteRunner = new SuiteRunner(parms);
|
this.suiteRunner = new SuiteRunner(parms);
|
||||||
this.outputManager = new OutputManager(parms);
|
this.outputManager = new OutputManager(parms);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean runSelectedSuites() {
|
/**
|
||||||
|
* Set up the run, run the selected suites, summarize the output, and clean
|
||||||
|
* up afterwards.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> iff all tests passed.
|
||||||
|
*/
|
||||||
|
public boolean run() {
|
||||||
boolean success;
|
boolean success;
|
||||||
try {
|
try {
|
||||||
listener.runStarted();
|
listener.runStarted();
|
||||||
outputManager.cleanOutputDirectory();
|
outputManager.cleanOutputDirectory();
|
||||||
|
|
||||||
|
runSelectedSuites();
|
||||||
|
tomcatController.cleanup();
|
||||||
|
|
||||||
|
listener.runEndTime();
|
||||||
|
Status status = outputManager.summarizeOutput();
|
||||||
|
success = (status == Status.OK);
|
||||||
|
} catch (IOException e) {
|
||||||
|
listener.runFailed(e);
|
||||||
|
success = false;
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (FatalException e) {
|
||||||
|
listener.runFailed(e);
|
||||||
|
success = false;
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
listener.runStopped();
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runSelectedSuites() {
|
||||||
for (File suiteDir : parms.getSelectedSuites()) {
|
for (File suiteDir : parms.getSelectedSuites()) {
|
||||||
listener.suiteStarted(suiteDir);
|
listener.suiteStarted(suiteDir);
|
||||||
try {
|
try {
|
||||||
|
@ -52,31 +82,6 @@ public class SeleniumRunner {
|
||||||
}
|
}
|
||||||
listener.suiteStopped(suiteDir);
|
listener.suiteStopped(suiteDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we've been starting and stopping Tomcat,
|
|
||||||
// stop it one more time.
|
|
||||||
if (parms.isCleanModel()) {
|
|
||||||
try {
|
|
||||||
modelCleaner.stopTheWebapp();
|
|
||||||
} catch (CommandRunnerException e) {
|
|
||||||
throw new FatalException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
listener.runEndTime();
|
|
||||||
Status status = outputManager.summarizeOutput();
|
|
||||||
success = (status == Status.OK);
|
|
||||||
} catch (IOException e) {
|
|
||||||
listener.runFailed(e);
|
|
||||||
success = false;
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (FatalException e) {
|
|
||||||
listener.runFailed(e);
|
|
||||||
success = false;
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
listener.runStopped();
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void selectAllSuites(SeleniumRunnerParameters parms) {
|
private static void selectAllSuites(SeleniumRunnerParameters parms) {
|
||||||
|
@ -145,7 +150,7 @@ public class SeleniumRunner {
|
||||||
System.out.println(parms);
|
System.out.println(parms);
|
||||||
|
|
||||||
SeleniumRunner runner = new SeleniumRunner(parms);
|
SeleniumRunner runner = new SeleniumRunner(parms);
|
||||||
success = runner.runSelectedSuites();
|
success = runner.run();
|
||||||
}
|
}
|
||||||
System.out.println("Exiting SeleniumRunner");
|
System.out.println("Exiting SeleniumRunner");
|
||||||
System.exit(success ? 0 : -1);
|
System.exit(success ? 0 : -1);
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start and stop the webapp, so we can clean the database.
|
||||||
|
*/
|
||||||
|
public class TomcatController {
|
||||||
|
private final SeleniumRunnerParameters parms;
|
||||||
|
private final ModelCleanerProperties properties;
|
||||||
|
private final Listener listener;
|
||||||
|
|
||||||
|
public TomcatController(SeleniumRunnerParameters parms) {
|
||||||
|
this.parms = parms;
|
||||||
|
this.properties = parms.getModelCleanerProperties();
|
||||||
|
this.listener = parms.getListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop Tomcat and wait the prescribed number of seconds for it to clean up.
|
||||||
|
*/
|
||||||
|
public void stopTheWebapp() throws CommandRunnerException {
|
||||||
|
String tomcatStopCommand = properties.getTomcatStopCommand();
|
||||||
|
int tomcatStopDelay = properties.getTomcatStopDelay();
|
||||||
|
|
||||||
|
CommandRunner runner = new CommandRunner(parms);
|
||||||
|
|
||||||
|
listener.webappStopping(tomcatStopCommand);
|
||||||
|
runner.run(parseCommandLine(tomcatStopCommand));
|
||||||
|
|
||||||
|
int returnCode = runner.getReturnCode();
|
||||||
|
if (returnCode != 0) {
|
||||||
|
listener.webappStopFailed(returnCode);
|
||||||
|
// Throw no exception - this can happen if Tomcat isn't running.
|
||||||
|
}
|
||||||
|
|
||||||
|
listener.webappWaitingForStop(tomcatStopDelay);
|
||||||
|
try {
|
||||||
|
Thread.sleep(tomcatStopDelay * 1000L);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// Just continue.
|
||||||
|
}
|
||||||
|
|
||||||
|
listener.webappStopped();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start Tomcat and wait for it to initialize.
|
||||||
|
*/
|
||||||
|
public void startTheWebapp() {
|
||||||
|
String tomcatStartCommand = properties.getTomcatStartCommand();
|
||||||
|
int tomcatStartDelay = properties.getTomcatStartDelay();
|
||||||
|
|
||||||
|
CommandRunner runner = new CommandRunner(parms);
|
||||||
|
|
||||||
|
listener.webappStarting(tomcatStartCommand);
|
||||||
|
try {
|
||||||
|
runner.runAsBackground(parseCommandLine(tomcatStartCommand));
|
||||||
|
} catch (CommandRunnerException e) {
|
||||||
|
throw new FatalException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can't check the return code because the process shouldn't end.
|
||||||
|
|
||||||
|
listener.webappWaitingForStart(tomcatStartDelay);
|
||||||
|
try {
|
||||||
|
Thread.sleep(tomcatStartDelay * 1000L);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// Just continue.
|
||||||
|
}
|
||||||
|
|
||||||
|
listener.webappStarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A command line must be broken into separate arguments, where arguments
|
||||||
|
* are delimited by blanks unless the blank (and the argument) is enclosed
|
||||||
|
* in quotes.
|
||||||
|
*/
|
||||||
|
static List<String> parseCommandLine(String commandLine) {
|
||||||
|
List<String> pieces = new ArrayList<String>();
|
||||||
|
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?
|
||||||
|
*/
|
||||||
|
public void cleanup() {
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
|
||||||
|
xmlns:owl="http://www.w3.org/2002/07/owl#"
|
||||||
|
xmlns:vitro="http://vitro.mannlib.cornell.edu/ns/vitro/0.7#"
|
||||||
|
xmlns="http://vitro.mannlib.cornell.edu/ns/vitro/default#"
|
||||||
|
xml:base="http://vitro.mannlib.cornell.edu/ns/vitro/default">
|
||||||
|
|
||||||
|
<vitro:User rdf:about="#defaultAdminUser">
|
||||||
|
<vitro:username rdf:datatype="http://www.w3.org/2001/XMLSchema#string">testAdmin</vitro:username>
|
||||||
|
<vitro:md5password rdf:datatype="http://www.w3.org/2001/XMLSchema#string">DC647EB65E6711E155375218212B3964</vitro:md5password>
|
||||||
|
<vitro:roleURI rdf:datatype="http://www.w3.org/2001/XMLSchema#string">role:/50</vitro:roleURI>
|
||||||
|
<vitro:firstTime rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-03-09T16:06:45</vitro:firstTime>
|
||||||
|
<vitro:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</vitro:loginCount>
|
||||||
|
</vitro:User>
|
||||||
|
|
||||||
|
<vitro:User rdf:about="http://vivo.mydomain.edu/individual/JoeUser">
|
||||||
|
<vitro:username rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Joe User</vitro:username>
|
||||||
|
<vitro:md5password rdf:datatype="http://www.w3.org/2001/XMLSchema#string">8A1A62B7B58B8B95564483BEA60CD99A</vitro:md5password>
|
||||||
|
<vitro:roleURI rdf:datatype="http://www.w3.org/2001/XMLSchema#string">role:/1</vitro:roleURI>
|
||||||
|
<vitro:firstTime rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-03-09T16:06:45</vitro:firstTime>
|
||||||
|
<vitro:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</vitro:loginCount>
|
||||||
|
</vitro:User>
|
||||||
|
|
||||||
|
<vitro:User rdf:about="http://vivo.mydomain.edu/individual/SallyEditor">
|
||||||
|
<vitro:username rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Sally Editor</vitro:username>
|
||||||
|
<vitro:md5password rdf:datatype="http://www.w3.org/2001/XMLSchema#string">8A1A62B7B58B8B95564483BEA60CD99A</vitro:md5password>
|
||||||
|
<vitro:roleURI rdf:datatype="http://www.w3.org/2001/XMLSchema#string">role:/4</vitro:roleURI>
|
||||||
|
<vitro:firstTime rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-03-09T16:06:45</vitro:firstTime>
|
||||||
|
<vitro:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</vitro:loginCount>
|
||||||
|
</vitro:User>
|
||||||
|
|
||||||
|
<vitro:User rdf:about="http://vivo.mydomain.edu/individual/JohnCurator">
|
||||||
|
<vitro:username rdf:datatype="http://www.w3.org/2001/XMLSchema#string">John Curator</vitro:username>
|
||||||
|
<vitro:md5password rdf:datatype="http://www.w3.org/2001/XMLSchema#string">8A1A62B7B58B8B95564483BEA60CD99A</vitro:md5password>
|
||||||
|
<vitro:roleURI rdf:datatype="http://www.w3.org/2001/XMLSchema#string">role:/5</vitro:roleURI>
|
||||||
|
<vitro:firstTime rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">2010-03-09T16:06:45</vitro:firstTime>
|
||||||
|
<vitro:loginCount rdf:datatype="http://www.w3.org/2001/XMLSchema#int">1</vitro:loginCount>
|
||||||
|
</vitro:User>
|
||||||
|
|
||||||
|
</rdf:RDF>
|
|
@ -11,7 +11,7 @@ import org.junit.Test;
|
||||||
/**
|
/**
|
||||||
* TODO
|
* TODO
|
||||||
*/
|
*/
|
||||||
public class ModelCleanerTest {
|
public class TomcatControllerTest {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Tests for parseCommandLine()
|
// Tests for parseCommandLine()
|
||||||
|
@ -45,7 +45,7 @@ public class ModelCleanerTest {
|
||||||
|
|
||||||
private void assertExpectedParsing(String commandLine,
|
private void assertExpectedParsing(String commandLine,
|
||||||
String... expectedPieces) {
|
String... expectedPieces) {
|
||||||
assertEquals("parse", Arrays.asList(expectedPieces), ModelCleaner
|
assertEquals("parse", Arrays.asList(expectedPieces),
|
||||||
.parseCommandLine(commandLine));
|
TomcatController.parseCommandLine(commandLine));
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue