com.thalesgroup.sonar.plugins.tusar.sensors.TUSARTestsDataExtractor.java Source code

Java tutorial

Introduction

Here is the source code for com.thalesgroup.sonar.plugins.tusar.sensors.TUSARTestsDataExtractor.java

Source

/*******************************************************************************
 * Copyright (c) 2010 Thales Corporate Services SAS                             *
 *                                                                              *
 * Permission is hereby granted, free of charge, to any person obtaining a copy *
 * of this software and associated documentation files (the "Software"), to deal*
 * in the Software without restriction, including without limitation the rights *
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell    *
 * copies of the Software, and to permit persons to whom the Software is        *
 * furnished to do so, subject to the following conditions:                     *
 *                                                                              *
 * The above copyright notice and this permission notice shall be included in   *
 * all copies or substantial portions of the Software.                          *
 *                                                                              *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR   *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,     *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  *
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER       *
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,*
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN    *
 * THE SOFTWARE.                                                                *
 *******************************************************************************/

package com.thalesgroup.sonar.plugins.tusar.sensors;

import com.thalesgroup.sonar.lib.model.v5.Sonar;
import com.thalesgroup.sonar.lib.model.v5.TestsComplexType;
import com.thalesgroup.sonar.plugins.tusar.TUSARResource;
import org.apache.commons.lang.StringEscapeUtils;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.ParsingUtils;

import javax.xml.stream.XMLStreamException;
import java.text.ParseException;
import java.util.*;

/**
 * Contains methods to extract TUSAR tests data.
 */
public class TUSARTestsDataExtractor {

    //   private Logger logger = LoggerFactory.getLogger(TUSARTestsDataExtractor.class);   

    public static Collection<TestSuiteReport> extractTestsData(Sonar model, SensorContext context)
            throws XMLStreamException {
        Map<String, TestSuiteReport> reportsPerPath = new HashMap<String, TestSuiteReport>();

        for (TestsComplexType.Testsuite testSuite : model.getTests().getTestsuite()) {

            //testSuite.getName();
            //testSuite.getSkipped();
            //testSuite.getTests();
            //testSuite.getTime();

            for (TestsComplexType.Testsuite.Testcase testCase : testSuite.getTestcase()) {

                String testCasePath = "";
                if (testCase.getFilepath() != null) {
                    testCasePath = testCase.getFilepath();
                } else if (testCase.getFulltestname() != null) {
                    testCasePath = testCase.getFulltestname();
                }

                //Fix bug : if testCasePath is empty, set it with the testname
                if (testCasePath.trim().isEmpty()) {
                    testCasePath = testCase.getTestname();
                }

                //Filter testCasePath
                testCasePath = testCasePath.replaceAll("\r", "");
                testCasePath = testCasePath.replaceAll("\\n", "");
                testCasePath = testCasePath.trim();

                TestSuiteReport testSuiteReport = reportsPerPath.get(testCasePath);
                if (testSuiteReport == null) {
                    testSuiteReport = new TestSuiteReport(testCasePath);
                    reportsPerPath.put(testCasePath, testSuiteReport);
                }

                TestCaseDetails testCaseDetails = new TestCaseDetails();

                testCaseDetails.setName(testCase.getTestname());
                if (testCase.getTime() == null) {
                    testCaseDetails.setTimeMS(0);
                } else {
                    testCaseDetails.setTimeMS(getTimeAttributeInMS(testCase.getTime()).intValue());
                }

                //testCase.getAssertions();
                //testCase.getFilename();

                String testCaseStatus = TestCaseDetails.STATUS_OK;

                if (testCase.getFailure() != null) {
                    testCaseStatus = TestCaseDetails.STATUS_FAILURE;
                    testCaseDetails.setErrorMessage(testCase.getFailure().getMessage());
                    testCaseDetails.setStackTrace(testCase.getFailure().getContent());

                    // cumulate data for test suite
                    testSuiteReport.setFailures(testSuiteReport.getFailures() + 1);
                } else if (testCase.getError() != null) {
                    testCaseStatus = TestCaseDetails.STATUS_ERROR;
                    testCaseDetails.setErrorMessage(testCase.getError().getMessage());
                    testCaseDetails.setStackTrace(testCase.getError().getContent());

                    // cumulate data for test suite
                    testSuiteReport.setErrors(testSuiteReport.getErrors() + 1);
                } else if (testCase.getSkipped() != null) {
                    testCaseStatus = TestCaseDetails.STATUS_SKIPPED;

                    // cumulate data for test suite
                    testSuiteReport.setSkipped(testSuiteReport.getSkipped() + 1);
                }

                testCaseDetails.setStatus(testCaseStatus);

                /* TODO check what to do with that
                if (testCase.getSystemOut() != null) {
                    systemOut.getContent();
                }
                if (testCase.getSystemErr() != null) {
                    systemErr.getContent();
                }
                */

                testSuiteReport.setTests(testSuiteReport.getTests() + 1);
                testSuiteReport.setTimeMS(testSuiteReport.getTimeMS() + testCaseDetails.getTimeMS());
                testSuiteReport.getDetails().add(testCaseDetails);
            }
        }

        return reportsPerPath.values();
    }

