From 7a2c5691cf7e3fbac04d80275b34099bd883392c Mon Sep 17 00:00:00 2001 From: jeb228 Date: Mon, 23 Aug 2010 15:00:34 +0000 Subject: [PATCH] NIHVIVO-222 Consolidate pre-run and post-run data into SuiteData, backing away from SuiteContents and SuiteResults, except as data-gathering classes. Distinguish between INGORED and WARN as two valid statuses with distinct meanings. --- .../utilities/testrunner/ModelCleaner.java | 7 + .../utilities/testrunner/SeleniumRunner.java | 2 +- .../testrunner/SeleniumRunnerParameters.java | 2 - .../vitro/utilities/testrunner/Status.java | 13 +- .../testrunner/datamodel/DataModel.java | 216 +++++-------- .../testrunner/datamodel/SuiteData.java | 189 ++++++++--- .../testrunner/output/OutputDataListener.java | 7 +- .../output/OutputSummaryFormatter.java | 296 ++++++++++-------- .../testrunner/output/SuiteResults.java | 16 +- .../utilities/testrunner/output/summary.css | 4 + 10 files changed, 435 insertions(+), 317 deletions(-) diff --git a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/ModelCleaner.java b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/ModelCleaner.java index 9a698431f..cc6d4bfc9 100644 --- a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/ModelCleaner.java +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/ModelCleaner.java @@ -29,6 +29,13 @@ public class ModelCleaner { this.tomcatController = tomcatController; sanityCheck(); + try { + tomcatController.stopTheWebapp(); + tomcatController.startTheWebapp(); + } catch (CommandRunnerException e) { + throw new FatalException( + "sanityCheck: Failed to stop and start Tomcat.", e); + } } private void sanityCheck() { diff --git a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/SeleniumRunner.java b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/SeleniumRunner.java index 3596460fb..b32877a92 100644 --- a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/SeleniumRunner.java +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/SeleniumRunner.java @@ -61,7 +61,7 @@ public class SeleniumRunner { listener.runEndTime(); outputManager.summarizeOutput(dataModel); - success = (dataModel.getRunStatus() == Status.OK); + success = Status.isSuccess(dataModel.getRunStatus()); } catch (IOException e) { listener.runFailed(e); success = false; 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 ff5d1b144..1fd8020f8 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 @@ -11,7 +11,6 @@ import java.io.Reader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Properties; @@ -411,7 +410,6 @@ public class SeleniumRunnerParameters { * recognize a suite directory because it contains a file named Suite.html. */ public Collection findSuiteDirs(File parentDir) { - System.out.println("parentDir: " + parentDir); return Arrays.asList(parentDir.listFiles(new FileFilter() { public boolean accept(File pathname) { if (!pathname.isDirectory()) { diff --git a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/Status.java b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/Status.java index 5089d372e..0fdb94e88 100644 --- a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/Status.java +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/Status.java @@ -12,13 +12,13 @@ public enum Status { /** * One or more tests have not been run yet. */ - PENDING(""), + PENDING("pending"), /** - * Any test failure was ignored, and any messages were no worse than - * warnings. + * Will not run because it is ignored, or has run and failed but the failure + * is ignored. */ - WARN("fair"), + IGNORED("fair"), /** * A test failed and could not be ignored, or an error message was @@ -44,4 +44,9 @@ public enum Status { return s2; } } + + /** Anything except ERROR is considered to be a success. */ + public static boolean isSuccess(Status status) { + return status != Status.ERROR; + } } 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 b8dbb6e36..a02f970be 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 @@ -6,6 +6,7 @@ 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; @@ -16,10 +17,10 @@ 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; -import edu.cornell.mannlib.vitro.utilities.testrunner.output.SuiteResults.TestResults; /** * Collect all that we know about suites, tests, and their current status. @@ -38,16 +39,12 @@ public class DataModel { private Status runStatus = Status.PENDING; private final SortedMap suiteDataMap = new TreeMap(); - private final List pendingSuites = new ArrayList(); - private final List passingSuites = new ArrayList(); - private final List failingSuites = new ArrayList(); - private final List ignoredSuites = new ArrayList(); + private final EnumMap> suiteMapByStatus = new EnumMap>( + Status.class); - private final List allTests = new ArrayList(); - private final List pendingTests = new ArrayList(); - private final List passingTests = new ArrayList(); - private final List failingTests = new ArrayList(); - private final List ignoredTests = new ArrayList(); + private final List allTests = new ArrayList(); + private final EnumMap> testMapByStatus = new EnumMap>( + Status.class); // ---------------------------------------------------------------------- // Constructor @@ -107,20 +104,19 @@ public class DataModel { runStatus = Status.OK; suiteDataMap.clear(); - - ignoredSuites.clear(); - pendingSuites.clear(); - failingSuites.clear(); - passingSuites.clear(); + suiteMapByStatus.clear(); + for (Status s : Status.values()) { + suiteMapByStatus.put(s, new ArrayList()); + } allTests.clear(); - ignoredTests.clear(); - pendingTests.clear(); - failingTests.clear(); - passingTests.clear(); + testMapByStatus.clear(); + for (Status s : Status.values()) { + testMapByStatus.put(s, new ArrayList()); + } /* - * Suite data. + * Populate the Suite map with all Suites. */ Map resultsMap = new HashMap(); for (SuiteResults result : suiteResults) { @@ -142,88 +138,28 @@ public class DataModel { } /* - * Tallys of suites and tests. + * Map the Suites by status. */ - for (SuiteData sd : suiteDataMap.values()) { - switch (sd.getSuiteStatus()) { - case ERROR: - failingSuites.add(sd); - break; - case PENDING: - pendingSuites.add(sd); - break; - case WARN: - ignoredSuites.add(sd); - break; - default: // Status.OK - passingSuites.add(sd); - break; + 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); } } - for (SuiteData sd : suiteDataMap.values()) { - SuiteResults sResult = sd.getResults(); - if (sResult != null) { - tallyTestResults(sResult); - } else if (sd.getContents() != null) { - tallyTestContents(sd); - } - } - for (TestResults tResult : allTests) { - switch (tResult.getStatus()) { - case OK: - passingTests.add(tResult); - break; - case PENDING: - pendingTests.add(tResult); - break; - case WARN: - ignoredTests.add(tResult); - break; - default: // Status.ERROR - failingTests.add(tResult); - break; - } - } - - /* - * Overall status. Warnings in the log are scary, but ignored tests are - * OK. - */ - if (logStats.hasErrors() || !failingSuites.isEmpty()) { + if (logStats.hasErrors() || !getSuites(Status.ERROR).isEmpty()) { runStatus = Status.ERROR; + } else if (!getSuites(Status.PENDING).isEmpty()) { + runStatus = Status.PENDING; } else { - if (logStats.hasWarnings()) { - runStatus = Status.WARN; - } else { - if (!pendingSuites.isEmpty()) { - runStatus = Status.PENDING; - } else { - runStatus = Status.OK; - } - } - } - } - - /** - * Categorize all test results according to status. - */ - private void tallyTestResults(SuiteResults sResult) { - for (TestResults tResult : sResult.getTests()) { - allTests.add(tResult); - } - } - - /** - * Populate {@link #allTests} with the tests for which we have no results. - */ - private void tallyTestContents(SuiteData suiteData) { - Status suiteStatus = suiteData.getSuiteStatus(); - - for (String testName : suiteData.getContents().getTestNames()) { - TestResults t = new TestResults(testName, suiteData.getName(), "", - suiteStatus, ""); - allTests.add(t); + runStatus = Status.OK; } } @@ -248,19 +184,19 @@ public class DataModel { } public boolean isAnyPasses() { - return !(passingSuites.isEmpty() && passingTests.isEmpty()); + return !getTests(Status.OK).isEmpty(); } public boolean isAnyFailures() { - return !(failingSuites.isEmpty() && failingTests.isEmpty()); + return !getTests(Status.ERROR).isEmpty(); } public boolean isAnyIgnores() { - return !(ignoredSuites.isEmpty() && ignoredTests.isEmpty()); + return !getTests(Status.IGNORED).isEmpty(); } public boolean isAnyPending() { - return !pendingSuites.isEmpty(); + return !getTests(Status.PENDING).isEmpty(); } public int getTotalSuiteCount() { @@ -268,23 +204,33 @@ public class DataModel { } public int getPassingSuiteCount() { - return passingSuites.size(); + return getSuites(Status.OK).size(); } public int getFailingSuiteCount() { - return failingSuites.size(); + return getSuites(Status.ERROR).size(); } public int getIgnoredSuiteCount() { - return ignoredSuites.size(); + return getSuites(Status.IGNORED).size(); } - public int getPendingSuitesCount() { - return pendingSuites.size(); + public int getPendingSuiteCount() { + return getSuites(Status.PENDING).size(); } - public Collection getSuiteResults() { - return Collections.unmodifiableCollection(suiteResults); + 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() { @@ -292,57 +238,57 @@ public class DataModel { } public int getPassingTestCount() { - return passingTests.size(); + return getTests(Status.OK).size(); } public int getFailingTestCount() { - return failingTests.size(); + return getTests(Status.ERROR).size(); } public int getIgnoredTestCount() { - return ignoredTests.size(); + return getTests(Status.IGNORED).size(); } - public int getPendingTestsCount() { - return pendingTests.size(); + public int getPendingTestCount() { + return getTests(Status.PENDING).size(); } - public Collection getAllTests() { + public Collection getAllTests() { return Collections.unmodifiableCollection(allTests); } - public Collection getFailingTests() { - return Collections.unmodifiableCollection(failingTests); + public Collection getFailingTests() { + return Collections.unmodifiableCollection(getTests(Status.ERROR)); } - public Collection getIgnoredTests() { - return Collections.unmodifiableCollection(ignoredTests); + public Collection getIgnoredTests() { + return Collections.unmodifiableCollection(getTests(Status.IGNORED)); } public Collection getIgnoredTestInfo() { return ignoredTestList.getList(); } - public String getOutputLink(String suiteName, String testName) { - SuiteData sd = suiteDataMap.get(suiteName); - if (sd != null) { - SuiteResults s = sd.getResults(); - if (s != null) { - if (testName.equals("*")) { - return s.getOutputLink(); - } else { - TestResults t = s.getTest(testName); - if (t != null) { - return t.getOutputLink(); - } - } - } - } - return ""; - } - 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/datamodel/SuiteData.java b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/datamodel/SuiteData.java index 6d4d1af52..2b60a61c7 100644 --- a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/datamodel/SuiteData.java +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/datamodel/SuiteData.java @@ -2,6 +2,9 @@ package edu.cornell.mannlib.vitro.utilities.testrunner.datamodel; +import java.util.LinkedHashMap; +import java.util.Map; + import edu.cornell.mannlib.vitro.utilities.testrunner.Status; import edu.cornell.mannlib.vitro.utilities.testrunner.output.OutputDataListener.ProcessOutput; import edu.cornell.mannlib.vitro.utilities.testrunner.output.SuiteResults; @@ -11,56 +14,168 @@ import edu.cornell.mannlib.vitro.utilities.testrunner.output.SuiteResults.TestRe * What do we know about this suite, both before it runs and after it has run? */ public class SuiteData { + /** + * If this suite has failure messages, the output link is to an anchor on + * the same page. + */ + public static String failureMessageAnchor(SuiteData s) { + return "suiteFailure_" + s.getName(); + } + private final String name; - private final boolean ignored; - private final SuiteContents contents; - private final SuiteResults results; + private final Status status; + private final String outputLink; private final ProcessOutput failureMessages; + /** + * This map iterates according to the order that the tests were specified in + * the suite file. + */ + private final Map testMap; + public SuiteData(String name, boolean ignored, SuiteContents contents, SuiteResults results, ProcessOutput failureMessages) { this.name = name; - this.ignored = ignored; - this.contents = contents; - this.results = results; this.failureMessages = failureMessages; + + if (ignored) { + this.status = Status.IGNORED; + this.outputLink = null; + this.testMap = buildTestMap(contents, results); + } else if (failureMessages != null) { + this.status = Status.ERROR; + this.outputLink = "#" + failureMessageAnchor(this); + this.testMap = buildTestMap(contents, results); + } else if (results != null) { + this.testMap = buildTestMap(contents, results); + this.status = buildStatusFromTestMap(); + this.outputLink = results.getOutputLink(); + } else { + this.status = Status.PENDING; + this.outputLink = null; + this.testMap = buildTestMap(contents, results); + } + } + + /** + * Build the test map. Do we have test results, or only the advance list of + * tests? + */ + private Map buildTestMap(SuiteContents contents, + SuiteResults results) { + if (results == null) { + return buildTestMapFromContents(contents); + } else { + return buildTestMapFromResults(contents, results); + } + } + + /** + * All we have to build from is the contents of the Suite HTML file. + */ + private Map buildTestMapFromContents( + SuiteContents contents) { + Map map = new LinkedHashMap(); + for (String testName : contents.getTestNames()) { + map.put(testName, new TestData(testName, this.name, this.status, + null)); + } + return map; + } + + /** + * We can build from both the contents of the Suite HTML file and from the + * test results output file. + */ + private Map buildTestMapFromResults( + SuiteContents contents, SuiteResults results) { + Map map = new LinkedHashMap(); + for (String testName : contents.getTestNames()) { + TestResults testResult = results.getTest(testName); + if (testResult == null) { + // This shouldn't happen. How do we show it? + map.put(testName, new TestData(testName, this.name, + Status.PENDING, null)); + } else { + map.put(testName, + new TestData(testName, this.name, testResult + .getStatus(), testResult.getOutputLink())); + } + } + return map; + } + + /** + * The suite ran to completion, so its status is the worst of the individual + * test statuses. + */ + private Status buildStatusFromTestMap() { + Status status = Status.OK; + for (TestData t : this.testMap.values()) { + status = Status.combine(status, t.getStatus()); + } + return status; } public String getName() { return name; } - public boolean isIgnored() { - return ignored; - } - - public SuiteContents getContents() { - return contents; - } - - public SuiteResults getResults() { - return results; - } - - public Status getSuiteStatus() { - if (ignored) { - return Status.WARN; - } - if (failureMessages != null) { - return Status.ERROR; - } - if (results == null) { - return Status.PENDING; - } - - /* - * If we have results and no failure messages, scan the results for the - * worst status. - */ - Status status = Status.OK; - for (TestResults t : results.getTests()) { - status = Status.combine(status, t.getStatus()); - } + public Status getStatus() { return status; } + + public String getOutputLink() { + return outputLink; + } + + public ProcessOutput getFailureMessages() { + return failureMessages; + } + + public Map getTestMap() { + return testMap; + } + + /** + * What do we know about this test, both before it runs and after it has + * run? + */ + public static class TestData { + private final String testName; + private final String suiteName; + private final Status status; + private final String outputLink; + + public TestData(String testName, String suiteName, Status status, + String outputLink) { + this.testName = testName; + this.suiteName = suiteName; + this.status = status; + this.outputLink = outputLink; + } + + public String getTestName() { + return testName; + } + + public String getSuiteName() { + return suiteName; + } + + public Status getStatus() { + return status; + } + + public String getOutputLink() { + return outputLink; + } + + @Override + public String toString() { + return "TestData[testName=" + testName + ", suiteName=" + suiteName + + ", status=" + status + ", outputLink=" + outputLink + "]"; + } + + } } diff --git a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/OutputDataListener.java b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/OutputDataListener.java index e877301eb..72778f896 100644 --- a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/OutputDataListener.java +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/OutputDataListener.java @@ -9,6 +9,8 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import edu.cornell.mannlib.vitro.utilities.testrunner.FileHelper; import edu.cornell.mannlib.vitro.utilities.testrunner.listener.Listener; @@ -138,6 +140,7 @@ public class OutputDataListener implements Listener { * interesting if it indicates a suite failure. */ public static class ProcessOutput { + private static final String SUITE_FAILURE_PATTERN = "exception|error(?i)"; private final String suiteName; private final StringBuilder stdout = new StringBuilder(); private final StringBuilder errout = new StringBuilder(); @@ -167,7 +170,9 @@ public class OutputDataListener implements Listener { } public boolean isSuiteFailure() { - return errout.length() > 0; + Pattern p = Pattern.compile(SUITE_FAILURE_PATTERN); + Matcher m = p.matcher(errout); + return m.find(); } } 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 0a9f51e6b..fe3afcad8 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 @@ -11,6 +11,7 @@ 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; @@ -18,7 +19,9 @@ 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.output.SuiteResults.TestResults; +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. @@ -60,6 +63,7 @@ public class OutputSummaryFormatter { writeIgnoreSection(writer); writeSuitesSection(writer); writeAllTestsSection(writer); + writeSuiteErrorMessagesSection(writer); writeFooter(writer); } catch (IOException e) { // There is no appeal for any problems here. Just report them. @@ -92,207 +96,234 @@ public class OutputSummaryFormatter { } } - private void writeHeader(PrintWriter writer) { + private void writeHeader(PrintWriter w) { Status runStatus = dataModel.getRunStatus(); String statusString = (runStatus == Status.PENDING) ? "IN PROGRESS" : runStatus.toString(); String startString = formatDateTime(dataModel.getStartTime()); - writer.println(""); - writer.println(""); - writer.println(" Summary of Acceptance Tests " + startString + w.println("<html>"); + w.println("<head>"); + w.println(" <title>Summary of Acceptance Tests " + startString + ""); - writer.println(" "); - writer.println(""); - writer.println(""); - writer.println(); - writer.println("
"); - writer.println(" Acceptance test results: " + startString); - writer.println("
"); + w.println(""); + w.println(); + w.println("
"); + w.println(" Acceptance test results: " + startString); + w.println("
" + statusString + "
"); - writer.println("
"); + w.println("
"); } - private void writeStatsSection(PrintWriter writer) { + private void writeStatsSection(PrintWriter w) { String passClass = dataModel.isAnyPasses() ? Status.OK.getHtmlClass() : ""; String failClass = dataModel.isAnyFailures() ? Status.ERROR .getHtmlClass() : ""; - String ignoreClass = dataModel.isAnyIgnores() ? Status.WARN + String ignoreClass = dataModel.isAnyIgnores() ? Status.IGNORED .getHtmlClass() : ""; String start = formatDateTime(dataModel.getStartTime()); String end = formatDateTime(dataModel.getEndTime()); String elapsed = formatElapsedTime(dataModel.getElapsedTime()); - writer.println("
Summary
"); - writer.println(); - writer.println(" "); - writer.println(" "); - writer.println("
"); - writer.println(" "); - writer.println(" "); + w.println(" "); + w.println("
Start time:" + start + w.println("
Summary
"); + w.println(); + w.println(" "); + w.println(" "); + w.println(" "); - writer.println("
"); + w.println(" "); + w.println(" "); - writer.println(" "); + w.println(" "); - writer.println(" "); - writer.println("
Start time:" + start + "
End time:" + end + w.println("
End time:" + end + "
Elapsed time" + elapsed + "
Elapsed time" + elapsed - + "
"); - writer.println("
"); - writer.println(" "); - writer.println(" "); - writer.println(" "); + w.println(" "); + w.println(" "); - writer.println(" "); - writer.println("
 SuitesTests
"); + w.println(" "); + w.println(" "); + w.println(" "); - writer.println(" "); - writer.println(" "); if (dataModel.isAnyPending()) { - writer.println(" "); + w.println(" "); } - writer.println(" "); - writer.println("
 SuitesTests
Passed" + dataModel.getPassingSuiteCount() + "" + dataModel.getPassingTestCount() + "
Failed" + dataModel.getFailingSuiteCount() + "" + dataModel.getFailingTestCount() + "
Ignored" + dataModel.getIgnoredSuiteCount() + "" + dataModel.getIgnoredTestCount() + "
Pending" - + dataModel.getPendingSuitesCount() + "" - + dataModel.getPendingTestsCount() + "
Pending" + + dataModel.getPendingSuiteCount() + "" + + dataModel.getPendingTestCount() + "
Total" + w.println("
Total" + dataModel.getTotalSuiteCount() + "" + dataModel.getTotalTestCount() + "
"); - writer.println("
"); - writer.println(); + w.println("
"); + w.println("
"); + w.println(); } - private void writeErrorMessagesSection(PrintWriter writer) { + private void writeErrorMessagesSection(PrintWriter w) { String errorClass = Status.ERROR.getHtmlClass(); - String warnClass = Status.WARN.getHtmlClass(); - writer.println("
Errors and warnings
"); - writer.println(); - writer.println(" "); + w.println("
Errors and warnings
"); + w.println(); + w.println("
"); if ((!logStats.hasErrors()) && (!logStats.hasWarnings())) { - writer.println(" "); + w.println(" "); } else { for (String e : logStats.getErrors()) { - writer.println(" "); } - for (String w : logStats.getWarnings()) { - writer.println(" "); - } } - writer.println("
No errors or warnings
No errors or warnings
ERROR" + e + "
ERROR" + w + "
"); - writer.println(); + w.println("
"); + w.println(); } - private void writeFailureSection(PrintWriter writer) { + private void writeFailureSection(PrintWriter w) { String errorClass = Status.ERROR.getHtmlClass(); - Collection failingTests = dataModel.getFailingTests(); + Collection failingTests = dataModel.getFailingTests(); - writer.println("
Failing tests
"); - writer.println(); - writer.println(" "); - writer.println(" \n"); + w.println("
Failures
"); + w.println(); + w.println("
Suite nameTest name
"); + w.println(" \n"); if (failingTests.isEmpty()) { - writer.println(" " + w.println(" " + ""); } else { - for (TestResults t : failingTests) { - writer.println(" "); - writer.println(" "); - writer.println(" "); - writer.println(" "); + Map failedSuiteMap = dataModel + .getSuitesWithFailureMessages(); + for (SuiteData s : failedSuiteMap.values()) { + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); + } + for (TestData t : failingTests) { + if (!failedSuiteMap.containsKey(t.getSuiteName())) { + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); + } } } - writer.println("
Suite nameTest name
No tests failed.
No tests failed.
" + t.getSuiteName() + "" + t.getTestName() + "
" + s.getName() + "" + outputLink(s) + "
" + t.getSuiteName() + "" + outputLink(t) + "
"); - writer.println(); + w.println(" "); + w.println(); } - private void writeIgnoreSection(PrintWriter writer) { - String warnClass = Status.WARN.getHtmlClass(); + private void writeIgnoreSection(PrintWriter w) { + String warnClass = Status.IGNORED.getHtmlClass(); Collection ignoredTests = dataModel .getIgnoredTestInfo(); - writer.println("
Ignored tests
"); - writer.println(); - writer.println(" "); - writer.println(" " + w.println("
Ignored
"); + w.println(); + w.println("
Suite nameTest name
"); + w.println(" " + "\n"); if (ignoredTests.isEmpty()) { - writer.println(" " + w.println(" " + ""); } else { for (IgnoredTestInfo info : ignoredTests) { String suiteName = info.suiteName; String testName = info.testName; - String link = dataModel.getOutputLink(suiteName, testName); String reason = dataModel.getReasonForIgnoring(suiteName, testName); - writer.println(" "); - writer.println(" "); - if (link.isEmpty()) { - writer.println(" "); - } else { - writer.println(" "); - } - writer.println(" "); - writer.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); } } - writer.println("
Suite nameTest nameReason for ignoring
No tests ignored.
No tests ignored.
" + suiteName + "" + testName + "" - + testName + "" + reason + "
" + suiteName + "" + testName + "" + reason + "
"); - writer.println(); + w.println(" "); + w.println(); } - private void writeSuitesSection(PrintWriter writer) { - writer.println("
Suites
"); - writer.println(); - writer.println(" "); + private void writeSuitesSection(PrintWriter w) { + w.println("
Suites Summary
"); + w.println(); + w.println("
"); - for (SuiteResults s : dataModel.getSuiteResults()) { - writer.println(" "); - writer.println(" "); - writer.println(" "); + for (SuiteData s : dataModel.getAllSuites()) { + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); } - writer.println("
" - + s.getName() + "
" + outputLink(s) + "" + s.getStatus() + "
"); - writer.println(); + w.println(" "); + w.println(); } - private void writeAllTestsSection(PrintWriter writer) { - Collection allTests = dataModel.getAllTests(); + private void writeAllTestsSection(PrintWriter w) { + Collection allTests = dataModel.getAllTests(); - writer.println("
All tests
"); - writer.println(); - writer.println(" "); + w.println("
All tests
"); + w.println(); + w.println("
"); - writer.println(" \n"); - for (TestResults t : allTests) { - writer.println(" "); - writer.println(" "); - writer.println(" "); - writer.println(" "); + w.println(" \n"); + for (TestData t : allTests) { + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); + w.println(" "); } - writer.println("
Suite nameTest name
" + t.getSuiteName() + "" - + t.getTestName() + "
Suite nameTest name 
" + t.getSuiteName() + "" + outputLink(t) + "" + t.getStatus() + "
"); - writer.println(); + w.println(" "); + w.println(); } - private void writeFooter(PrintWriter writer) { - writer.println("
Log
"); - writer.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 writeFooter(PrintWriter w) { + w.println("
Log
"); + w.println("
");
 
 		Reader reader = null;
 		try {
@@ -300,7 +331,7 @@ public class OutputSummaryFormatter {
 			char[] buffer = new char[4096];
 			int howMany;
 			while (-1 != (howMany = reader.read(buffer))) {
-				writer.write(buffer, 0, howMany);
+				w.write(buffer, 0, howMany);
 			}
 		} catch (IOException e) {
 			e.printStackTrace();
@@ -314,9 +345,9 @@ public class OutputSummaryFormatter {
 			}
 		}
 
-		writer.println("  
"); - writer.println(""); - writer.println(""); + w.println("
"); + w.println(""); + w.println(""); } private String formatElapsedTime(long elapsed) { @@ -350,4 +381,21 @@ public class OutputSummaryFormatter { 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() + + ""; + } + } } diff --git a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/SuiteResults.java b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/SuiteResults.java index b519df934..b611643bd 100644 --- a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/SuiteResults.java +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/SuiteResults.java @@ -76,21 +76,16 @@ public class SuiteResults { String testLink = outputLink + m.group(2); Status testStatus; - String reasonForIgnoring; if ("status_passed".equals(m.group(1))) { testStatus = Status.OK; - reasonForIgnoring = ""; } else if (ignoredTests.isIgnored(suiteName, testName)) { - testStatus = Status.WARN; - reasonForIgnoring = ignoredTests.getReasonForIgnoring( - suiteName, testName); + testStatus = Status.IGNORED; } else { testStatus = Status.ERROR; - reasonForIgnoring = ""; } tests.add(new TestResults(testName, suiteName, testLink, - testStatus, reasonForIgnoring)); + testStatus)); } } @@ -163,15 +158,13 @@ public class SuiteResults { private final String suite; private final String outputLink; private final Status status; - private final String reasonForIgnoring; public TestResults(String name, String suite, String outputLink, - Status status, String reasonForIgnoring) { + Status status) { this.name = name; this.suite = suite; this.outputLink = outputLink; this.status = status; - this.reasonForIgnoring = reasonForIgnoring; } public Status getStatus() { @@ -190,9 +183,6 @@ public class SuiteResults { return outputLink; } - public String getReasonForIgnoring() { - return reasonForIgnoring; - } } } diff --git a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/summary.css b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/summary.css index e5368483d..eb532716b 100644 --- a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/summary.css +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/output/summary.css @@ -67,6 +67,10 @@ table.tallys td.total { background: rgb(100%, 100%, 60%); } +.pending { + background: rgb(90%, 90%, 100%); +} + .one-word { width: 20%; text-align: center;