+ The reference job is the baseline used to determine the relative differences to the current build. + Several plugins that report build statistics (test results, code coverage, metrics, static + analysis warnings) typically show their reports in two different ways: either as absolute report + (e.g., total number of tests or warnings, overall code coverage) or as relative delta report (e.g., additional + tests, increased or decreased coverage, new or fixed warnings). To compute a relative delta report, a plugin needs + to select another build to compare the current results to (a so-called reference build). This reference build is + obtained from the specified reference job. +
++ In Multibranch Pipelines this parameter can be left empty: in these jobs, the plugin selects the build automatically + from the associated job that builds the main target branch. For all other jobs, the last completed build of the + current job will be used as reference build if the reference job is not specified. +
diff --git a/plugin/src/main/resources/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorder/help-requiredResult.html b/plugin/src/main/resources/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorder/help-requiredResult.html new file mode 100644 index 00000000..6f12e271 --- /dev/null +++ b/plugin/src/main/resources/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorder/help-requiredResult.html @@ -0,0 +1,15 @@ +When a reference build is searched for in the baseline (see the parameter reference job) then it +sometimes makes sense to only consider builds that have a certain result. +For example, you may want to skip the computation of a delta coverage when the reference build has +failed tests. Or you may want to skip the computation of new warnings when the reference build has +a compilation error. + +The following enumeration shows the possible values for this parameter and the corresponding behavior: +* {@code * M: [M1]#1 @@ -95,7 +99,7 @@ void shouldFindCorrectBuildInPipelines() { WorkflowJob mainBranch = createPipeline(MAIN); mainBranch.setDefinition(asStage(createLocalGitCheckout(MAIN))); - Run, ?> masterBuild = buildSuccessfully(mainBranch); + Run, ?> mainBuild = buildSuccessfully(mainBranch); createFeatureBranchAndAddCommits(); @@ -104,7 +108,7 @@ void shouldFindCorrectBuildInPipelines() { "discoverGitReferenceBuild(referenceJob: '" + MAIN + "')", "gitDiffStat()")); - verifyPipelineResult(masterBuild, featureBranch); + verifyPipelineResult(mainBuild, featureBranch); assertThat(getCommitStatisticsOf(featureBranch.getLastBuild())) .hasCommitCount(1) @@ -113,9 +117,172 @@ void shouldFindCorrectBuildInPipelines() { .hasDeletedLines(0); } + /** + * Creates a pipeline that checks if the reference build is found if the main is one commit and build ahead of the + * feature branch. + * + *+ * {@code + * M: [M1]#1 - [M2]#2 + * \ + * F: [F1]#1} + *+ * @see #shouldHandleExtraCommitsAfterBranchPointOnMain() + */ + @Test + void shouldFindCorrectBuildInPipelinesAfterBranchPointOnMain() { + WorkflowJob mainBranch = createPipeline(MAIN); + mainBranch.setDefinition(asStage(createLocalGitCheckout(MAIN))); + + Run, ?> mainBuild = buildSuccessfully(mainBranch); + + createFeatureBranchAndAddCommits(); + + addAdditionalFileTo(MAIN); + + buildAgain(mainBranch); + + WorkflowJob featureBranch = createPipeline(FEATURE); + featureBranch.setDefinition(asStage(createLocalGitCheckout(FEATURE), + "discoverGitReferenceBuild(referenceJob: '" + MAIN + "')")); + + Run, ?> featureBuild = buildSuccessfully(featureBranch); + assertThat(featureBuild.getNumber()).isEqualTo(1); + + assertThat(featureBuild.getAction(ReferenceBuild.class)).isNotNull() + .hasOwner(featureBuild) + .hasReferenceBuildId(mainBuild.getExternalizableId()) + .hasReferenceBuild(Optional.of(mainBuild)) + .hasMessages("Configured reference job: 'main'", + "Found reference build '#1' for target branch"); + } + + /** + * Creates a pipeline that ignores failed builds. + * + *+ * {@code + * M: [M1]#1 - [M2]#2 + * \ + * F: [F1]#1} + *+ * + * @param requiredResult + * the required result + * @param latestBuildIfNotFound + * determines whether the latest build should be used if the required result is not found + * + * @see #shouldHandleExtraCommitsAfterBranchPointOnMain() + */ + @Issue("JENKINS-72015") + @ParameterizedTest(name = "should skip failed builds: status: {0} - latestBuildIfNotFound: {1}") + @CsvSource({ + "SUCCESS, false", "UNSTABLE, false", ", false", + "SUCCESS, true ", "UNSTABLE, true ", ", true "}) + void shouldSkipFailedBuildsIfStatusIsWorseThanRequired(final String requiredResult, final boolean latestBuildIfNotFound) { + WorkflowJob mainBranch = createPipeline(MAIN); + mainBranch.setDefinition(asStage(createLocalGitCheckout(MAIN) + + "error('FAILURE')\n")); + + buildWithResult(mainBranch, Result.FAILURE); + + createFeatureBranchAndAddCommits(); + + addAdditionalFileTo(MAIN); + + var latestBuild = buildAgain(mainBranch); + + WorkflowJob featureBranch = createPipeline(FEATURE); + var requiredParameter = StringUtils.isBlank(requiredResult) ? StringUtils.EMPTY : ", requiredResult: '" + requiredResult + "'"; + featureBranch.setDefinition(asStage(createLocalGitCheckout(FEATURE), + "discoverGitReferenceBuild(" + + "referenceJob: '" + MAIN + "'" + + requiredParameter + + ", latestBuildIfNotFound: " + latestBuildIfNotFound + ")")); + + Run, ?> featureBuild = buildSuccessfully(featureBranch); + assertThat(featureBuild.getNumber()).isEqualTo(1); + + var expectedResult = StringUtils.isBlank(requiredResult) ? "UNSTABLE" : requiredResult; + + var referenceBuildAssert = assertThat(featureBuild.getAction(ReferenceBuild.class)) + .isNotNull() + .hasOwner(featureBuild) + .hasMessages("Configured reference job: 'main'", + "-> found build '#1' in reference job with matching commits", + "-> ignoring reference build '#1' or one of its predecessors since none have a result of " + + expectedResult + " or better", + NOT_FOUND_MESSAGE); + + if (latestBuildIfNotFound) { + referenceBuildAssert + .hasReferenceBuild(Optional.of(latestBuild)) + .hasReferenceBuildId(latestBuild.getExternalizableId()) + .hasMessages("Falling back to latest completed build of reference job: '#2'"); + } + else { + referenceBuildAssert + .hasReferenceBuild(Optional.empty()); + } + } + + /** + * Creates a pipeline that uses a previous build of the actual reference build, because the reference build failed. + * + *+ * {@code + * M: [M1]#1 - [M2]#2 + * \ + * F: [F1]#1} + *+ * + * @param requiredResult + * the required result + * + * @see #shouldHandleExtraCommitsAfterBranchPointOnMain() + */ + @Issue("JENKINS-72015") + @ParameterizedTest(name = "should skip failed builds: status: {0}") + @ValueSource(strings = {"SUCCESS", "UNSTABLE", ""}) + void shouldUseSkipFailedBuildsIfStatusIsWorseThanRequired(final String requiredResult) { + WorkflowJob mainBranch = createPipeline(MAIN); + + mainBranch.setDefinition(asStage(createLocalGitCheckout(MAIN))); + + Run, ?> successful = buildSuccessfully(mainBranch); + + addAdditionalFileTo(MAIN); + mainBranch.setDefinition(asStage(createLocalGitCheckout(MAIN) + + "error('FAILURE')\n")); + + buildWithResult(mainBranch, Result.FAILURE); + + createFeatureBranchAndAddCommits(); + + WorkflowJob featureBranch = createPipeline(FEATURE); + var requiredParameter = StringUtils.isBlank(requiredResult) ? StringUtils.EMPTY : ", requiredResult: '" + requiredResult + "'"; + featureBranch.setDefinition(asStage(createLocalGitCheckout(FEATURE), + "discoverGitReferenceBuild(" + + "referenceJob: '" + MAIN + "'" + + requiredParameter + ")")); + + Run, ?> featureBuild = buildSuccessfully(featureBranch); + assertThat(featureBuild.getNumber()).isEqualTo(1); + + assertThat(featureBuild.getAction(ReferenceBuild.class)) + .isNotNull() + .hasOwner(featureBuild) + .hasMessages("Configured reference job: 'main'", + "-> found build '#2' in reference job with matching commits", + "Found reference build '#2' for target branch", + "-> Previous build '#1' has a result SUCCESS") + .hasReferenceBuild(Optional.of(successful)) + .hasReferenceBuildId(successful.getExternalizableId()); + } + /** * Creates a pipeline for the main branch and another pipeline for the feature branch, builds them and removes the - * commits action from the reference job. This simulates a setup where the last master build was finished before + * commits action from the reference job. This simulates a setup where the last main build was finished before * the Git forensics plugin has been added. */ @Test @@ -123,8 +290,8 @@ void shouldFindNoReferenceBuildIfReferenceJobHasNoCommitsAction() { WorkflowJob mainBranch = createPipeline(MAIN); mainBranch.setDefinition(asStage(createLocalGitCheckout(MAIN))); - Run, ?> masterBuild = buildSuccessfully(mainBranch); - masterBuild.removeAction(masterBuild.getAction(GitCommitsRecord.class)); // simulate a master build without records + Run, ?> mainBuild = buildSuccessfully(mainBranch); + mainBuild.removeAction(mainBuild.getAction(GitCommitsRecord.class)); // simulate a main build without records createFeatureBranchAndAddCommits(); WorkflowJob featureBranch = createPipeline(FEATURE); @@ -148,7 +315,7 @@ private CommitStatistics getCommitStatisticsOf(final WorkflowRun lastBuild) { /** * Creates a pipeline for the main branch and another pipeline for the feature branch, builds them and checks if - * the correct reference build will be found. The main branch contains an additional but unrelated SCM + * the correct reference build is found. The main branch contains an additional but unrelated SCM * repository. ** {@code @@ -167,7 +334,7 @@ void shouldFindCorrectBuildInPipelinesWithMultipleReposInReference() { createForensicsCheckoutStep(), createLocalGitCheckout(MAIN))); - Run, ?> masterBuild = buildSuccessfully(mainBranch); + Run, ?> mainBuild = buildSuccessfully(mainBranch); createFeatureBranchAndAddCommits(); @@ -176,12 +343,12 @@ void shouldFindCorrectBuildInPipelinesWithMultipleReposInReference() { createLocalGitCheckout(FEATURE), "discoverGitReferenceBuild(referenceJob: '" + MAIN + "', scm: 'git file')")); - verifyPipelineResult(masterBuild, featureBranch); + verifyPipelineResult(mainBuild, featureBranch); } /** * Creates a pipeline for the main branch and another pipeline for the feature branch, builds them and checks if - * the correct reference build will be found. The main branch contains an additional but unrelated SCM + * the correct reference build is found. The main branch contains an additional but unrelated SCM * repository. ** {@code @@ -199,7 +366,7 @@ void shouldFindCorrectBuildInPipelinesWithMultipleReposInFeature() { mainBranch.setDefinition(asStage( createLocalGitCheckout(MAIN))); - Run, ?> masterBuild = buildSuccessfully(mainBranch); + Run, ?> mainBuild = buildSuccessfully(mainBranch); createFeatureBranchAndAddCommits(); @@ -209,7 +376,7 @@ void shouldFindCorrectBuildInPipelinesWithMultipleReposInFeature() { createLocalGitCheckout(FEATURE), "discoverGitReferenceBuild(referenceJob: '" + MAIN + "', scm: 'git file')")); - verifyPipelineResult(masterBuild, featureBranch); + verifyPipelineResult(mainBuild, featureBranch); } private String createLocalGitCheckout(final String branch) { @@ -217,7 +384,7 @@ private String createLocalGitCheckout(final String branch) { + "branches: [[name: '" + branch + "' ]],\n" + getUrl() + "extensions: [[$class: 'RelativeTargetDirectory', \n" - + " relativeTargetDir: 'forensics-api']]])"; + + " relativeTargetDir: 'forensics-api']]])\n"; } private String createForensicsCheckoutStep() { @@ -228,22 +395,22 @@ private String createForensicsCheckoutStep() { + " relativeTargetDir: 'forensics-api']]])"; } - private void verifyPipelineResult(final Run, ?> masterBuild, final WorkflowJob featureBranch) { + private void verifyPipelineResult(final Run, ?> mainBuild, final WorkflowJob featureBranch) { Run, ?> featureBuild = buildSuccessfully(featureBranch); assertThat(featureBuild.getNumber()).isEqualTo(1); String featureCommit = getHead(); checkout(MAIN); - String masterCommit = getHead(); + String mainCommit = getHead(); assertThat(featureBuild.getAction(ReferenceBuild.class)).isNotNull() .hasOwner(featureBuild) - .hasReferenceBuildId(masterBuild.getExternalizableId()) - .hasReferenceBuild(Optional.of(masterBuild)) + .hasReferenceBuildId(mainBuild.getExternalizableId()) + .hasReferenceBuild(Optional.of(mainBuild)) .hasMessages("Configured reference job: 'main'", String.format("-> detected 2 commits in current branch (last one: '%s')", DECORATOR.asText(featureCommit)), - String.format("-> adding 1 commits from build '#1' of reference job (last one: '%s')", DECORATOR.asText(masterCommit)), - String.format("-> found a matching commit in current branch and target branch: '%s'", DECORATOR.asText(masterCommit)), + String.format("-> adding 1 commits from build '#1' of reference job (last one: '%s')", DECORATOR.asText(mainCommit)), + String.format("-> found a matching commit in current branch and target branch: '%s'", DECORATOR.asText(mainCommit)), "Found reference build '#1' for target branch"); } @@ -265,8 +432,8 @@ void shouldFindCorrectBuildForMultibranchPipeline() { WorkflowMultiBranchProject project = initializeGitAndMultiBranchProject(); buildProject(project); - WorkflowRun masterBuild = verifyMasterBuild(project, 1); - verifyRecordSize(masterBuild, 2); + WorkflowRun mainBuild = verifyMainBuild(project, 1); + verifyRecordSize(mainBuild, 2); String mainCommit = getHead(); String featureCommit = createFeatureBranchAndAddCommits(); @@ -277,8 +444,8 @@ void shouldFindCorrectBuildForMultibranchPipeline() { assertThat(featureBuild.getAction(ReferenceBuild.class)).isNotNull() .hasOwner(featureBuild) - .hasReferenceBuildId(masterBuild.getExternalizableId()) - .hasReferenceBuild(Optional.of(masterBuild)) + .hasReferenceBuildId(mainBuild.getExternalizableId()) + .hasReferenceBuild(Optional.of(mainBuild)) .hasMessages(MULTI_BRANCH_PROJECT, MAIN_IS_TARGET, String.format("-> detected 3 commits in current branch (last one: '%s')", DECORATOR.asText(featureCommit)), @@ -304,8 +471,8 @@ void shouldFindCorrectBuildForMultibranchPipelineWithComplexBranchNames() { WorkflowMultiBranchProject project = initializeGitAndMultiBranchProject(); buildProject(project); - WorkflowRun masterBuild = verifyBuild(project, 1, target, "main content"); - verifyRecordSize(masterBuild, 2); + WorkflowRun mainBuild = verifyBuild(project, 1, target, "main content"); + verifyRecordSize(mainBuild, 2); String feature = "bugfixes/hotfix-124"; createBranchAndAddCommits(feature, "targetBranch: '" + target + "'"); @@ -316,8 +483,8 @@ void shouldFindCorrectBuildForMultibranchPipelineWithComplexBranchNames() { assertThat(featureBuild.getAction(ReferenceBuild.class)).isNotNull() .hasOwner(featureBuild) - .hasReferenceBuildId(masterBuild.getExternalizableId()) - .hasReferenceBuild(Optional.of(masterBuild)); + .hasReferenceBuildId(mainBuild.getExternalizableId()) + .hasReferenceBuild(Optional.of(mainBuild)); } /** @@ -331,20 +498,20 @@ void shouldFindCorrectBuildForMultibranchPipelineWithComplexBranchNames() { **/ @Test - void shouldHandleExtraCommitsAfterBranchPointOnMaster() { + void shouldHandleExtraCommitsAfterBranchPointOnMain() { WorkflowMultiBranchProject project = initializeGitAndMultiBranchProject(); buildProject(project); - WorkflowRun masterBuild = verifyMasterBuild(project, 1); - verifyRecordSize(masterBuild, 2); + WorkflowRun mainBuild = verifyMainBuild(project, 1); + verifyRecordSize(mainBuild, 2); String initialMain = getHead(); String featureCommit = createFeatureBranchAndAddCommits(); String mainCommit = addAdditionalFileTo(MAIN); - buildAgain(masterBuild.getParent()); - WorkflowRun nextMaster = verifyMasterBuild(project, 2); + buildAgain(mainBuild.getParent()); + WorkflowRun nextMaster = verifyMainBuild(project, 2); verifyRecordSize(nextMaster, 1); buildProject(project); @@ -353,8 +520,8 @@ void shouldHandleExtraCommitsAfterBranchPointOnMaster() { assertThat(featureBuild.getAction(ReferenceBuild.class)).isNotNull() .hasOwner(featureBuild) - .hasReferenceBuildId(masterBuild.getExternalizableId()) - .hasReferenceBuild(Optional.of(masterBuild)) + .hasReferenceBuildId(mainBuild.getExternalizableId()) + .hasReferenceBuild(Optional.of(mainBuild)) .hasMessages(MULTI_BRANCH_PROJECT, MAIN_IS_TARGET, String.format("-> detected 3 commits in current branch (last one: '%s')", DECORATOR.asText(featureCommit)), @@ -372,7 +539,7 @@ void shouldHandleExtraCommitsAfterBranchPointOnMaster() { } /** - * Checks if the reference build is found even if the reference build has commits that the feature build does not. + * Checks if the reference build is found even if the reference build contains commits that the feature build does not. * This also checks the algorithm if the config {@code skipUnknownCommits} is disabled. * *@@ -387,8 +554,8 @@ void shouldFindBuildWithMultipleCommitsInReferenceBuild() throws IOException { WorkflowMultiBranchProject project = initializeGitAndMultiBranchProject(); buildProject(project); - WorkflowRun masterBuild = verifyMasterBuild(project, 1); - verifyRecordSize(masterBuild, 2); + WorkflowRun mainBuild = verifyMainBuild(project, 1); + verifyRecordSize(mainBuild, 2); addAdditionalFileTo(MAIN); @@ -397,7 +564,7 @@ void shouldFindBuildWithMultipleCommitsInReferenceBuild() throws IOException { String mainCommit = changeContentOfAdditionalFile(MAIN, CHANGED_CONTENT); buildProject(project); - WorkflowRun nextMaster = verifyMasterBuild(project, 2); + WorkflowRun nextMaster = verifyMainBuild(project, 2); verifyRecordSize(nextMaster, 2); WorkflowRun firstFeature = verifyFeatureBuild(project, 1); @@ -451,8 +618,8 @@ void shouldSkipBuildWithUnknownBuildsEnabled() { WorkflowMultiBranchProject project = initializeGitAndMultiBranchProject(); buildProject(project); - WorkflowRun masterBuild = verifyMasterBuild(project, 1); - verifyRecordSize(masterBuild, 2); + WorkflowRun mainBuild = verifyMainBuild(project, 1); + verifyRecordSize(mainBuild, 2); String firstMainCommit = getHead(); @@ -462,9 +629,9 @@ void shouldSkipBuildWithUnknownBuildsEnabled() { String mainCommit = changeContentOfAdditionalFile(MAIN, CHANGED_CONTENT); - buildAgain(masterBuild.getParent()); + buildAgain(mainBuild.getParent()); - WorkflowRun nextMaster = verifyMasterBuild(project, 2); + WorkflowRun nextMaster = verifyMainBuild(project, 2); verifyRecordSize(nextMaster, 2); buildProject(project); @@ -473,8 +640,8 @@ void shouldSkipBuildWithUnknownBuildsEnabled() { assertThat(featureBuild.getAction(ReferenceBuild.class)).isNotNull() .hasOwner(featureBuild) - .hasReferenceBuildId(masterBuild.getExternalizableId()) - .hasReferenceBuild(Optional.of(masterBuild)) + .hasReferenceBuildId(mainBuild.getExternalizableId()) + .hasReferenceBuild(Optional.of(mainBuild)) .hasMessages(MULTI_BRANCH_PROJECT, MAIN_IS_TARGET, String.format("-> detected 4 commits in current branch (last one: '%s')", DECORATOR.asText(featureCommit)), @@ -500,8 +667,8 @@ void shouldNotFindBuildWithInsufficientMaxCommitsForMultibranchPipeline() { WorkflowMultiBranchProject project = initializeGitAndMultiBranchProject(); buildProject(project); - WorkflowRun masterBuild = verifyMasterBuild(project, 1); - verifyRecordSize(masterBuild, 2); + WorkflowRun mainBuild = verifyMainBuild(project, 1); + verifyRecordSize(mainBuild, 2); createFeatureBranchAndAddCommits("maxCommits: 1"); @@ -509,8 +676,8 @@ void shouldNotFindBuildWithInsufficientMaxCommitsForMultibranchPipeline() { String mainHead = changeContentOfAdditionalFile(MAIN, CHANGED_CONTENT); - buildAgain(masterBuild.getParent()); - WorkflowRun additionalMaster = verifyMasterBuild(project, 2); + buildAgain(mainBuild.getParent()); + WorkflowRun additionalMaster = verifyMainBuild(project, 2); verifyRecordSize(additionalMaster, 1); buildProject(project); @@ -545,13 +712,13 @@ void shouldUseNewestBuildIfNewestBuildIfNotFoundIsEnabled() { WorkflowMultiBranchProject project = initializeGitAndMultiBranchProject(); buildProject(project); - WorkflowRun masterBuild = verifyMasterBuild(project, 1); - verifyRecordSize(masterBuild, 2); + WorkflowRun mainBuild = verifyMainBuild(project, 1); + verifyRecordSize(mainBuild, 2); addAdditionalFileTo(MAIN); buildProject(project); - WorkflowRun nextMaster = verifyMasterBuild(project, 2); + WorkflowRun nextMaster = verifyMainBuild(project, 2); verifyRecordSize(nextMaster, 1); createFeatureBranchAndAddCommits("maxCommits: 2", "latestBuildIfNotFound: true"); @@ -592,8 +759,8 @@ void shouldFindMasterReferenceIfBranchIsCheckedOutFromAnotherFeatureBranch() { WorkflowMultiBranchProject project = initializeGitAndMultiBranchProject(); buildProject(project); - WorkflowRun masterBuild = verifyMasterBuild(project, 1); - verifyRecordSize(masterBuild, 2); + WorkflowRun mainBuild = verifyMainBuild(project, 1); + verifyRecordSize(mainBuild, 2); createFeatureBranchAndAddCommits(); @@ -602,8 +769,8 @@ void shouldFindMasterReferenceIfBranchIsCheckedOutFromAnotherFeatureBranch() { verifyRecordSize(featureBuild, 3); assertThat(featureBuild.getAction(ReferenceBuild.class)).isNotNull() .hasOwner(featureBuild) - .hasReferenceBuildId(masterBuild.getExternalizableId()) - .hasReferenceBuild(Optional.of(masterBuild)); + .hasReferenceBuildId(mainBuild.getExternalizableId()) + .hasReferenceBuild(Optional.of(mainBuild)); checkoutNewBranch("feature2"); addAdditionalFileTo("feature2"); @@ -614,8 +781,8 @@ void shouldFindMasterReferenceIfBranchIsCheckedOutFromAnotherFeatureBranch() { assertThat(anotherBranch.getAction(ReferenceBuild.class)).isNotNull() .hasOwner(anotherBranch) - .hasReferenceBuildId(masterBuild.getExternalizableId()) - .hasReferenceBuild(Optional.of(masterBuild)); + .hasReferenceBuildId(mainBuild.getExternalizableId()) + .hasReferenceBuild(Optional.of(mainBuild)); } /** @@ -633,7 +800,7 @@ void shouldNotFindIntersectionIfBuildWasDeleted() { WorkflowMultiBranchProject project = initializeGitAndMultiBranchProject(); buildProject(project); - WorkflowRun toDelete = verifyMasterBuild(project, 1); + WorkflowRun toDelete = verifyMainBuild(project, 1); verifyRecordSize(toDelete, 2); String toDeleteId = toDelete.getExternalizableId(); @@ -644,7 +811,7 @@ void shouldNotFindIntersectionIfBuildWasDeleted() { addAdditionalFileTo(MAIN); WorkflowRun nextMaster = buildAgain(toDelete.getParent()); - verifyMasterBuild(project, 2); + verifyMainBuild(project, 2); verifyRecordSize(nextMaster, 1); // Now delete Build before the feature branch is build. @@ -675,7 +842,7 @@ void shouldTakeNewestMasterBuildIfBuildWasDeletedAndNewestBuildIfNotFoundIsEnabl WorkflowMultiBranchProject project = initializeGitAndMultiBranchProject(); buildProject(project); - WorkflowRun toDelete = verifyMasterBuild(project, 1); + WorkflowRun toDelete = verifyMainBuild(project, 1); verifyRecordSize(toDelete, 2); String toDeleteId = toDelete.getExternalizableId(); @@ -690,7 +857,7 @@ void shouldTakeNewestMasterBuildIfBuildWasDeletedAndNewestBuildIfNotFoundIsEnabl addAdditionalFileTo(MAIN); buildProject(project); - WorkflowRun nextMaster = verifyMasterBuild(project, 2); + WorkflowRun nextMaster = verifyMainBuild(project, 2); verifyRecordSize(nextMaster, 1); changeContentOfAdditionalFile(FEATURE, CHANGED_CONTENT); @@ -770,7 +937,7 @@ private void delete(final String toDeleteId) { } } - private WorkflowRun verifyMasterBuild(final WorkflowMultiBranchProject project, final int buildNumber) { + private WorkflowRun verifyMainBuild(final WorkflowMultiBranchProject project, final int buildNumber) { return verifyBuild(project, buildNumber, GitITest.INITIAL_BRANCH, MAIN + " content"); } diff --git a/plugin/src/test/java/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorderTest.java b/plugin/src/test/java/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorderTest.java deleted file mode 100644 index 2fe65c95..00000000 --- a/plugin/src/test/java/io/jenkins/plugins/forensics/git/reference/GitReferenceRecorderTest.java +++ /dev/null @@ -1,71 +0,0 @@ -package io.jenkins.plugins.forensics.git.reference; - -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -import hudson.model.BuildableItem; -import hudson.model.FreeStyleProject; -import hudson.model.Item; -import hudson.util.ComboBoxModel; -import hudson.util.FormValidation; - -import io.jenkins.plugins.forensics.git.reference.GitReferenceRecorder.Descriptor; -import io.jenkins.plugins.util.JenkinsFacade; - -import static io.jenkins.plugins.forensics.git.assertions.Assertions.*; -import static org.mockito.Mockito.*; - -/** - * Tests the class {@link GitReferenceRecorder}. - * - * @author Ullrich Hafner - */ -class GitReferenceRecorderTest { - private static final String JOB_NAME = "reference"; - private static final FormValidation ERROR = FormValidation.error("error"); - private static final FormValidation OK = FormValidation.ok(); - - @Nested - class DescriptorTest { - @Test - void shouldValidateJobName() { - GitReferenceJobModelValidation model = mock(GitReferenceJobModelValidation.class); - when(model.validateJob(JOB_NAME)).thenReturn(ERROR, OK); - - JenkinsFacade jenkins = mock(JenkinsFacade.class); - - Descriptor descriptor = new Descriptor(jenkins, model); - - FreeStyleProject project = mock(FreeStyleProject.class); - assertThat(descriptor.doCheckReferenceJob((BuildableItem) project, JOB_NAME)).isEqualTo(OK); - verifyNoInteractions(model); - - // Now enable permission - when(jenkins.hasPermission(Item.CONFIGURE, (BuildableItem)project)).thenReturn(true); - // first call stub returns ERROR - assertThat(descriptor.doCheckReferenceJob((BuildableItem) project, JOB_NAME)).isEqualTo(ERROR); - // second call stub returns ERROR - assertThat(descriptor.doCheckReferenceJob((BuildableItem) project, JOB_NAME)).isEqualTo(OK); - } - - @Test - void shouldFillModel() { - GitReferenceJobModelValidation model = mock(GitReferenceJobModelValidation.class); - ComboBoxModel jobs = new ComboBoxModel(); - jobs.add("A Job"); - when(model.getAllJobs()).thenReturn(jobs); - - JenkinsFacade jenkins = mock(JenkinsFacade.class); - - Descriptor descriptor = new Descriptor(jenkins, model); - - FreeStyleProject project = mock(FreeStyleProject.class); - assertThat(descriptor.doFillReferenceJobItems((BuildableItem) project)).isEqualTo(new ComboBoxModel()); - verifyNoInteractions(model); - - // Now enable permission - when(jenkins.hasPermission(Item.CONFIGURE, (BuildableItem)project)).thenReturn(true); - assertThat(descriptor.doFillReferenceJobItems((BuildableItem) project)).isEqualTo(jobs); - } - } -}