From 213f002842ff35312ae7dd43cef662537a731f22 Mon Sep 17 00:00:00 2001 From: Maarten Tijhof Date: Fri, 29 Mar 2019 09:35:12 +0100 Subject: [PATCH 1/2] Added new post conditions, as per the manual at https://jenkins.io/doc/book/pipeline/syntax/#post. Additions in pipeline-model-definition v1.3.7, see JENKINS-41060 and JENKINS-41239. --- Jenkinsfile | 20 +++++++++++++++++++ .../testSupport/PipelineTestHelper.groovy | 17 +++++++++++++++- ...radle_validate_false_gradle_build test.txt | 7 +++++++ ...d_Run_Gradle_validate_null_gradle_null.txt | 7 +++++++ ...d_Run_Gradle_validate_true_gradle_test.txt | 7 +++++++ 5 files changed, 57 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 93414b8..7d45ef5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -107,5 +107,25 @@ pipeline { unstable { echo 'pipeline unit tests have gone UNSTABLE' } + + fixed { + echo 'pipeline unit tests are FIXED' + } + + regression { + echo 'pipeline unit tests were SUCCESSFUL, but are now FAILED, UNSTABLE or ABORTED' + } + + aborted { + echo 'pipeline unit tests are ABORTED' + } + + unsuccessful { + echo 'pipeline unit tests have not PASSED' + } + + cleanup { + echo 'This is where cleanup is done' + } } } \ No newline at end of file diff --git a/pipelineTests/groovy/testSupport/PipelineTestHelper.groovy b/pipelineTests/groovy/testSupport/PipelineTestHelper.groovy index 0b10afe..603eb58 100644 --- a/pipelineTests/groovy/testSupport/PipelineTestHelper.groovy +++ b/pipelineTests/groovy/testSupport/PipelineTestHelper.groovy @@ -187,12 +187,22 @@ class PipelineTestHelper extends BasePipelineTest { switch (section) { case 'always': case 'changed': // How to handle changed? It may happen so just run it.. + case 'cleanup': return c.call() break case 'success': + case 'fixed': if(currentBuild.result == 'SUCCESS') { return c.call() } else { println "post ${section} skipped as not SUCCESS"; return null} break + case 'regression': + if(currentBuild.result == 'UNSTABLE' || + currentBuild.result == 'FAILURE' || + currentBuild.result == 'ABORTED') { return c.call() } + else { println "post ${section} skipped as not UNSTABLE, FAILURE or ABORTED"; return null} + case 'unsuccessful': + if(currentBuild.result != 'SUCCESS') { return c.call() } + else { println "post ${section} skipped as SUCCESS"; return null} case 'unstable': if(currentBuild.result == 'UNSTABLE') { return c.call() } else { println "post ${section} skipped as SUCCESS"; return null} @@ -212,9 +222,14 @@ class PipelineTestHelper extends BasePipelineTest { } helper.registerAllowedMethod('always', [Closure.class], postResultEmulator.curry('always')) helper.registerAllowedMethod('changed', [Closure.class], postResultEmulator.curry('changed')) + helper.registerAllowedMethod('fixed', [Closure.class], postResultEmulator.curry('fixed')) + helper.registerAllowedMethod('regression', [Closure.class], postResultEmulator.curry('regression')) + helper.registerAllowedMethod('aborted', [Closure.class], postResultEmulator.curry('aborted')) + helper.registerAllowedMethod('failure', [Closure.class], postResultEmulator.curry('failure')) helper.registerAllowedMethod('success', [Closure.class], postResultEmulator.curry('success')) helper.registerAllowedMethod('unstable', [Closure.class], postResultEmulator.curry('unstable')) - helper.registerAllowedMethod('failure', [Closure.class], postResultEmulator.curry('failure')) + helper.registerAllowedMethod('unsuccessful', [Closure.class], postResultEmulator.curry('unsuccessful')) + helper.registerAllowedMethod('cleanup', [Closure.class], postResultEmulator.curry('cleanup')) } /** diff --git a/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_false_gradle_build test.txt b/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_false_gradle_build test.txt index e2a891a..1336e38 100644 --- a/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_false_gradle_build test.txt +++ b/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_false_gradle_build test.txt @@ -36,3 +36,10 @@ Jenkinsfile.changed(groovy.lang.Closure) Jenkinsfile.echo(pipeline unit tests results have CHANGED) Jenkinsfile.unstable(groovy.lang.Closure) + Jenkinsfile.fixed(groovy.lang.Closure) + Jenkinsfile.echo(pipeline unit tests are FIXED) + Jenkinsfile.regression(groovy.lang.Closure) + Jenkinsfile.aborted(groovy.lang.Closure) + Jenkinsfile.unsuccessful(groovy.lang.Closure) + Jenkinsfile.cleanup(groovy.lang.Closure) + Jenkinsfile.echo(This is where cleanup is done) diff --git a/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_null_gradle_null.txt b/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_null_gradle_null.txt index 59f77c6..1d7a86b 100644 --- a/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_null_gradle_null.txt +++ b/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_null_gradle_null.txt @@ -41,3 +41,10 @@ Jenkinsfile.changed(groovy.lang.Closure) Jenkinsfile.echo(pipeline unit tests results have CHANGED) Jenkinsfile.unstable(groovy.lang.Closure) + Jenkinsfile.fixed(groovy.lang.Closure) + Jenkinsfile.echo(pipeline unit tests are FIXED) + Jenkinsfile.regression(groovy.lang.Closure) + Jenkinsfile.aborted(groovy.lang.Closure) + Jenkinsfile.unsuccessful(groovy.lang.Closure) + Jenkinsfile.cleanup(groovy.lang.Closure) + Jenkinsfile.echo(This is where cleanup is done) diff --git a/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_true_gradle_test.txt b/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_true_gradle_test.txt index 243c803..4df2877 100644 --- a/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_true_gradle_test.txt +++ b/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_true_gradle_test.txt @@ -41,3 +41,10 @@ Jenkinsfile.changed(groovy.lang.Closure) Jenkinsfile.echo(pipeline unit tests results have CHANGED) Jenkinsfile.unstable(groovy.lang.Closure) + Jenkinsfile.fixed(groovy.lang.Closure) + Jenkinsfile.echo(pipeline unit tests are FIXED) + Jenkinsfile.regression(groovy.lang.Closure) + Jenkinsfile.aborted(groovy.lang.Closure) + Jenkinsfile.unsuccessful(groovy.lang.Closure) + Jenkinsfile.cleanup(groovy.lang.Closure) + Jenkinsfile.echo(This is where cleanup is done) From 4dabdb6c1e1d3be776937d75a143c8872ea1fcac Mon Sep 17 00:00:00 2001 From: Maarten Tijhof Date: Mon, 1 Apr 2019 10:43:05 +0200 Subject: [PATCH 2/2] Added previous build result (SUCCESS) to environment. Expanded tests for new post conditions. --- .../testSupport/PipelineTestHelper.groovy | 28 ++++++++++++++----- ...radle_validate_false_gradle_build test.txt | 2 -- ...d_Run_Gradle_validate_null_gradle_null.txt | 2 -- ...d_Run_Gradle_validate_true_gradle_test.txt | 2 -- .../tests/job/JenkinsfileTestSpec.groovy | 20 +++++++++---- 5 files changed, 35 insertions(+), 19 deletions(-) diff --git a/pipelineTests/groovy/testSupport/PipelineTestHelper.groovy b/pipelineTests/groovy/testSupport/PipelineTestHelper.groovy index 603eb58..606d556 100644 --- a/pipelineTests/groovy/testSupport/PipelineTestHelper.groovy +++ b/pipelineTests/groovy/testSupport/PipelineTestHelper.groovy @@ -183,26 +183,38 @@ class PipelineTestHelper extends BasePipelineTest { def postResultEmulator = { String section, Closure c -> def currentBuild = binding.getVariable('currentBuild') + def previousBuild = binding.getVariable('currentBuild').previousBuild switch (section) { case 'always': - case 'changed': // How to handle changed? It may happen so just run it.. case 'cleanup': return c.call() break - case 'success': + case 'changed': + if(currentBuild.result != previousBuild.result) { return c.call() } + else { println "post ${section} skipped as not CHANGED"; return null} + break case 'fixed': + if(currentBuild.result == 'SUCCESS' && + (previousBuild.result == 'FAILED' || + previousBuild.result == 'UNSTABLE')) { return c.call() } + else { println "post ${section} skipped as not FIXED"; return null} + break + case 'success': if(currentBuild.result == 'SUCCESS') { return c.call() } else { println "post ${section} skipped as not SUCCESS"; return null} break case 'regression': - if(currentBuild.result == 'UNSTABLE' || - currentBuild.result == 'FAILURE' || - currentBuild.result == 'ABORTED') { return c.call() } - else { println "post ${section} skipped as not UNSTABLE, FAILURE or ABORTED"; return null} + if(previousBuild.result == 'SUCCESS' && + (currentBuild.result == 'UNSTABLE' || + currentBuild.result == 'FAILURE' || + currentBuild.result == 'ABORTED')) { return c.call() } + else { println "post ${section} skipped as not UNSTABLE, FAILURE or ABORTED after SUCCESS"; return null} + break case 'unsuccessful': if(currentBuild.result != 'SUCCESS') { return c.call() } else { println "post ${section} skipped as SUCCESS"; return null} + break case 'unstable': if(currentBuild.result == 'UNSTABLE') { return c.call() } else { println "post ${section} skipped as SUCCESS"; return null} @@ -287,8 +299,10 @@ class PipelineTestHelper extends BasePipelineTest { /** * The currentBuild in the job + * Includes a previous build which finished successfully */ - binding.setVariable('currentBuild', new Expando(result: 'SUCCESS', displayName: 'Build #1234')) + def previous = new Expando(result: 'SUCCESS', displayName: 'Build #1233') + binding.setVariable('currentBuild', new Expando(result: 'SUCCESS', displayName: 'Build #1234', previousBuild: previous)) /** * agent any diff --git a/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_false_gradle_build test.txt b/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_false_gradle_build test.txt index 1336e38..772fd55 100644 --- a/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_false_gradle_build test.txt +++ b/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_false_gradle_build test.txt @@ -34,10 +34,8 @@ Jenkinsfile.echo(pipeline unit tests PASSED) Jenkinsfile.failure(groovy.lang.Closure) Jenkinsfile.changed(groovy.lang.Closure) - Jenkinsfile.echo(pipeline unit tests results have CHANGED) Jenkinsfile.unstable(groovy.lang.Closure) Jenkinsfile.fixed(groovy.lang.Closure) - Jenkinsfile.echo(pipeline unit tests are FIXED) Jenkinsfile.regression(groovy.lang.Closure) Jenkinsfile.aborted(groovy.lang.Closure) Jenkinsfile.unsuccessful(groovy.lang.Closure) diff --git a/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_null_gradle_null.txt b/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_null_gradle_null.txt index 1d7a86b..3827dfa 100644 --- a/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_null_gradle_null.txt +++ b/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_null_gradle_null.txt @@ -39,10 +39,8 @@ Jenkinsfile.echo(pipeline unit tests PASSED) Jenkinsfile.failure(groovy.lang.Closure) Jenkinsfile.changed(groovy.lang.Closure) - Jenkinsfile.echo(pipeline unit tests results have CHANGED) Jenkinsfile.unstable(groovy.lang.Closure) Jenkinsfile.fixed(groovy.lang.Closure) - Jenkinsfile.echo(pipeline unit tests are FIXED) Jenkinsfile.regression(groovy.lang.Closure) Jenkinsfile.aborted(groovy.lang.Closure) Jenkinsfile.unsuccessful(groovy.lang.Closure) diff --git a/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_true_gradle_test.txt b/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_true_gradle_test.txt index 4df2877..82d1ad7 100644 --- a/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_true_gradle_test.txt +++ b/pipelineTests/groovy/tests/callstacks/JenkinsfileTestSpec_Jenkinsfile_Should_Run_Gradle_validate_true_gradle_test.txt @@ -39,10 +39,8 @@ Jenkinsfile.echo(pipeline unit tests PASSED) Jenkinsfile.failure(groovy.lang.Closure) Jenkinsfile.changed(groovy.lang.Closure) - Jenkinsfile.echo(pipeline unit tests results have CHANGED) Jenkinsfile.unstable(groovy.lang.Closure) Jenkinsfile.fixed(groovy.lang.Closure) - Jenkinsfile.echo(pipeline unit tests are FIXED) Jenkinsfile.regression(groovy.lang.Closure) Jenkinsfile.aborted(groovy.lang.Closure) Jenkinsfile.unsuccessful(groovy.lang.Closure) diff --git a/pipelineTests/groovy/tests/job/JenkinsfileTestSpec.groovy b/pipelineTests/groovy/tests/job/JenkinsfileTestSpec.groovy index 9961987..6336a00 100644 --- a/pipelineTests/groovy/tests/job/JenkinsfileTestSpec.groovy +++ b/pipelineTests/groovy/tests/job/JenkinsfileTestSpec.groovy @@ -86,7 +86,7 @@ class JenkinsfileTestSpec extends PipelineSpockTestBase { } @Unroll - def "Jenkinsfile cover all build results for post sections - #RESULT"() { + def "Jenkinsfile cover all build results for post sections - #SCENARIO"() { given: helper.registerAllowedMethod('validateDeclarativePipeline', [String.class], { true } ) @@ -97,6 +97,7 @@ class JenkinsfileTestSpec extends PipelineSpockTestBase { and: binding.getVariable('currentBuild').result = RESULT + binding.getVariable('currentBuild').previousBuild.result = PREVIOUS when: runScript('Jenkinsfile') @@ -105,10 +106,17 @@ class JenkinsfileTestSpec extends PipelineSpockTestBase { printCallStack() where: - RESULT | NONE - 'SUCCESS' | _ - 'FAILURE' | _ - 'ABORTED' | _ - 'UNSTABLE' | _ + RESULT | PREVIOUS | SCENARIO + 'SUCCESS' | 'SUCCESS' | 'SUCCESS' + 'FAILURE' | 'SUCCESS' | 'REGRESSION FAILURE' + 'UNSTABLE' | 'SUCCESS' | 'REGRESSION UNSTABLE' + 'ABORTED' | 'SUCCESS' | 'REGRESSION ABORTED' + 'FAILURE' | 'FAILURE' | 'FAILURE' + 'FAILURE' | 'UNSTABLE' | 'CHANGED' + 'ABORTED' | 'ABORTED' | 'ABORTED' + 'UNSTABLE' | 'UNSTABLE' | 'UNSTABLE' + 'SUCCESS' | 'UNSTABLE' | 'FIXED UNSTABLE' + 'SUCCESS' | 'FAILED' | 'FIXED FAILED' + 'FAILURE' | 'ABORTED' | 'UNSUCCESSFUL' } }