NIHVIVO-222 Parse the HTML Suite files to get a list of tests before they are run.
This commit is contained in:
parent
146e648b50
commit
68887fef02
5 changed files with 206 additions and 46 deletions
|
@ -10,6 +10,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.utilities.testrunner.datamodel.DataModel;
|
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.listener.Listener;
|
||||||
import edu.cornell.mannlib.vitro.utilities.testrunner.output.OutputManager;
|
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 <code>true</code> 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<SuiteContents> allContents = new ArrayList<SuiteContents>();
|
||||||
|
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.
|
* Select all test suites which aren't explicitly ignored.
|
||||||
*/
|
*/
|
||||||
|
@ -63,37 +114,6 @@ public class SeleniumRunner {
|
||||||
dataModel.setSelectedSuites(suites);
|
dataModel.setSelectedSuites(suites);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up the run, run the selected suites, summarize the output, and clean
|
|
||||||
* up afterwards.
|
|
||||||
*
|
|
||||||
* @return <code>true</code> iff all tests passed.
|
|
||||||
*/
|
|
||||||
public boolean run() {
|
|
||||||
boolean success;
|
|
||||||
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() {
|
public void runSelectedSuites() {
|
||||||
for (File suiteDir : dataModel.getSelectedSuites()) {
|
for (File suiteDir : dataModel.getSelectedSuites()) {
|
||||||
outputManager.summarizeOutput(dataModel);
|
outputManager.summarizeOutput(dataModel);
|
||||||
|
@ -163,9 +183,7 @@ public class SeleniumRunner {
|
||||||
|
|
||||||
System.out.println(parms);
|
System.out.println(parms);
|
||||||
|
|
||||||
SeleniumRunner runner = new SeleniumRunner(parms);
|
success = new SeleniumRunner(parms).run();
|
||||||
runner.selectSuites();
|
|
||||||
success = runner.run();
|
|
||||||
}
|
}
|
||||||
} catch (FatalException e) {
|
} catch (FatalException e) {
|
||||||
System.err.println("\n\n-----------------\n"
|
System.err.println("\n\n-----------------\n"
|
||||||
|
|
|
@ -22,6 +22,7 @@ import edu.cornell.mannlib.vitro.utilities.testrunner.output.SuiteResults.TestRe
|
||||||
public class DataModel {
|
public class DataModel {
|
||||||
|
|
||||||
/* base data */
|
/* base data */
|
||||||
|
private Collection<SuiteContents> suiteContents = Collections.emptyList();
|
||||||
private Collection<File> selectedSuites = Collections.emptyList();
|
private Collection<File> selectedSuites = Collections.emptyList();
|
||||||
private Collection<SuiteResults> suiteResults = Collections.emptyList();
|
private Collection<SuiteResults> suiteResults = Collections.emptyList();
|
||||||
private OutputDataListener.Info dataListenerInfo = OutputDataListener.Info.EMPTY_INFO;
|
private OutputDataListener.Info dataListenerInfo = OutputDataListener.Info.EMPTY_INFO;
|
||||||
|
@ -54,6 +55,11 @@ public class DataModel {
|
||||||
// Update the base data.
|
// Update the base data.
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
public void setSuiteContents(Collection<SuiteContents> suiteContents) {
|
||||||
|
this.suiteContents = new ArrayList<SuiteContents>(suiteContents);
|
||||||
|
calculate();
|
||||||
|
}
|
||||||
|
|
||||||
public void setSelectedSuites(Collection<File> selectedSuites) {
|
public void setSelectedSuites(Collection<File> selectedSuites) {
|
||||||
this.selectedSuites = new ArrayList<File>(selectedSuites);
|
this.selectedSuites = new ArrayList<File>(selectedSuites);
|
||||||
calculate();
|
calculate();
|
||||||
|
@ -108,25 +114,29 @@ public class DataModel {
|
||||||
for (SuiteResults result : suiteResults) {
|
for (SuiteResults result : suiteResults) {
|
||||||
resultsMap.put(result.getName(), result);
|
resultsMap.put(result.getName(), result);
|
||||||
}
|
}
|
||||||
|
Map<String, SuiteContents> contentsMap = new HashMap<String, SuiteContents>();
|
||||||
|
for (SuiteContents contents : suiteContents) {
|
||||||
|
contentsMap.put(contents.getName(), contents);
|
||||||
|
}
|
||||||
|
|
||||||
for (String name : dataListenerInfo.getSuiteNames()) {
|
for (String name : dataListenerInfo.getSuiteNames()) {
|
||||||
if (dataListenerInfo.getIgnoredSuiteNames().contains(name)) {
|
SuiteContents contents = contentsMap.get(name);
|
||||||
allSuiteData.add(new SuiteData(name, true, null));
|
SuiteResults result = resultsMap.get(name);
|
||||||
} else if (resultsMap.containsKey(name)) {
|
boolean ignored = dataListenerInfo.getIgnoredSuiteNames().contains(
|
||||||
allSuiteData.add(new SuiteData(name, false, resultsMap
|
name);
|
||||||
.get(name)));
|
allSuiteData.add(new SuiteData(name, ignored, contents, result));
|
||||||
} else {
|
|
||||||
allSuiteData.add(new SuiteData(name, false, null));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tallys of suites and tests.
|
* Tallys of suites and tests.
|
||||||
*/
|
*/
|
||||||
for (SuiteData sd : allSuiteData) {
|
for (SuiteData sd : allSuiteData) {
|
||||||
|
SuiteContents contents = sd.getContents();
|
||||||
SuiteResults result = sd.getResults();
|
SuiteResults result = sd.getResults();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
tallyTests(result);
|
tallyTestResults(result);
|
||||||
|
} else if (contents != null) {
|
||||||
|
tallyTestContents(sd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sd.isIgnored()) {
|
if (sd.isIgnored()) {
|
||||||
|
@ -162,7 +172,7 @@ public class DataModel {
|
||||||
/**
|
/**
|
||||||
* Categorize all test results according to status.
|
* Categorize all test results according to status.
|
||||||
*/
|
*/
|
||||||
private void tallyTests(SuiteResults sResult) {
|
private void tallyTestResults(SuiteResults sResult) {
|
||||||
for (TestResults tResult : sResult.getTests()) {
|
for (TestResults tResult : sResult.getTests()) {
|
||||||
allTests.add(tResult);
|
allTests.add(tResult);
|
||||||
switch (tResult.getStatus()) {
|
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.
|
// Access the derived data.
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
@ -258,6 +289,10 @@ public class DataModel {
|
||||||
return ignoredTests.size();
|
return ignoredTests.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getPendingTestsCount() {
|
||||||
|
return pendingTests.size();
|
||||||
|
}
|
||||||
|
|
||||||
public Collection<TestResults> getAllTests() {
|
public Collection<TestResults> getAllTests() {
|
||||||
return Collections.unmodifiableCollection(allTests);
|
return Collections.unmodifiableCollection(allTests);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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("<title>Test Suite</title>");
|
||||||
|
private static final Pattern TEST_PATTERN = Pattern
|
||||||
|
.compile("<tr><td><a\\s+href=[^>]*>([^<]+)</a></td></tr>(?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<String> testNames = new ArrayList<String>();
|
||||||
|
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<String> testNames;
|
||||||
|
|
||||||
|
public SuiteContents(String name, Collection<String> testNames) {
|
||||||
|
this.name = name;
|
||||||
|
this.testNames = Collections
|
||||||
|
.unmodifiableCollection(new ArrayList<String>(testNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<String> getTestNames() {
|
||||||
|
return testNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -10,11 +10,13 @@ import edu.cornell.mannlib.vitro.utilities.testrunner.output.SuiteResults;
|
||||||
public class SuiteData {
|
public class SuiteData {
|
||||||
private final String name;
|
private final String name;
|
||||||
private final boolean ignored;
|
private final boolean ignored;
|
||||||
|
private final SuiteContents contents;
|
||||||
private final SuiteResults results;
|
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.name = name;
|
||||||
this.ignored = ignored;
|
this.ignored = ignored;
|
||||||
|
this.contents = contents;
|
||||||
this.results = results;
|
this.results = results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +28,10 @@ public class SuiteData {
|
||||||
return ignored;
|
return ignored;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SuiteContents getContents() {
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
public SuiteResults getResults() {
|
public SuiteResults getResults() {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,8 @@ public class OutputSummaryFormatter {
|
||||||
+ "</td><td>" + dataModel.getIgnoredTestCount() + "</td>");
|
+ "</td><td>" + dataModel.getIgnoredTestCount() + "</td>");
|
||||||
if (dataModel.isAnyPending()) {
|
if (dataModel.isAnyPending()) {
|
||||||
writer.println(" <tr><td>Pending</td><td>"
|
writer.println(" <tr><td>Pending</td><td>"
|
||||||
+ dataModel.getPendingSuitesCount() + "</td><td>?</td>");
|
+ dataModel.getPendingSuitesCount() + "</td><td>"
|
||||||
|
+ dataModel.getPendingTestsCount() + "</td>");
|
||||||
}
|
}
|
||||||
writer.println(" <tr><td class=\"total\">Total</td><td>"
|
writer.println(" <tr><td class=\"total\">Total</td><td>"
|
||||||
+ dataModel.getTotalSuiteCount() + "</td><td>"
|
+ dataModel.getTotalSuiteCount() + "</td><td>"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue