From 2e8ef62bb178e8721a3495f3fc62c6a49eab156f Mon Sep 17 00:00:00 2001 From: j2blake Date: Thu, 19 Dec 2013 11:44:10 -0500 Subject: [PATCH] Line-ending characters --- .../testrunner/CommandRunnerException.java | 52 +- .../utilities/testrunner/FatalException.java | 52 +- .../testrunner/SeleniumRunnerParameters.java | 868 +++++++++--------- .../testrunner/datamodel/DataModel.java | 588 ++++++------ .../output/OutputSummaryFormatter.java | 750 +++++++-------- 5 files changed, 1155 insertions(+), 1155 deletions(-) diff --git a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/CommandRunnerException.java b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/CommandRunnerException.java index 8550abbb7..31074b2e7 100644 --- a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/CommandRunnerException.java +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/CommandRunnerException.java @@ -1,26 +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 with the attempt to run a command in a sub-process. - */ -public class CommandRunnerException extends Exception { - - public CommandRunnerException() { - super(); - } - - public CommandRunnerException(String message) { - super(message); - } - - public CommandRunnerException(Throwable cause) { - super(cause); - } - - public CommandRunnerException(String message, Throwable cause) { - super(message, cause); - } - -} +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.utilities.testrunner; + +/** + * Indicates a problem with the attempt to run a command in a sub-process. + */ +public class CommandRunnerException extends Exception { + + public CommandRunnerException() { + super(); + } + + public CommandRunnerException(String message) { + super(message); + } + + public CommandRunnerException(Throwable cause) { + super(cause); + } + + public CommandRunnerException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/FatalException.java b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/FatalException.java index 42b11ef7b..98721bed1 100644 --- a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/FatalException.java +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/FatalException.java @@ -1,26 +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); - } - -} +/* $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); + } + +} diff --git a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/SeleniumRunnerParameters.java b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/SeleniumRunnerParameters.java index 1fd8020f8..bb04f3ed4 100644 --- a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/SeleniumRunnerParameters.java +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/SeleniumRunnerParameters.java @@ -1,434 +1,434 @@ -/* $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.FileFilter; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.Reader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Properties; - -import edu.cornell.mannlib.vitro.utilities.testrunner.listener.Listener; -import edu.cornell.mannlib.vitro.utilities.testrunner.listener.LoggingListener; -import edu.cornell.mannlib.vitro.utilities.testrunner.listener.MulticastListener; - -/** - * Holds the runtime parameters that are read from the properties file, perhaps - * with modifications from the GUI if we are running interactively. - */ -public class SeleniumRunnerParameters { - 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"; - public static final String PROP_IGNORED_TESTS = "ignored_tests_file"; - public static final String PROP_SUMMARY_CSS = "summary_css_file"; - - 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 suiteParentDirectories; - private final ModelCleanerProperties modelCleanerProperties; - private final IgnoredTests ignoredTests; - - private boolean cleanModel = true; - private boolean cleanUploads = true; - - // If we fail during the parameter parsing, we'll still write the log - // somewhere. - private Listener listener = new LoggingListener(System.out); - - /** - * Read the required properties from the property file, and do some checks - * on them. - */ - public SeleniumRunnerParameters(String propertiesFilepath) - throws IOException { - Properties props = loadPropertiesFile(propertiesFilepath); - - 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 = checkOutputDirectory(props); - this.logFile = new File(this.outputDirectory, LOGFILE_NAME); - this.listener = new MulticastListener(); - addListener(new LoggingListener(this.logFile)); - - this.suiteParentDirectories = checkSuiteParentDirectories(props); - - this.modelCleanerProperties = new ModelCleanerProperties(props); - - // Get the list of ignored tests. - String ignoredFilesPath = getRequiredProperty(props, PROP_IGNORED_TESTS); - File ignoredFilesFile = new File(ignoredFilesPath); - FileHelper.checkReadableFile(ignoredFilesFile, "File '" - + ignoredFilesPath + "'"); - this.ignoredTests = new IgnoredTests(ignoredFilesFile); - } - - /** - * Load the properties from the properties file. - */ - private Properties loadPropertiesFile(String propertiesFilepath) - throws FileNotFoundException, IOException { - File propsFile = new File(propertiesFilepath); - if (!propsFile.exists()) { - throw new FileNotFoundException("Property file does not exist: '" - + propsFile + "'"); - } - - Reader propsReader = null; - try { - propsReader = new FileReader(propsFile); - Properties props = new Properties(); - props.load(propsReader); - return props; - } finally { - if (propsReader != null) { - try { - propsReader.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - - /** - * 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; - } - - value = value.trim(); - if (value.trim().length() == 0) { - 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 required directory path, and that - * it points to a valid directory. - */ - private File checkReadWriteDirectory(Properties props, String key) { - String value = getRequiredProperty(props, key); - - File dir = new File(value); - - if (!dir.exists()) { - throw new IllegalArgumentException("Directory " + key + " '" - + value + "' does not exist. (" + dir.getAbsolutePath() - + ")"); - } - - if (!dir.isDirectory()) { - throw new IllegalArgumentException("Directory " + key + " '" - + value + "' is not a directory. (" + dir.getAbsolutePath() - + ")"); - } - - if (!dir.canRead()) { - throw new IllegalArgumentException("Directory " + key + " '" - + value + "' is not readable. (" + dir.getAbsolutePath() - + ")"); - } - - if (!dir.canWrite()) { - throw new IllegalArgumentException("Directory " + key + " '" - + value + "' is not writeable. (" + dir.getAbsolutePath() - + ")"); - } - 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 + ": '" + value - + "' does not exist. (" + file.getAbsolutePath() + ")"); - } - if (!file.isFile()) { - throw new IllegalArgumentException("File " + key + ": '" + value - + "' is not a file. (" + file.getAbsolutePath() + ")"); - } - if (!file.canRead()) { - throw new IllegalArgumentException("File " + key + ": '" + value - + "' is not readable. (" + file.getAbsolutePath() + ")"); - } - return file; - } - - /** - * Get the property for the output directory. If it does not exist, create - * it (the parent must exist). Ensure that it is writeable. - */ - private File checkOutputDirectory(Properties props) throws IOException { - String value = getRequiredProperty(props, PROP_OUTPUT_DIRECTORY); - File outputDirectory = new File(value); - File outputParent = outputDirectory.getParentFile(); - - if (!outputDirectory.exists()) { - if (!outputParent.exists()) { - throw new IllegalArgumentException( - "Output directory does not exist, nor does its parent. '" - + outputDirectory + "' (" - + outputDirectory.getAbsolutePath() + ")"); - } - outputDirectory.mkdir(); - if (!outputDirectory.exists()) { - throw new IOException("Failed to create output directory: '" - + outputDirectory + "' (" - + outputDirectory.getAbsolutePath() + ")"); - } - } - - if (!outputDirectory.isDirectory()) { - throw new IllegalArgumentException("Suite directory '" - + outputDirectory.getPath() + "' is not a directory. (" - + outputDirectory.getAbsolutePath() + ")"); - } - if (!outputDirectory.canRead()) { - throw new IllegalArgumentException("Suite directory '" - + outputDirectory.getPath() + "' is not readable. (" - + outputDirectory.getAbsolutePath() + ")"); - } - if (!outputDirectory.canWrite()) { - throw new IllegalArgumentException("Suite directory '" - + outputDirectory.getPath() + "' is not writeable. (" - + outputDirectory.getAbsolutePath() + ")"); - } - - return outputDirectory; - } - - /** - * Get the property for the suite directories and ensure that each one is - * indeed a readable directory. - */ - private Collection checkSuiteParentDirectories(Properties props) { - String value = getRequiredProperty(props, PROP_SUITE_DIRECTORIES); - - List dirs = new ArrayList(); - String[] paths = value.split("[:;]"); - for (String path : paths) { - File dir = new File(path.trim()); - - if (!dir.exists()) { - throw new IllegalArgumentException("Suite directory '" - + dir.getPath() + "' does not exist. (" - + dir.getAbsolutePath() + ")"); - } - if (!dir.isDirectory()) { - throw new IllegalArgumentException("Suite directory '" - + dir.getPath() + "' is not a directory. (" - + dir.getAbsolutePath() + ")"); - } - if (!dir.canRead()) { - throw new IllegalArgumentException("Suite directory '" - + dir.getPath() + "' is not readable. (" - + dir.getAbsolutePath() + ")"); - } - dirs.add(dir); - } - return dirs; - } - - /** - * 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; - } - - /** - * 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 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 void addListener(Listener l) { - if (listener instanceof MulticastListener) { - ((MulticastListener) listener).addListener(l); - } else { - throw new IllegalStateException("Listener is not a multi-cast -- " - + "can't add new listeners."); - } - } - - public Listener getListener() { - return listener; - } - - public void setListener(Listener logger) { - this.listener = logger; - } - - public File getUploadDirectory() { - return uploadDirectory; - } - - public File getOutputDirectory() { - return outputDirectory; - } - - public File getLogFile() { - return logFile; - } - - public Collection getSuiteParentDirectories() { - return suiteParentDirectories; - } - - public ModelCleanerProperties getModelCleanerProperties() { - return modelCleanerProperties; - } - - public IgnoredTests getIgnoredTests() { - return ignoredTests; - } - - public boolean isCleanModel() { - return cleanModel; - } - - public void setCleanModel(boolean cleanModel) { - this.cleanModel = cleanModel; - } - - public boolean isCleanUploads() { - return cleanUploads; - } - - public void setCleanUploads(boolean cleanUploads) { - this.cleanUploads = cleanUploads; - } - - public String toString() { - return "Parameters:" + "\n websiteUrl: " + websiteUrl - + "\n userExtensionsFile: " + userExtensionsFile - + "\n firefoxProfileDir: " + firefoxProfileDir - + "\n suiteTimeoutLimit: " + suiteTimeoutLimit - + "\n seleniumJarPath: " + seleniumJarPath - + "\n uploadDirectory: " + uploadDirectory - + "\n outputDirectory: " + outputDirectory - + "\n suiteParentDirectories: " + suiteParentDirectories - + "\n modelCleanerProperties: " + modelCleanerProperties - + "\n" + ignoredTests + "\n cleanModel: " + cleanModel - + "\n cleanUploads: " + cleanUploads; - } - - /** - * 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 findSuiteDirs(File 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 { - listener.subProcessErrout("Warning: suite file '" - + suiteFile.getPath() + "' does not exist.\n"); - return false; - } - } - })); - } - -} +/* $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.FileFilter; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Properties; + +import edu.cornell.mannlib.vitro.utilities.testrunner.listener.Listener; +import edu.cornell.mannlib.vitro.utilities.testrunner.listener.LoggingListener; +import edu.cornell.mannlib.vitro.utilities.testrunner.listener.MulticastListener; + +/** + * Holds the runtime parameters that are read from the properties file, perhaps + * with modifications from the GUI if we are running interactively. + */ +public class SeleniumRunnerParameters { + 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"; + public static final String PROP_IGNORED_TESTS = "ignored_tests_file"; + public static final String PROP_SUMMARY_CSS = "summary_css_file"; + + 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 suiteParentDirectories; + private final ModelCleanerProperties modelCleanerProperties; + private final IgnoredTests ignoredTests; + + private boolean cleanModel = true; + private boolean cleanUploads = true; + + // If we fail during the parameter parsing, we'll still write the log + // somewhere. + private Listener listener = new LoggingListener(System.out); + + /** + * Read the required properties from the property file, and do some checks + * on them. + */ + public SeleniumRunnerParameters(String propertiesFilepath) + throws IOException { + Properties props = loadPropertiesFile(propertiesFilepath); + + 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 = checkOutputDirectory(props); + this.logFile = new File(this.outputDirectory, LOGFILE_NAME); + this.listener = new MulticastListener(); + addListener(new LoggingListener(this.logFile)); + + this.suiteParentDirectories = checkSuiteParentDirectories(props); + + this.modelCleanerProperties = new ModelCleanerProperties(props); + + // Get the list of ignored tests. + String ignoredFilesPath = getRequiredProperty(props, PROP_IGNORED_TESTS); + File ignoredFilesFile = new File(ignoredFilesPath); + FileHelper.checkReadableFile(ignoredFilesFile, "File '" + + ignoredFilesPath + "'"); + this.ignoredTests = new IgnoredTests(ignoredFilesFile); + } + + /** + * Load the properties from the properties file. + */ + private Properties loadPropertiesFile(String propertiesFilepath) + throws FileNotFoundException, IOException { + File propsFile = new File(propertiesFilepath); + if (!propsFile.exists()) { + throw new FileNotFoundException("Property file does not exist: '" + + propsFile + "'"); + } + + Reader propsReader = null; + try { + propsReader = new FileReader(propsFile); + Properties props = new Properties(); + props.load(propsReader); + return props; + } finally { + if (propsReader != null) { + try { + propsReader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + /** + * 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; + } + + value = value.trim(); + if (value.trim().length() == 0) { + 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 required directory path, and that + * it points to a valid directory. + */ + private File checkReadWriteDirectory(Properties props, String key) { + String value = getRequiredProperty(props, key); + + File dir = new File(value); + + if (!dir.exists()) { + throw new IllegalArgumentException("Directory " + key + " '" + + value + "' does not exist. (" + dir.getAbsolutePath() + + ")"); + } + + if (!dir.isDirectory()) { + throw new IllegalArgumentException("Directory " + key + " '" + + value + "' is not a directory. (" + dir.getAbsolutePath() + + ")"); + } + + if (!dir.canRead()) { + throw new IllegalArgumentException("Directory " + key + " '" + + value + "' is not readable. (" + dir.getAbsolutePath() + + ")"); + } + + if (!dir.canWrite()) { + throw new IllegalArgumentException("Directory " + key + " '" + + value + "' is not writeable. (" + dir.getAbsolutePath() + + ")"); + } + 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 + ": '" + value + + "' does not exist. (" + file.getAbsolutePath() + ")"); + } + if (!file.isFile()) { + throw new IllegalArgumentException("File " + key + ": '" + value + + "' is not a file. (" + file.getAbsolutePath() + ")"); + } + if (!file.canRead()) { + throw new IllegalArgumentException("File " + key + ": '" + value + + "' is not readable. (" + file.getAbsolutePath() + ")"); + } + return file; + } + + /** + * Get the property for the output directory. If it does not exist, create + * it (the parent must exist). Ensure that it is writeable. + */ + private File checkOutputDirectory(Properties props) throws IOException { + String value = getRequiredProperty(props, PROP_OUTPUT_DIRECTORY); + File outputDirectory = new File(value); + File outputParent = outputDirectory.getParentFile(); + + if (!outputDirectory.exists()) { + if (!outputParent.exists()) { + throw new IllegalArgumentException( + "Output directory does not exist, nor does its parent. '" + + outputDirectory + "' (" + + outputDirectory.getAbsolutePath() + ")"); + } + outputDirectory.mkdir(); + if (!outputDirectory.exists()) { + throw new IOException("Failed to create output directory: '" + + outputDirectory + "' (" + + outputDirectory.getAbsolutePath() + ")"); + } + } + + if (!outputDirectory.isDirectory()) { + throw new IllegalArgumentException("Suite directory '" + + outputDirectory.getPath() + "' is not a directory. (" + + outputDirectory.getAbsolutePath() + ")"); + } + if (!outputDirectory.canRead()) { + throw new IllegalArgumentException("Suite directory '" + + outputDirectory.getPath() + "' is not readable. (" + + outputDirectory.getAbsolutePath() + ")"); + } + if (!outputDirectory.canWrite()) { + throw new IllegalArgumentException("Suite directory '" + + outputDirectory.getPath() + "' is not writeable. (" + + outputDirectory.getAbsolutePath() + ")"); + } + + return outputDirectory; + } + + /** + * Get the property for the suite directories and ensure that each one is + * indeed a readable directory. + */ + private Collection checkSuiteParentDirectories(Properties props) { + String value = getRequiredProperty(props, PROP_SUITE_DIRECTORIES); + + List dirs = new ArrayList(); + String[] paths = value.split("[:;]"); + for (String path : paths) { + File dir = new File(path.trim()); + + if (!dir.exists()) { + throw new IllegalArgumentException("Suite directory '" + + dir.getPath() + "' does not exist. (" + + dir.getAbsolutePath() + ")"); + } + if (!dir.isDirectory()) { + throw new IllegalArgumentException("Suite directory '" + + dir.getPath() + "' is not a directory. (" + + dir.getAbsolutePath() + ")"); + } + if (!dir.canRead()) { + throw new IllegalArgumentException("Suite directory '" + + dir.getPath() + "' is not readable. (" + + dir.getAbsolutePath() + ")"); + } + dirs.add(dir); + } + return dirs; + } + + /** + * 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; + } + + /** + * 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 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 void addListener(Listener l) { + if (listener instanceof MulticastListener) { + ((MulticastListener) listener).addListener(l); + } else { + throw new IllegalStateException("Listener is not a multi-cast -- " + + "can't add new listeners."); + } + } + + public Listener getListener() { + return listener; + } + + public void setListener(Listener logger) { + this.listener = logger; + } + + public File getUploadDirectory() { + return uploadDirectory; + } + + public File getOutputDirectory() { + return outputDirectory; + } + + public File getLogFile() { + return logFile; + } + + public Collection getSuiteParentDirectories() { + return suiteParentDirectories; + } + + public ModelCleanerProperties getModelCleanerProperties() { + return modelCleanerProperties; + } + + public IgnoredTests getIgnoredTests() { + return ignoredTests; + } + + public boolean isCleanModel() { + return cleanModel; + } + + public void setCleanModel(boolean cleanModel) { + this.cleanModel = cleanModel; + } + + public boolean isCleanUploads() { + return cleanUploads; + } + + public void setCleanUploads(boolean cleanUploads) { + this.cleanUploads = cleanUploads; + } + + public String toString() { + return "Parameters:" + "\n websiteUrl: " + websiteUrl + + "\n userExtensionsFile: " + userExtensionsFile + + "\n firefoxProfileDir: " + firefoxProfileDir + + "\n suiteTimeoutLimit: " + suiteTimeoutLimit + + "\n seleniumJarPath: " + seleniumJarPath + + "\n uploadDirectory: " + uploadDirectory + + "\n outputDirectory: " + outputDirectory + + "\n suiteParentDirectories: " + suiteParentDirectories + + "\n modelCleanerProperties: " + modelCleanerProperties + + "\n" + ignoredTests + "\n cleanModel: " + cleanModel + + "\n cleanUploads: " + cleanUploads; + } + + /** + * 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 findSuiteDirs(File 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 { + listener.subProcessErrout("Warning: suite file '" + + suiteFile.getPath() + "' does not exist.\n"); + return false; + } + } + })); + } + +} diff --git a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/datamodel/DataModel.java b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/datamodel/DataModel.java index a02f970be..fc6689f5e 100644 --- a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/datamodel/DataModel.java +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/datamodel/DataModel.java @@ -1,294 +1,294 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.utilities.testrunner.datamodel; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; - -import edu.cornell.mannlib.vitro.utilities.testrunner.IgnoredTests; -import edu.cornell.mannlib.vitro.utilities.testrunner.IgnoredTests.IgnoredTestInfo; -import edu.cornell.mannlib.vitro.utilities.testrunner.LogStats; -import edu.cornell.mannlib.vitro.utilities.testrunner.Status; -import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.SuiteData.TestData; -import edu.cornell.mannlib.vitro.utilities.testrunner.output.OutputDataListener; -import edu.cornell.mannlib.vitro.utilities.testrunner.output.OutputDataListener.ProcessOutput; -import edu.cornell.mannlib.vitro.utilities.testrunner.output.SuiteResults; - -/** - * Collect all that we know about suites, tests, and their current status. - */ -public class DataModel { - - /* base data */ - private Collection suiteContents = Collections.emptyList(); - private Collection selectedSuites = Collections.emptyList(); - private Collection suiteResults = Collections.emptyList(); - private OutputDataListener.Info dataListenerInfo = OutputDataListener.Info.EMPTY_INFO; - private IgnoredTests ignoredTestList = IgnoredTests.EMPTY_LIST; - private LogStats logStats = LogStats.EMPTY_LOG_STATS; // TODO - - /* derived data */ - private Status runStatus = Status.PENDING; - - private final SortedMap suiteDataMap = new TreeMap(); - private final EnumMap> suiteMapByStatus = new EnumMap>( - Status.class); - - private final List allTests = new ArrayList(); - private final EnumMap> testMapByStatus = new EnumMap>( - Status.class); - - // ---------------------------------------------------------------------- - // Constructor - // ---------------------------------------------------------------------- - - public DataModel() { - calculate(); - } - - // ---------------------------------------------------------------------- - // Update the base data. - // ---------------------------------------------------------------------- - - public void setSuiteContents(Collection suiteContents) { - this.suiteContents = new ArrayList(suiteContents); - calculate(); - } - - public void setSelectedSuites(Collection selectedSuites) { - this.selectedSuites = new ArrayList(selectedSuites); - calculate(); - } - - public Collection getSelectedSuites() { - return new ArrayList(selectedSuites); - } - - public void setSuiteResults(Collection suiteResults) { - this.suiteResults = new ArrayList(suiteResults); - calculate(); - } - - public void captureDataListener(OutputDataListener dataListener) { - this.dataListenerInfo = dataListener.getInfo(); - calculate(); - } - - public void setIgnoredTestList(IgnoredTests ignoredTestList) { - this.ignoredTestList = ignoredTestList; - calculate(); - } - - public void setLogStats(LogStats logStats) { // TODO - this.logStats = logStats; - calculate(); - } - - // ---------------------------------------------------------------------- - // Keep the derived data current. - // ---------------------------------------------------------------------- - - /** - * Data in the model has been updated. Refresh all derived data. - */ - private void calculate() { - // Clear all derived data. - runStatus = Status.OK; - - suiteDataMap.clear(); - suiteMapByStatus.clear(); - for (Status s : Status.values()) { - suiteMapByStatus.put(s, new ArrayList()); - } - - allTests.clear(); - testMapByStatus.clear(); - for (Status s : Status.values()) { - testMapByStatus.put(s, new ArrayList()); - } - - /* - * Populate the Suite map with all Suites. - */ - Map resultsMap = new HashMap(); - for (SuiteResults result : suiteResults) { - resultsMap.put(result.getName(), result); - } - Map contentsMap = new HashMap(); - for (SuiteContents contents : suiteContents) { - contentsMap.put(contents.getName(), contents); - } - - for (SuiteContents contents : suiteContents) { - String name = contents.getName(); - SuiteResults result = resultsMap.get(name); - boolean ignored = ignoredTestList.isIgnored(name); - ProcessOutput failureMessages = dataListenerInfo - .getFailureMessages().get(name); - suiteDataMap.put(name, new SuiteData(name, ignored, contents, - result, failureMessages)); - } - - /* - * Map the Suites by status. - */ - for (SuiteData s : suiteDataMap.values()) { - getSuites(s.getStatus()).add(s); - } - - /** - * Populate the Test map with all Tests, and map by status. - */ - for (SuiteData s : suiteDataMap.values()) { - for (TestData t : s.getTestMap().values()) { - allTests.add(t); - getTests(t.getStatus()).add(t); - } - } - - if (logStats.hasErrors() || !getSuites(Status.ERROR).isEmpty()) { - runStatus = Status.ERROR; - } else if (!getSuites(Status.PENDING).isEmpty()) { - runStatus = Status.PENDING; - } else { - runStatus = Status.OK; - } - } - - // ---------------------------------------------------------------------- - // Access the derived data. - // ---------------------------------------------------------------------- - - public Status getRunStatus() { - return runStatus; - } - - public long getStartTime() { - return dataListenerInfo.getStartTime(); - } - - public long getEndTime() { - return dataListenerInfo.getEndTime(); - } - - public long getElapsedTime() { - return dataListenerInfo.getElapsedTime(); - } - - public boolean isAnyPasses() { - return !getTests(Status.OK).isEmpty(); - } - - public boolean isAnyFailures() { - return !getTests(Status.ERROR).isEmpty(); - } - - public boolean isAnyIgnores() { - return !getTests(Status.IGNORED).isEmpty(); - } - - public boolean isAnyPending() { - return !getTests(Status.PENDING).isEmpty(); - } - - public int getTotalSuiteCount() { - return suiteDataMap.size(); - } - - public int getPassingSuiteCount() { - return getSuites(Status.OK).size(); - } - - public int getFailingSuiteCount() { - return getSuites(Status.ERROR).size(); - } - - public int getIgnoredSuiteCount() { - return getSuites(Status.IGNORED).size(); - } - - public int getPendingSuiteCount() { - return getSuites(Status.PENDING).size(); - } - - public Collection getAllSuites() { - return suiteDataMap.values(); - } - - public Map getSuitesWithFailureMessages() { - Map map = new TreeMap(); - for (SuiteData s : suiteDataMap.values()) { - if (s.getFailureMessages() != null) { - map.put(s.getName(), s); - } - } - return map; - } - - public int getTotalTestCount() { - return allTests.size(); - } - - public int getPassingTestCount() { - return getTests(Status.OK).size(); - } - - public int getFailingTestCount() { - return getTests(Status.ERROR).size(); - } - - public int getIgnoredTestCount() { - return getTests(Status.IGNORED).size(); - } - - public int getPendingTestCount() { - return getTests(Status.PENDING).size(); - } - - public Collection getAllTests() { - return Collections.unmodifiableCollection(allTests); - } - - public Collection getFailingTests() { - return Collections.unmodifiableCollection(getTests(Status.ERROR)); - } - - public Collection getIgnoredTests() { - return Collections.unmodifiableCollection(getTests(Status.IGNORED)); - } - - public Collection getIgnoredTestInfo() { - return ignoredTestList.getList(); - } - - public String getReasonForIgnoring(String suiteName, String testName) { - return ignoredTestList.getReasonForIgnoring(suiteName, testName); - } - - // ---------------------------------------------------------------------- - // Helper methods - // ---------------------------------------------------------------------- - - /** - * Get the list of suites that have this status. - */ - private List getSuites(Status st) { - return suiteMapByStatus.get(st); - } - - /** - * Get the list of tests that have this status. - */ - private List getTests(Status st) { - return testMapByStatus.get(st); - } - -} +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.utilities.testrunner.datamodel; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +import edu.cornell.mannlib.vitro.utilities.testrunner.IgnoredTests; +import edu.cornell.mannlib.vitro.utilities.testrunner.IgnoredTests.IgnoredTestInfo; +import edu.cornell.mannlib.vitro.utilities.testrunner.LogStats; +import edu.cornell.mannlib.vitro.utilities.testrunner.Status; +import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.SuiteData.TestData; +import edu.cornell.mannlib.vitro.utilities.testrunner.output.OutputDataListener; +import edu.cornell.mannlib.vitro.utilities.testrunner.output.OutputDataListener.ProcessOutput; +import edu.cornell.mannlib.vitro.utilities.testrunner.output.SuiteResults; + +/** + * Collect all that we know about suites, tests, and their current status. + */ +public class DataModel { + + /* base data */ + private Collection suiteContents = Collections.emptyList(); + private Collection selectedSuites = Collections.emptyList(); + private Collection suiteResults = Collections.emptyList(); + private OutputDataListener.Info dataListenerInfo = OutputDataListener.Info.EMPTY_INFO; + private IgnoredTests ignoredTestList = IgnoredTests.EMPTY_LIST; + private LogStats logStats = LogStats.EMPTY_LOG_STATS; // TODO + + /* derived data */ + private Status runStatus = Status.PENDING; + + private final SortedMap suiteDataMap = new TreeMap(); + private final EnumMap> suiteMapByStatus = new EnumMap>( + Status.class); + + private final List allTests = new ArrayList(); + private final EnumMap> testMapByStatus = new EnumMap>( + Status.class); + + // ---------------------------------------------------------------------- + // Constructor + // ---------------------------------------------------------------------- + + public DataModel() { + calculate(); + } + + // ---------------------------------------------------------------------- + // Update the base data. + // ---------------------------------------------------------------------- + + public void setSuiteContents(Collection suiteContents) { + this.suiteContents = new ArrayList(suiteContents); + calculate(); + } + + public void setSelectedSuites(Collection selectedSuites) { + this.selectedSuites = new ArrayList(selectedSuites); + calculate(); + } + + public Collection getSelectedSuites() { + return new ArrayList(selectedSuites); + } + + public void setSuiteResults(Collection suiteResults) { + this.suiteResults = new ArrayList(suiteResults); + calculate(); + } + + public void captureDataListener(OutputDataListener dataListener) { + this.dataListenerInfo = dataListener.getInfo(); + calculate(); + } + + public void setIgnoredTestList(IgnoredTests ignoredTestList) { + this.ignoredTestList = ignoredTestList; + calculate(); + } + + public void setLogStats(LogStats logStats) { // TODO + this.logStats = logStats; + calculate(); + } + + // ---------------------------------------------------------------------- + // Keep the derived data current. + // ---------------------------------------------------------------------- + + /** + * Data in the model has been updated. Refresh all derived data. + */ + private void calculate() { + // Clear all derived data. + runStatus = Status.OK; + + suiteDataMap.clear(); + suiteMapByStatus.clear(); + for (Status s : Status.values()) { + suiteMapByStatus.put(s, new ArrayList()); + } + + allTests.clear(); + testMapByStatus.clear(); + for (Status s : Status.values()) { + testMapByStatus.put(s, new ArrayList()); + } + + /* + * Populate the Suite map with all Suites. + */ + Map resultsMap = new HashMap(); + for (SuiteResults result : suiteResults) { + resultsMap.put(result.getName(), result); + } + Map contentsMap = new HashMap(); + for (SuiteContents contents : suiteContents) { + contentsMap.put(contents.getName(), contents); + } + + for (SuiteContents contents : suiteContents) { + String name = contents.getName(); + SuiteResults result = resultsMap.get(name); + boolean ignored = ignoredTestList.isIgnored(name); + ProcessOutput failureMessages = dataListenerInfo + .getFailureMessages().get(name); + suiteDataMap.put(name, new SuiteData(name, ignored, contents, + result, failureMessages)); + } + + /* + * Map the Suites by status. + */ + for (SuiteData s : suiteDataMap.values()) { + getSuites(s.getStatus()).add(s); + } + + /** + * Populate the Test map with all Tests, and map by status. + */ + for (SuiteData s : suiteDataMap.values()) { + for (TestData t : s.getTestMap().values()) { + allTests.add(t); + getTests(t.getStatus()).add(t); + } + } + + if (logStats.hasErrors() || !getSuites(Status.ERROR).isEmpty()) { + runStatus = Status.ERROR; + } else if (!getSuites(Status.PENDING).isEmpty()) { + runStatus = Status.PENDING; + } else { + runStatus = Status.OK; + } + } + + // ---------------------------------------------------------------------- + // Access the derived data. + // ---------------------------------------------------------------------- + + public Status getRunStatus() { + return runStatus; + } + + public long getStartTime() { + return dataListenerInfo.getStartTime(); + } + + public long getEndTime() { + return dataListenerInfo.getEndTime(); + } + + public long getElapsedTime() { + return dataListenerInfo.getElapsedTime(); + } + + public boolean isAnyPasses() { + return !getTests(Status.OK).isEmpty(); + } + + public boolean isAnyFailures() { + return !getTests(Status.ERROR).isEmpty(); + } + + public boolean isAnyIgnores() { + return !getTests(Status.IGNORED).isEmpty(); + } + + public boolean isAnyPending() { + return !getTests(Status.PENDING).isEmpty(); + } + + public int getTotalSuiteCount() { + return suiteDataMap.size(); + } + + public int getPassingSuiteCount() { + return getSuites(Status.OK).size(); + } + + public int getFailingSuiteCount() { + return getSuites(Status.ERROR).size(); + } + + public int getIgnoredSuiteCount() { + return getSuites(Status.IGNORED).size(); + } + + public int getPendingSuiteCount() { + return getSuites(Status.PENDING).size(); + } + + public Collection getAllSuites() { + return suiteDataMap.values(); + } + + public Map getSuitesWithFailureMessages() { + Map map = new TreeMap(); + for (SuiteData s : suiteDataMap.values()) { + if (s.getFailureMessages() != null) { + map.put(s.getName(), s); + } + } + return map; + } + + public int getTotalTestCount() { + return allTests.size(); + } + + public int getPassingTestCount() { + return getTests(Status.OK).size(); + } + + public int getFailingTestCount() { + return getTests(Status.ERROR).size(); + } + + public int getIgnoredTestCount() { + return getTests(Status.IGNORED).size(); + } + + public int getPendingTestCount() { + return getTests(Status.PENDING).size(); + } + + public Collection getAllTests() { + return Collections.unmodifiableCollection(allTests); + } + + public Collection getFailingTests() { + return Collections.unmodifiableCollection(getTests(Status.ERROR)); + } + + public Collection getIgnoredTests() { + return Collections.unmodifiableCollection(getTests(Status.IGNORED)); + } + + public Collection getIgnoredTestInfo() { + return ignoredTestList.getList(); + } + + public String getReasonForIgnoring(String suiteName, String testName) { + return ignoredTestList.getReasonForIgnoring(suiteName, testName); + } + + // ---------------------------------------------------------------------- + // Helper methods + // ---------------------------------------------------------------------- + + /** + * Get the list of suites that have this status. + */ + private List getSuites(Status st) { + return suiteMapByStatus.get(st); + } + + /** + * Get the list of tests that have this status. + */ + private List getTests(Status st) { + return testMapByStatus.get(st); + } + +} diff --git a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/OutputSummaryFormatter.java b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/OutputSummaryFormatter.java index 2d76e2929..815ae31ba 100644 --- a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/OutputSummaryFormatter.java +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/OutputSummaryFormatter.java @@ -1,375 +1,375 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.utilities.testrunner.output; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.Reader; -import java.text.SimpleDateFormat; -import java.util.Collection; -import java.util.Date; -import java.util.Map; - -import edu.cornell.mannlib.vitro.utilities.testrunner.FileHelper; -import edu.cornell.mannlib.vitro.utilities.testrunner.IgnoredTests.IgnoredTestInfo; -import edu.cornell.mannlib.vitro.utilities.testrunner.LogStats; -import edu.cornell.mannlib.vitro.utilities.testrunner.SeleniumRunnerParameters; -import edu.cornell.mannlib.vitro.utilities.testrunner.Status; -import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.DataModel; -import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.SuiteData; -import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.SuiteData.TestData; -import edu.cornell.mannlib.vitro.utilities.testrunner.output.OutputDataListener.ProcessOutput; - -/** - * Creates the summary HTML file. - */ -public class OutputSummaryFormatter { - public static final String SUMMARY_HTML_FILENAME = "summary.html"; - public static final String SUMMARY_CSS_FILENAME = "summary.css"; - private final SimpleDateFormat dateFormat = new SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss"); - private final SeleniumRunnerParameters parms; - - private LogStats logStats; - private DataModel dataModel; - - public OutputSummaryFormatter(SeleniumRunnerParameters parms) { - this.parms = parms; - } - - /** - * Create a summary HTML file from the info contained in this log file and - * these suite outputs. - */ - public void format(LogStats logStats, DataModel dataModel) { - this.logStats = logStats; - this.dataModel = dataModel; - - PrintWriter writer = null; - try { - copyCssFile(); - - File outputFile = new File(parms.getOutputDirectory(), - SUMMARY_HTML_FILENAME); - writer = new PrintWriter(outputFile); - - writeHeader(writer); - writeStatsSection(writer); - writeErrorMessagesSection(writer); - writeCondensedTable(writer); - writeIgnoreSection(writer); - writeSuiteErrorMessagesSection(writer); - writeFooter(writer); - } catch (IOException e) { - // There is no appeal for any problems here. Just report them. - e.printStackTrace(); - } finally { - if (writer != null) { - writer.close(); - } - } - } - - /** - * Copy the CSS file into the output directory. - */ - private void copyCssFile() { - InputStream cssStream = this.getClass().getResourceAsStream( - SUMMARY_CSS_FILENAME); - if (cssStream == null) { - System.out.println("Couldn't find the CSS file: '" - + SUMMARY_CSS_FILENAME + "'"); - } else { - File cssTarget = new File(parms.getOutputDirectory(), - SUMMARY_CSS_FILENAME); - try { - FileHelper.copy(cssStream, cssTarget); - cssStream.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - private void writeHeader(PrintWriter w) { - Status runStatus = dataModel.getRunStatus(); - String statusString = (runStatus == Status.PENDING) ? "IN PROGRESS" - : runStatus.toString(); - String startString = formatDateTime(dataModel.getStartTime()); - - w.println(""); - w.println(""); - w.println(" Summary of Acceptance Tests " + startString - + ""); - w.println(" "); - w.println(""); - w.println(""); - w.println(); - w.println("
"); - w.println(" Acceptance test results: " + startString); - w.println("
" + statusString + "
"); - w.println("
"); - } - - private void writeStatsSection(PrintWriter w) { - String passClass = dataModel.isAnyPasses() ? Status.OK.getHtmlClass() - : ""; - String failClass = dataModel.isAnyFailures() ? Status.ERROR - .getHtmlClass() : ""; - String ignoreClass = dataModel.isAnyIgnores() ? Status.IGNORED - .getHtmlClass() : ""; - - String start = formatDateTime(dataModel.getStartTime()); - String end = formatDateTime(dataModel.getEndTime()); - String elapsed = formatElapsedTime(dataModel.getElapsedTime()); - - w.println("
Summary
"); - w.println(); - w.println(" "); - w.println(" "); - w.println(" "); - w.println(" "); - w.println(" "); - w.println("
"); - w.println(" "); - w.println(" "); - w.println(" "); - w.println(" "); - w.println("
Start time:" + start - + "
End time:" + end + "
Elapsed time" + elapsed - + "
"); - w.println("
"); - w.println(" "); - w.println(" "); - w.println(" "); - w.println(" "); - w.println(" "); - if (dataModel.isAnyPending()) { - w.println(" "); - } - w.println(" "); - w.println("
 SuitesTests
Passed" + dataModel.getPassingSuiteCount() - + "" + dataModel.getPassingTestCount() + "
Failed" + dataModel.getFailingSuiteCount() - + "" + dataModel.getFailingTestCount() + "
Ignored" + dataModel.getIgnoredSuiteCount() - + "" + dataModel.getIgnoredTestCount() + "
Pending" - + dataModel.getPendingSuiteCount() + "" - + dataModel.getPendingTestCount() + "
Total" - + dataModel.getTotalSuiteCount() + "" - + dataModel.getTotalTestCount() + "
"); - w.println("
"); - w.println(); - } - - private void writeErrorMessagesSection(PrintWriter w) { - String errorClass = Status.ERROR.getHtmlClass(); - - w.println("
Errors and warnings
"); - w.println(); - w.println(" "); - - if ((!logStats.hasErrors()) && (!logStats.hasWarnings())) { - w.println(" "); - } else { - for (String e : logStats.getErrors()) { - w.println(" "); - } - } - w.println("
No errors or warnings
ERROR" + e + "
"); - w.println(); - } - - private void writeCondensedTable(PrintWriter w) { - w.println("
Condensed List
"); - w.println(); - w.println(" "); - for (SuiteData s : dataModel.getAllSuites()) { - String sReason = ""; - if (s.getStatus() == Status.IGNORED) { - sReason = dataModel.getReasonForIgnoring(s.getName(), "*"); - } else if (s.getFailureMessages() != null) { - sReason = s.getFailureMessages().getErrout(); - } else if (s.getStatus() == Status.PENDING) { - sReason = Status.PENDING.toString(); - } - - w.println(" "); - w.println(" "); - w.println(" "); - } - w.println("
"); - w.println("
" + outputLink(s) - + "
"); - if (!sReason.isEmpty()) { - // The entire class is either failed or pending or ignored. - w.println("
" + sReason + "
"); - } else { - // Show the individual tests. - for (TestData t : s.getTestMap().values()) { - String tClass = t.getStatus().getHtmlClass(); - String tReason = dataModel.getReasonForIgnoring( - s.getName(), t.getTestName()); - - w.println("
"); - w.println(" " + outputLink(t)); - if (!tReason.isEmpty()) { - w.println("
" + tReason - + "
"); - } - w.println("
"); - } - } - w.println("
"); - w.println(); - } - - private void writeSuiteErrorMessagesSection(PrintWriter w) { - Map failedSuiteMap = dataModel - .getSuitesWithFailureMessages(); - if (failedSuiteMap.isEmpty()) { - return; - } - - w.println("
All tests
"); - w.println(); - for (SuiteData s : failedSuiteMap.values()) { - ProcessOutput output = s.getFailureMessages(); - - w.println(" "); - w.println(" "); - w.println(" \n"); - w.println(" \n"); - w.println("
Standard Output
" + output.getStdout()
-					+ "
"); - w.println("
 
"); - - w.println(" "); - w.println(" \n"); - w.println(" \n"); - w.println("
Error Output
" + output.getErrout()
-					+ "
"); - w.println("
 
"); - w.println(); - } - } - - private void writeIgnoreSection(PrintWriter w) { - String warnClass = Status.IGNORED.getHtmlClass(); - Collection ignoredTests = dataModel - .getIgnoredTestInfo(); - - w.println("
Ignored
"); - w.println(); - w.println(" "); - w.println(" " - + "\n"); - if (ignoredTests.isEmpty()) { - w.println(" " - + ""); - } else { - for (IgnoredTestInfo info : ignoredTests) { - String suiteName = info.suiteName; - String testName = info.testName; - String reason = dataModel.getReasonForIgnoring(suiteName, - testName); - - w.println(" "); - w.println(" "); - w.println(" "); - w.println(" "); - w.println(" "); - } - } - w.println("
Suite nameTest nameReason for ignoring
No tests ignored.
" + suiteName + "" + testName + "" + reason + "
"); - w.println(); - } - - private void writeFooter(PrintWriter w) { - w.println("
Log
"); - w.println("
");
-
-		Reader reader = null;
-		try {
-			reader = new FileReader(parms.getLogFile());
-			char[] buffer = new char[4096];
-			int howMany;
-			while (-1 != (howMany = reader.read(buffer))) {
-				w.write(buffer, 0, howMany);
-			}
-		} catch (IOException e) {
-			e.printStackTrace();
-		} finally {
-			if (reader != null) {
-				try {
-					reader.close();
-				} catch (IOException e) {
-					e.printStackTrace();
-				}
-			}
-		}
-
-		w.println("  
"); - w.println(""); - w.println(""); - } - - private String formatElapsedTime(long elapsed) { - if (elapsed == 0) { - return "---"; - } - - long elapsedSeconds = elapsed / 1000L; - long seconds = elapsedSeconds % 60L; - long elapsedMinutes = elapsedSeconds / 60L; - long minutes = elapsedMinutes % 60L; - long hours = elapsedMinutes / 60L; - - String elapsedTime = ""; - if (hours > 0) { - elapsedTime += hours + "h "; - } - if (minutes > 0 || hours > 0) { - elapsedTime += minutes + "m "; - } - elapsedTime += seconds + "s"; - - return elapsedTime; - } - - private String formatDateTime(long dateTime) { - if (dateTime == 0) { - return "---"; - } - - return dateFormat.format(new Date(dateTime)); - } - - private String outputLink(SuiteData s) { - if (s.getOutputLink() == null) { - return s.getName(); - } else { - return "
" + s.getName() - + ""; - } - } - - private String outputLink(TestData t) { - if (t.getOutputLink() == null) { - return t.getTestName(); - } else { - return "" + t.getTestName() - + ""; - } - } -} +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.utilities.testrunner.output; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.Reader; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; +import java.util.Map; + +import edu.cornell.mannlib.vitro.utilities.testrunner.FileHelper; +import edu.cornell.mannlib.vitro.utilities.testrunner.IgnoredTests.IgnoredTestInfo; +import edu.cornell.mannlib.vitro.utilities.testrunner.LogStats; +import edu.cornell.mannlib.vitro.utilities.testrunner.SeleniumRunnerParameters; +import edu.cornell.mannlib.vitro.utilities.testrunner.Status; +import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.DataModel; +import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.SuiteData; +import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.SuiteData.TestData; +import edu.cornell.mannlib.vitro.utilities.testrunner.output.OutputDataListener.ProcessOutput; + +/** + * Creates the summary HTML file. + */ +public class OutputSummaryFormatter { + public static final String SUMMARY_HTML_FILENAME = "summary.html"; + public static final String SUMMARY_CSS_FILENAME = "summary.css"; + private final SimpleDateFormat dateFormat = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + private final SeleniumRunnerParameters parms; + + private LogStats logStats; + private DataModel dataModel; + + public OutputSummaryFormatter(SeleniumRunnerParameters parms) { + this.parms = parms; + } + + /** + * Create a summary HTML file from the info contained in this log file and + * these suite outputs. + */ + public void format(LogStats logStats, DataModel dataModel) { + this.logStats = logStats; + this.dataModel = dataModel; + + PrintWriter writer = null; + try { + copyCssFile(); + + File outputFile = new File(parms.getOutputDirectory(), + SUMMARY_HTML_FILENAME); + writer = new PrintWriter(outputFile); + + writeHeader(writer); + writeStatsSection(writer); + writeErrorMessagesSection(writer); + writeCondensedTable(writer); + writeIgnoreSection(writer); + writeSuiteErrorMessagesSection(writer); + writeFooter(writer); + } catch (IOException e) { + // There is no appeal for any problems here. Just report them. + e.printStackTrace(); + } finally { + if (writer != null) { + writer.close(); + } + } + } + + /** + * Copy the CSS file into the output directory. + */ + private void copyCssFile() { + InputStream cssStream = this.getClass().getResourceAsStream( + SUMMARY_CSS_FILENAME); + if (cssStream == null) { + System.out.println("Couldn't find the CSS file: '" + + SUMMARY_CSS_FILENAME + "'"); + } else { + File cssTarget = new File(parms.getOutputDirectory(), + SUMMARY_CSS_FILENAME); + try { + FileHelper.copy(cssStream, cssTarget); + cssStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + private void writeHeader(PrintWriter w) { + Status runStatus = dataModel.getRunStatus(); + String statusString = (runStatus == Status.PENDING) ? "IN PROGRESS" + : runStatus.toString(); + String startString = formatDateTime(dataModel.getStartTime()); + + w.println(""); + w.println(""); + w.println(" Summary of Acceptance Tests " + startString + + ""); + w.println(" "); + w.println(""); + w.println(""); + w.println(); + w.println("
"); + w.println(" Acceptance test results: " + startString); + w.println("
" + statusString + "
"); + w.println("
"); + } + + private void writeStatsSection(PrintWriter w) { + String passClass = dataModel.isAnyPasses() ? Status.OK.getHtmlClass() + : ""; + String failClass = dataModel.isAnyFailures() ? Status.ERROR + .getHtmlClass() : ""; + String ignoreClass = dataModel.isAnyIgnores() ? Status.IGNORED + .getHtmlClass() : ""; + + String start = formatDateTime(dataModel.getStartTime()); + String end = formatDateTime(dataModel.getEndTime()); + String elapsed = formatElapsedTime(dataModel.getElapsedTime()); + + w.println("
Summary
"); + w.println(); + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); + w.println("
"); + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); + w.println("
Start time:" + start + + "
End time:" + end + "
Elapsed time" + elapsed + + "
"); + w.println("
"); + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); + if (dataModel.isAnyPending()) { + w.println(" "); + } + w.println(" "); + w.println("
 SuitesTests
Passed" + dataModel.getPassingSuiteCount() + + "" + dataModel.getPassingTestCount() + "
Failed" + dataModel.getFailingSuiteCount() + + "" + dataModel.getFailingTestCount() + "
Ignored" + dataModel.getIgnoredSuiteCount() + + "" + dataModel.getIgnoredTestCount() + "
Pending" + + dataModel.getPendingSuiteCount() + "" + + dataModel.getPendingTestCount() + "
Total" + + dataModel.getTotalSuiteCount() + "" + + dataModel.getTotalTestCount() + "
"); + w.println("
"); + w.println(); + } + + private void writeErrorMessagesSection(PrintWriter w) { + String errorClass = Status.ERROR.getHtmlClass(); + + w.println("
Errors and warnings
"); + w.println(); + w.println(" "); + + if ((!logStats.hasErrors()) && (!logStats.hasWarnings())) { + w.println(" "); + } else { + for (String e : logStats.getErrors()) { + w.println(" "); + } + } + w.println("
No errors or warnings
ERROR" + e + "
"); + w.println(); + } + + private void writeCondensedTable(PrintWriter w) { + w.println("
Condensed List
"); + w.println(); + w.println(" "); + for (SuiteData s : dataModel.getAllSuites()) { + String sReason = ""; + if (s.getStatus() == Status.IGNORED) { + sReason = dataModel.getReasonForIgnoring(s.getName(), "*"); + } else if (s.getFailureMessages() != null) { + sReason = s.getFailureMessages().getErrout(); + } else if (s.getStatus() == Status.PENDING) { + sReason = Status.PENDING.toString(); + } + + w.println(" "); + w.println(" "); + w.println(" "); + } + w.println("
"); + w.println("
" + outputLink(s) + + "
"); + if (!sReason.isEmpty()) { + // The entire class is either failed or pending or ignored. + w.println("
" + sReason + "
"); + } else { + // Show the individual tests. + for (TestData t : s.getTestMap().values()) { + String tClass = t.getStatus().getHtmlClass(); + String tReason = dataModel.getReasonForIgnoring( + s.getName(), t.getTestName()); + + w.println("
"); + w.println(" " + outputLink(t)); + if (!tReason.isEmpty()) { + w.println("
" + tReason + + "
"); + } + w.println("
"); + } + } + w.println("
"); + w.println(); + } + + private void writeSuiteErrorMessagesSection(PrintWriter w) { + Map failedSuiteMap = dataModel + .getSuitesWithFailureMessages(); + if (failedSuiteMap.isEmpty()) { + return; + } + + w.println("
All tests
"); + w.println(); + for (SuiteData s : failedSuiteMap.values()) { + ProcessOutput output = s.getFailureMessages(); + + w.println(" "); + w.println(" "); + w.println(" \n"); + w.println(" \n"); + w.println("
Standard Output
" + output.getStdout()
+					+ "
"); + w.println("
 
"); + + w.println(" "); + w.println(" \n"); + w.println(" \n"); + w.println("
Error Output
" + output.getErrout()
+					+ "
"); + w.println("
 
"); + w.println(); + } + } + + private void writeIgnoreSection(PrintWriter w) { + String warnClass = Status.IGNORED.getHtmlClass(); + Collection ignoredTests = dataModel + .getIgnoredTestInfo(); + + w.println("
Ignored
"); + w.println(); + w.println(" "); + w.println(" " + + "\n"); + if (ignoredTests.isEmpty()) { + w.println(" " + + ""); + } else { + for (IgnoredTestInfo info : ignoredTests) { + String suiteName = info.suiteName; + String testName = info.testName; + String reason = dataModel.getReasonForIgnoring(suiteName, + testName); + + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); + } + } + w.println("
Suite nameTest nameReason for ignoring
No tests ignored.
" + suiteName + "" + testName + "" + reason + "
"); + w.println(); + } + + private void writeFooter(PrintWriter w) { + w.println("
Log
"); + w.println("
");
+
+		Reader reader = null;
+		try {
+			reader = new FileReader(parms.getLogFile());
+			char[] buffer = new char[4096];
+			int howMany;
+			while (-1 != (howMany = reader.read(buffer))) {
+				w.write(buffer, 0, howMany);
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (reader != null) {
+				try {
+					reader.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+
+		w.println("  
"); + w.println(""); + w.println(""); + } + + private String formatElapsedTime(long elapsed) { + if (elapsed == 0) { + return "---"; + } + + long elapsedSeconds = elapsed / 1000L; + long seconds = elapsedSeconds % 60L; + long elapsedMinutes = elapsedSeconds / 60L; + long minutes = elapsedMinutes % 60L; + long hours = elapsedMinutes / 60L; + + String elapsedTime = ""; + if (hours > 0) { + elapsedTime += hours + "h "; + } + if (minutes > 0 || hours > 0) { + elapsedTime += minutes + "m "; + } + elapsedTime += seconds + "s"; + + return elapsedTime; + } + + private String formatDateTime(long dateTime) { + if (dateTime == 0) { + return "---"; + } + + return dateFormat.format(new Date(dateTime)); + } + + private String outputLink(SuiteData s) { + if (s.getOutputLink() == null) { + return s.getName(); + } else { + return "
" + s.getName() + + ""; + } + } + + private String outputLink(TestData t) { + if (t.getOutputLink() == null) { + return t.getTestName(); + } else { + return "" + t.getTestName() + + ""; + } + } +}