/*******************************************************************************
* Copyright (c) 2010 Thales Corporate Services SAS *
* Author : Gregory Boissinot, Guillaume Tanier *
* *
* 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.hudson.plugins.tusarnotifier;
import com.thalesgroup.dtkit.metrics.api.InputMetric;
import com.thalesgroup.dtkit.metrics.hudson.api.type.*;
import com.thalesgroup.dtkit.util.converter.ConvertException;
import com.thalesgroup.dtkit.util.validator.ValidatorError;
import com.thalesgroup.dtkit.util.validator.ValidatorException;
import com.thalesgroup.hudson.plugins.tusarnotifier.exception.TusarNotifierException;
import com.thalesgroup.hudson.plugins.tusarnotifier.util.TusarNotifierLogger;
import hudson.FilePath;
import hudson.Util;
import hudson.model.TaskListener;
import junit.framework.Assert;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.FileSet;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
public class TusarTransformer implements FilePath.FileCallable<String>, Serializable {
private TaskListener listener;
private TestType[] typesTests;
private CoverageType[] typesCoverage;
private ViolationsType[] typesViolations;
private MeasureType[] typesMeasures;
public TusarTransformer(TaskListener listener, TestType[] typesTests, CoverageType[] typesCoverage, ViolationsType[] typesViolations, MeasureType[] typesMeasures) {
this.listener = listener;
this.typesTests = typesTests;
this.typesCoverage = typesCoverage;
this.typesViolations = typesViolations;
this.typesMeasures = typesMeasures;
}
/**
* Get the name display in the tool
*
* @param tool the current tool
*
* @return the label in UI of the tool
* @throws TusarNotifierException
*
*/
private String getDisplayName(MetricsType tool) throws TusarNotifierException {
if (tool instanceof TestType) {
return ((TestType) tool).getDescriptor().getDisplayName();
}
if (tool instanceof MeasureType) {
return ((MeasureType) tool).getDescriptor().getDisplayName();
}
if (tool instanceof ViolationsType) {
return ((ViolationsType) tool).getDescriptor().getDisplayName();
}
if (tool instanceof CoverageType) {
return ((CoverageType) tool).getDescriptor().getDisplayName();
}
throw new TusarNotifierException();
}
/**
* /**
* Collect reports from the given parentpath and the pattern, while
* filtering out all files that were created before the given time.
*
* @param listener the listener
* @param tool the current tool
* @param parentPath the parent output directory
* @param pattern pattern to seach files
* @return an array of strings
* @throws com.thalesgroup.hudson.plugins.tusarnotifier.exception.TusarNotifierException
*
*/
private List<String> findtReports(TaskListener listener, MetricsType tool, File parentPath, String pattern)
throws TusarNotifierException {
FileSet fs = Util.createFileSet(parentPath, pattern);
DirectoryScanner ds = fs.getDirectoryScanner();
String[] xunitFiles = ds.getIncludedFiles();
if (xunitFiles.length == 0) {
String msg = "[ERROR] - No test report file(s) were found with the pattern '"
+ pattern + "' relative to '" + parentPath + "' for the ressource '" + getDisplayName(tool) + "'."
+ " Did you enter a pattern relative to the correct directory?"
+ " Did you generate the result report(s) for '" + getDisplayName(tool) + "'?";
TusarNotifierLogger.log(listener, msg);
return null;
}
return Arrays.asList(xunitFiles);
}
/**
* Convert
*
* @param listener
* @param workspace
* @param generatedDirectory
* @param metricsType
* @return
* @throws com.thalesgroup.hudson.plugins.tusarnotifier.exception.TusarNotifierException
*
*/
private boolean convertTusar(TaskListener listener, File workspace, File generatedDirectory, MetricsType metricsType)
throws TusarNotifierException {
//Get the associated inputMetric object
InputMetric inputMetric = metricsType.getInputMetric();
Assert.assertNotNull(inputMetric);
TusarNotifierLogger.log(listener, "Starting to process " + inputMetric.getLabel());
//Retrieve the pattern and filter it with environment variables
String curPattern = metricsType.getPattern();
curPattern = curPattern.replaceAll("[\t\r\n]+", " ");
//curPattern = Util.replaceMacro(curPattern, listener);
//Get all input files matching the user pattern
List<String> resultFiles = findtReports(listener, metricsType, workspace, curPattern);
if (resultFiles == null || resultFiles.size() == 0) {
return false;
}
try {
TusarNotifierLogger.log(listener, "[" + getDisplayName(metricsType) + "] - Processing " + resultFiles.size() + " files with the pattern '" + metricsType.getPattern() + "' relative to '" + workspace + "'.");
for (String resultFileName : resultFiles) {
File resultFile = new File(workspace, resultFileName);
if (resultFile.length() == 0) {
//Ignore the empty result file (some reason)
String msg = "[WARNING] - The file '" + resultFile.getPath() + "' is empty. This file has been ignored.";
TusarNotifierLogger.log(listener, msg);
for (ValidatorError validatorError : inputMetric.getInputValidationErrors()) {
TusarNotifierLogger.log(listener, "[WARNING] " + validatorError.toString());
}
continue;
}
//Validate the input file (nom empty)
if (!inputMetric.validateInputFile(resultFile)) {
//Ignore invalid files
TusarNotifierLogger.log(listener, "[WARNING] - The file '" + resultFile + "' is an invalid file. It has been ignored.");
continue;
}
// Process the conversion
File tusarTargetFile = new File(generatedDirectory, resultFile.hashCode() + ".xml");
TusarNotifierLogger.log(listener, "[INFO] - Converting '" + resultFile + "' .");
inputMetric.convert(resultFile, tusarTargetFile);
//Validate the output
boolean validateOutput = inputMetric.validateOutputFile(tusarTargetFile);
if (!validateOutput) {
TusarNotifierLogger.log(listener, "[WARNING] - The converted file for the input file '" + resultFile + "' doesn't match the TUSAR format");
for (ValidatorError validatorError : inputMetric.getOutputValidationErrors()) {
TusarNotifierLogger.log(listener, "[WARNING] " + validatorError.toString());
}
TusarNotifierLogger.log(listener, "Ending to process " + inputMetric.getLabel());
return false;
}
}
}
catch (ConvertException ce) {
throw new TusarNotifierException("Can't convert " + inputMetric, ce);
}
catch (ValidatorException vae) {
throw new TusarNotifierException("Can't validate " + inputMetric, vae);
}
TusarNotifierLogger.log(listener, "Ending to process " + inputMetric.getLabel());
return true;
}
public String invoke(File workspace, hudson.remoting.VirtualChannel channel) throws IOException, InterruptedException {
final StringBuffer sb = new StringBuffer();
final String generatedFolder = "generatedTUSARFiles";
final String generatedTests = generatedFolder + "/TESTS";
final String generatedCoverage = generatedFolder + "/COVERAGE";
final String generatedMeasures = generatedFolder + "/MEASURES";
final String generatedViolations = generatedFolder + "/VIOLATIONS";
try {
// Apply conversion for all tests tools
if (typesTests.length != 0) {
File outputTestsFileParent = new File(workspace, generatedTests);
if (!outputTestsFileParent.mkdirs()) {
TusarNotifierLogger.log(listener, "Can't create " + outputTestsFileParent + ". Maybe the directory already exists.");
}
for (TestType testsType : typesTests) {
boolean convertOK = convertTusar(listener, workspace, outputTestsFileParent, testsType);
if (!convertOK) {
return null;
}
}
sb.append(";").append(generatedTests);
}
// Apply conversion for all coverage tools
if (typesCoverage.length != 0) {
File outputCoverageFileParent = new File(workspace, generatedCoverage);
if (!outputCoverageFileParent.mkdirs()) {
TusarNotifierLogger.log(listener, "Can't create " + outputCoverageFileParent + ". Maybe the directory already exists.");
}
for (CoverageType coverageType : typesCoverage) {
boolean convertOK = convertTusar(listener, workspace, outputCoverageFileParent, coverageType);
if (!convertOK) {
return null;
}
}
sb.append(";").append(generatedCoverage);
}
//-- Apply conversion for all violations tools
if (typesViolations.length != 0) {
File outputViolationsFileParent = new File(workspace, generatedViolations);
if (!outputViolationsFileParent.mkdirs()) {
TusarNotifierLogger.log(listener, "Can't create " + outputViolationsFileParent + ". Maybe the directory already exists.");
}
for (ViolationsType violationsType : typesViolations) {
boolean convertOK = convertTusar(listener, workspace, outputViolationsFileParent, violationsType);
if (!convertOK) {
return null;
}
}
sb.append(";").append(generatedViolations);
}
// Apply conversion for all measures tools
if (typesMeasures.length != 0) {
File outputMeasuresFileParent = new File(workspace, generatedMeasures);
if (!outputMeasuresFileParent.mkdirs()) {
TusarNotifierLogger.log(listener, "Can't create " + outputMeasuresFileParent + ". Maybe the directory already exists.");
}
for (MeasureType measuresType : typesMeasures) {
boolean convertOK = convertTusar(listener, workspace, outputMeasuresFileParent, measuresType);
if (!convertOK) {
return null;
}
}
sb.append(";").append(generatedMeasures);
}
// Remove the first character
sb.delete(0, 1);
}
catch (Exception e) {
TusarNotifierLogger.log(listener, "Tusar notifier error : " + e);
return null;
}
return sb.toString();
}
}