package hudson.plugins.analysis.core; import static hudson.plugins.analysis.util.ThresholdValidator.*; import java.util.Collection; import hudson.model.Result; import hudson.plugins.analysis.util.PluginLogger; import hudson.plugins.analysis.util.model.FileAnnotation; import hudson.plugins.analysis.util.model.Priority; /** * Evaluates if the number of annotations exceeds a given threshold value. * * @author Ulli Hafner */ public class BuildResultEvaluator { /** * Evaluates the build result. The build is marked as unstable if one of the * thresholds has been exceeded. * * @param logger * logs the results * @param descriptor * health descriptor * @param allAnnotations * all annotations * @param annotationDelta * the annotation difference between this build and the reference * build (i.e., the difference #numbersOfAnnotations(build) - #numbersOfAnnotations(referenceBuild)) * @return the build result */ public Result evaluateBuildResult(final PluginLogger logger, final HealthDescriptor descriptor, final Collection<FileAnnotation> allAnnotations, final int annotationDelta) { int annotationCount = extractNumberOfRelevantAnnotations(logger, descriptor, "", allAnnotations); if (descriptor.getMinimumPriority() != Priority.LOW) { logger.log(String.format("Considering %d annotations for build status evaluation", annotationCount)); logger.log(String.format("Considering %d new annotations for build status evaluation", annotationDelta)); } if (isAnnotationCountExceeded(annotationCount, descriptor.getFailureThreshold())) { logger.log("Setting build status to FAILURE since total number of annotations exceeds the threshold " + descriptor.getFailureThreshold()); return Result.FAILURE; } if (isAnnotationCountExceeded(annotationDelta, descriptor.getNewFailureThreshold())) { logger.log("Setting build status to FAILURE since total number of new annotations exceeds the threshold " + descriptor.getNewFailureThreshold()); return Result.FAILURE; } if (isAnnotationCountExceeded(annotationCount, descriptor.getThreshold())) { logger.log("Setting build status to UNSTABLE since total number of annotations exceeds the threshold " + descriptor.getThreshold()); return Result.UNSTABLE; } if (isAnnotationCountExceeded(annotationDelta, descriptor.getNewThreshold())) { logger.log("Setting build status to UNSTABLE since total number of new annotations exceeds the threshold " + descriptor.getNewThreshold()); return Result.UNSTABLE; } logger.log("Not changing build status, since no threshold has been exceeded"); return Result.SUCCESS; } /** * Evaluates the build result. The build is marked as unstable if one of the * thresholds has been exceeded. * * @param logger * logs the results * @param descriptor * health descriptor * @param allAnnotations * all annotations * @param newAnnotations * the asymmetric set intersection of the annotations of this build and the annotations of the reference * build (i.e., the operation annotations(referenceBuild).removeAll(numbersOfAnnotations(build)) * @return the build result */ public Result evaluateBuildResult(final PluginLogger logger, final HealthDescriptor descriptor, final Collection<FileAnnotation> allAnnotations, final Collection<FileAnnotation> newAnnotations) { int newAnnotationCount = extractNumberOfRelevantAnnotations(logger, descriptor, "new", newAnnotations); return evaluateBuildResult(logger, descriptor, allAnnotations, newAnnotationCount); } /** * Extracts the relevant annotations from the specified collection of * annotations. A annotation is relevant, if its priority is greater or * equal than the minimum priority of the health descriptor. * * @param logger * logs the results * @param descriptor * health descriptor * @param description * the description of the analyzed annotations * @param annotations * the annotations to consider * @return the number of relevant annotations */ private int extractNumberOfRelevantAnnotations(final PluginLogger logger, final HealthDescriptor descriptor, final String description, final Collection<FileAnnotation> annotations) { ParserResult result = new ParserResult(annotations); int annotationCount = 0; for (Priority priority : Priority.collectPrioritiesFrom(descriptor.getMinimumPriority())) { annotationCount += result.getNumberOfAnnotations(priority); } logger.log(String.format("Found %d %s annotations (%d high, %d normal, %d low)", result.getNumberOfAnnotations(), description, result.getNumberOfAnnotations(Priority.HIGH), result.getNumberOfAnnotations(Priority.NORMAL), result.getNumberOfAnnotations(Priority.LOW))); return annotationCount; } /** * Returns whether the new annotation count exceeds the user defined threshold * and the build should be set to unstable. * * @param annotationCount * the number of new annotations * @param annotationThreshold * string representation of the threshold value * @return <code>true</code> if the build should be set to unstable */ public boolean isAnnotationCountExceeded(final int annotationCount, final String annotationThreshold) { if (annotationCount > 0 && isValid(annotationThreshold)) { return annotationCount > convert(annotationThreshold); } return false; } }