    public static void saveToSonarTestsData(Collection<TestSuiteReport> testSuiteReports, SensorContext context,
            Project project) {

        for (TestSuiteReport testSuiteReport : testSuiteReports) {

            TUSARResource resource = TUSARResource.fromAbsOrRelativePath(testSuiteReport.getPath(), project, true);

            double testsCount = testSuiteReport.getTests() - testSuiteReport.getSkipped();
            context.saveMeasure(resource, CoreMetrics.TESTS, testsCount);
            context.saveMeasure(resource, CoreMetrics.TEST_ERRORS, (double) testSuiteReport.getErrors());
            context.saveMeasure(resource, CoreMetrics.TEST_FAILURES, (double) testSuiteReport.getFailures());
            context.saveMeasure(resource, CoreMetrics.SKIPPED_TESTS, (double) testSuiteReport.getSkipped());
            context.saveMeasure(resource, CoreMetrics.TEST_EXECUTION_TIME, (double) testSuiteReport.getTimeMS());

            double passedTests = testSuiteReport.getTests() - testSuiteReport.getErrors()
                    - testSuiteReport.getFailures();
            if (testsCount > 0) {
                double percentage = ParsingUtils.scaleValue(passedTests * 100d / testsCount);
                context.saveMeasure(resource, CoreMetrics.TEST_SUCCESS_DENSITY, percentage);
            }

            String testCaseDetails = computeTestsDetails(context, testSuiteReport);
            context.saveMeasure(resource, new Measure(CoreMetrics.TEST_DATA, testCaseDetails));
        }
    }

    private static String computeTestsDetails(SensorContext context, TestSuiteReport fileReport) {
        StringBuilder testCaseDetails = new StringBuilder(256);
        testCaseDetails.append("<tests-details>");
        List<TestCaseDetails> details = fileReport.getDetails();

        for (TestCaseDetails detail : details) {
            testCaseDetails.append("<testcase status=\"").append(detail.getStatus()).append("\" time=\"")
                    .append(detail.getTimeMS()).append("\" name=\"").append(detail.getName()).append("\"");

            boolean isError = detail.getStatus().equals(TestCaseDetails.STATUS_ERROR);
            if (isError || detail.getStatus().equals(TestCaseDetails.STATUS_FAILURE)) {
                testCaseDetails.append(">").append(isError ? "<error message=\"" : "<failure message=\"")
                        .append(StringEscapeUtils.escapeXml(detail.getErrorMessage())).append("\">")
                        .append("<![CDATA[").append(StringEscapeUtils.escapeXml(detail.getStackTrace()))
                        .append("]]>").append(isError ? "</error>" : "</failure>").append("</testcase>");
            } else {
                testCaseDetails.append("/>");
            }
        }
        testCaseDetails.append("</tests-details>");
        return testCaseDetails.toString();
    }

    private static Double getTimeAttributeInMS(String stringTime) throws XMLStreamException {
        // hardcoded to Locale.ENGLISH see http://jira.codehaus.org/browse/SONAR-602
        try {
            Double time = ParsingUtils.parseNumber(stringTime, Locale.ENGLISH);
            return !Double.isNaN(time) ? ParsingUtils.scaleValue(time * 1000, 3) : 0;
        } catch (ParseException e) {
            throw new XMLStreamException(e);
        }
    }
}