/**
* Copyright (C) 2010-2017 Gordon Fraser, Andrea Arcuri and EvoSuite
* contributors
*
* This file is part of EvoSuite.
*
* EvoSuite is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* EvoSuite is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>.
*/
package org.evosuite.jenkins.recorder;
import org.evosuite.jenkins.actions.BuildAction;
import org.evosuite.jenkins.actions.ProjectAction;
import org.evosuite.jenkins.scm.Git;
import org.evosuite.jenkins.scm.Mercurial;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import hudson.Extension;
import hudson.Launcher;
import hudson.maven.AbstractMavenProject;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.BuildListener;
import hudson.model.Result;
import hudson.plugins.git.GitSCM;
import hudson.plugins.mercurial.MercurialSCM;
import hudson.scm.SCM;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Publisher;
import hudson.tasks.Recorder;
import net.sf.json.JSONObject;
public class EvoSuiteRecorder extends Recorder {
public static final String LOG_PREFIX = "[EvoSuite] ";
public static final DecimalFormat decimalFormat = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ENGLISH);
@Extension
public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();
private boolean disableAutoCommit;
private boolean disableAutoPush;
private String branchName;
private String ctgBestsDir;
@DataBoundConstructor
public EvoSuiteRecorder(boolean disableAutoCommit, boolean disableAutoPush,
String branchName, String ctgBestsDir) {
this.disableAutoCommit = disableAutoCommit;
this.disableAutoPush = disableAutoPush;
this.branchName = branchName;
this.ctgBestsDir = ctgBestsDir;
}
public boolean getDisableAutoCommit() {
return this.disableAutoCommit;
}
public boolean getDisableAutoPush() {
return this.disableAutoPush;
}
public String getBranchName() {
return this.branchName;
}
public String getCtgBestsDir() {
return this.ctgBestsDir;
}
public void setDisableAutoCommit(boolean disableAutoCommit) {
this.disableAutoCommit = disableAutoCommit;
}
public void setDisableAutoPush(boolean disableAutoPush) {
this.disableAutoPush = disableAutoPush;
}
public void setBranchName(String branchName) {
this.branchName = branchName;
}
public void setCtgBestsDir(String ctgBestsDir) {
this.ctgBestsDir = ctgBestsDir;
}
@Override
public Action getProjectAction(AbstractProject<?, ?> project) {
if (!project.getBuilds().isEmpty() /*|| !project.getActions().isEmpty()*/) {
BuildAction buildAction = project.getLastBuild().getAction(BuildAction.class);
if (buildAction != null) {
ProjectAction lastProject = buildAction.getProjectAction();
return new ProjectAction(project, lastProject.getModules());
}
}
return new ProjectAction(project);
}
@Override
public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE;
}
@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
if (build.getResult().isWorseThan(Result.SUCCESS)) {
listener.getLogger().println(EvoSuiteRecorder.LOG_PREFIX + "Build did not succeed, so no test case generation by EvoSuite will occur.");
return true;
}
AbstractMavenProject<?, ?> project = ((AbstractMavenProject<?, ?>) build.getProject());
ProjectAction projectAction = new ProjectAction(project);
projectAction.perform(project, build, listener);
BuildAction build_action = new BuildAction(build, projectAction);
build.addAction(build_action);
// Deliver new test cases (i.e., commit and push the new test cases generated)
if (this.disableAutoCommit) {
return true;
}
SCM scm = project.getScm();
if (scm == null) {
listener.getLogger().println(EvoSuiteRecorder.LOG_PREFIX + "Project '" + project.getName() + "' has no Source-Control-Management (SCM) defined.");
return true;
}
org.evosuite.jenkins.scm.SCM scmWrapper = null;
if (scm instanceof MercurialSCM) {
scmWrapper = new Mercurial((MercurialSCM) scm, project, build, launcher, listener);
} else if (scm instanceof GitSCM) {
scmWrapper = new Git((GitSCM) scm, build, listener);
} else {
listener.getLogger().println(EvoSuiteRecorder.LOG_PREFIX + "SCM of type " + scm.getType() + " not supported!");
return true;
}
assert scmWrapper != null;
// perform commit action
int number_of_files_committed = scmWrapper.commit(project, build, listener, this.branchName, this.ctgBestsDir);
if (number_of_files_committed == -1) {
return false;
}
if (!this.disableAutoPush && number_of_files_committed > 0) {
if (!scmWrapper.push(build, listener, this.branchName)) {
return false;
}
}
return true;
}
/*
* (non-Javadoc)
*
* @see hudson.tasks.Recorder#getDescriptor()
*/
@Override
public BuildStepDescriptor<Publisher> getDescriptor() {
return DESCRIPTOR;
}
public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {
public DescriptorImpl() {
super(EvoSuiteRecorder.class);
}
/*
* (non-Javadoc)
*
* @see hudson.model.Descriptor#getDisplayName()
*/
@Override
public String getDisplayName() {
return "EvoSuite";
}
/*
* (non-Javadoc)
*
* @see hudson.tasks.BuildStepDescriptor#isApplicable(java.lang.Class)
*/
@Override
@SuppressWarnings("rawtypes")
public boolean isApplicable(Class<? extends AbstractProject> jobType) {
return true;
}
/*
* (non-Javadoc)
*
* @see hudson.model.Descriptor#newInstance(org.kohsuke.stapler.StaplerRequest, net.sf.json.JSONObject)
*/
@Override
public Publisher newInstance(StaplerRequest req, JSONObject formData)
throws hudson.model.Descriptor.FormException {
return (EvoSuiteRecorder) super.newInstance(req, formData);
}
}
}