/*
* The MIT License (MIT)
*
* Copyright (c) 2014, Gregory Boissinot
*
* 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 org.jenkinsci.plugins.xunit;
import hudson.DescriptorExtensionList;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.BuildListener;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Publisher;
import hudson.tasks.Recorder;
import hudson.tasks.junit.JUnitResultArchiver;
import hudson.tasks.test.TestResultProjectAction;
import jenkins.tasks.SimpleBuildStep;
import org.jenkinsci.lib.dryrun.DryRun;
import org.jenkinsci.lib.dtkit.descriptor.TestTypeDescriptor;
import org.jenkinsci.lib.dtkit.type.TestType;
import org.jenkinsci.plugins.xunit.threshold.FailedThreshold;
import org.jenkinsci.plugins.xunit.threshold.SkippedThreshold;
import org.jenkinsci.plugins.xunit.threshold.XUnitThreshold;
import org.jenkinsci.plugins.xunit.threshold.XUnitThresholdDescriptor;
import org.kohsuke.stapler.DataBoundConstructor;
import java.io.IOException;
import java.io.Serializable;
/**
* Class that converting custom reports to Junit reports and records them
*
* @author Gregory Boissinot
*/
@SuppressWarnings({"unchecked", "unused"})
public class XUnitPublisher extends Recorder implements DryRun, Serializable, SimpleBuildStep {
private TestType[] types;
private XUnitThreshold[] thresholds;
private int thresholdMode;
private ExtraConfiguration extraConfiguration;
public XUnitPublisher(TestType[] types, XUnitThreshold[] thresholds) {
this.types = types;
this.thresholds = thresholds;
this.thresholdMode = 1;
}
@DataBoundConstructor
public XUnitPublisher(TestType[] tools, XUnitThreshold[] thresholds, int thresholdMode, String testTimeMargin) {
this.types = tools;
this.thresholds = thresholds;
this.thresholdMode = thresholdMode;
long longTestTimeMargin = XUnitDefaultValues.TEST_REPORT_TIME_MARGING;
if (testTimeMargin != null && testTimeMargin.trim().length() != 0) {
longTestTimeMargin = Long.parseLong(testTimeMargin);
}
this.extraConfiguration = new ExtraConfiguration(longTestTimeMargin);
}
/**
* Needed to support Snippet Generator and Workflow properly.
*/
public TestType[] getTools() {
return types;
}
/**
* Needed to support Snippet Generator and Workflow properly
*/
public String getTestTimeMargin() {
return String.valueOf(getExtraConfiguration().getTestTimeMargin());
}
public TestType[] getTypes() {
return types;
}
public XUnitThreshold[] getThresholds() {
return thresholds;
}
public int getThresholdMode() {
return thresholdMode;
}
public ExtraConfiguration getExtraConfiguration() {
if (extraConfiguration == null) {
extraConfiguration = new ExtraConfiguration(XUnitDefaultValues.TEST_REPORT_TIME_MARGING);
}
return extraConfiguration;
}
@SuppressWarnings("deprecation")
@Override
public Action getProjectAction(AbstractProject<?, ?> project) {
JUnitResultArchiver jUnitResultArchiver = project.getPublishersList().get(JUnitResultArchiver.class);
if (jUnitResultArchiver == null) {
return new TestResultProjectAction(project);
}
return null;
}
@Override
public boolean perform(final AbstractBuild<?, ?> build, Launcher launcher, final BuildListener listener)
throws InterruptedException, IOException {
perform(build, build.getWorkspace(), launcher, listener);
return true;
}
@Override
public void perform(final Run<?, ?> build, FilePath workspace, Launcher launcher, final TaskListener listener)
throws InterruptedException, IOException {
XUnitProcessor xUnitProcessor = new XUnitProcessor(getTypes(), getThresholds(), getThresholdMode(), getExtraConfiguration());
xUnitProcessor.performXUnit(false, build, workspace, listener);
}
public boolean performDryRun(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener)
throws InterruptedException, IOException {
try {
XUnitProcessor xUnitProcessor = new XUnitProcessor(getTypes(), getThresholds(), getThresholdMode(), getExtraConfiguration());
xUnitProcessor.performXUnit(true, build, build.getWorkspace(), listener);
} catch (Throwable t) {
listener.getLogger().println("[ERROR] - There is an error: " + t.getCause().getMessage());
}
//Always exit on success (returned code and status)
build.setResult(Result.SUCCESS);
return true;
}
public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE;
}
@Extension
@SuppressWarnings("unused")
public static final class XUnitDescriptorPublisher extends BuildStepDescriptor<Publisher> {
public XUnitDescriptorPublisher() {
super(XUnitPublisher.class);
load();
}
@Override
public String getDisplayName() {
return Messages.xUnit_PublisherName();
}
@Override
public boolean isApplicable(Class type) {
return true;
}
@Override
public String getHelpFile() {
return "/plugin/xunit/help.html";
}
public DescriptorExtensionList<TestType, TestTypeDescriptor<?>> getListXUnitTypeDescriptors() {
return TestTypeDescriptor.all();
}
public DescriptorExtensionList<XUnitThreshold, XUnitThresholdDescriptor<?>> getListXUnitThresholdDescriptors() {
return XUnitThresholdDescriptor.all();
}
public XUnitThreshold[] getListXUnitThresholdInstance() {
return new XUnitThreshold[]{
new FailedThreshold(),
new SkippedThreshold()
};
}
}
}