Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated for compatibility with Jenkins 2.0 workflow API #6

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
6 changes: 5 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.447</version>
<version>1.609.1</version>
<relativePath />
</parent>

Expand Down Expand Up @@ -33,6 +33,10 @@
<id>kbrandt</id>
<name>Karsten Brandt</name>
</developer>
<developer>
<id>cjbush</id>
<name>Chris Bush</name>
</developer>
</developers>

<scm>
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/hudson/plugins/emma/AbstractReport.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import hudson.model.AbstractBuild;
import hudson.model.ModelObject;
import hudson.model.Run;

import java.io.IOException;

Expand Down Expand Up @@ -64,7 +65,7 @@ public SELF getPreviousResult() {
}

@Override
public AbstractBuild<?,?> getBuild() {
public Run<?,?> getBuild() {
return parent.getBuild();
}

Expand Down
5 changes: 3 additions & 2 deletions src/main/java/hudson/plugins/emma/CoverageObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import hudson.Util;
import hudson.model.AbstractBuild;
import hudson.model.Api;
import hudson.model.Run;
import hudson.util.ChartUtil;
import hudson.util.ColorPalette;
import hudson.util.DataSetBuilder;
Expand Down Expand Up @@ -96,7 +97,7 @@ public Ratio getConditionCoverage() {
/**
* Gets the build object that owns the whole coverage report tree.
*/
public abstract AbstractBuild<?,?> getBuild();
public abstract Run<?,?> getBuild();

/**
* Gets the corresponding coverage report object in the previous
Expand Down Expand Up @@ -172,7 +173,7 @@ public void doGraph(StaplerRequest req, StaplerResponse rsp) throws IOException
return;
}

AbstractBuild<?,?> build = getBuild();
Run<?,?> build = getBuild();
Calendar t = build.getTimestamp();

String w = Util.fixEmptyAndTrim(req.getParameter("width"));
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/hudson/plugins/emma/CoverageReport.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package hudson.plugins.emma;

import hudson.model.AbstractBuild;
import hudson.model.Run;
import hudson.util.IOException2;
import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;
Expand Down Expand Up @@ -54,7 +55,7 @@ public CoverageReport getPreviousResult() {
}

@Override
public AbstractBuild<?,?> getBuild() {
public Run<?,?> getBuild() {
return action.owner;
}

Expand Down
15 changes: 8 additions & 7 deletions src/main/java/hudson/plugins/emma/EmmaBuildAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import hudson.model.HealthReport;
import hudson.model.HealthReportingAction;
import hudson.model.Result;
import hudson.model.Run;
import hudson.util.IOException2;
import hudson.util.NullStream;
import hudson.util.StreamTaskListener;
Expand Down Expand Up @@ -32,7 +33,7 @@
*/
public final class EmmaBuildAction extends CoverageObject<EmmaBuildAction> implements HealthReportingAction, StaplerProxy {

public final AbstractBuild<?,?> owner;
public final Run<?,?> owner;

private transient WeakReference<CoverageReport> report;

Expand All @@ -47,7 +48,7 @@ public final class EmmaBuildAction extends CoverageObject<EmmaBuildAction> imple
*/
private final EmmaHealthReportThresholds thresholds;

public EmmaBuildAction(AbstractBuild<?,?> owner, Rule rule, Ratio classCoverage, Ratio methodCoverage, Ratio blockCoverage, Ratio lineCoverage, Ratio conditionCoverage, EmmaHealthReportThresholds thresholds) {
public EmmaBuildAction(Run<?,?> owner, Rule rule, Ratio classCoverage, Ratio methodCoverage, Ratio blockCoverage, Ratio lineCoverage, Ratio conditionCoverage, EmmaHealthReportThresholds thresholds) {
this.owner = owner;
this.rule = rule;
this.clazz = classCoverage;
Expand Down Expand Up @@ -148,7 +149,7 @@ public Object getTarget() {
}

@Override
public AbstractBuild<?,?> getBuild() {
public Run<?,?> getBuild() {
return owner;
}

Expand Down Expand Up @@ -212,8 +213,8 @@ public EmmaBuildAction getPreviousResult() {
/**
* Gets the previous {@link EmmaBuildAction} of the given build.
*/
/*package*/ static EmmaBuildAction getPreviousResult(AbstractBuild<?,?> start) {
AbstractBuild<?,?> b = start;
/*package*/ static EmmaBuildAction getPreviousResult(Run<?,?> start) {
Run<?,?> b = start;
while(true) {
b = b.getPreviousBuild();
if(b==null)
Expand All @@ -233,14 +234,14 @@ public EmmaBuildAction getPreviousResult() {
* @throws IOException
* if failed to parse the file.
*/
public static EmmaBuildAction load(AbstractBuild<?,?> owner, Rule rule, EmmaHealthReportThresholds thresholds, FilePath... files) throws IOException {
public static EmmaBuildAction load(Run<?,?> owner, Rule rule, EmmaHealthReportThresholds thresholds, FilePath... files) throws IOException, InterruptedException {
Ratio ratios[] = null;
for (FilePath f: files ) {
InputStream in = f.read();
try {
ratios = loadRatios(in, ratios);
} catch (XmlPullParserException e) {
throw new IOException2("Failed to parse " + f, e);
throw new IOException("Failed to parse " + f, e);
} finally {
in.close();
}
Expand Down
153 changes: 82 additions & 71 deletions src/main/java/hudson/plugins/emma/EmmaPublisher.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
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;
Expand All @@ -26,13 +28,14 @@
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import jenkins.tasks.SimpleBuildStep;

/**
* {@link Publisher} that captures Emma coverage reports.
*
* @author Kohsuke Kawaguchi
*/
public class EmmaPublisher extends Recorder {
public class EmmaPublisher extends Recorder implements SimpleBuildStep {

/**
* Relative path to the Emma XML file inside the workspace.
Expand Down Expand Up @@ -104,79 +107,15 @@ protected static void saveCoverageReports(FilePath folder, FilePath[] files) thr

@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
final PrintStream logger = listener.getLogger();

// Make sure Emma actually ran
if (build instanceof MavenBuild) {
MavenBuild mavenBuild = (MavenBuild) build;
if (!didEmmaRun(mavenBuild)) {
listener.getLogger().println("Skipping Emma coverage report as mojo did not run.");
return true;
}
} else if (build instanceof MavenModuleSetBuild) {
MavenModuleSetBuild moduleSetBuild = (MavenModuleSetBuild) build;
if (!didEmmaRun(moduleSetBuild.getModuleLastBuilds().values())) {
listener.getLogger().println("Skipping Emma coverage report as mojo did not run.");
return true;
}
}
EnvVars env = build.getEnvironment(listener);

env.overrideAll(build.getBuildVariables());
includes = env.expand(includes);

FilePath[] reports;
if (includes == null || includes.trim().length() == 0) {
logger.println("Emma: looking for coverage reports in the entire workspace: " + build.getWorkspace().getRemote());
reports = locateCoverageReports(build.getWorkspace(), "**/emma/coverage.xml");
} else {
logger.println("Emma: looking for coverage reports in the provided path: " + includes);
reports = locateCoverageReports(build.getWorkspace(), includes);
}

if (reports.length == 0) {
if (build.getResult().isWorseThan(Result.UNSTABLE)) {
return true;
}

logger.println("Emma: no coverage files found in workspace. Was any report generated?");
build.setResult(Result.FAILURE);
try{
perform(build, build.getWorkspace(), launcher, listener);
return true;
} else {
String found = "";
for (FilePath f : reports) {
found += "\n " + f.getRemote();
}
logger.println("Emma: found " + reports.length + " report files: " + found);
} catch(Exception ex){
return false;
}

FilePath emmafolder = new FilePath(getEmmaReport(build));
saveCoverageReports(emmafolder, reports);
logger.println("Emma: stored " + reports.length + " report files in the build folder: " + emmafolder);

final EmmaBuildAction action = EmmaBuildAction.load(build, rule, healthReports, reports);

action.applySettings(advancedSettings);

logger.println("Emma: " + action.getBuildHealth().getDescription());

build.getActions().add(action);

final CoverageReport result = action.getResult();
if (result == null) {
logger.println("Emma: Could not parse coverage results. Setting Build to failure.");
build.setResult(Result.FAILURE);
} else if (result.isFailed()) {
logger.println("Emma: code coverage enforcement failed. Setting Build to unstable.");
build.setResult(Result.UNSTABLE);
}

checkThreshold(build, logger, env, action);

return true;
}

private void checkThreshold(AbstractBuild<?, ?> build,
private void checkThreshold(Run<?, ?> build,
final PrintStream logger, EnvVars env, final EmmaBuildAction action) {
if (useThreshold) {
if (isMethodCoverageOk(action)
Expand Down Expand Up @@ -230,7 +169,7 @@ public BuildStepMonitor getRequiredMonitorService() {
/**
* Gets the directory to store report files
*/
static File getEmmaReport(AbstractBuild<?, ?> build) {
static File getEmmaReport(Run<?, ?> build) {
return new File(build.getRootDir(), "emma");
}

Expand Down Expand Up @@ -260,6 +199,78 @@ private boolean didEmmaRun(MavenBuild mavenBuild) {
@Extension
public static final BuildStepDescriptor<Publisher> DESCRIPTOR = new DescriptorImpl();

@Override
public void perform(Run<?, ?> build, FilePath workspace, Launcher launcher, TaskListener listener) throws InterruptedException, IOException {
final PrintStream logger = listener.getLogger();

// Make sure Emma actually ran
if (build instanceof MavenBuild) {
MavenBuild mavenBuild = (MavenBuild) build;
if (!didEmmaRun(mavenBuild)) {
listener.getLogger().println("Skipping Emma coverage report as mojo did not run.");
return;
}
} else if (build instanceof MavenModuleSetBuild) {
MavenModuleSetBuild moduleSetBuild = (MavenModuleSetBuild) build;
if (!didEmmaRun(moduleSetBuild.getModuleLastBuilds().values())) {
listener.getLogger().println("Skipping Emma coverage report as mojo did not run.");
return;
}
}
EnvVars env = build.getEnvironment(listener);

//env.overrideAll(build.getBuildVariables());
includes = env.expand(includes);

FilePath[] reports;
if (includes == null || includes.trim().length() == 0) {
logger.println("Emma: looking for coverage reports in the entire workspace: " + workspace.getRemote());
reports = locateCoverageReports(workspace, "**/emma/coverage.xml");
} else {
logger.println("Emma: looking for coverage reports in the provided path: " + includes);
reports = locateCoverageReports(workspace, includes);
}

if (reports.length == 0) {
if (build.getResult().isWorseThan(Result.UNSTABLE)) {
return;
}

logger.println("Emma: no coverage files found in workspace. Was any report generated?");
build.setResult(Result.FAILURE);
return;
} else {
String found = "";
for (FilePath f : reports) {
found += "\n " + f.getRemote();
}
logger.println("Emma: found " + reports.length + " report files: " + found);
}

FilePath emmafolder = new FilePath(getEmmaReport(build));
saveCoverageReports(emmafolder, reports);
logger.println("Emma: stored " + reports.length + " report files in the build folder: " + emmafolder);

final EmmaBuildAction action = EmmaBuildAction.load(build, rule, healthReports, reports);

action.applySettings(advancedSettings);

logger.println("Emma: " + action.getBuildHealth().getDescription());

build.getActions().add(action);

final CoverageReport result = action.getResult();
if (result == null) {
logger.println("Emma: Could not parse coverage results. Setting Build to failure.");
build.setResult(Result.FAILURE);
} else if (result.isFailed()) {
logger.println("Emma: code coverage enforcement failed. Setting Build to unstable.");
build.setResult(Result.UNSTABLE);
}

checkThreshold(build, logger, env, action);
}

public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {

public DescriptorImpl() {
Expand Down
20 changes: 10 additions & 10 deletions src/test/java/hudson/plugins/emma/CoverageObjectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ public void testPrintRatioTable() throws Exception {
r = new Ratio(0,100);
b = new StringBuilder();
CoverageObject.printRatioTable(r, b, no_tests_required);
assertEquals("<table class='percentgraph' cellpadding='0px' cellspacing='0px'><tr class='percentgraph'><td width='64px' class='data'>0.0%</td><td class='percentgraph'><div class='percentgraph'><div class='greenbar' style='width: 0.0px;'><span class='text'>0/100</span></div></div></td></tr></table>", b.toString());
//[KB-] assertEquals("<table class='percentgraph' cellpadding='0px' cellspacing='0px'><tr class='percentgraph'><td width='64px' class='data'>0,0%</td><td class='percentgraph'><div class='percentgraph'><div class='greenbar' style='width: 0.0px;'><span class='text'>0/100</span></div></div></td></tr></table>", b.toString());
double value = 0;
String expected = String.format("<table class='percentgraph' cellpadding='0px' cellspacing='0px'><tr class='percentgraph'><td width='64px' class='data'>%.1f%%</td><td class='percentgraph'><div class='percentgraph'><div class='greenbar' style='width: 0.0px;'><span class='text'>0/100</span></div></div></td></tr></table>", value);
assertEquals(expected, b.toString());

r = new Ratio(51,200);
b = new StringBuilder();
CoverageObject.printRatioTable(r, b, no_tests_required);
assertEquals("<table class='percentgraph' cellpadding='0px' cellspacing='0px'><tr class='percentgraph'><td width='64px' class='data'>25.5%</td><td class='percentgraph'><div class='percentgraph'><div class='greenbar' style='width: 25.5px;'><span class='text'>51/200</span></div></div></td></tr></table>", b.toString());
//[KB-] assertEquals("<table class='percentgraph' cellpadding='0px' cellspacing='0px'><tr class='percentgraph'><td width='64px' class='data'>25,5%</td><td class='percentgraph'><div class='percentgraph'><div class='greenbar' style='width: 25.5px;'><span class='text'>51/200</span></div></div></td></tr></table>", b.toString());

value = 25.5;
expected = String.format("<table class='percentgraph' cellpadding='0px' cellspacing='0px'><tr class='percentgraph'><td width='64px' class='data'>%.1f%%</td><td class='percentgraph'><div class='percentgraph'><div class='greenbar' style='width: 25.5px;'><span class='text'>51/200</span></div></div></td></tr></table>", value);
assertEquals(expected, b.toString());
}


Expand All @@ -48,11 +49,10 @@ public void testPrintColumnt() throws Exception {
r = new Ratio(51,200);
b = new StringBuilder();
CoverageObject.printRatioCell(false, r, b, no_tests_required);
assertEquals("<td class='nowrap' data='025.50'>\n" +
"<table class='percentgraph' cellpadding='0px' cellspacing='0px'><tr class='percentgraph'><td width='64px' class='data'>25.5%</td><td class='percentgraph'><div class='percentgraph'><div class='greenbar' style='width: 25.5px;'><span class='text'>51/200</span></div></div></td></tr></table></td>\n", b.toString());
//[KB-] assertEquals("<td class='nowrap' data='025,50'>\n" +
//[KB-] "<table class='percentgraph' cellpadding='0px' cellspacing='0px'><tr class='percentgraph'><td width='64px' class='data'>25,5%</td><td class='percentgraph'><div class='percentgraph'><div class='greenbar' style='width: 25.5px;'><span class='text'>51/200</span></div></div></td></tr></table></td>\n", b.toString());

double value = 25.5;
String expected = String.format("<td class='nowrap' data='0%.2f'>\n" +
"<table class='percentgraph' cellpadding='0px' cellspacing='0px'><tr class='percentgraph'><td width='64px' class='data'>%.1f%%</td><td class='percentgraph'><div class='percentgraph'><div class='greenbar' style='width: 25.5px;'><span class='text'>51/200</span></div></div></td></tr></table></td>\n", value, value);
assertEquals(expected, b.toString());

r = new Ratio(0,0);
b = new StringBuilder();
Expand Down
Loading