package hudson.plugins.performance.constraints; import java.lang.reflect.InvocationTargetException; import java.util.List; import hudson.AbortException; import hudson.Extension; import hudson.model.Run; import hudson.plugins.performance.actions.PerformanceBuildAction; import hudson.plugins.performance.constraints.blocks.TestCaseBlock; import hudson.plugins.performance.descriptors.ConstraintDescriptor; import hudson.plugins.performance.reports.PerformanceReport; import hudson.plugins.performance.reports.UriReport; import hudson.util.FormValidation; import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; /** * Absolute Constraints compare the result of a new load test against some user defined values. * * @author Rene Kugel */ public class AbsoluteConstraint extends AbstractConstraint { @Extension public static class DescriptorImpl extends ConstraintDescriptor { @Override public String getDisplayName() { return "Absolute Constraint"; } public FormValidation doCheckRelatedPerfReport(@QueryParameter String relatedPerfReport) { if (StringUtils.isEmpty(relatedPerfReport)) { return FormValidation.error("This field must not be empty"); } return FormValidation.ok(); } public FormValidation doCheckTestCase(@QueryParameter String testCase) { if (StringUtils.isEmpty(testCase)) { return FormValidation.error("This field must not be empty"); } return FormValidation.ok(); } } /** * User defined absolute value which must not be exceeded */ private long value = 0; @DataBoundConstructor public AbsoluteConstraint(Metric meteredValue, Operator operator, String relatedPerfReport, Escalation escalationLevel, boolean success, TestCaseBlock testCaseBlock, long value) { super(meteredValue, operator, relatedPerfReport, escalationLevel, success, testCaseBlock); this.value = value; } /** * Cloning of a AbsoluteConstraint Note that this is not from the Interface Clonable * * @return clone of this object */ public AbsoluteConstraint clone() { AbsoluteConstraint clone = new AbsoluteConstraint(this.getMeteredValue(), this.getOperator(), this.getRelatedPerfReport(), this.getEscalationLevel(), this.getSuccess(), new TestCaseBlock(this .getTestCaseBlock().getTestCase()), this.getValue()); return clone; } @Override public ConstraintEvaluation evaluate(List<? extends Run<?, ?>> builds) throws InvocationTargetException, AbortException { if (builds.isEmpty()) { throw new AbortException("Performance: No builds found to evaluate!"); } checkForDefectiveParams(builds); PerformanceReport pr = builds.get(0).getAction(PerformanceBuildAction.class).getPerformanceReportMap().getPerformanceReport(getRelatedPerfReport()); // calculate the double newValue = 0; if (!isSpecifiedTestCase()) { newValue = checkMetredValueforPerfReport(getMeteredValue(), pr); } else { List<UriReport> uriList = pr.getUriListOrdered(); for (UriReport ur : uriList) { if (getTestCaseBlock().getTestCase().equals(ur.getUri())) { newValue = checkMetredValueforUriReport(getMeteredValue(), ur); break; } } } return check(newValue); } /** * Compares the values and sets the success and a result message of a constraint. * * @param newValue measured value of a specified metric of the newly created test * @return evaluated constraint */ private ConstraintEvaluation check(double newValue) { switch (getOperator()) { case NOT_LESS: if (newValue >= getValue()) { setSuccess(true); } else { setSuccess(false); } break; case NOT_GREATER: if (newValue <= getValue()) { setSuccess(true); } else { setSuccess(false); } break; case NOT_EQUAL: if (newValue != getValue()) { setSuccess(true); } else { setSuccess(false); } break; } ConstraintEvaluation evaluation = new ConstraintEvaluation(this, getValue(), newValue); String measuredLevel = isSpecifiedTestCase() ? getTestCaseBlock().getTestCase() : "all test cases"; if (getSuccess()) { setResultMessage("Absolute constraint successful! - Report: " + getRelatedPerfReport() + " \n" + "The constraint says: " + getMeteredValue() + " of " + measuredLevel + " must " + getOperator().text + " " + getValue() + "\n" + "Measured value for " + getMeteredValue() + ": " + newValue + "\n" + "Escalation Level: " + getEscalationLevel()); } else { setResultMessage("Absolute constraint failed! - Report: " + getRelatedPerfReport() + " \n" + "The constraint says: " + getMeteredValue() + " of " + measuredLevel + " must " + getOperator().text + " " + getValue() + "\n" + "Measured value for " + getMeteredValue() + ": " + newValue + "\n" + "Escalation Level: " + getEscalationLevel()); } return evaluation; } public long getValue() { return value; } public void setValue(long value) { this.value = value; } }