/src/main/java/com/atlassian/bamboo/plugin/dotnet/tests/mbunit/MBUnitXmlTestResultsParser.java
Java | 292 lines | 226 code | 32 blank | 34 comment | 21 complexity | f2727249aa18e318e4de285d1141af12 MD5 | raw file
Possible License(s): BSD-3-Clause
- package com.atlassian.bamboo.plugin.dotnet.tests.mbunit;
- import com.atlassian.bamboo.plugin.dotnet.tests.TestResultContentHandler;
- import com.atlassian.bamboo.plugin.dotnet.tests.TestResultsParser;
- import com.atlassian.bamboo.results.tests.TestResults;
- import com.atlassian.bamboo.resultsummary.tests.TestCaseResultErrorImpl;
- import com.atlassian.bamboo.resultsummary.tests.TestState;
- import com.google.common.collect.ImmutableList;
- import com.google.common.collect.Lists;
- import net.jcip.annotations.NotThreadSafe;
- import org.dom4j.Document;
- import org.dom4j.DocumentFactory;
- import org.dom4j.Node;
- import org.dom4j.io.DocumentSource;
- import org.dom4j.io.SAXReader;
- import org.jaxen.JaxenException;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import javax.xml.transform.Source;
- import javax.xml.transform.Transformer;
- import javax.xml.transform.TransformerFactory;
- import javax.xml.transform.stream.StreamResult;
- import javax.xml.transform.stream.StreamSource;
- import java.io.ByteArrayOutputStream;
- import java.io.InputStream;
- import java.util.Collections;
- import java.util.List;
- import java.util.Map;
- /**
- * Handles parsing MBUnit report files.
- *
- * @author Ross Rowe
- */
- @NotThreadSafe
- public class MBUnitXmlTestResultsParser extends TestResultContentHandler implements TestResultsParser
- {
- private static final Logger log = LoggerFactory.getLogger(MBUnitXmlTestResultsParser.class);
- private String testName;
- private List<TestResults> failedTests;
- private List<TestResults> inconclusiveTests;
- private List<TestResults> passedTests;
- private String systemOut;
- private String errorOut;
- public String getTestName() {
- return testName;
- }
- public void setTestName(String testName) {
- this.testName = testName;
- }
- /**
- * Indicates whether the test file contains errors.
- *
- * @return
- */
- public boolean hasErrors() {
- return getNumberOfErrors() > 0;
- }
- public int getNumberOfErrors() {
- return failedTests.size();
- }
- public int getNumberOfTests() {
- return failedTests.size() + passedTests.size();
- }
- @Override
- public ImmutableList<TestResults> getSuccessfulTests()
- {
- return ImmutableList.copyOf(passedTests);
- }
- @Override
- public ImmutableList<TestResults> getFailedTests()
- {
- return ImmutableList.copyOf(failedTests);
- }
- @Override
- public ImmutableList<TestResults> getInconclusiveTests()
- {
- return ImmutableList.copyOf(inconclusiveTests);
- }
- public String getSystemOut() {
- return systemOut;
- }
- public String getSystemErr() {
- return errorOut;
- }
- /**
- * @param inputStream
- */
- @Override
- public void parse(InputStream inputStream)
- {
- failedTests = Lists.newArrayList();
- inconclusiveTests = Lists.newArrayList();
- passedTests = Lists.newArrayList();
- try
- {
- final Map<String, String> uris = Collections.singletonMap("g", "http://www.gallio.org/");
- final DocumentFactory factory = new DocumentFactory();
- factory.setXPathNamespaceURIs(uris);
- // parse or create a document
- final SAXReader reader = new SAXReader();
- reader.setDocumentFactory(factory);
- final Document document = reader.read(inputStream);
- parse(document);
- }
- catch (Exception e)
- {
- log.error("Failed to parse xml test results. File was null.", e);
- }
- }
- /**
- * @param document
- * @throws JaxenException
- */
- private void parse(Document document) throws JaxenException
- {
- // handle pre MBUnit 3.0.5 format
- parsePreThreeZeroFiveFormat(document);
- // handle MBUnit 3.0.5 format
- parseThreeZeroFiveFormat(document);
- }
- /**
- * @param document
- */
- private void parseThreeZeroFiveFormat(Document document)
- {
- List testStepRuns = document.selectNodes("//g:testStepRun[g:testStep/g:metadata/g:entry/g:value/text()='Fixture']");
- for (Object object : testStepRuns)
- {
- Node testStepRun = (Node) object;
- // if the testStep is a fixture
- String fixtureName = testStepRun.selectSingleNode("g:testStep/g:codeReference/@type").getStringValue();
- List runs = testStepRun.selectNodes("g:children/g:testStepRun");
- for (Object runObject : runs)
- {
- Node run = (Node) runObject;
- final String testName = run.selectSingleNode("g:testStep/@name").getStringValue();
- final String testDuration = run.selectSingleNode("g:result/@duration").getStringValue();
- final String result = run.selectSingleNode("g:result/g:outcome/@status").getStringValue();
- final TestResults testResult = new TestResults(fixtureName, testName, testDuration);
- if ("passed".equalsIgnoreCase(result))
- {
- testResult.setState(TestState.SUCCESS);
- passedTests.add(testResult);
- }
- else if ("failed".equalsIgnoreCase(result))
- {
- //run a stylesheet transformation to print out the
- //test information
- InputStream inputStream = getClass()
- .getClassLoader()
- .getResourceAsStream("com/atlassian/bamboo/plugin/dotnet/tests/mbunit/Gallio-Report.txt.xsl");
- StreamSource source = new StreamSource(inputStream);
- Document newDocument = DocumentFactory.getInstance().createDocument();
- newDocument.add(run.detach());
- try
- {
- testResult.addError(new TestCaseResultErrorImpl(transform(newDocument, source)));
- }
- catch (Exception e)
- {
- log.error("Failed to transform the document", e);
- }
- testResult.setState(TestState.FAILED);
- failedTests.add(testResult);
- }
- else if ("skipped".equalsIgnoreCase(result))
- {
- testResult.setState(TestState.SKIPPED);
- inconclusiveTests.add(testResult);
- }
- else
- {
- log.info("Skipping testStepRun node with status {}", result);
- }
- }
- }
- }
- /**
- * @param document
- */
- private void parsePreThreeZeroFiveFormat(Document document)
- {
- List fixtures = document.selectNodes("//fixture");
- for (Object object : fixtures)
- {
- Node fixtureNode = (Node) object;
- String fixtureName = fixtureNode.selectSingleNode("@name").getStringValue();
- List runs = fixtureNode.selectNodes("//run");
- for (Object runObject : runs)
- {
- Node run = (Node) runObject;
- String fqTestName = run.selectSingleNode("@name").getStringValue();
- String testName = fqTestName.contains(".") && fqTestName.length() > fqTestName.lastIndexOf(".")
- ? fqTestName.substring(fqTestName.lastIndexOf(".") + 1)
- : fqTestName;
- String testDuration = run.selectSingleNode("@duration").getStringValue();
- String result = run.selectSingleNode("@result").getStringValue();
- if (result == null)
- {
- continue;
- }
- else
- {
- final TestResults testResult = new TestResults(fixtureName, testName, testDuration);
- if ("success".equalsIgnoreCase(result))
- {
- testResult.setState(TestState.SUCCESS);
- passedTests.add(testResult);
- }
- else if ("failure".equalsIgnoreCase(result))
- {
- // if we have an error, store it
- Node exceptionNode = run.selectSingleNode("exception");
- if (exceptionNode != null)
- {
- Node messageNode = exceptionNode.selectSingleNode("message");
- if (messageNode != null)
- {
- testResult.addError(new TestCaseResultErrorImpl(messageNode.getStringValue()));
- }
- }
- testResult.setState(TestState.FAILED);
- failedTests.add(testResult);
- }
- else if ("ignore".equalsIgnoreCase(result))
- {
- testResult.setState(TestState.SKIPPED);
- inconclusiveTests.add(testResult);
- }
- else
- {
- log.info("Skipping run node with result {}", result);
- }
- }
- }
- }
- }
- public String getErrorOut() {
- return errorOut;
- }
- public void setErrorOut(String errorOut) {
- this.errorOut = errorOut;
- }
- public void setSystemOut(String systemOut) {
- this.systemOut = systemOut;
- }
- public String transform(Node node, Source styleSheet) throws Exception
- {
- // perform transformation
- // System.setProperty("javax.xml.transform.TransformerFactory",
- // "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
- TransformerFactory factory = TransformerFactory.newInstance();
- Transformer transformer = factory.newTransformer(styleSheet);
- DocumentSource source = new DocumentSource(node);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- StreamResult result = new StreamResult(out);
- transformer.transform(source, result);
- // return resulting document
- return out.toString();
- }
- }