From 68887fef029ad37d1573883745442dcba03b1bf9 Mon Sep 17 00:00:00 2001 From: jeb228 Date: Fri, 20 Aug 2010 14:05:36 +0000 Subject: [PATCH] NIHVIVO-222 Parse the HTML Suite files to get a list of tests before they are run. --- .../utilities/testrunner/SeleniumRunner.java | 86 +++++++++------ .../testrunner/datamodel/DataModel.java | 55 ++++++++-- .../testrunner/datamodel/SuiteContents.java | 100 ++++++++++++++++++ .../testrunner/datamodel/SuiteData.java | 8 +- .../output/OutputSummaryFormatter.java | 3 +- 5 files changed, 206 insertions(+), 46 deletions(-) create mode 100644 utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/datamodel/SuiteContents.java 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 b64689993..045f8dbbd 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 @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.List; import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.DataModel; +import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.SuiteContents; import edu.cornell.mannlib.vitro.utilities.testrunner.listener.Listener; import edu.cornell.mannlib.vitro.utilities.testrunner.output.OutputManager; @@ -39,6 +40,56 @@ public class SeleniumRunner { } + /** + * Set up the run, run the selected suites, summarize the output, and clean + * up afterwards. + * + * @return true iff all tests passed. + */ + public boolean run() { + boolean success; + try { + listener.runStarted(); + outputManager.cleanOutputDirectory(); + + parseSuites(); + selectSuites(); + + runSelectedSuites(); + tomcatController.cleanup(); + + listener.runEndTime(); + outputManager.summarizeOutput(dataModel); + success = (dataModel.getRunStatus() == Status.OK); + } catch (IOException e) { + listener.runFailed(e); + success = false; + e.printStackTrace(); + } catch (FatalException e) { + listener.runFailed(e); + success = false; + e.printStackTrace(); + } + listener.runStopped(); + return success; + } + + /** + * Scan the suite directories in the suite files. + */ + public void parseSuites() { + List allContents = new ArrayList(); + for (File parentDir : parms.getSuiteParentDirectories()) { + for (File suiteDir : parms.findSuiteDirs(parentDir)) { + SuiteContents contents = SuiteContents.parse(suiteDir); + if (contents != null) { + allContents.add(contents); + } + } + } + dataModel.setSuiteContents(allContents); + } + /** * Select all test suites which aren't explicitly ignored. */ @@ -63,37 +114,6 @@ public class SeleniumRunner { dataModel.setSelectedSuites(suites); } - /** - * Set up the run, run the selected suites, summarize the output, and clean - * up afterwards. - * - * @return true iff all tests passed. - */ - public boolean run() { - boolean success; - try { - listener.runStarted(); - outputManager.cleanOutputDirectory(); - - runSelectedSuites(); - tomcatController.cleanup(); - - listener.runEndTime(); - outputManager.summarizeOutput(dataModel); - success = (dataModel.getRunStatus() == Status.OK); - } catch (IOException e) { - listener.runFailed(e); - success = false; - e.printStackTrace(); - } catch (FatalException e) { - listener.runFailed(e); - success = false; - e.printStackTrace(); - } - listener.runStopped(); - return success; - } - public void runSelectedSuites() { for (File suiteDir : dataModel.getSelectedSuites()) { outputManager.summarizeOutput(dataModel); @@ -163,9 +183,7 @@ public class SeleniumRunner { System.out.println(parms); - SeleniumRunner runner = new SeleniumRunner(parms); - runner.selectSuites(); - success = runner.run(); + success = new SeleniumRunner(parms).run(); } } catch (FatalException e) { System.err.println("\n\n-----------------\n" 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 0112aa085..de9eac4ab 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 @@ -22,6 +22,7 @@ import edu.cornell.mannlib.vitro.utilities.testrunner.output.SuiteResults.TestRe 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; @@ -54,6 +55,11 @@ public class DataModel { // 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(); @@ -108,25 +114,29 @@ public class DataModel { for (SuiteResults result : suiteResults) { resultsMap.put(result.getName(), result); } + Map contentsMap = new HashMap(); + for (SuiteContents contents : suiteContents) { + contentsMap.put(contents.getName(), contents); + } for (String name : dataListenerInfo.getSuiteNames()) { - if (dataListenerInfo.getIgnoredSuiteNames().contains(name)) { - allSuiteData.add(new SuiteData(name, true, null)); - } else if (resultsMap.containsKey(name)) { - allSuiteData.add(new SuiteData(name, false, resultsMap - .get(name))); - } else { - allSuiteData.add(new SuiteData(name, false, null)); - } + SuiteContents contents = contentsMap.get(name); + SuiteResults result = resultsMap.get(name); + boolean ignored = dataListenerInfo.getIgnoredSuiteNames().contains( + name); + allSuiteData.add(new SuiteData(name, ignored, contents, result)); } /* * Tallys of suites and tests. */ for (SuiteData sd : allSuiteData) { + SuiteContents contents = sd.getContents(); SuiteResults result = sd.getResults(); if (result != null) { - tallyTests(result); + tallyTestResults(result); + } else if (contents != null) { + tallyTestContents(sd); } if (sd.isIgnored()) { @@ -162,7 +172,7 @@ public class DataModel { /** * Categorize all test results according to status. */ - private void tallyTests(SuiteResults sResult) { + private void tallyTestResults(SuiteResults sResult) { for (TestResults tResult : sResult.getTests()) { allTests.add(tResult); switch (tResult.getStatus()) { @@ -182,6 +192,27 @@ public class DataModel { } } + /** + * Categorize all tests for which we have no results. + */ + private void tallyTestContents(SuiteData suiteData) { + SuiteContents contents = suiteData.getContents(); + + for (String testName : contents.getTestNames()) { + if (suiteData.isIgnored()) { + TestResults t = new TestResults(testName, suiteData.getName(), + "", Status.WARN, ""); + allTests.add(t); + ignoredTests.add(t); + } else { + TestResults t = new TestResults(testName, suiteData.getName(), + "", Status.PENDING, ""); + allTests.add(t); + pendingTests.add(t); + } + } + } + // ---------------------------------------------------------------------- // Access the derived data. // ---------------------------------------------------------------------- @@ -258,6 +289,10 @@ public class DataModel { return ignoredTests.size(); } + public int getPendingTestsCount() { + return pendingTests.size(); + } + public Collection getAllTests() { return Collections.unmodifiableCollection(allTests); } diff --git a/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/datamodel/SuiteContents.java b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/datamodel/SuiteContents.java new file mode 100644 index 000000000..9dbcadf03 --- /dev/null +++ b/utilities/testrunner/src/edu/cornell/mannlib/vitro/utilities/testrunner/datamodel/SuiteContents.java @@ -0,0 +1,100 @@ +/* $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.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import edu.cornell.mannlib.vitro.utilities.testrunner.FileHelper; + +/** + * Parses the actual HTML test suite file, and holds the results. + */ +public class SuiteContents { + /** + * If the file doesn't contain a line that includes this pattern, it is not + * a suite contents file. + */ + private static final Pattern TITLE_LINE_PATTERN = Pattern + .compile("Test Suite"); + private static final Pattern TEST_PATTERN = Pattern + .compile("]*>([^<]+)(?m)"); + + private static final String SUITE_FILE_NAME = "Suite.html"; + + /** + * Parse the test names fields from this file and attempt to produce a + * {@link SuiteContents} object. If this is not an appropriate file, just + * return null. + */ + public static SuiteContents parse(File suiteDirectory) { + StringBuilder fileContents = new StringBuilder(); + BufferedReader reader = null; + try { + File suiteFile = new File(suiteDirectory, SUITE_FILE_NAME); + if (!suiteFile.exists()) { + return null; + } + + reader = new BufferedReader(new FileReader(suiteFile)); + String line; + while (null != (line = reader.readLine())) { + fileContents.append(line).append('\n'); + } + + } catch (IOException e) { + e.printStackTrace(); + return null; + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + // If it doesn't contain the title line, it's not a suite file. + if (!TITLE_LINE_PATTERN.matcher(fileContents).find()) { + return null; + } + + // Accumulate all of the test names. + List testNames = new ArrayList(); + Matcher m = TEST_PATTERN.matcher(fileContents); + int lookHere = 0; + while (m.find(lookHere)) { + testNames.add(m.group(1)); + lookHere = m.end(); + } + + return new SuiteContents(FileHelper.baseName(suiteDirectory), testNames); + } + + private final String name; + private final Collection testNames; + + public SuiteContents(String name, Collection testNames) { + this.name = name; + this.testNames = Collections + .unmodifiableCollection(new ArrayList(testNames)); + } + + public String getName() { + return name; + } + + public Collection getTestNames() { + return testNames; + } + +} 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 8792b79fb..cf21d8d42 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 @@ -10,11 +10,13 @@ import edu.cornell.mannlib.vitro.utilities.testrunner.output.SuiteResults; public class SuiteData { private final String name; private final boolean ignored; + private final SuiteContents contents; private final SuiteResults results; - public SuiteData(String name, boolean ignored, SuiteResults results) { + public SuiteData(String name, boolean ignored, SuiteContents contents, SuiteResults results) { this.name = name; this.ignored = ignored; + this.contents = contents; this.results = results; } @@ -26,6 +28,10 @@ public class SuiteData { return ignored; } + public SuiteContents getContents() { + return contents; + } + public SuiteResults getResults() { return results; } 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 f942d899c..d34429462 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 @@ -151,7 +151,8 @@ public class OutputSummaryFormatter { + "" + dataModel.getIgnoredTestCount() + ""); if (dataModel.isAnyPending()) { writer.println(" Pending" - + dataModel.getPendingSuitesCount() + "?"); + + dataModel.getPendingSuitesCount() + "" + + dataModel.getPendingTestsCount() + ""); } writer.println(" Total" + dataModel.getTotalSuiteCount() + ""