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

Use new status icons in quality gate of pull request portlet #986

Merged
merged 1 commit into from
Jul 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,24 @@ public boolean hasQualityGate() {
*
* @return
* the image url of the icon.
* @deprecated replaced by {@link #getQualityGateResultClass()}
*/
@SuppressWarnings("unused") // used by jelly view
@Deprecated
public String getQualityGateResultIconUrl() {
return result.getQualityGateStatus().getResult().color.getImageOf("16x16");
}

/**
* Get the icon class of the quality gate.
*
* @return
* the image class of the Jenkins status icon.
*/
@SuppressWarnings("unused") // used by jelly view
public String getQualityGateResultClass() {
return result.getQualityGateStatus().getIconClass();
}

/**
* Get the human readable description of quality gate.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ public BallColor getColor() {
return result.color;
}

/**
* Returns the associated {@link Result} icon class to be used in the UI.
*
* @return Jenkins' {@link Result} icon class
*/
public String getIconClass() {
return getColor().getIconClassName();
}

/**
* Returns whether the quality gate has been passed (or has not been activated at all).
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?jelly escape-by-default='true'?>

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:fa="/font-awesome" xmlns:c="/charts">
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:fa="/font-awesome" xmlns:c="/charts">

<st:adjunct includes="io.jenkins.plugins.echarts"/>

Expand Down Expand Up @@ -34,7 +34,7 @@

<j:if test="${it.hasQualityGate()}">
<p class="portlet-quality-gate-label">${%qualityGate.Name}
<img src="${it.getQualityGateResultIconUrl()}"/>
<l:icon class="${it.getQualityGateResultClass()} icon-sm"/>
${it.getQualityGateResultDescription()}</p>
</j:if>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import hudson.model.Descriptor;
import hudson.model.FreeStyleProject;
import hudson.model.Item;
import hudson.model.Job;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.Slave;
Expand Down Expand Up @@ -1016,6 +1017,25 @@ protected ResultAction getResultAction(final Run<?, ?> build) {
return action;
}

/**
* Returns the {@link ResultAction} for the specified job. Note that this method does only return the first match,
* even if a test registered multiple actions.
*
* @param job
* the job
*
* @return the action of the specified build
*/
protected ResultAction getResultAction(final Job<?, ?> job) {
Run<?, ?> build = job.getLastCompletedBuild();
assertThat(build).as("No completed build found for job %s", job).isNotNull();

ResultAction action = build.getAction(ResultAction.class);
assertThat(action).as("No ResultAction found in run %s", build).isNotNull();

return action;
}

/**
* Returns the created {@link AnalysisResult analysis result} of a build.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import io.jenkins.plugins.analysis.core.model.IssuesModel.IssuesRow;
import io.jenkins.plugins.analysis.core.model.ReportScanningTool;
import io.jenkins.plugins.analysis.core.model.ResultAction;
import io.jenkins.plugins.analysis.core.portlets.PullRequestMonitoringPortlet;
import io.jenkins.plugins.analysis.core.steps.IssuesRecorder;
import io.jenkins.plugins.analysis.core.testutil.IntegrationTestWithJenkinsPerSuite;
import io.jenkins.plugins.analysis.core.util.QualityGateStatus;
Expand All @@ -37,6 +38,7 @@
import io.jenkins.plugins.analysis.warnings.tasks.OpenTasks;

import static io.jenkins.plugins.analysis.core.assertions.Assertions.*;
import static net.javacrumbs.jsonunit.assertj.JsonAssertions.*;

/**
* Integration tests of the warnings plug-in in freestyle jobs. Tests the new recorder {@link IssuesRecorder}.
Expand Down Expand Up @@ -232,6 +234,15 @@ public void shouldHaveOriginsIfBuildContainsWarnings() {
assertThat(result.getSizePerOrigin()).containsExactly(entry("checkstyle", 0), entry("pmd", 0));
assertThat(result).hasId("analysis");
assertThat(result).hasQualityGateStatus(QualityGateStatus.INACTIVE);

PullRequestMonitoringPortlet portlet = new PullRequestMonitoringPortlet(getResultAction(project));

assertThat(portlet.hasQualityGate()).isFalse();
assertThat(portlet.isEmpty()).isTrue();
assertThat(portlet.getId()).endsWith("analysis");
assertThat(portlet.getTitle()).endsWith("Static Analysis");
assertThat(portlet.getIconUrl()).contains("/plugin/warnings-ng/icons/analysis-24x24.png");
assertThat(portlet.getDetailViewUrl()).contains("analysis");
}

/**
Expand Down Expand Up @@ -337,6 +348,44 @@ public void shouldCreateFixedWarnings() {
assertThat(result.getTotalSize() - result.getNewSize()).isEqualTo(5); // Outstanding
assertThat(result).hasTotalSize(5);
assertThat(result).hasQualityGateStatus(QualityGateStatus.INACTIVE);

PullRequestMonitoringPortlet portlet = createPortlet(project);

String successfulModel = portlet.getWarningsModel();
assertThatJson(successfulModel).node("fixed").isEqualTo(3);
assertThatJson(successfulModel).node("outstanding").isEqualTo(5);
assertThatJson(successfulModel).node("new").node("total").isEqualTo(0);
assertThatJson(successfulModel).node("new").node("low").isEqualTo(0);
assertThatJson(successfulModel).node("new").node("normal").isEqualTo(0);
assertThatJson(successfulModel).node("new").node("high").isEqualTo(0);
assertThatJson(successfulModel).node("new").node("error").isEqualTo(0);

verifyNoNewWarningsPortletModel(portlet, 5, 3);
}

private void verifyNoNewWarningsPortletModel(final PullRequestMonitoringPortlet portlet,
final int expectedOutstandingWarnings, final int expectedFixedWarnings) {
assertThat(portlet.hasNoNewWarnings()).isTrue();

String simpleModel = portlet.getNoNewWarningsModel();
assertThatJson(simpleModel).node("data").isArray().hasSize(2);
assertThatJson(simpleModel).node("data[0]").node("name").isEqualTo("outstanding");
assertThatJson(simpleModel).node("data[0]").node("value").isEqualTo(expectedOutstandingWarnings);
assertThatJson(simpleModel).node("data[1]").node("name").isEqualTo("fixed");
assertThatJson(simpleModel).node("data[1]").node("value").isEqualTo(expectedFixedWarnings);
}

private PullRequestMonitoringPortlet createPortlet(final FreeStyleProject project) {
PullRequestMonitoringPortlet portlet = new PullRequestMonitoringPortlet(getResultAction(project));

assertThat(portlet.hasQualityGate()).isFalse();
assertThat(portlet.getId()).endsWith("eclipse");
assertThat(portlet.getTitle()).endsWith("Eclipse ECJ");
assertThat(portlet.getIconUrl()).contains("/plugin/warnings-ng/icons/analysis-24x24.png");
assertThat(portlet.getDetailViewUrl()).contains("eclipse");
assertThat(portlet.isEmpty()).isFalse();

return portlet;
}

/**
Expand All @@ -362,6 +411,18 @@ public void shouldCreateNewWarnings() {
assertThat(result.getTotalSize() - result.getNewSize()).isEqualTo(5); // Outstanding
assertThat(result).hasTotalSize(8);
assertThat(result).hasQualityGateStatus(QualityGateStatus.INACTIVE);

PullRequestMonitoringPortlet portlet = createPortlet(project);
assertThat(portlet.hasNoNewWarnings()).isFalse();

String successfulModel = portlet.getWarningsModel();
assertThatJson(successfulModel).node("fixed").isEqualTo(0);
assertThatJson(successfulModel).node("outstanding").isEqualTo(5);
assertThatJson(successfulModel).node("new").node("total").isEqualTo(3);
assertThatJson(successfulModel).node("new").node("low").isEqualTo(0);
assertThatJson(successfulModel).node("new").node("normal").isEqualTo(3);
assertThatJson(successfulModel).node("new").node("high").isEqualTo(0);
assertThatJson(successfulModel).node("new").node("error").isEqualTo(0);
}

/**
Expand All @@ -387,6 +448,19 @@ public void shouldCreateNoFixedWarningsOrNewWarnings() {
assertThat(result.getTotalSize() - result.getNewSize()).isEqualTo(8); // Outstanding
assertThat(result).hasTotalSize(8);
assertThat(result).hasQualityGateStatus(QualityGateStatus.INACTIVE);

PullRequestMonitoringPortlet portlet = createPortlet(project);

String successfulModel = portlet.getWarningsModel();
assertThatJson(successfulModel).node("fixed").isEqualTo(0);
assertThatJson(successfulModel).node("outstanding").isEqualTo(8);
assertThatJson(successfulModel).node("new").node("total").isEqualTo(0);
assertThatJson(successfulModel).node("new").node("low").isEqualTo(0);
assertThatJson(successfulModel).node("new").node("normal").isEqualTo(0);
assertThatJson(successfulModel).node("new").node("high").isEqualTo(0);
assertThatJson(successfulModel).node("new").node("error").isEqualTo(0);

verifyNoNewWarningsPortletModel(portlet, 8, 0);
}

/**
Expand All @@ -413,6 +487,19 @@ public void shouldCreateSomeNewWarningsAndSomeFixedWarnings() {
assertThat(result.getTotalSize() - result.getNewSize()).isEqualTo(2); // Outstanding
assertThat(result).hasTotalSize(4);
assertThat(result).hasQualityGateStatus(QualityGateStatus.INACTIVE);

PullRequestMonitoringPortlet successPortlet = createPortlet(project);

String successfulModel = successPortlet.getWarningsModel();
assertThatJson(successfulModel).node("fixed").isEqualTo(3);
assertThatJson(successfulModel).node("outstanding").isEqualTo(2);
assertThatJson(successfulModel).node("new").node("total").isEqualTo(2);
assertThatJson(successfulModel).node("new").node("low").isEqualTo(0);
assertThatJson(successfulModel).node("new").node("normal").isEqualTo(2);
assertThatJson(successfulModel).node("new").node("high").isEqualTo(0);
assertThatJson(successfulModel).node("new").node("error").isEqualTo(0);

assertThat(successPortlet.hasQualityGate()).isFalse();
}

private ReportScanningTool createEclipse(final String pattern) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import io.jenkins.plugins.analysis.core.model.AnalysisResult;
import io.jenkins.plugins.analysis.core.model.ResultAction;
import io.jenkins.plugins.analysis.core.portlets.PullRequestMonitoringPortlet;
import io.jenkins.plugins.analysis.core.steps.IssuesRecorder;
import io.jenkins.plugins.analysis.core.testutil.IntegrationTestWithJenkinsPerSuite;
import io.jenkins.plugins.analysis.core.util.QualityGate.QualityGateResult;
Expand Down Expand Up @@ -501,11 +502,15 @@ private IssuesRecorder enableAndConfigureCheckstyle(final AbstractProject<?, ?>

@SuppressWarnings("illegalcatch")
private void scheduleBuildAndAssertStatus(final AbstractProject<?, ?> job, final Result result,
final QualityGateStatus qualityGateStatus) {
final QualityGateStatus expectedQualityGateStatus) {
try {
Run<?, ?> build = getJenkins().assertBuildStatus(result, job.scheduleBuild2(0));
ResultAction action = build.getAction(ResultAction.class);
assertThat(action.getResult()).hasQualityGateStatus(qualityGateStatus);
assertThat(action.getResult()).hasQualityGateStatus(expectedQualityGateStatus);

PullRequestMonitoringPortlet portlet = new PullRequestMonitoringPortlet(action);
assertThat(portlet.hasQualityGate()).isTrue();
assertThat(portlet.getQualityGateResultClass()).isEqualTo(expectedQualityGateStatus.getIconClass());
}
catch (Exception e) {
throw new AssertionError(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ public void shouldShowWarningsOfGroovyParserWhenScanningConsoleLogWhenThatIsPerm
* configuration and runs this parser on the console that's showing an error log
* with 8 issues ... but when we're configured not to allow groovy parsers to
* scan the console at all so we expect it to fail.
*
*
* @throws IOException if the test fails unexpectedly
*/
@Test
Expand Down Expand Up @@ -987,10 +987,8 @@ public void shouldHandleMissingJobBuildIdAsReference() {

AnalysisResult result = scheduleSuccessfulBuild(job);

assertThat(not(result.getReferenceBuild().isPresent()));

assertThat(result.getNewIssues()).hasSize(0);
assertThat(result.getOutstandingIssues()).hasSize(2);
assertThat(result.getReferenceBuild()).isEmpty();
assertThat(result).hasNewSize(0).hasTotalSize(2);
assertThat(result.getErrorMessages()).contains(
"Reference job 'reference' does not contain configured build '1'");
}
Expand Down Expand Up @@ -1092,13 +1090,16 @@ public void shouldGenerateJsonDataModel() {
ResultAction action = baseline.getAction(ResultAction.class);
PullRequestMonitoringPortlet portlet = new PullRequestMonitoringPortlet(action);

assertThatJson(portlet.getWarningsModel()).node("fixed").isEqualTo(0);
assertThatJson(portlet.getWarningsModel()).node("outstanding").isEqualTo(3);
assertThatJson(portlet.getWarningsModel()).node("new").node("total").isEqualTo(0);
assertThatJson(portlet.getWarningsModel()).node("new").node("low").isEqualTo(0);
assertThatJson(portlet.getWarningsModel()).node("new").node("normal").isEqualTo(0);
assertThatJson(portlet.getWarningsModel()).node("new").node("high").isEqualTo(0);
assertThatJson(portlet.getWarningsModel()).node("new").node("error").isEqualTo(0);
String model = portlet.getWarningsModel();
assertThatJson(model).node("fixed").isEqualTo(0);
assertThatJson(model).node("outstanding").isEqualTo(3);
assertThatJson(model).node("new").node("total").isEqualTo(0);
assertThatJson(model).node("new").node("low").isEqualTo(0);
assertThatJson(model).node("new").node("normal").isEqualTo(0);
assertThatJson(model).node("new").node("high").isEqualTo(0);
assertThatJson(model).node("new").node("error").isEqualTo(0);

assertThat(portlet.hasQualityGate()).isFalse();
}

private void write(final String adaptedOobFileContent) {
Expand Down