package hudson.plugins.im.build_notify;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.kohsuke.stapler.DataBoundConstructor;
import hudson.Extension;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.plugins.im.IMPublisher;
import hudson.plugins.im.tools.MessageHelper;
import hudson.tasks.junit.CaseResult;
import hudson.tasks.test.AbstractTestResultAction;
/**
* Extends {@link DefaultBuildToChatNotifier} and also prints
* failed tests if any.
* Up to 5 failing tests are printed. Youngest failing tests are displayed first.
*
* @author kutzi
*/
public class PrintFailingTestsBuildToChatNotifier extends
DefaultBuildToChatNotifier {
@DataBoundConstructor
public PrintFailingTestsBuildToChatNotifier() {
}
@Override
public String buildCompletionMessage(IMPublisher publisher,
AbstractBuild<?, ?> build, BuildListener listener)
throws IOException, InterruptedException {
String msg = super.buildCompletionMessage(publisher, build, listener);
return msg + getFailedTestsReport(build);
}
@Override
public String culpritMessage(IMPublisher publisher,
AbstractBuild<?, ?> build, BuildListener listener) {
String msg = super.culpritMessage(publisher, build, listener);
return msg + getFailedTestsReport(build);
}
@Override
public String suspectMessage(IMPublisher publisher,
AbstractBuild<?, ?> build, BuildListener listener,
boolean firstFailure) {
String msg = super.suspectMessage(publisher, build, listener, firstFailure);
return msg + getFailedTestsReport(build);
}
@Override
public String upstreamCommitterMessage(IMPublisher publisher,
AbstractBuild<?, ?> build, BuildListener listener,
AbstractBuild<?, ?> upstreamBuild) {
String msg = super
.upstreamCommitterMessage(publisher, build, listener, upstreamBuild);
return msg + getFailedTestsReport(build);
}
private CharSequence getFailedTestsReport(AbstractBuild<?, ?> build) {
AbstractTestResultAction testResultAction = build.getAction(AbstractTestResultAction.class);
if (testResultAction == null || testResultAction.getFailCount() == 0) {
return "";
}
StringBuilder buf = new StringBuilder();
List<CaseResult> failedTests = testResultAction.getFailedTests();
Collections.sort(failedTests, new Comparator<CaseResult>() {
@Override
public int compare(CaseResult o1, CaseResult o2) {
if (o1.getAge() < o2.getAge()) {
return -1;
} else if (o2.getAge() < o1.getAge()) {
return 1;
}
return o1.getFullName().compareTo(o2.getFullName());
}
});
final int maxNumberOfTestsToPrint = 5;
buf.append("\nFailed tests:\n");
for (int i=0; i < Math.min(maxNumberOfTestsToPrint, failedTests.size()); i++) {
CaseResult test = failedTests.get(i);
buf.append(test.getFullName())
.append(": ")
.append(MessageHelper.getTestUrl(test))
.append("\n");
}
int more = failedTests.size() - maxNumberOfTestsToPrint;
if (more > 0) {
buf.append("(").append(more).append(" more)");
}
return buf;
}
@Extension
public static class DescriptorImpl extends BuildToChatNotifierDescriptor {
@Override
public String getDisplayName() {
return "Summary, SCM changes and failed tests";
}
}
}