diff --git a/checkstyle-suppressions.xml b/checkstyle-suppressions.xml new file mode 100644 index 00000000..2780fb5d --- /dev/null +++ b/checkstyle-suppressions.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/pom.xml b/pom.xml index cc918f4f..a022d861 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,8 @@ jenkinsci/${project.artifactId}-plugin - 2.14.0 + 2.16.0 + 1.17.1 @@ -82,6 +83,31 @@ test + + org.jenkins-ci.plugins + ssh-credentials + test + + + + org.jenkins-ci.plugins + ssh-slaves + test + + + + org.testcontainers + testcontainers + ${testcontainers.version} + test + + + org.testcontainers + junit-jupiter + ${testcontainers.version} + test + + org.jenkins-ci.plugins.workflow @@ -104,6 +130,13 @@ + + org.apache.maven.plugins + maven-checkstyle-plugin + + ${maven.multiModuleProjectDirectory}/checkstyle-suppressions.xml + + org.assertj assertj-assertions-generator-maven-plugin diff --git a/src/test/java/io/jenkins/plugins/checks/ArchitectureTest.java b/src/test/java/io/jenkins/plugins/checks/ArchitectureTest.java index e05482eb..440d17f9 100644 --- a/src/test/java/io/jenkins/plugins/checks/ArchitectureTest.java +++ b/src/test/java/io/jenkins/plugins/checks/ArchitectureTest.java @@ -20,7 +20,7 @@ class ArchitectureTest { static final ArchRule NO_JENKINS_INSTANCE_CALL = PluginArchitectureRules.NO_JENKINS_INSTANCE_CALL; @ArchTest - static final ArchRule NO_PUBLIC_TEST_CLASSES = ((ClassesShouldConjunction) PluginArchitectureRules.NO_PUBLIC_TEST_CLASSES) + static final ArchRule NO_PUBLIC_TEST_CLASSES = ((ClassesShouldConjunction) ArchitectureRules.NO_PUBLIC_TEST_CLASSES) .andShould().notBeAnnotatedWith(RunWith.class); // Allow for JUnit4 tests. @ArchTest diff --git a/src/test/java/io/jenkins/plugins/checks/api/TruncatedStringTest.java b/src/test/java/io/jenkins/plugins/checks/api/TruncatedStringTest.java index 30827a7d..5aa4e420 100644 --- a/src/test/java/io/jenkins/plugins/checks/api/TruncatedStringTest.java +++ b/src/test/java/io/jenkins/plugins/checks/api/TruncatedStringTest.java @@ -1,12 +1,13 @@ package io.jenkins.plugins.checks.api; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import java.nio.charset.StandardCharsets; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -15,51 +16,26 @@ * Test behavior of the {@link TruncatedString}. */ @SuppressWarnings({"VisibilityModifier", "MissingJavadocMethod"}) -@RunWith(Parameterized.class) -@SuppressFBWarnings("NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") -public class TruncatedStringTest { +class TruncatedStringTest { private static final String MESSAGE = "Truncated"; // length 9 - /** - * Human readable test name. - */ - @Parameterized.Parameter - public String testName; - - /** - * Parameter for chunking on new lines (or not!). - */ - @Parameterized.Parameter(1) - public boolean chunkOnNewlines; - - /** - * Parameter for chunking on chars (or not!). - */ - @Parameterized.Parameter(2) - public boolean chunkOnChars; - - @Parameterized.Parameters(name = "{0}") - public static Object[][] parameters() { - return new Object[][]{ - {"Chunks+Bytes", false, false}, - {"Newlines+Bytes", true, false}, - {"Chunks+Chars", false, true}, - {"Newlines+Chars", true, true} - }; + @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Called by JUnit") + private static Stream parameters() { + return Stream.of( + Arguments.of(false, false), + Arguments.of(true, false), + Arguments.of(false, true), + Arguments.of(true, true)); } private TruncatedString.Builder builder; - @Before + @BeforeEach public void makeBuilder() { - this.builder = new TruncatedString.Builder() - .withTruncationText(MESSAGE); - if (chunkOnNewlines) { - builder.setChunkOnNewlines(); - } + this.builder = new TruncatedString.Builder().withTruncationText(MESSAGE); } - private String build(final int maxSize) { + private String build(final boolean chunkOnChars, final int maxSize) { return chunkOnChars ? builder.build().buildByChars(maxSize) : builder.build().buildByBytes(maxSize); } @@ -67,91 +43,126 @@ private String buildRawString() { return builder.build().toString(); } - @Test - public void shouldBuildStrings() { + @ParameterizedTest + @MethodSource("parameters") + public void shouldBuildStrings(final boolean chunkOnNewlines, final boolean chunkOnChars) { + if (chunkOnNewlines) { + builder.setChunkOnNewlines(); + } builder.addText("Hello\n"); assertThat(buildRawString()).isEqualTo("Hello\n"); - assertThat(build(1000)).isEqualTo("Hello\n"); + assertThat(build(chunkOnChars, 1000)).isEqualTo("Hello\n"); builder.addText(", world!"); assertThat(buildRawString()).isEqualTo("Hello\n, world!"); - assertThat(build(1000)).isEqualTo("Hello\n, world!"); + assertThat(build(chunkOnChars, 1000)).isEqualTo("Hello\n, world!"); } - @Test - public void shouldTruncateStrings() { + @ParameterizedTest + @MethodSource("parameters") + public void shouldTruncateStrings(final boolean chunkOnNewlines, final boolean chunkOnChars) { + if (chunkOnNewlines) { + builder.setChunkOnNewlines(); + } builder.addText("xxxxxxxxx\n"); // 10 - assertThat(build(20)).isEqualTo("xxxxxxxxx\n"); + assertThat(build(chunkOnChars, 20)).isEqualTo("xxxxxxxxx\n"); builder.addText("yyyy\n"); // 5, doesn't cause overflow - assertThat(build(20)).isEqualTo("xxxxxxxxx\nyyyy\n"); + assertThat(build(chunkOnChars, 20)).isEqualTo("xxxxxxxxx\nyyyy\n"); builder.addText("zzzzzz\n"); // 7, does cause overflow - assertThat(build(20)).isEqualTo("xxxxxxxxx\nTruncated"); + assertThat(build(chunkOnChars, 20)).isEqualTo("xxxxxxxxx\nTruncated"); } - @Test - public void shouldHandleEdgeCases() { - assertThat(build(10)).isEqualTo(""); + @ParameterizedTest + @MethodSource("parameters") + public void shouldHandleEdgeCases(final boolean chunkOnNewlines, final boolean chunkOnChars) { + if (chunkOnNewlines) { + builder.setChunkOnNewlines(); + } + assertThat(build(chunkOnChars, 10)).isEqualTo(""); assertThat(buildRawString()).isEqualTo(""); builder.addText("xxxxxxxxxxxxxx\n"); // 15 - assertThat(build(10)).isEqualTo("Truncated"); + assertThat(build(chunkOnChars, 10)).isEqualTo("Truncated"); assertThatThrownBy(() -> { - build(5); + build(chunkOnChars, 5); }).isInstanceOf(IllegalArgumentException.class) .hasMessage("Maximum length is less than truncation text."); } - @Test - public void shouldHandleReversedChunking() { + @ParameterizedTest + @MethodSource("parameters") + public void shouldHandleReversedChunking(final boolean chunkOnNewlines, final boolean chunkOnChars) { + if (chunkOnNewlines) { + builder.setChunkOnNewlines(); + } builder.setTruncateStart(); builder.addText("zzzz\n"); // 5 - assertThat(build(20)).isEqualTo("zzzz\n"); + assertThat(build(chunkOnChars, 20)).isEqualTo("zzzz\n"); builder.addText("xxxx\n"); // 5, doesn't cause overflow - assertThat(build(20)).isEqualTo("zzzz\nxxxx\n"); + assertThat(build(chunkOnChars, 20)).isEqualTo("zzzz\nxxxx\n"); builder.addText("cccc\n"); // 5, doesn't cause overflow - assertThat(build(20)).isEqualTo("zzzz\nxxxx\ncccc\n"); + assertThat(build(chunkOnChars, 20)).isEqualTo("zzzz\nxxxx\ncccc\n"); builder.addText("aaaaaa\n"); // 7, does cause overflow - assertThat(build(20)).isEqualTo("Truncatedcccc\naaaaaa\n"); + assertThat(build(chunkOnChars, 20)).isEqualTo("Truncatedcccc\naaaaaa\n"); } - @Test - public void shouldHandleEdgeCasesReversed() { + @ParameterizedTest + @MethodSource("parameters") + public void shouldHandleEdgeCasesReversed(final boolean chunkOnNewlines, final boolean chunkOnChars) { + if (chunkOnNewlines) { + builder.setChunkOnNewlines(); + } builder.setTruncateStart(); - assertThat(build(10)).isEqualTo(""); + assertThat(build(chunkOnChars, 10)).isEqualTo(""); assertThat(buildRawString()).isEqualTo(""); builder.addText("xxxxxxxxxxxxxx\n"); // 15 - assertThat(build(10)).isEqualTo("Truncated"); + assertThat(build(chunkOnChars, 10)).isEqualTo("Truncated"); assertThatThrownBy(() -> { - build(5); + build(chunkOnChars, 5); }).isInstanceOf(IllegalArgumentException.class) .hasMessage("Maximum length is less than truncation text."); } - @Test - public void shouldChunkNewlinesDifferently() { + @ParameterizedTest + @MethodSource("parameters") + public void shouldChunkNewlinesDifferently(final boolean chunkOnNewlines, final boolean chunkOnChars) { + if (chunkOnNewlines) { + builder.setChunkOnNewlines(); + } builder.addText("xxxxxxxxxx"); // 10 builder.addText("yyyyyyyyyyy"); // 11 - assertThat(build(20)).isEqualTo(chunkOnNewlines ? "Truncated" : "xxxxxxxxxxTruncated"); + assertThat(build(chunkOnChars, 20)).isEqualTo(chunkOnNewlines ? "Truncated" : "xxxxxxxxxxTruncated"); makeBuilder(); + if (chunkOnNewlines) { + builder.setChunkOnNewlines(); + } builder.addText("wwww\n"); // 5 builder.addText("xxxx\nyyyy\nzzzzz\n"); // 16 - assertThat(build(20)).isEqualTo(chunkOnNewlines ? "wwww\nxxxx\nTruncated" : "wwww\nTruncated"); + assertThat(build(chunkOnChars, 20)).isEqualTo(chunkOnNewlines ? "wwww\nxxxx\nTruncated" : "wwww\nTruncated"); } - @Test - public void shouldTruncateByBytesOrChars() { + @ParameterizedTest + @MethodSource("parameters") + public void shouldTruncateByBytesOrChars(final boolean chunkOnNewlines, final boolean chunkOnChars) { + if (chunkOnNewlines) { + builder.setChunkOnNewlines(); + } builder.addText("☃☃☃\n"); // 3 + 1 assertThat(buildRawString().length()).isEqualTo(4); assertThat(buildRawString().getBytes(StandardCharsets.UTF_8).length).isEqualTo(10); - assertThat(build(20)).isEqualTo("☃☃☃\n"); + assertThat(build(chunkOnChars, 20)).isEqualTo("☃☃☃\n"); builder.addText("🕴️🕴️\n"); // 2 + 1 assertThat(buildRawString().length()).isEqualTo(11); assertThat(buildRawString().getBytes(StandardCharsets.UTF_8).length).isEqualTo(25); - assertThat(build(20)).isEqualTo(chunkOnChars ? "☃☃☃\n🕴️🕴️\n" : "☃☃☃\nTruncated"); + assertThat(build(chunkOnChars, 20)).isEqualTo(chunkOnChars ? "☃☃☃\n🕴️🕴️\n" : "☃☃☃\nTruncated"); } - @Test - public void shouldHandleLongCharsInTruncationText() { + @ParameterizedTest + @MethodSource("parameters") + public void shouldHandleLongCharsInTruncationText(final boolean chunkOnNewlines, final boolean chunkOnChars) { + if (chunkOnNewlines) { + builder.setChunkOnNewlines(); + } String truncationText = "E_TOO_MUCH_☃"; assertThat(truncationText.length()).isEqualTo(12); assertThat(truncationText.getBytes(StandardCharsets.UTF_8).length).isEqualTo(14); @@ -159,8 +170,8 @@ public void shouldHandleLongCharsInTruncationText() { builder.withTruncationText(truncationText); builder.addText("xxxx\n"); // 5 builder.addText("x\n"); // 2 - assertThat(build(20)).isEqualTo("xxxx\nx\n"); + assertThat(build(chunkOnChars, 20)).isEqualTo("xxxx\nx\n"); builder.addText("xxxxxxxxxxxxxxx"); // 15 - assertThat(build(20)).isEqualTo(chunkOnChars ? "xxxx\nx\nE_TOO_MUCH_☃" : "xxxx\nE_TOO_MUCH_☃"); + assertThat(build(chunkOnChars, 20)).isEqualTo(chunkOnChars ? "xxxx\nx\nE_TOO_MUCH_☃" : "xxxx\nE_TOO_MUCH_☃"); } } diff --git a/src/test/java/io/jenkins/plugins/checks/status/BuildStatusChecksPublisherITest.java b/src/test/java/io/jenkins/plugins/checks/status/BuildStatusChecksPublisherITest.java index 282ecdb8..a37397e3 100644 --- a/src/test/java/io/jenkins/plugins/checks/status/BuildStatusChecksPublisherITest.java +++ b/src/test/java/io/jenkins/plugins/checks/status/BuildStatusChecksPublisherITest.java @@ -4,8 +4,8 @@ import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.TestExtension; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -18,6 +18,7 @@ import io.jenkins.plugins.checks.api.ChecksConclusion; import io.jenkins.plugins.checks.api.ChecksDetails; +import io.jenkins.plugins.checks.api.ChecksPublisherFactory; import io.jenkins.plugins.checks.api.ChecksStatus; import io.jenkins.plugins.checks.util.CapturingChecksPublisher; import io.jenkins.plugins.util.IntegrationTestWithJenkinsPerTest; @@ -30,27 +31,31 @@ */ @SuppressWarnings({"PMD.AddEmptyString", "checkstyle:LambdaBodyLength"}) @SuppressFBWarnings("NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") -public class BuildStatusChecksPublisherITest extends IntegrationTestWithJenkinsPerTest { - - /** - * Provide a {@link io.jenkins.plugins.checks.util.CapturingChecksPublisher} to capture details. - */ - @TestExtension - public static final CapturingChecksPublisher.Factory PUBLISHER_FACTORY = new CapturingChecksPublisher.Factory(); +class BuildStatusChecksPublisherITest extends IntegrationTestWithJenkinsPerTest { + + private CapturingChecksPublisher.Factory getFactory() { + return getJenkins().getInstance().getExtensionList(ChecksPublisherFactory.class) + .stream() + .filter(f -> f instanceof CapturingChecksPublisher.Factory) + .map(f -> (CapturingChecksPublisher.Factory) f) + .findAny() + .orElseThrow(() -> new AssertionError("No CapturingChecksPublisher registered as @TestExtension?")); + } /** * Clean captured checks between tests. */ - @After + @AfterEach public void clearChecks() { - PUBLISHER_FACTORY.getPublishedChecks().clear(); + getFactory().getPublishedChecks().clear(); } - /** - * Provide inject an implementation of {@link AbstractStatusChecksProperties} to control the checks. - */ - @TestExtension - public static final ChecksProperties PROPERTIES = new ChecksProperties(); + private ChecksProperties getProperties() { + return getJenkins().getInstance().getExtensionList(ChecksProperties.class) + .stream() + .findAny() + .orElseThrow(() -> new AssertionError("No ChecksProperties registered as @TestExtension?")); + } /** * Tests when the implementation of {@link AbstractStatusChecksProperties} is not applicable, @@ -58,11 +63,11 @@ public void clearChecks() { */ @Test public void shouldNotPublishStatusWhenNotApplicable() { - PROPERTIES.setApplicable(false); + getProperties().setApplicable(false); buildSuccessfully(createFreeStyleProject()); - assertThat(PUBLISHER_FACTORY.getPublishedChecks()).hasSize(0); + assertThat(getFactory().getPublishedChecks()).hasSize(0); } /** @@ -70,13 +75,13 @@ public void shouldNotPublishStatusWhenNotApplicable() { */ @Test public void shouldNotPublishStatusWhenSkipped() { - PROPERTIES.setApplicable(true); - PROPERTIES.setSkipped(true); - PROPERTIES.setName("Test Status"); + getProperties().setApplicable(true); + getProperties().setSkipped(true); + getProperties().setName("Test Status"); buildSuccessfully(createFreeStyleProject()); - assertThat(PUBLISHER_FACTORY.getPublishedChecks()).hasSize(0); + assertThat(getFactory().getPublishedChecks()).hasSize(0); } /** @@ -85,27 +90,27 @@ public void shouldNotPublishStatusWhenSkipped() { */ @Test public void shouldPublishStatusWithProperties() { - PROPERTIES.setApplicable(true); - PROPERTIES.setSkipped(false); - PROPERTIES.setName("Test Status"); + getProperties().setApplicable(true); + getProperties().setSkipped(false); + getProperties().setName("Test Status"); buildSuccessfully(createFreeStyleProject()); - assertThat(PUBLISHER_FACTORY.getPublishedChecks()).hasSize(3); + assertThat(getFactory().getPublishedChecks()).hasSize(3); - ChecksDetails details = PUBLISHER_FACTORY.getPublishedChecks().get(0); + ChecksDetails details = getFactory().getPublishedChecks().get(0); assertThat(details.getName()).isPresent().get().isEqualTo("Test Status"); assertThat(details.getStatus()).isEqualTo(ChecksStatus.QUEUED); assertThat(details.getConclusion()).isEqualTo(ChecksConclusion.NONE); - details = PUBLISHER_FACTORY.getPublishedChecks().get(1); + details = getFactory().getPublishedChecks().get(1); assertThat(details.getName()).isPresent().get().isEqualTo("Test Status"); assertThat(details.getStatus()).isEqualTo(ChecksStatus.IN_PROGRESS); assertThat(details.getConclusion()).isEqualTo(ChecksConclusion.NONE); - details = PUBLISHER_FACTORY.getPublishedChecks().get(2); + details = getFactory().getPublishedChecks().get(2); assertThat(details.getName()).isPresent().get().isEqualTo("Test Status"); assertThat(details.getStatus()).isEqualTo(ChecksStatus.COMPLETED); @@ -117,10 +122,10 @@ public void shouldPublishStatusWithProperties() { */ @Test public void shouldPublishStageDetails() { - PROPERTIES.setApplicable(true); - PROPERTIES.setSkipped(false); - PROPERTIES.setSuppressLogs(false); - PROPERTIES.setName("Test Status"); + getProperties().setApplicable(true); + getProperties().setSkipped(false); + getProperties().setSuppressLogs(false); + getProperties().setName("Test Status"); WorkflowJob job = createPipeline(); job.setDefinition(new CpsFlowDefinition("" @@ -143,7 +148,7 @@ public void shouldPublishStageDetails() { buildWithResult(job, Result.FAILURE); - List checksDetails = PUBLISHER_FACTORY.getPublishedChecks(); + List checksDetails = getFactory().getPublishedChecks(); assertThat(checksDetails).hasSize(9); @@ -232,10 +237,10 @@ public void shouldPublishStageDetails() { */ @Test public void shouldPublishStageDetailsWithoutLogsIfRequested() { - PROPERTIES.setApplicable(true); - PROPERTIES.setSkipped(false); - PROPERTIES.setName("Test Status"); - PROPERTIES.setSuppressLogs(true); + getProperties().setApplicable(true); + getProperties().setSkipped(false); + getProperties().setName("Test Status"); + getProperties().setSuppressLogs(true); WorkflowJob job = createPipeline(); job.setDefinition(new CpsFlowDefinition("" @@ -258,7 +263,7 @@ public void shouldPublishStageDetailsWithoutLogsIfRequested() { buildWithResult(job, Result.FAILURE); - List checksDetails = PUBLISHER_FACTORY.getPublishedChecks(); + List checksDetails = getFactory().getPublishedChecks(); assertThat(checksDetails).hasSize(9); @@ -297,9 +302,9 @@ public void shouldPublishStageDetailsWithoutLogsIfRequested() { */ @Test public void shouldPublishSimplePipeline() { - PROPERTIES.setApplicable(true); - PROPERTIES.setSkipped(false); - PROPERTIES.setName("Test Status"); + getProperties().setApplicable(true); + getProperties().setSkipped(false); + getProperties().setName("Test Status"); WorkflowJob job = createPipeline(); job.setDefinition(new CpsFlowDefinition("" @@ -309,12 +314,28 @@ public void shouldPublishSimplePipeline() { buildWithResult(job, Result.SUCCESS); - List checksDetails = PUBLISHER_FACTORY.getPublishedChecks(); + List checksDetails = getFactory().getPublishedChecks(); ChecksDetails details = checksDetails.get(1); assertThat(details.getOutput()).isPresent().get().satisfies(output -> assertThat(output.getTitle()).isPresent().get().isEqualTo("Success")); } + /** + * Provide a {@link io.jenkins.plugins.checks.util.CapturingChecksPublisher} to capture details. + */ + @TestExtension + public static class CapturingChecksPublisherTestExtension extends CapturingChecksPublisher.Factory { + // activate test extension + } + + /** + * Provide inject an implementation of {@link AbstractStatusChecksProperties} to control the checks. + */ + @TestExtension + public static class ChecksPropertiesTestExtension extends ChecksProperties { + // activate test extension + } + static class ChecksProperties extends AbstractStatusChecksProperties { private boolean applicable; private boolean skipped; diff --git a/src/test/java/io/jenkins/plugins/checks/steps/PublishChecksStepITest.java b/src/test/java/io/jenkins/plugins/checks/steps/PublishChecksStepITest.java index 7431de6d..8d05dd79 100644 --- a/src/test/java/io/jenkins/plugins/checks/steps/PublishChecksStepITest.java +++ b/src/test/java/io/jenkins/plugins/checks/steps/PublishChecksStepITest.java @@ -5,11 +5,12 @@ import io.jenkins.plugins.checks.api.ChecksConclusion; import io.jenkins.plugins.checks.api.ChecksDetails; import io.jenkins.plugins.checks.api.ChecksOutput; +import io.jenkins.plugins.checks.api.ChecksPublisherFactory; import io.jenkins.plugins.checks.api.ChecksStatus; import io.jenkins.plugins.checks.util.CapturingChecksPublisher; import io.jenkins.plugins.util.IntegrationTestWithJenkinsPerTest; import org.jenkinsci.plugins.workflow.job.WorkflowJob; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; @@ -20,13 +21,16 @@ /** * Tests the pipeline step to publish checks. */ -public class PublishChecksStepITest extends IntegrationTestWithJenkinsPerTest { +class PublishChecksStepITest extends IntegrationTestWithJenkinsPerTest { - /** - * Provide a {@link CapturingChecksPublisher} to check published checks on each test. - */ - @TestExtension - public static final CapturingChecksPublisher.Factory PUBLISHER_FACTORY = new CapturingChecksPublisher.Factory(); + private CapturingChecksPublisher.Factory getFactory() { + return getJenkins().getInstance().getExtensionList(ChecksPublisherFactory.class) + .stream() + .filter(f -> f instanceof CapturingChecksPublisher.Factory) + .map(f -> (CapturingChecksPublisher.Factory) f) + .findAny() + .orElseThrow(() -> new AssertionError("No CapturingChecksPublisher registered as @TestExtension?")); + } /** * Tests that the step "publishChecks" can be used in pipeline script. @@ -49,9 +53,9 @@ public void shouldPublishChecksWhenUsingPipeline() throws IOException { assertThat(JenkinsRule.getLog(buildSuccessfully(job))) .contains("[Pipeline] publishChecks"); - assertThat(PUBLISHER_FACTORY.getPublishedChecks().size()).isEqualTo(1); + assertThat(getFactory().getPublishedChecks().size()).isEqualTo(1); - ChecksDetails details = PUBLISHER_FACTORY.getPublishedChecks().get(0); + ChecksDetails details = getFactory().getPublishedChecks().get(0); assertThat(details.getName()).isPresent().get().isEqualTo("customized-check"); assertThat(details.getOutput()).isPresent(); @@ -84,4 +88,12 @@ public void shouldPublishChecksWhenUsingPipeline() throws IOException { .withRawDetails("raw details") .build()); } + + /** + * Provide a {@link CapturingChecksPublisher} to check published checks on each test. + */ + @TestExtension + public static class CapturingChecksPublisherTestExtension extends CapturingChecksPublisher.Factory { + // activate test extension + } } diff --git a/src/test/java/io/jenkins/plugins/checks/steps/WithChecksStepITest.java b/src/test/java/io/jenkins/plugins/checks/steps/WithChecksStepITest.java index 936d8cdb..3e871993 100644 --- a/src/test/java/io/jenkins/plugins/checks/steps/WithChecksStepITest.java +++ b/src/test/java/io/jenkins/plugins/checks/steps/WithChecksStepITest.java @@ -4,15 +4,17 @@ import hudson.model.Run; import io.jenkins.plugins.checks.api.ChecksConclusion; import io.jenkins.plugins.checks.api.ChecksDetails; +import io.jenkins.plugins.checks.api.ChecksPublisherFactory; import io.jenkins.plugins.checks.api.ChecksStatus; import io.jenkins.plugins.checks.util.CapturingChecksPublisher; +import io.jenkins.plugins.checks.util.CapturingChecksPublisher.Factory; import io.jenkins.plugins.util.IntegrationTestWithJenkinsPerTest; import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.steps.*; import org.jenkinsci.plugins.workflow.support.steps.ExecutorStepExecution; -import org.junit.After; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.DataBoundConstructor; @@ -27,7 +29,7 @@ /** * Tests the "withChecks" step. */ -public class WithChecksStepITest extends IntegrationTestWithJenkinsPerTest { +class WithChecksStepITest extends IntegrationTestWithJenkinsPerTest { /** * Tests that the step can inject the {@link ChecksInfo} into the closure. @@ -40,18 +42,21 @@ public void shouldInjectChecksInfoIntoClosure() { buildSuccessfully(job); } - /** - * Provide a {@link CapturingChecksPublisher} to check published checks on each test. - */ - @TestExtension - public static final CapturingChecksPublisher.Factory PUBLISHER_FACTORY = new CapturingChecksPublisher.Factory(); + private CapturingChecksPublisher.Factory getFactory() { + return getJenkins().getInstance().getExtensionList(ChecksPublisherFactory.class) + .stream() + .filter(f -> f instanceof Factory) + .map(f -> (Factory) f) + .findAny() + .orElseThrow(() -> new AssertionError("No CapturingChecksPublisher registered as @TestExtension?")); + } /** - * Clear captured checks on the {@link WithChecksStepITest#PUBLISHER_FACTORY} after each test. + * Clear captured checks on the {@link CapturingChecksPublisher.Factory} after each test. */ - @After + @AfterEach public void clearPublisher() { - PUBLISHER_FACTORY.getPublishedChecks().clear(); + getFactory().getPublishedChecks().clear(); } /** @@ -64,9 +69,9 @@ public void publishChecksShouldTakeNameFromWithChecks() { buildSuccessfully(job); - assertThat(PUBLISHER_FACTORY.getPublishedChecks().size()).isEqualTo(2); - ChecksDetails autoChecks = PUBLISHER_FACTORY.getPublishedChecks().get(0); - ChecksDetails manualChecks = PUBLISHER_FACTORY.getPublishedChecks().get(1); + assertThat(getFactory().getPublishedChecks().size()).isEqualTo(2); + ChecksDetails autoChecks = getFactory().getPublishedChecks().get(0); + ChecksDetails manualChecks = getFactory().getPublishedChecks().get(1); assertThat(autoChecks.getName()).isPresent().get().isEqualTo("test injection"); assertThat(autoChecks.getStatus()).isEqualTo(ChecksStatus.IN_PROGRESS); @@ -87,9 +92,9 @@ public void publishChecksShouldTakeNameFromWithChecksUnlessOverridden() { buildSuccessfully(job); - assertThat(PUBLISHER_FACTORY.getPublishedChecks().size()).isEqualTo(2); - ChecksDetails autoChecks = PUBLISHER_FACTORY.getPublishedChecks().get(0); - ChecksDetails manualChecks = PUBLISHER_FACTORY.getPublishedChecks().get(1); + assertThat(getFactory().getPublishedChecks().size()).isEqualTo(2); + ChecksDetails autoChecks = getFactory().getPublishedChecks().get(0); + ChecksDetails manualChecks = getFactory().getPublishedChecks().get(1); assertThat(autoChecks.getName()).isPresent().get().isEqualTo("test injection"); assertThat(autoChecks.getStatus()).isEqualTo(ChecksStatus.IN_PROGRESS); @@ -110,8 +115,8 @@ public void withChecksShouldDetectFailure() { buildWithResult(job, Result.FAILURE); - assertThat(PUBLISHER_FACTORY.getPublishedChecks().size()).isEqualTo(2); - ChecksDetails failure = PUBLISHER_FACTORY.getPublishedChecks().get(1); + assertThat(getFactory().getPublishedChecks().size()).isEqualTo(2); + ChecksDetails failure = getFactory().getPublishedChecks().get(1); assertThat(failure.getStatus()).isEqualTo(ChecksStatus.COMPLETED); assertThat(failure.getConclusion()).isEqualTo(ChecksConclusion.FAILURE); @@ -133,8 +138,8 @@ public void withChecksShouldDetectAbort() { buildWithResult(job, Result.ABORTED); - assertThat(PUBLISHER_FACTORY.getPublishedChecks().size()).isEqualTo(2); - ChecksDetails abort = PUBLISHER_FACTORY.getPublishedChecks().get(1); + assertThat(getFactory().getPublishedChecks().size()).isEqualTo(2); + ChecksDetails abort = getFactory().getPublishedChecks().get(1); assertThat(abort.getStatus()).isEqualTo(ChecksStatus.COMPLETED); assertThat(abort.getConclusion()).isEqualTo(ChecksConclusion.CANCELED); @@ -214,4 +219,12 @@ protected Void run() throws Exception { } } } + + /** + * Provide a {@link CapturingChecksPublisher} to check published checks on each test. + */ + @TestExtension + public static class CapturingChecksPublisherTestExtension extends CapturingChecksPublisher.Factory { + // activate test extension + } }