package hudson.plugins.PerfPublisher;
import hudson.Launcher;
import hudson.matrix.MatrixAggregatable;
import hudson.matrix.MatrixAggregator;
import hudson.matrix.MatrixBuild;
import hudson.matrix.MatrixConfiguration;
import hudson.matrix.MatrixProject;
import hudson.model.*;
import hudson.plugins.PerfPublisher.Report.ReportContainer;
import hudson.plugins.PerfPublisher.projectsAction.PerfPublisherFreestyleProjectAction;
import hudson.plugins.PerfPublisher.projectsAction.PerfPublisherMatrixConfigurationAction;
import hudson.plugins.PerfPublisher.projectsAction.PerfPublisherMatrixProjectAction;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Publisher;
import hudson.util.FormFieldValidator;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletException;
/**
* The publisher creates the results we want from the PerfPublisher execution.
*
* @author Georges Bossert
*/
public class PerfPublisherPublisher extends HealthPublisher implements MatrixAggregatable {
private String name;
private String threshold;
private String healthy;
private String unhealthy;
private String metrics;
@DataBoundConstructor
public PerfPublisherPublisher(String name, String threshold,
String healthy, String unhealthy, String metrics) {
this.name = name;
if (threshold != "") {
this.threshold = threshold;
} else {
this.threshold = "0";
}
if (healthy != "") {
this.healthy = healthy;
} else {
this.healthy = "0";
}
if (unhealthy != "") {
this.unhealthy = unhealthy;
} else {
this.unhealthy = "0";
}
this.metrics = metrics;
}
/**
* Return the metrics
* @return
*/
public String getMetrics() {
return metrics;
}
/**
* @return the healthy
*/
public String getHealthy() {
return healthy;
}
/**
* @return the unhealthy
*/
public String getUnhealthy() {
return unhealthy;
}
public String getThreshold() {
return threshold;
}
public String getName() {
return name;
}
public void doValidateMetricsConfiguration(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
new FormFieldValidator(req,rsp,true) {
protected void check() throws IOException, ServletException {
try {
ok("Success");
} catch (Exception e) {
error("Client error : "+e.getMessage());
}
}
}.process();
}
public Descriptor<Publisher> getDescriptor() {
return DESCRIPTOR;
}
public MatrixAggregator createAggregator(final MatrixBuild matrixBuild, Launcher launcher, BuildListener listener) {
return new PerfPublisherResultAggregator(matrixBuild, launcher, listener);
}
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
BuildListener listener) throws InterruptedException, IOException {
PrintStream logger = listener.getLogger();
/**
* Compute metrics parametring
*/
Map<String, String> list_metrics = new HashMap<String, String>();
//Parse the field to understand the metrics
//Format : name=xmlfield;
if (metrics!=null && metrics.length()>0) {
List<String> tmps = Arrays.asList(this.metrics.split(";"));
for (String tmp : tmps) {
List<String> f = Arrays.asList(tmp.split("="));
if (f.size()==2 && f.get(0).trim().length()>0 && f.get(1).length()>0) {
list_metrics.put(f.get(0).trim(), f.get(1).trim());
}
}
}
/**
* Compute the HealthDescription
*/
HealthDescriptor hl = new HealthDescriptor();
try {
hl.setMaxHealth(Integer.parseInt(unhealthy));
} catch (java.lang.NumberFormatException e) {
hl.setMaxHealth(0);
}
try {
hl.setMinHealth(Integer.parseInt(healthy));
} catch (java.lang.NumberFormatException e) {
hl.setMinHealth(0);
}
try {
hl.setUnstableHealth(Integer.parseInt(threshold));
} catch (java.lang.NumberFormatException e) {
hl.setUnstableHealth(0);
}
/**
* Define if we must parse multiple file by searching for , in the name
* var
*/
String[] files = name.split(",");
if (files.length > 1) {
logger.println("[CapsAnalysis] Multiple reports detected.");
}
ArrayList<String> filesToParse = new ArrayList<String>();
for (int i = 0; i < files.length; i++) {
FileSet fileSet = new FileSet();
File workspace = new File(build.getWorkspace().toURI());
fileSet.setDir(workspace);
fileSet.setIncludes(files[i].trim());
Project antProject = new Project();
fileSet.setProject(antProject);
String[] tmp_files = fileSet.getDirectoryScanner(antProject).getIncludedFiles();
for (int j=0; j<tmp_files.length; j++) {
if (build.getProject().getWorkspace().child(tmp_files[j]).exists()) {
filesToParse.add(tmp_files[j]);
} else {
logger.println("[CapsAnalysis] Impossible to analyse report " + tmp_files[j] + " file not found!");
build.setResult(Result.UNSTABLE);
}
}
}
try {
build.addAction(new PerfPublisherBuildAction(build, filesToParse,
logger, hl, list_metrics));
} catch (PerfPublisherParseException gpe) {
logger
.println("[CapsAnalysis] generating reports analysis failed!");
build.setResult(Result.UNSTABLE);
}
return true;
}
public Action getProjectAction(AbstractProject project) {
if (project instanceof MatrixProject) {
return new PerfPublisherMatrixProjectAction((MatrixProject)project);
}else if (project instanceof MatrixConfiguration) {
return new PerfPublisherMatrixConfigurationAction((MatrixConfiguration) project);
}else if (project instanceof FreeStyleProject) {
return new PerfPublisherFreestyleProjectAction((FreeStyleProject)project);
}
return null;
}
public static final Descriptor<Publisher> DESCRIPTOR = new PerfPublisherDescriptor();
/**
* Descriptor for the PerfPublisher plugin
* Must extends BuildStepDescriptor since issue HUDSON-5612
* @author gbossert
*
*/
public static final class PerfPublisherDescriptor extends BuildStepDescriptor<Publisher> {
protected PerfPublisherDescriptor() {
super(PerfPublisherPublisher.class);
}
public String getDisplayName() {
return PerfPublisherPlugin.CONFIG_DISPLAY_NAME;
}
@Override
public boolean isApplicable(Class<? extends AbstractProject> jobType) {
return true;
}
}
public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.BUILD;
}
}