NIHVIVO-222 Second step at coding the Java-based SeleniumRunner.
This commit is contained in:
parent
1c5e7fdde8
commit
92f9280af0
11 changed files with 908 additions and 176 deletions
|
@ -34,12 +34,12 @@ public class CommandRunner {
|
|||
private File workingDirectory;
|
||||
|
||||
/* Gets informed of output as it arrives. Never null. */
|
||||
private final Logger logger;
|
||||
private final Listener listener;
|
||||
|
||||
private final Map<String, String> environmentAdditions = new HashMap<String, String>();
|
||||
|
||||
public CommandRunner(SeleniumRunnerParameters parms) {
|
||||
this.logger = parms.getLogger();
|
||||
this.listener = parms.getListener();
|
||||
}
|
||||
|
||||
/** Set the directory that the command will run in. */
|
||||
|
@ -61,7 +61,7 @@ public class CommandRunner {
|
|||
* {@link java.lang.ProcessBuilder#ProcessBuilder(List)}.
|
||||
*/
|
||||
public void run(List<String> command) throws CommandRunnerException {
|
||||
logger.subProcessStart(command);
|
||||
listener.subProcessStart(command);
|
||||
try {
|
||||
ProcessBuilder builder = new ProcessBuilder(command);
|
||||
|
||||
|
@ -93,7 +93,43 @@ public class CommandRunner {
|
|||
throw new CommandRunnerException(
|
||||
"Exception when handling sub-process:", e);
|
||||
}
|
||||
logger.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();
|
||||
StreamEater outputEater = new StreamEater(process.getInputStream(),
|
||||
false);
|
||||
StreamEater errorEater = new StreamEater(process.getErrorStream(),
|
||||
true);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new CommandRunnerException(
|
||||
"Exception when handling sub-process:", e);
|
||||
}
|
||||
}
|
||||
|
||||
public int getReturnCode() {
|
||||
|
@ -136,11 +172,11 @@ public class CommandRunner {
|
|||
if (howMany > 0) {
|
||||
String string = new String(buffer, 0, howMany);
|
||||
contents.write(string);
|
||||
|
||||
|
||||
if (isError) {
|
||||
logger.subProcessErrout(string);
|
||||
listener.subProcessErrout(string);
|
||||
} else {
|
||||
logger.subProcessStdout(string);
|
||||
listener.subProcessStdout(string);
|
||||
}
|
||||
} else if (howMany == 0) {
|
||||
Thread.yield();
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
||||
|
||||
/**
|
||||
* Indicates a problem so severe that we might as well stop now.
|
||||
*/
|
||||
public class FatalException extends RuntimeException {
|
||||
|
||||
public FatalException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public FatalException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public FatalException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public FatalException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Writer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A listener for all events that occur during the run. In this basic
|
||||
* implementation, each event is simply formatted and written to a log file or
|
||||
* {@link PrintStream}.
|
||||
*/
|
||||
public class Listener {
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
|
||||
"yyyy-MM-dd HH:mm:ss.SSS");
|
||||
|
||||
private final Writer writer;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Listener methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public Listener(PrintStream out) {
|
||||
this.writer = new OutputStreamWriter(out);
|
||||
}
|
||||
|
||||
public Listener(File logFile) throws IOException {
|
||||
this.writer = new FileWriter(logFile);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Listener methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public void runStarted() {
|
||||
log("Run started.");
|
||||
}
|
||||
|
||||
public void runFailed(Exception e) {
|
||||
log("Run failed - fatal error");
|
||||
log(e);
|
||||
}
|
||||
|
||||
public void runStopped() {
|
||||
log("Run stopped.");
|
||||
}
|
||||
|
||||
public void webappStopping(String tomcatStopCommand) {
|
||||
log("Stopping tomcat: " + tomcatStopCommand);
|
||||
}
|
||||
|
||||
public void webappStopFailed(int returnCode) {
|
||||
log("Failed to stop tomcat; return code was " + returnCode);
|
||||
}
|
||||
|
||||
public void webappWaitingForStop(int tomcatStopDelay) {
|
||||
log("Waiting " + tomcatStopDelay + " seconds for tomcat to stop.");
|
||||
}
|
||||
|
||||
public void webappStopped() {
|
||||
log("Tomcat stopped.");
|
||||
}
|
||||
|
||||
public void dropDatabaseStarting(String statement) {
|
||||
log("Dropping database: " + statement);
|
||||
}
|
||||
|
||||
public void dropDatabaseFailed(int returnCode) {
|
||||
log("Failed to drop the database; return code was " + returnCode);
|
||||
}
|
||||
|
||||
public void dropDatabaseComplete() {
|
||||
log("Dropped database.");
|
||||
}
|
||||
|
||||
public void loadDatabaseStarting(String statement) {
|
||||
log("Loading the database: " + statement);
|
||||
}
|
||||
|
||||
public void loadDatabaseFailed(int returnCode) {
|
||||
log("Failed to load the database; return code was " + returnCode);
|
||||
}
|
||||
|
||||
public void loadDatabaseComplete() {
|
||||
log("Loaded the database.");
|
||||
}
|
||||
|
||||
public void webappStarting(String tomcatStartCommand) {
|
||||
log("Starting tomcat: " + tomcatStartCommand);
|
||||
}
|
||||
|
||||
public void webappStartFailed(int returnCode) {
|
||||
log("Failed to start tomcat; return code was " + returnCode);
|
||||
}
|
||||
|
||||
public void webappWaitingForStart(int tomcatStartDelay) {
|
||||
log("Waiting " + tomcatStartDelay + " seconds for tomcat to start.");
|
||||
}
|
||||
|
||||
public void webappStarted() {
|
||||
log("Tomcat started.");
|
||||
}
|
||||
|
||||
public void subProcessStart(List<String> command) {
|
||||
log("Subprocess started: " + command);
|
||||
}
|
||||
|
||||
public void subProcessStartInBackground(List<String> command) {
|
||||
log("Subprocess started in background: " + command);
|
||||
}
|
||||
|
||||
public void subProcessStdout(String string) {
|
||||
logRawText(string);
|
||||
}
|
||||
|
||||
public void subProcessErrout(String string) {
|
||||
logRawText(string);
|
||||
}
|
||||
|
||||
public void subProcessStop(List<String> command) {
|
||||
log("Subprocess stopped: " + command);
|
||||
}
|
||||
|
||||
public void suiteStarted(File suiteDir) {
|
||||
log("Suite started: " + suiteDir.getName());
|
||||
}
|
||||
|
||||
public void suiteTestingStarted(File suiteDir) {
|
||||
log("Suite testing started: " + suiteDir.getName());
|
||||
}
|
||||
|
||||
public void suiteFailed(File suiteDir, int returnCode) {
|
||||
log("Suite failed: " + suiteDir.getName() + ", returnCode="
|
||||
+ returnCode);
|
||||
}
|
||||
|
||||
public void suiteFailed(File suiteDir, Exception e) {
|
||||
log("Suite failed: " + suiteDir.getName());
|
||||
log(e);
|
||||
}
|
||||
|
||||
public void suiteTestingStopped(File suiteDir) {
|
||||
log("Suite testing stopped: " + suiteDir.getName());
|
||||
}
|
||||
|
||||
public void suiteStopped(File suiteDir) {
|
||||
log("Suite stopped: " + suiteDir.getName());
|
||||
}
|
||||
|
||||
public void cleanUploadStart(File uploadDirectory) {
|
||||
log("Upload cleaning started: " + uploadDirectory.getPath());
|
||||
}
|
||||
|
||||
public void cleanUploadFailed(File uploadDirectory, IOException e) {
|
||||
log("Upload cleaning failed: " + uploadDirectory.getPath());
|
||||
log(e);
|
||||
}
|
||||
|
||||
public void cleanUploadStop(File uploadDirectory) {
|
||||
log("Upload cleaning stopped: " + uploadDirectory.getPath());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Helper methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private void logRawText(String rawText) {
|
||||
try {
|
||||
writer.write(rawText);
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void log(String message) {
|
||||
try {
|
||||
writer.write(timeStamp() + " " + message + "\n");
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void log(Throwable t) {
|
||||
try {
|
||||
t.printStackTrace(new PrintWriter(writer));
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the current date and time to a string for the log.
|
||||
*/
|
||||
private String timeStamp() {
|
||||
return DATE_FORMAT.format(new Date());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Writer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class Logger {
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
|
||||
"yyyy-MM-dd HH:mm:ss.SSS");
|
||||
|
||||
private final Writer writer;
|
||||
|
||||
public Logger(PrintStream out) {
|
||||
this.writer = new OutputStreamWriter(out);
|
||||
}
|
||||
|
||||
public Logger(File logFile) throws IOException {
|
||||
this.writer = new FileWriter(logFile);
|
||||
}
|
||||
|
||||
public void runStarted() {
|
||||
log("Run started.");
|
||||
}
|
||||
|
||||
public void runStopped() {
|
||||
log("Run stopped.");
|
||||
}
|
||||
|
||||
public void subProcessStart(List<String> command) {
|
||||
log("Subprocess started: " + command);
|
||||
}
|
||||
|
||||
public void subProcessStdout(String string) {
|
||||
logRawText(string);
|
||||
}
|
||||
|
||||
public void subProcessErrout(String string) {
|
||||
logRawText(string);
|
||||
}
|
||||
|
||||
public void subProcessStop(List<String> command) {
|
||||
log("Subprocess stopped: " + command);
|
||||
}
|
||||
|
||||
public void suiteStarted(File suiteDir) {
|
||||
log("Suite started: " + suiteDir.getName());
|
||||
}
|
||||
|
||||
public void suiteFailed(File suiteDir, IOException e) {
|
||||
log("Suite failed: " + suiteDir.getName());
|
||||
log(e);
|
||||
}
|
||||
|
||||
public void suiteStopped(File suiteDir) {
|
||||
log("Suite stopped: " + suiteDir.getName());
|
||||
}
|
||||
|
||||
public void cleanUploadStart(File uploadDirectory) {
|
||||
log("Upload cleaning started: " + uploadDirectory.getPath());
|
||||
}
|
||||
|
||||
public void cleanUploadFailed(File uploadDirectory, IOException e) {
|
||||
log("Upload cleaning failed: " + uploadDirectory.getPath());
|
||||
log(e);
|
||||
}
|
||||
|
||||
public void cleanUploadStop(File uploadDirectory) {
|
||||
log("Upload cleaning stopped: " + uploadDirectory.getPath());
|
||||
}
|
||||
|
||||
private void logRawText(String rawText) {
|
||||
try {
|
||||
writer.write(rawText);
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void log(String message) {
|
||||
try {
|
||||
writer.write(timeStamp() + " " + message + "\n");
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void log(Throwable t) {
|
||||
try {
|
||||
t.printStackTrace(new PrintWriter(writer));
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the current date and time to a string for the log.
|
||||
*/
|
||||
private String timeStamp() {
|
||||
return DATE_FORMAT.format(new Date());
|
||||
}
|
||||
|
||||
}
|
|
@ -2,25 +2,215 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Resets the RDF-Model to a known state, in preparation for the next Selenium
|
||||
* test suite.
|
||||
*/
|
||||
public class ModelCleaner {
|
||||
private final ModelCleanerProperties properties;
|
||||
private final CommandRunner runner;
|
||||
private final Listener listener;
|
||||
|
||||
/**
|
||||
* @param parms
|
||||
*/
|
||||
public ModelCleaner(SeleniumRunnerParameters parms) {
|
||||
// TODO Auto-generated constructor stub
|
||||
throw new RuntimeException("ModelCleaner Constructor not implemented.");
|
||||
this.properties = parms.getModelCleanerProperties();
|
||||
this.listener = parms.getListener();
|
||||
this.runner = new CommandRunner(parms);
|
||||
|
||||
sanityCheck();
|
||||
}
|
||||
|
||||
private void sanityCheck() {
|
||||
executeMysqlStatement("show databases;");
|
||||
|
||||
int returnCode = runner.getReturnCode();
|
||||
if (returnCode != 0) {
|
||||
throw new FatalException(
|
||||
"sanityCheck: Failed to execute a MySQL statement: "
|
||||
+ "return code=" + returnCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the RDF-Model to a known state, according to the parameters in the
|
||||
* properties file.
|
||||
*
|
||||
* @throws CommandRunnerException
|
||||
* if a problem occurs in a sub-process.
|
||||
*/
|
||||
public void clean() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("ModelCleaner.clean() not implemented.");
|
||||
public void clean() throws CommandRunnerException {
|
||||
stopTheWebapp();
|
||||
dropDatabase();
|
||||
createAndLoadDatabase();
|
||||
startTheWebapp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop Tomcat and wait the prescribed number of seconds for it to clean up.
|
||||
*/
|
||||
private void stopTheWebapp() throws CommandRunnerException {
|
||||
String tomcatStopCommand = properties.getTomcatStopCommand();
|
||||
int tomcatStopDelay = properties.getTomcatStopDelay();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the database.
|
||||
*/
|
||||
private void dropDatabase() {
|
||||
String mysqlStatement = "drop database " + properties.getMysqlDbName()
|
||||
+ "; create database " + properties.getMysqlDbName()
|
||||
+ " character set utf8;";
|
||||
|
||||
listener.dropDatabaseStarting(mysqlStatement);
|
||||
executeMysqlStatement(mysqlStatement);
|
||||
|
||||
int returnCode = runner.getReturnCode();
|
||||
if (returnCode != 0) {
|
||||
listener.dropDatabaseFailed(returnCode);
|
||||
throw new FatalException("dropDatabase() failed: return code="
|
||||
+ returnCode);
|
||||
}
|
||||
|
||||
listener.dropDatabaseComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild the database.
|
||||
*/
|
||||
private void createAndLoadDatabase() {
|
||||
String mysqlStatement = "source "
|
||||
+ convertBackslashes(properties.getMysqlDumpfile()) + ";";
|
||||
|
||||
listener.loadDatabaseStarting(mysqlStatement);
|
||||
executeMysqlStatement(mysqlStatement);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell MySQL to execute this statement. If it fails, throw a fatal
|
||||
* exception.
|
||||
*/
|
||||
private void executeMysqlStatement(String mysqlStatement) {
|
||||
List<String> cmd = new ArrayList<String>();
|
||||
cmd.add("mysql");
|
||||
cmd.add("--user=" + properties.getMysqlUsername());
|
||||
cmd.add("--password=" + properties.getMysqlPassword());
|
||||
cmd.add("--database=" + properties.getMysqlDbName());
|
||||
cmd.add("--execute=" + mysqlStatement);
|
||||
|
||||
try {
|
||||
runner.run(cmd);
|
||||
} catch (CommandRunnerException e) {
|
||||
throw new FatalException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
static String convertBackslashes(File file) {
|
||||
return file.getPath().replace("\\", "/");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Hold the runtime properties that pertain specifically to cleaning the data
|
||||
* model.
|
||||
*/
|
||||
public class ModelCleanerProperties {
|
||||
public static final String PROP_TOMCAT_START_COMMAND = "tomcat_start_command";
|
||||
public static final String PROP_TOMCAT_START_DELAY = "tomcat_start_delay";
|
||||
public static final String PROP_TOMCAT_STOP_COMMAND = "tomcat_stop_command";
|
||||
public static final String PROP_TOMCAT_STOP_DELAY = "tomcat_stop_delay";
|
||||
public static final String PROP_MYSQL_USERNAME = "mysql_username";
|
||||
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_DUMPFILE = "mysql_dumpfile";
|
||||
|
||||
private final String tomcatStartCommand;
|
||||
private final int tomcatStartDelay;
|
||||
private final String tomcatStopCommand;
|
||||
private final int tomcatStopDelay;
|
||||
private final String mysqlUsername;
|
||||
private final String mysqlPassword;
|
||||
private final String mysqlDbName;
|
||||
private final File mysqlDumpfile;
|
||||
|
||||
/**
|
||||
* Confirm that we have the expected properties, and that their values seem
|
||||
* reasonable.
|
||||
*/
|
||||
public ModelCleanerProperties(Properties props) {
|
||||
this.tomcatStartCommand = getRequiredProperty(props,
|
||||
PROP_TOMCAT_START_COMMAND);
|
||||
this.tomcatStartDelay = getRequiredIntegerProperty(props,
|
||||
PROP_TOMCAT_START_DELAY);
|
||||
|
||||
this.tomcatStopCommand = getRequiredProperty(props,
|
||||
PROP_TOMCAT_STOP_COMMAND);
|
||||
this.tomcatStopDelay = getRequiredIntegerProperty(props,
|
||||
PROP_TOMCAT_STOP_DELAY);
|
||||
|
||||
this.mysqlUsername = getRequiredProperty(props, PROP_MYSQL_USERNAME);
|
||||
this.mysqlPassword = getRequiredProperty(props, PROP_MYSQL_PASSWORD);
|
||||
this.mysqlDbName = getRequiredProperty(props, PROP_MYSQL_DB_NAME);
|
||||
|
||||
this.mysqlDumpfile = confirmDumpfile(props);
|
||||
}
|
||||
|
||||
public String getTomcatStartCommand() {
|
||||
return tomcatStartCommand;
|
||||
}
|
||||
|
||||
public int getTomcatStartDelay() {
|
||||
return tomcatStartDelay;
|
||||
}
|
||||
|
||||
public String getTomcatStopCommand() {
|
||||
return tomcatStopCommand;
|
||||
}
|
||||
|
||||
public int getTomcatStopDelay() {
|
||||
return tomcatStopDelay;
|
||||
}
|
||||
|
||||
public String getMysqlUsername() {
|
||||
return mysqlUsername;
|
||||
}
|
||||
|
||||
public String getMysqlPassword() {
|
||||
return mysqlPassword;
|
||||
}
|
||||
|
||||
public String getMysqlDbName() {
|
||||
return mysqlDbName;
|
||||
}
|
||||
|
||||
public File getMysqlDumpfile() {
|
||||
return mysqlDumpfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for this property. If there isn't one, or if it's empty,
|
||||
* complain.
|
||||
*/
|
||||
private String getRequiredProperty(Properties props, String key) {
|
||||
String value = props.getProperty(key);
|
||||
if ((value == null) || (value.trim().length() == 0)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property file must provide a value for '" + key + "'");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private int getRequiredIntegerProperty(Properties props, String key) {
|
||||
String value = getRequiredProperty(props, key);
|
||||
try {
|
||||
return Integer.parseInt(value.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Property value for '" + key
|
||||
+ "' is not a valid integer: " + value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The dumpfile parameter must point to an existing file.
|
||||
*/
|
||||
private File confirmDumpfile(Properties props) {
|
||||
String filename = getRequiredProperty(props, PROP_MYSQL_DUMPFILE);
|
||||
File dumpfile = new File(filename);
|
||||
if (!dumpfile.exists()) {
|
||||
throw new IllegalArgumentException("Invalid value for '"
|
||||
+ PROP_MYSQL_DUMPFILE + "': file '" + filename
|
||||
+ "' does not exist.");
|
||||
}
|
||||
if (!dumpfile.isFile()) {
|
||||
throw new IllegalArgumentException("Invalid value for '"
|
||||
+ PROP_MYSQL_DUMPFILE + "': '" + filename
|
||||
+ "' is not a file.");
|
||||
}
|
||||
if (!dumpfile.canRead()) {
|
||||
throw new IllegalArgumentException("Invalid value for '"
|
||||
+ PROP_MYSQL_DUMPFILE + "': file '" + filename
|
||||
+ "' is not readable.");
|
||||
}
|
||||
return dumpfile;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "\n tomcatStartCommand: " + tomcatStartCommand
|
||||
+ "\n tomcatStartDelay: " + tomcatStartDelay
|
||||
+ "\n tomcatStopCommand: " + tomcatStopCommand
|
||||
+ "\n tomcatStopDelay: " + tomcatStopDelay;
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.utilities.testrunner.SeleniumRunnerParameters.LOGFILE_NAME;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -13,23 +15,23 @@ import java.util.List;
|
|||
*/
|
||||
public class SeleniumRunner {
|
||||
private final SeleniumRunnerParameters parms;
|
||||
private final Logger logger;
|
||||
private final Listener listener;
|
||||
private final UploadAreaCleaner uploadCleaner;
|
||||
private final ModelCleaner modelCleaner;
|
||||
private final SuiteRunner suiteRunner;
|
||||
|
||||
public SeleniumRunner(SeleniumRunnerParameters parms) {
|
||||
this.parms = parms;
|
||||
this.logger = parms.getLogger();
|
||||
this.listener = parms.getListener();
|
||||
this.uploadCleaner = new UploadAreaCleaner(parms);
|
||||
this.modelCleaner = new ModelCleaner(parms);
|
||||
this.suiteRunner = new SuiteRunner(parms);
|
||||
}
|
||||
|
||||
public void runSelectedSuites() {
|
||||
logger.runStarted();
|
||||
listener.runStarted();
|
||||
for (File suiteDir : parms.getSelectedSuites()) {
|
||||
logger.suiteStarted(suiteDir);
|
||||
listener.suiteStarted(suiteDir);
|
||||
try {
|
||||
if (parms.isCleanModel()) {
|
||||
modelCleaner.clean();
|
||||
|
@ -39,11 +41,17 @@ public class SeleniumRunner {
|
|||
}
|
||||
suiteRunner.runSuite(suiteDir);
|
||||
} catch (IOException e) {
|
||||
logger.suiteFailed(suiteDir, e);
|
||||
listener.suiteFailed(suiteDir, e);
|
||||
} catch (CommandRunnerException e) {
|
||||
listener.suiteFailed(suiteDir, e);
|
||||
} catch (FatalException e) {
|
||||
listener.runFailed(e);
|
||||
e.printStackTrace();
|
||||
break;
|
||||
}
|
||||
logger.suiteStopped(suiteDir);
|
||||
listener.suiteStopped(suiteDir);
|
||||
}
|
||||
logger.runStopped();
|
||||
listener.runStopped();
|
||||
}
|
||||
|
||||
private static void selectAllSuites(SeleniumRunnerParameters parms) {
|
||||
|
@ -54,9 +62,13 @@ public class SeleniumRunner {
|
|||
parms.setSelectedSuites(suites);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
private static void usage(String message) {
|
||||
System.out.println(message);
|
||||
System.out.println("Usage is: SeleniumRunner <parameters_file> "
|
||||
+ "[\"interactive\"]");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SeleniumRunnerParameters parms = null;
|
||||
boolean interactive = false;
|
||||
|
@ -82,20 +94,20 @@ public class SeleniumRunner {
|
|||
// TODO hook up the GUI.
|
||||
throw new RuntimeException("interactive mode not implemented.");
|
||||
} else {
|
||||
File logFile = new File(parms.getOutputDirectory(), LOGFILE_NAME);
|
||||
System.out.println("Log file is '" + logFile.getPath() + "'");
|
||||
|
||||
// Run all of the suites.
|
||||
// For each suite, clean the model and the upload area.
|
||||
selectAllSuites(parms);
|
||||
parms.setCleanModel(true);
|
||||
parms.setCleanUploads(true);
|
||||
|
||||
System.out.println(parms);
|
||||
|
||||
SeleniumRunner runner = new SeleniumRunner(parms);
|
||||
runner.runSelectedSuites();
|
||||
}
|
||||
}
|
||||
|
||||
private static void usage(String message) {
|
||||
System.out.println(message);
|
||||
System.out.println("Usage is: SeleniumRunner <parameters_file> "
|
||||
+ "[\"interactive\"]");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,22 +19,32 @@ import java.util.Properties;
|
|||
* with modifications from the GUI if we are running interactively.
|
||||
*/
|
||||
public class SeleniumRunnerParameters {
|
||||
private static final String PROP_OUTPUT_DIRECTORY = "output_directory";
|
||||
private static final String PROP_UPLOAD_DIRECTORY = "upload_directory";
|
||||
private static final String PROP_SUITE_DIRECTORIES = "suite_parent_directories";
|
||||
public static final String PROP_OUTPUT_DIRECTORY = "output_directory";
|
||||
public static final String PROP_UPLOAD_DIRECTORY = "upload_directory";
|
||||
public static final String PROP_SUITE_DIRECTORIES = "suite_parent_directories";
|
||||
public static final String PROP_WEBSITE_URL = "website_url";
|
||||
public static final String PROP_USER_EXTENSIONS_PATH = "user_extensions_path";
|
||||
public static final String PROP_FIREFOX_PROFILE_PATH = "firefox_profile_template_path";
|
||||
public static final String PROP_SUITE_TIMEOUT_LIMIT = "suite_timeout_limit";
|
||||
public static final String PROP_SELENIUM_JAR_PATH = "selenium_jar_path";
|
||||
|
||||
private static final String LOGFILE_NAME = "log_file.txt";
|
||||
public static final String LOGFILE_NAME = "log_file.txt";
|
||||
|
||||
private final String websiteUrl;
|
||||
private final File userExtensionsFile;
|
||||
private final File firefoxProfileDir;
|
||||
private final int suiteTimeoutLimit;
|
||||
private final File seleniumJarPath;
|
||||
private final File uploadDirectory;
|
||||
private final File outputDirectory;
|
||||
private final File logFile;
|
||||
|
||||
private final Collection<File> suiteParentDirectories;
|
||||
private final ModelCleanerProperties modelCleanerProperties;
|
||||
|
||||
private Collection<File> selectedSuites = Collections.emptySet();
|
||||
private boolean cleanModel = true;
|
||||
private boolean cleanUploads = true;
|
||||
private Logger logger = new Logger(System.out);
|
||||
private Listener listener = new Listener(System.out);
|
||||
|
||||
/**
|
||||
* Read the required properties from the property file, and do some checks
|
||||
|
@ -48,15 +58,26 @@ public class SeleniumRunnerParameters {
|
|||
Properties props = new Properties();
|
||||
props.load(propsReader);
|
||||
|
||||
this.websiteUrl = getRequiredProperty(props, PROP_WEBSITE_URL);
|
||||
this.userExtensionsFile = checkReadableFile(props,
|
||||
PROP_USER_EXTENSIONS_PATH);
|
||||
this.firefoxProfileDir = checkOptionalReadableDirectory(props,
|
||||
PROP_FIREFOX_PROFILE_PATH);
|
||||
this.suiteTimeoutLimit = getRequiredIntegerProperty(props,
|
||||
PROP_SUITE_TIMEOUT_LIMIT);
|
||||
this.seleniumJarPath = checkReadableFile(props,
|
||||
PROP_SELENIUM_JAR_PATH);
|
||||
this.uploadDirectory = checkReadWriteDirectory(props,
|
||||
PROP_UPLOAD_DIRECTORY);
|
||||
|
||||
this.outputDirectory = checkReadWriteDirectory(props,
|
||||
PROP_OUTPUT_DIRECTORY);
|
||||
this.logFile = new File(this.outputDirectory, LOGFILE_NAME);
|
||||
this.logger = new Logger(this.logFile);
|
||||
this.listener = new Listener(this.logFile);
|
||||
|
||||
this.suiteParentDirectories = checkSuiteParentDirectories(props);
|
||||
|
||||
this.modelCleanerProperties = new ModelCleanerProperties(props);
|
||||
} finally {
|
||||
if (propsReader != null) {
|
||||
try {
|
||||
|
@ -68,6 +89,36 @@ public class SeleniumRunnerParameters {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is a parameter for this key, it should point to a readable
|
||||
* directory.
|
||||
*/
|
||||
private File checkOptionalReadableDirectory(Properties props, String key) {
|
||||
String value = props.getProperty(key);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
File dir = new File(value);
|
||||
|
||||
if (!dir.exists()) {
|
||||
throw new IllegalArgumentException("Directory " + key + " '"
|
||||
+ value + "' does not exist.");
|
||||
}
|
||||
|
||||
if (!dir.isDirectory()) {
|
||||
throw new IllegalArgumentException("Directory " + key + " '"
|
||||
+ value + "' is not a directory.");
|
||||
}
|
||||
|
||||
if (!dir.canRead()) {
|
||||
throw new IllegalArgumentException("Directory " + key + " '"
|
||||
+ value + "' is not readable.");
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that there is a property for the output directory, and that it
|
||||
* points to a valid directory.
|
||||
|
@ -99,6 +150,26 @@ public class SeleniumRunnerParameters {
|
|||
return dir;
|
||||
}
|
||||
|
||||
private File checkReadableFile(Properties props, String key) {
|
||||
String value = getRequiredProperty(props, key);
|
||||
|
||||
File file = new File(value);
|
||||
|
||||
if (!file.exists()) {
|
||||
throw new IllegalArgumentException("File " + key
|
||||
+ ": '' does not exist.");
|
||||
}
|
||||
if (!file.isFile()) {
|
||||
throw new IllegalArgumentException("File " + key
|
||||
+ ": '' is not a file.");
|
||||
}
|
||||
if (!file.canRead()) {
|
||||
throw new IllegalArgumentException("File " + key
|
||||
+ ": '' is not readable.");
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the property for the suite directories and ensure that each one is
|
||||
* indeed a readable directory.
|
||||
|
@ -123,6 +194,7 @@ public class SeleniumRunnerParameters {
|
|||
throw new IllegalArgumentException("Suite directory '"
|
||||
+ dir.getPath() + "' is not readable.");
|
||||
}
|
||||
dirs.add(dir);
|
||||
}
|
||||
return dirs;
|
||||
}
|
||||
|
@ -140,22 +212,67 @@ public class SeleniumRunnerParameters {
|
|||
return value;
|
||||
}
|
||||
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
/**
|
||||
* This required property must be a valid integer.
|
||||
*/
|
||||
private int getRequiredIntegerProperty(Properties props, String key) {
|
||||
String value = getRequiredProperty(props, key);
|
||||
try {
|
||||
return Integer.parseInt(value.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Property value for '" + key
|
||||
+ "' is not a valid integer: " + value);
|
||||
}
|
||||
}
|
||||
|
||||
public void setLogger(Logger logger) {
|
||||
this.logger = logger;
|
||||
public String getWebsiteUrl() {
|
||||
return websiteUrl;
|
||||
}
|
||||
|
||||
public File getUserExtensionsFile() {
|
||||
return userExtensionsFile;
|
||||
}
|
||||
|
||||
public boolean hasFirefoxProfileDir() {
|
||||
return firefoxProfileDir != null;
|
||||
}
|
||||
|
||||
public File getFirefoxProfileDir() {
|
||||
return firefoxProfileDir;
|
||||
}
|
||||
|
||||
public int getSuiteTimeoutLimit() {
|
||||
return suiteTimeoutLimit;
|
||||
}
|
||||
|
||||
public File getSeleniumJarPath() {
|
||||
return seleniumJarPath;
|
||||
}
|
||||
|
||||
public Listener getListener() {
|
||||
return listener;
|
||||
}
|
||||
|
||||
public void setListener(Listener logger) {
|
||||
this.listener = logger;
|
||||
}
|
||||
|
||||
public File getUploadDirectory() {
|
||||
return uploadDirectory;
|
||||
}
|
||||
|
||||
public File getOutputDirectory() {
|
||||
return outputDirectory;
|
||||
}
|
||||
|
||||
public Collection<File> getSuiteParentDirectories() {
|
||||
return suiteParentDirectories;
|
||||
}
|
||||
|
||||
public ModelCleanerProperties getModelCleanerProperties() {
|
||||
return modelCleanerProperties;
|
||||
}
|
||||
|
||||
public void setSelectedSuites(Collection<File> selectedSuites) {
|
||||
this.selectedSuites = selectedSuites;
|
||||
}
|
||||
|
@ -180,22 +297,50 @@ public class SeleniumRunnerParameters {
|
|||
this.cleanUploads = cleanUploads;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Parameters:" + "\n websiteUrl: " + websiteUrl
|
||||
+ "\n userExtensionsFile: " + userExtensionsFile.getPath()
|
||||
+ "\n firefoxProfileDir: " + firefoxProfileDir.getPath()
|
||||
+ "\n suiteTimeoutLimit: " + suiteTimeoutLimit
|
||||
+ "\n seleniumJarPath: " + seleniumJarPath.getPath()
|
||||
+ "\n uploadDirectory: " + uploadDirectory.getPath()
|
||||
+ "\n outputDirectory: " + outputDirectory.getPath()
|
||||
+ "\n suiteParentDirectories: " + suiteParentDirectories
|
||||
+ "\n modelCleanerProperties: " + modelCleanerProperties
|
||||
+ "\n\n selectedSuites: " + showSelectedSuites()
|
||||
+ "\n cleanModel: " + cleanModel + "\n cleanUploads: "
|
||||
+ cleanUploads;
|
||||
}
|
||||
|
||||
private String showSelectedSuites() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
for (File suite : selectedSuites) {
|
||||
buffer.append("\n ").append(suite.getPath());
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Look inside this parent directory and find any suite directories. You can
|
||||
* recognize a suite directory because it contains a file named Suite.html.
|
||||
*/
|
||||
public Collection<File> findSuiteDirs(File parentDir) {
|
||||
System.out.println("parentDir: " + parentDir);
|
||||
return Arrays.asList(parentDir.listFiles(new FileFilter() {
|
||||
public boolean accept(File pathname) {
|
||||
if (!pathname.isDirectory()) {
|
||||
return false;
|
||||
}
|
||||
if (pathname.getName().charAt(0) == '.') {
|
||||
return false;
|
||||
}
|
||||
|
||||
File suiteFile = new File(pathname, "Suite.html");
|
||||
if (suiteFile.exists()) {
|
||||
return true;
|
||||
} else {
|
||||
logger.subProcessErrout("Warning: suite file '" + suiteFile.getPath()
|
||||
+ "' does not exist.\n");
|
||||
listener.subProcessErrout("Warning: suite file '"
|
||||
+ suiteFile.getPath() + "' does not exist.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,26 +3,68 @@
|
|||
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* Run a Selenium TestSuite in a sub-process.
|
||||
*/
|
||||
public class SuiteRunner {
|
||||
|
||||
/**
|
||||
* @param parms
|
||||
*/
|
||||
private final SeleniumRunnerParameters parms;
|
||||
private final CommandRunner runner;
|
||||
private final Listener listener;
|
||||
|
||||
public SuiteRunner(SeleniumRunnerParameters parms) {
|
||||
// TODO Auto-generated constructor stub
|
||||
throw new RuntimeException("SuiteRunner Constructor not implemented.");
|
||||
this.parms = parms;
|
||||
this.runner = new CommandRunner(parms);
|
||||
this.listener = parms.getListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param suiteDir
|
||||
* Run the suite.
|
||||
*/
|
||||
public void runSuite(File suiteDir) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("SuiteRunner.runSuite() not implemented.");
|
||||
listener.suiteTestingStarted(suiteDir);
|
||||
|
||||
List<String> cmd = new ArrayList<String>();
|
||||
cmd.add("java");
|
||||
cmd.add("-jar");
|
||||
cmd.add(parms.getSeleniumJarPath().getPath());
|
||||
cmd.add("-singleWindow");
|
||||
cmd.add("-timeout");
|
||||
cmd.add(String.valueOf(parms.getSuiteTimeoutLimit()));
|
||||
cmd.add("-userExtensions");
|
||||
cmd.add(parms.getUserExtensionsFile().getPath());
|
||||
|
||||
if (parms.hasFirefoxProfileDir()) {
|
||||
cmd.add("-firefoxProfileTemplate");
|
||||
cmd.add(parms.getFirefoxProfileDir().getPath());
|
||||
}
|
||||
|
||||
String suiteName = suiteDir.getName();
|
||||
File outputFile = new File(parms.getOutputDirectory(), suiteName
|
||||
+ ".html");
|
||||
File suiteFile = new File(suiteDir, "Suite.html");
|
||||
|
||||
cmd.add("-htmlSuite");
|
||||
cmd.add("*firefox");
|
||||
cmd.add(parms.getWebsiteUrl());
|
||||
cmd.add(suiteFile.getPath());
|
||||
cmd.add(outputFile.getPath());
|
||||
|
||||
try {
|
||||
runner.run(cmd);
|
||||
} catch (CommandRunnerException e) {
|
||||
throw new FatalException(e);
|
||||
}
|
||||
|
||||
int returnCode = runner.getReturnCode();
|
||||
if (returnCode != 0) {
|
||||
listener.suiteFailed(suiteDir, returnCode);
|
||||
}
|
||||
|
||||
listener.suiteTestingStopped(suiteDir);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@ import java.io.IOException;
|
|||
*/
|
||||
public class UploadAreaCleaner {
|
||||
private final SeleniumRunnerParameters parms;
|
||||
private final Logger logger;
|
||||
private final Listener listener;
|
||||
|
||||
public UploadAreaCleaner(SeleniumRunnerParameters parms) {
|
||||
this.parms = parms;
|
||||
this.logger = parms.getLogger();
|
||||
this.listener = parms.getListener();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,7 +29,7 @@ public class UploadAreaCleaner {
|
|||
+ "' is not a directory.");
|
||||
}
|
||||
|
||||
logger.cleanUploadStart(uploadDirectory);
|
||||
listener.cleanUploadStart(uploadDirectory);
|
||||
|
||||
try {
|
||||
for (File file : uploadDirectory.listFiles()) {
|
||||
|
@ -40,10 +40,10 @@ public class UploadAreaCleaner {
|
|||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.cleanUploadFailed(uploadDirectory, e);
|
||||
listener.cleanUploadFailed(uploadDirectory, e);
|
||||
throw e;
|
||||
} finally {
|
||||
logger.cleanUploadStop(uploadDirectory);
|
||||
listener.cleanUploadStop(uploadDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.utilities.testrunner;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class ModelCleanerTest {
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Tests for parseCommandLine()
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void oneArgument() {
|
||||
assertExpectedParsing("oneArgument", "oneArgument");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleArguments() {
|
||||
assertExpectedParsing("more than one", "more", "than", "one");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void quotedArgument() {
|
||||
assertExpectedParsing("contains \"quoted blank\" string", "contains",
|
||||
"quoted blank", "string");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void mismatchedQuotes() {
|
||||
assertExpectedParsing("contains mismatched \"quote");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyLine() {
|
||||
assertExpectedParsing("");
|
||||
}
|
||||
|
||||
private void assertExpectedParsing(String commandLine,
|
||||
String... expectedPieces) {
|
||||
assertEquals("parse", Arrays.asList(expectedPieces), ModelCleaner
|
||||
.parseCommandLine(commandLine));
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue