Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #10 from cizezsy/corner-case
[JENKINS-51611] Add several tests
  • Loading branch information
cizezsy committed Jun 6, 2018
2 parents a4f7c81 + 898a083 commit cc5a519
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 149 deletions.
54 changes: 41 additions & 13 deletions src/main/java/io/jenkins/plugins/coverage/CoverageProcessor.java
Expand Up @@ -19,6 +19,7 @@
import io.jenkins.plugins.coverage.threshold.Threshold;
import jenkins.MasterToSlaveFileCallable;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.jvnet.localizer.Localizable;

Expand All @@ -31,6 +32,8 @@
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
Expand Down Expand Up @@ -165,33 +168,52 @@ private Map<CoverageReportAdapter, List<CoverageResult>> convertToResults(List<C

}

if (copiedReport.size() == 0) {
logger.println("No reports were found in this path");
if (getFailNoReports()) {
throw new CoverageException("Publish Coverage Failed : No Reports were found");
}
} else {
logger.printf("A total of %d reports were found%n", copiedReport.size());
}

reports.clear();

// convert report to results
Map<CoverageReportAdapter, List<CoverageResult>> results = new HashMap<>();
for (Map.Entry<CoverageReportAdapter, List<File>> adapterReports : copiedReport.entrySet()) {
CoverageReportAdapter adapter = adapterReports.getKey();
for (File s : adapterReports.getValue()) {
CoverageReportAdapterDescriptor descriptor = (CoverageReportAdapterDescriptor) adapter.getDescriptor();
for (File foundedFile : adapterReports.getValue()) {
try {
results.putIfAbsent(adapter, new LinkedList<>());
results.get(adapter).add(adapter.getResult(s));
boolean isValidate;

// If is Detectable, then use detect to validate file, else simply use file length
if (descriptor instanceof Detectable) {
isValidate = ((Detectable) descriptor).detect(foundedFile);
} else {
// skip file if file is empty
isValidate = Files.size(Paths.get(foundedFile.toURI())) > 0;
}

if (isValidate) {
results.putIfAbsent(adapter, new LinkedList<>());
results.get(adapter).add(adapter.getResult(foundedFile));
}
} catch (CoverageException e) {
e.printStackTrace();
logger.printf("report for %s has met some errors: %s",
adapter.getDescriptor().getDisplayName(), e.getMessage());
}
FileUtils.deleteQuietly(s);
FileUtils.deleteQuietly(foundedFile);
}
}


if (results.size() == 0) {
logger.println("No reports were found");
if (getFailNoReports()) {
throw new CoverageException("Publish Coverage Failed : No Reports were found");
}
} else {
logger.printf("A total of %d reports were found%n",
results.values()
.stream()
.mapToLong(Collection::size)
.sum());
}

return results;
}

Expand Down Expand Up @@ -383,6 +405,7 @@ public boolean isEnableAutoDetect() {

/**
* Getter for property 'failUnhealthy'
*
* @return value for property 'failUnhealthy'
*/
public boolean getFailUnhealthy() {
Expand All @@ -391,6 +414,7 @@ public boolean getFailUnhealthy() {

/**
* Setter for property 'failUnhealthy'
*
* @param failUnhealthy value to set for property 'failUnhealthy'
*/
public void setFailUnhealthy(boolean failUnhealthy) {
Expand All @@ -399,6 +423,7 @@ public void setFailUnhealthy(boolean failUnhealthy) {

/**
* Getter for property 'failUnstable'
*
* @return value for property 'failUnstable'
*/
public boolean getFailUnstable() {
Expand All @@ -407,6 +432,7 @@ public boolean getFailUnstable() {

/**
* Setter for property 'failUnstable'
*
* @param failUnstable value to set for property 'failUnstable'
*/
public void setFailUnstable(boolean failUnstable) {
Expand All @@ -415,6 +441,7 @@ public void setFailUnstable(boolean failUnstable) {

/**
* Getter for property 'failNoReports'
*
* @return value for property 'failNoReports'
*/
public boolean getFailNoReports() {
Expand All @@ -423,6 +450,7 @@ public boolean getFailNoReports() {

/**
* Setter for property 'failNoReports'
*
* @param failNoReports value to set for property 'failNoReports'
*/
public void setFailNoReports(boolean failNoReports) {
Expand Down
@@ -0,0 +1,67 @@
package io.jenkins.plugins.coverage;

import hudson.FilePath;
import io.jenkins.plugins.coverage.adapter.JacocoReportAdapter;
import org.apache.commons.io.FileUtils;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;

public class CoverageCornerCaseTest {

@Rule
public JenkinsRule j = new JenkinsRule();

@Test
public void testIfNoReportFound() throws Exception {
CoverageScriptedPipelineScriptBuilder builder = CoverageScriptedPipelineScriptBuilder.builder();

WorkflowJob project = j.createProject(WorkflowJob.class, "coverage-corner-test");
project.setDefinition(new CpsFlowDefinition(builder.build(), true));

WorkflowRun r = Objects.requireNonNull(project.scheduleBuild2(0)).waitForStart();
Assert.assertNotNull(r);

j.assertBuildStatusSuccess(j.waitForCompletion(r));
j.assertLogContains("No reports were found", r);
}

@Test
public void testIfFoundEmptyReport() throws Exception {
CoverageScriptedPipelineScriptBuilder builder = CoverageScriptedPipelineScriptBuilder.builder()
.addAdapter(new JacocoReportAdapter("jacoco.xml"));

WorkflowJob project = j.createProject(WorkflowJob.class, "coverage-corner-test");
FilePath workspace = j.jenkins.getWorkspaceFor(project);

Path emptyFile = Files.createTempFile("test", "found-empty-report");

Objects.requireNonNull(workspace)
.child("jacoco.xml")
.copyFrom(emptyFile.toUri().toURL());
FileUtils.deleteQuietly(emptyFile.toFile());

workspace.child("cobertura-coverage.xml");
FileUtils.deleteQuietly(emptyFile.toFile());

project.setDefinition(new CpsFlowDefinition(builder.build(), true));

WorkflowRun r = Objects.requireNonNull(project.scheduleBuild2(0)).waitForStart();


Assert.assertNotNull(r);

j.assertBuildStatusSuccess(j.waitForCompletion(r));
j.assertLogContains("No reports were found", r);
}


}
Expand Up @@ -2,14 +2,11 @@

import com.google.common.collect.Lists;
import hudson.FilePath;
import hudson.model.Descriptor;
import hudson.model.Result;
import io.jenkins.plugins.coverage.adapter.CoberturaReportAdapter;
import io.jenkins.plugins.coverage.adapter.CoverageReportAdapter;
import io.jenkins.plugins.coverage.adapter.JacocoReportAdapter;
import io.jenkins.plugins.coverage.targets.CoverageMetric;
import io.jenkins.plugins.coverage.threshold.Threshold;
import org.jenkinsci.Symbol;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
Expand All @@ -18,8 +15,6 @@
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;

import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

public class CoveragePublisherPipelineTest {
Expand Down Expand Up @@ -142,7 +137,7 @@ public void testFailNoReports() throws Exception {
Assert.assertNotNull(r);

j.assertBuildStatus(Result.FAILURE, j.waitForCompletion(r));
j.assertLogContains("No reports were found in this path", r);
j.assertLogContains("No reports were found", r);
j.assertLogContains("Publish Coverage Failed : No Reports were found", r);
}

Expand Down Expand Up @@ -204,134 +199,4 @@ public void testAdapterThresholdFailUnhealthy() throws Exception {
j.assertLogContains("Publish Coverage Failed (Unhealthy):", r);
}

public static class CoverageScriptedPipelineScriptBuilder {

private String autoDetectPath = "*.xml";

private List<CoverageReportAdapter> adapters = new LinkedList<>();

private List<Threshold> globalThresholds = new LinkedList<>();

private boolean failUnhealthy;
private boolean failUnstable;
private boolean failNoReports;

private CoverageScriptedPipelineScriptBuilder() {
}


public static CoverageScriptedPipelineScriptBuilder builder() {
return new CoverageScriptedPipelineScriptBuilder();
}

public String getAutoDetectPath() {
return autoDetectPath;
}

public CoverageScriptedPipelineScriptBuilder setAutoDetectPath(String autoDetectPath) {
this.autoDetectPath = autoDetectPath;
return this;
}

public CoverageScriptedPipelineScriptBuilder addAdapter(CoverageReportAdapter adapter) {
adapters.add(adapter);
return this;
}

public CoverageScriptedPipelineScriptBuilder addGlobalThreshold(Threshold threshold) {
globalThresholds.add(threshold);
return this;
}


public String build() {
StringBuilder sb = new StringBuilder();
sb.append("node {")
.append("publishCoverage(");

sb.append("autoDetectPath:'").append(autoDetectPath).append("'");

sb.append(",failUnhealthy:").append(failUnhealthy);
sb.append(",failUnstable:").append(failUnstable);
sb.append(",failNoReports:").append(failNoReports);

if (adapters.size() > 0) {
sb.append(",adapters:[");
for (int i = 0; i < adapters.size(); i++) {
if (i > 0) sb.append(",");

CoverageReportAdapter adapter = adapters.get(i);
sb.append(generateSnippetForAdapter(adapter));
}
sb.append(']');
}

sb.append(",globalThresholds: ").append(generateSnippetForThresholds(globalThresholds));

sb.append(")").append("}");

return sb.toString();
}

private String generateSnippetForAdapter(CoverageReportAdapter adapter) {
Descriptor<CoverageReportAdapter> d = adapter.getDescriptor();
Class c = d.getClass();

if (c.isAnnotationPresent(Symbol.class)) {
Symbol s = (Symbol) c.getAnnotation(Symbol.class);
String[] symbolValues = s.value();

if (symbolValues.length > 0) {
String symbol = symbolValues[0];

return symbol + "(path:'" + adapter.getPath()
+ "', thresholds: " + generateSnippetForThresholds(adapter.getThresholds()) + ")";
}
}

//TODO condition when adapter do not have @Symbol annotation.
return "";
}

private String generateSnippetForThresholds(List<Threshold> thresholds) {
StringBuilder sb = new StringBuilder();

sb.append("[");
for (int i = 0; i < thresholds.size(); i++) {
if (i > 0) sb.append(",");

Threshold threshold = thresholds.get(i);
sb.append("[thresholdTarget: '").append(threshold.getThresholdTarget())
.append("', unhealthyThreshold: ").append(threshold.getUnhealthyThreshold())
.append(", unstableThreshold: ").append(threshold.getUnstableThreshold())
.append(", failUnhealthy: ").append(threshold.isFailUnhealthy())
.append("]");
}
sb.append("]");

return sb.toString();
}


public CoverageScriptedPipelineScriptBuilder setFailUnhealthy(boolean failUnhealthy) {
this.failUnhealthy = failUnhealthy;
return this;
}

public CoverageScriptedPipelineScriptBuilder setFailUnstable(boolean failUnstable) {
this.failUnstable = failUnstable;
return this;
}

public CoverageScriptedPipelineScriptBuilder setFailNoReports(boolean failNoReports) {
this.failNoReports = failNoReports;
return this;
}

@Override
public String toString() {
return build();
}
}

}

0 comments on commit cc5a519

Please sign in to comment.