From 7452beed74d11f83ba0bf760b827ecb096fb8958 Mon Sep 17 00:00:00 2001 From: Kezhi Xiong Date: Tue, 22 Dec 2020 18:12:34 +0800 Subject: [PATCH] Add LoggingChecksPublisher and tests for status checks --- .../BuildStatusChecksPublisherITest.java | 102 ++++++++++++++++++ .../checks/util/LoggingChecksPublisher.java | 45 ++++++++ 2 files changed, 147 insertions(+) create mode 100644 src/test/java/io/jenkins/plugins/checks/status/BuildStatusChecksPublisherITest.java create mode 100644 src/test/java/io/jenkins/plugins/checks/util/LoggingChecksPublisher.java diff --git a/src/test/java/io/jenkins/plugins/checks/status/BuildStatusChecksPublisherITest.java b/src/test/java/io/jenkins/plugins/checks/status/BuildStatusChecksPublisherITest.java new file mode 100644 index 00000000..468eda75 --- /dev/null +++ b/src/test/java/io/jenkins/plugins/checks/status/BuildStatusChecksPublisherITest.java @@ -0,0 +1,102 @@ +package io.jenkins.plugins.checks.status; + +import hudson.model.Job; +import hudson.model.Run; +import io.jenkins.plugins.checks.util.LoggingChecksPublisher; +import io.jenkins.plugins.util.IntegrationTestWithJenkinsPerTest; +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.TestExtension; + +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; + +public class BuildStatusChecksPublisherITest extends IntegrationTestWithJenkinsPerTest { + private static final String STATUS_TEMPLATE = "Published Checks (name: %s, status: %s, conclusion %s)%n"; + + /** + * Provide a {@link io.jenkins.plugins.checks.util.LoggingChecksPublisher} to log details. + */ + @TestExtension + public static final LoggingChecksPublisher.Factory PUBLISHER_FACTORY = new LoggingChecksPublisher.Factory(); + + @TestExtension + public static final ChecksProperties PROPERTIES = new ChecksProperties(); + + @Test + public void shouldNotPublishStatusWhenNotApplicable() throws IOException { + PUBLISHER_FACTORY.setFormatter(details -> String.format(STATUS_TEMPLATE, + details.getName().orElse(StringUtils.EMPTY), details.getStatus(), details.getConclusion())); + + PROPERTIES.setApplicable(false); + + assertThat(JenkinsRule.getLog(buildSuccessfully(createFreeStyleProject()))) + .doesNotContain(String.format(STATUS_TEMPLATE, "Test Status", "IN_PROGRESS", "NONE")) + .doesNotContain(String.format(STATUS_TEMPLATE, "Test Status", "COMPLETED", "SUCCESS")); + } + + @Test + public void shouldNotPublishStatusWhenSkipped() throws IOException { + PUBLISHER_FACTORY.setFormatter(details -> String.format(STATUS_TEMPLATE, + details.getName().orElse(StringUtils.EMPTY), details.getStatus(), details.getConclusion())); + + PROPERTIES.setApplicable(true); + PROPERTIES.setSkipped(true); + PROPERTIES.setName("Test Status"); + + assertThat(JenkinsRule.getLog(buildSuccessfully(createFreeStyleProject()))) + .doesNotContain(String.format(STATUS_TEMPLATE, "Test Status", "IN_PROGRESS", "NONE")) + .doesNotContain(String.format(STATUS_TEMPLATE, "Test Status", "COMPLETED", "SUCCESS")); + + } + + @Test + public void shouldPublishStatusWithProperties() throws IOException { + PUBLISHER_FACTORY.setFormatter(details -> String.format(STATUS_TEMPLATE, + details.getName().orElse(StringUtils.EMPTY), details.getStatus(), details.getConclusion())); + + PROPERTIES.setApplicable(true); + PROPERTIES.setSkipped(false); + PROPERTIES.setName("Test Status"); + + Run run = buildSuccessfully(createFreeStyleProject()); + assertThat(JenkinsRule.getLog(run)) + .contains(String.format(STATUS_TEMPLATE, "Test Status", "IN_PROGRESS", "NONE")) + .contains(String.format(STATUS_TEMPLATE, "Test Status", "COMPLETED", "SUCCESS")); + } + + static class ChecksProperties extends AbstractStatusChecksProperties { + private boolean applicable; + private boolean skipped; + private String name; + + public void setApplicable(final boolean applicable) { + this.applicable = applicable; + } + + public void setSkipped(final boolean skipped) { + this.skipped = skipped; + } + + public void setName(final String name) { + this.name = name; + } + + @Override + public boolean isApplicable(final Job job) { + return applicable; + } + + @Override + public String getName(final Job job) { + return name; + } + + @Override + public boolean isSkipped(final Job job) { + return skipped; + } + } +} diff --git a/src/test/java/io/jenkins/plugins/checks/util/LoggingChecksPublisher.java b/src/test/java/io/jenkins/plugins/checks/util/LoggingChecksPublisher.java new file mode 100644 index 00000000..598156d5 --- /dev/null +++ b/src/test/java/io/jenkins/plugins/checks/util/LoggingChecksPublisher.java @@ -0,0 +1,45 @@ +package io.jenkins.plugins.checks.util; + +import hudson.model.Job; +import hudson.model.Run; +import hudson.model.TaskListener; +import io.jenkins.plugins.checks.api.ChecksDetails; +import io.jenkins.plugins.checks.api.ChecksPublisher; +import io.jenkins.plugins.checks.api.ChecksPublisherFactory; + +import java.util.Optional; + +public class LoggingChecksPublisher extends ChecksPublisher { + @FunctionalInterface + public interface Formatter { + String format(ChecksDetails details); + } + + private Formatter formatter = ChecksDetails::toString; + private TaskListener listener = TaskListener.NULL; + + @Override + public void publish(final ChecksDetails details) { + listener.getLogger().print(formatter.format(details)); + } + + public static class Factory extends ChecksPublisherFactory { + private final LoggingChecksPublisher publisher = new LoggingChecksPublisher(); + + public void setFormatter(final Formatter formatter) { + publisher.formatter = formatter; + } + + @Override + protected Optional createPublisher(final Run run, final TaskListener listener) { + publisher.listener = listener; + return Optional.of(publisher); + } + + @Override + protected Optional createPublisher(final Job job, final TaskListener listener) { + publisher.listener = listener; + return Optional.of(publisher); + } + } +}