package org.jenkinsci.plugins.quarantine;
import hudson.Extension;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.model.Descriptor;
import hudson.model.Saveable;
import hudson.tasks.junit.CaseResult;
import hudson.tasks.junit.SuiteResult;
import hudson.tasks.junit.TestAction;
import hudson.tasks.junit.TestDataPublisher;
import hudson.tasks.junit.TestObject;
import hudson.tasks.junit.TestResult;
import hudson.tasks.junit.TestResultAction;
import hudson.tasks.test.AbstractTestResultAction;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.kohsuke.stapler.DataBoundConstructor;
public class QuarantineTestDataPublisher extends TestDataPublisher {
@DataBoundConstructor
public QuarantineTestDataPublisher() {
}
@Override
public Data getTestData(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener, TestResult testResult) {
Data data = new Data(build);
MailNotifier notifier = new MailNotifier(listener);
for (SuiteResult suite : testResult.getSuites()) {
for (CaseResult result : suite.getCases()) {
QuarantineTestAction previousAction = null;
CaseResult previous = result.getPreviousResult();
AbstractBuild<?, ?> previousBuild = build.getPreviousCompletedBuild();
if (previous != null) {
previousAction = previous.getTestAction(QuarantineTestAction.class);
}
// no immediate predecessor (e.g. because job failed or did not
// run), try and go back in build history
while (previous == null && previousBuild != null) {
if (previousBuild.getAction(AbstractTestResultAction.class) != null) {
hudson.tasks.test.TestResult tr = null;
try {
tr = previousBuild.getAction(AbstractTestResultAction.class).findCorrespondingResult(
result.getId());
}
catch (Exception e){
listener.getLogger().println("could not find result for id " + result.getId() + " in build " + previousBuild + ": " + e.getMessage());
}
if (tr != null) {
listener.getLogger().println("found " + tr.getDisplayName() + " in build " + previousBuild);
previousAction = tr.getTestAction(QuarantineTestAction.class);
break;
}
}
else
{
listener.getLogger().println("build " + previousBuild + " does not have test results");
}
previousBuild = previousBuild.getPreviousCompletedBuild();
}
if (previousAction != null && previousAction.isQuarantined()) {
QuarantineTestAction action = new QuarantineTestAction(data, result.getId());
action.quarantine(previousAction);
data.addQuarantine(result.getId(), action);
// send email if failed
if (!result.isPassed()) {
notifier.addResult(result, action);
}
}
}
}
notifier.sendEmails();
return data;
}
public static class Data extends TestResultAction.Data implements Saveable {
private Map<String, QuarantineTestAction> quarantines = new HashMap<String, QuarantineTestAction>();
private final AbstractBuild<?, ?> build;
public Data(AbstractBuild<?, ?> build) {
this.build = build;
}
@Override
public List<TestAction> getTestAction(TestObject testObject) {
if (build.getParent().getPublishersList().get(QuarantinableJUnitResultArchiver.class) == null) {
// only display if QuarantinableJUnitResultArchiver chosen, to avoid
// confusion
System.out.println("not right publisher");
return Collections.emptyList();
}
String id = testObject.getId();
QuarantineTestAction result = quarantines.get(id);
if (result != null) {
return Collections.<TestAction> singletonList(result);
}
if (testObject instanceof CaseResult) {
return Collections.<TestAction> singletonList(new QuarantineTestAction(this, id));
}
return Collections.emptyList();
}
public boolean isLatestResult() {
return build.getParent().getLastCompletedBuild() == build;
}
public hudson.tasks.test.TestResult getResultForTestId(String testObjectId) {
TestResultAction action = build.getAction(TestResultAction.class);
if (action != null && action.getResult() != null) {
return action.getResult().findCorrespondingResult(testObjectId);
}
return null;
}
public void save() throws IOException {
build.save();
}
public void addQuarantine(String testObjectId, QuarantineTestAction quarantine) {
quarantines.put(testObjectId, quarantine);
}
}
@Extension
public static class DescriptorImpl extends Descriptor<TestDataPublisher> {
public String getHelpFile() {
return "/plugin/quarantine/help.html";
}
@Override
public String getDisplayName() {
return Messages.QuarantineTestDataPublisher_DisplayName();
}
}
}