github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/test/groovy/templates/PiperPipelineTest.groovy (about)

     1  package templates
     2  
     3  import org.junit.Before
     4  import org.junit.Rule
     5  import org.junit.Test
     6  import org.junit.rules.RuleChain
     7  import util.BasePiperTest
     8  import util.JenkinsReadYamlRule
     9  import util.JenkinsStepRule
    10  import util.PipelineWhenException
    11  import util.Rules
    12  
    13  import static org.hamcrest.Matchers.*
    14  import static org.junit.Assert.assertThat
    15  
    16  class PiperPipelineTest extends BasePiperTest {
    17      private JenkinsStepRule jsr = new JenkinsStepRule(this)
    18  
    19      @Rule
    20      public RuleChain rules = Rules
    21          .getCommonRules(this)
    22          .around(new JenkinsReadYamlRule(this))
    23          .around(jsr)
    24  
    25      private skipDefaultCheckout = false
    26      private timestamps = false
    27      private stagesExecuted = []
    28      private stepsCalled = []
    29  
    30      @Before
    31      void init() {
    32  
    33          helper.registerAllowedMethod('library', [String.class], null)
    34  
    35          helper.registerAllowedMethod('pipeline', [Closure.class], null)
    36  
    37          helper.registerAllowedMethod('agent', [Closure.class], null)
    38          binding.setVariable('any', {})
    39          binding.setVariable('none', {})
    40  
    41          helper.registerAllowedMethod('options', [Closure.class], null)
    42  
    43          helper.registerAllowedMethod('skipDefaultCheckout', [], {skipDefaultCheckout = true})
    44          helper.registerAllowedMethod('timestamps', [], {timestamps = true})
    45  
    46          helper.registerAllowedMethod('triggers', [Closure.class], null)
    47          helper.registerAllowedMethod('issueCommentTrigger', [String.class], { s ->
    48              assertThat(s, is('.*/piper ([a-z]*).*'))
    49          })
    50  
    51          helper.registerAllowedMethod('stages', [Closure.class], null)
    52  
    53          helper.registerAllowedMethod('stage', [String.class, Closure.class], {stageName, body ->
    54  
    55              def stageResult
    56  
    57              binding.variables.env.STAGE_NAME = stageName
    58  
    59              helper.registerAllowedMethod('when', [Closure.class], {cWhen ->
    60  
    61                  helper.registerAllowedMethod('allOf', [Closure.class], {cAllOf ->
    62                      def branchResult = false
    63                      helper.registerAllowedMethod('branch', [String.class], {branchName  ->
    64                          if (!branchResult)
    65                              branchResult = (branchName == env.BRANCH_NAME)
    66                          if( !branchResult) {
    67                              throw new PipelineWhenException("Stage '${stageName}' skipped - expression: '${branchResult}'")
    68                          }
    69                      })
    70                      helper.registerAllowedMethod('expression', [Closure.class], { Closure cExp ->
    71                          def result = cExp()
    72                          if(!result) {
    73                              throw new PipelineWhenException("Stage '${stageName}' skipped - expression: '${result}'")
    74                          }
    75                          return result
    76                      })
    77                      return cAllOf()
    78                  })
    79  
    80                  helper.registerAllowedMethod('anyOf', [Closure.class], {cAnyOf ->
    81                      def result = false
    82                      helper.registerAllowedMethod('branch', [String.class], {branchName  ->
    83                          if (!result)
    84                              result = (branchName == env.BRANCH_NAME)
    85                          return result
    86                      })
    87                      helper.registerAllowedMethod('expression', [Closure.class], { Closure cExp ->
    88                          if (!result)
    89                              result = cExp()
    90                          return result
    91                      })
    92                      cAnyOf()
    93                      if(!result) {
    94                          throw new PipelineWhenException("Stage '${stageName}' skipped - anyOf: '${result}'")
    95                      }
    96                      return cAnyOf()
    97                  })
    98  
    99                  helper.registerAllowedMethod('branch', [String.class], {branchName  ->
   100                      def result =  (branchName == env.BRANCH_NAME)
   101                      if(result == false) {
   102                          throw new PipelineWhenException("Stage '${stageName}' skipped - expected branch: '${branchName}' while current branch: '${env.BRANCH_NAME}'")
   103                      }
   104                      return result
   105                  })
   106  
   107                  helper.registerAllowedMethod('expression', [Closure.class], { Closure cExp ->
   108                      def result = cExp()
   109                      if(!result) {
   110                          throw new PipelineWhenException("Stage '${stageName}' skipped - expression: '${result}'")
   111                      }
   112                      return result
   113                  })
   114                  return cWhen()
   115              })
   116  
   117              // Stage is not executed if build fails or aborts
   118              def status = currentBuild.result
   119              switch (status) {
   120                  case 'FAILURE':
   121                  case 'ABORTED':
   122                      break
   123                  default:
   124                      try {
   125                          stageResult = body()
   126                          stagesExecuted.add(stageName)
   127                      }
   128                      catch (PipelineWhenException pwe) {
   129                          //skip stage due to not met when expression
   130                      }
   131                      catch (Exception e) {
   132                          throw e
   133                      }
   134              }
   135              return stageResult
   136          })
   137  
   138          helper.registerAllowedMethod('steps', [Closure], null)
   139          helper.registerAllowedMethod('post', [Closure], {c -> c()})
   140          helper.registerAllowedMethod('success', [Closure], {c -> c()})
   141          helper.registerAllowedMethod('failure', [Closure], {c -> c()})
   142          helper.registerAllowedMethod('aborted', [Closure], {c -> c()})
   143          helper.registerAllowedMethod('unstable', [Closure], {c -> c()})
   144          helper.registerAllowedMethod('cleanup', [Closure], {c -> c()})
   145  
   146          helper.registerAllowedMethod('input', [Map], {m -> return null})
   147  
   148          helper.registerAllowedMethod('influxWriteData', [Map], {m ->
   149              assertThat(m.wrapInNode, is(true))
   150          })
   151          helper.registerAllowedMethod('mailSendNotification', [Map], {m ->
   152              assertThat(m.wrapInNode, is(true))
   153          })
   154  
   155          helper.registerAllowedMethod('piperPipelineStageInit', [Map.class], {m ->
   156              stepsCalled.add('piperPipelineStageInit')
   157          })
   158          helper.registerAllowedMethod('piperPipelineStagePRVoting', [Map.class], {m ->
   159              stepsCalled.add('piperPipelineStagePRVoting')
   160          })
   161          helper.registerAllowedMethod('piperPipelineStageBuild', [Map.class], {m ->
   162              stepsCalled.add('piperPipelineStageBuild')
   163          })
   164          helper.registerAllowedMethod('piperPipelineStageAdditionalUnitTests', [Map.class], {m ->
   165              stepsCalled.add('piperPipelineStageAdditionalUnitTests')
   166          })
   167          helper.registerAllowedMethod('piperPipelineStageIntegration', [Map.class], {m ->
   168              stepsCalled.add('piperPipelineStageIntegration')
   169          })
   170          helper.registerAllowedMethod('piperPipelineStageAcceptance', [Map.class], {m ->
   171              stepsCalled.add('piperPipelineStageAcceptance')
   172          })
   173          helper.registerAllowedMethod('piperPipelineStageSecurity', [Map.class], {m ->
   174              stepsCalled.add('piperPipelineStageSecurity')
   175          })
   176          helper.registerAllowedMethod('piperPipelineStagePerformance', [Map.class], {m ->
   177              stepsCalled.add('piperPipelineStagePerformance')
   178          })
   179          helper.registerAllowedMethod('piperPipelineStageCompliance', [Map.class], {m ->
   180              stepsCalled.add('piperPipelineStageCompliance')
   181          })
   182          helper.registerAllowedMethod('piperPipelineStageConfirm', [Map.class], {m ->
   183              stepsCalled.add('piperPipelineStageConfirm')
   184          })
   185          helper.registerAllowedMethod('piperPipelineStagePromote', [Map.class], {m ->
   186              stepsCalled.add('piperPipelineStagePromote')
   187          })
   188          helper.registerAllowedMethod('piperPipelineStageRelease', [Map.class], {m ->
   189              stepsCalled.add('piperPipelineStageRelease')
   190          })
   191          helper.registerAllowedMethod('piperPipelineStagePost', [Map.class], {m ->
   192              stepsCalled.add('piperPipelineStagePost')
   193          })
   194  
   195          nullScript.prepareDefaultValues(script: nullScript)
   196  
   197      }
   198  
   199      @Test
   200      void testPRVoting() {
   201  
   202          helper.registerAllowedMethod('piperPipelineStageInit', [Map], null)
   203  
   204          binding.variables.env.BRANCH_NAME = 'PR-*'
   205  
   206          nullScript.commonPipelineEnvironment.configuration = [runStage:[Integration:[test: 'test']]]
   207          jsr.step.piperPipeline(script: nullScript)
   208  
   209          assertThat(skipDefaultCheckout, is(true))
   210          assertThat(timestamps, is(true))
   211  
   212          assertThat(stagesExecuted.size(), is(2))
   213          assertThat(stagesExecuted, allOf(hasItem('Init'), hasItem('Pull-Request Voting')))
   214  
   215          assertThat(stepsCalled, hasItem('piperPipelineStagePRVoting'))
   216      }
   217  
   218      @Test
   219      void testConfirmUnstable() {
   220          nullScript.commonPipelineEnvironment.configuration = [
   221              general: [
   222                  manualConfirmation: false
   223              ]
   224          ]
   225          binding.setVariable('currentBuild', [result: 'UNSTABLE'])
   226  
   227          jsr.step.piperPipeline(script: nullScript)
   228  
   229          assertThat(stepsCalled, hasItem('piperPipelineStageConfirm'))
   230  
   231      }
   232  
   233      @Test
   234      void testNoConfirm() {
   235          nullScript.commonPipelineEnvironment.configuration = [
   236              general: [
   237                  manualConfirmation: false
   238              ]
   239          ]
   240          jsr.step.piperPipeline(script: nullScript)
   241  
   242          assertThat(stepsCalled, not(hasItem('piperPipelineStageConfirm')))
   243      }
   244  
   245      @Test
   246      void testMasterPipelineAllOn() {
   247  
   248          nullScript.commonPipelineEnvironment.configuration.runStage = [
   249              Build: true,
   250              'Additional Unit Tests': true,
   251              Integration: true,
   252              Acceptance: true,
   253              Security: true,
   254              Performance: true,
   255              Compliance: true,
   256              Promote: true,
   257              Release: true
   258          ]
   259          jsr.step.piperPipeline(script: nullScript)
   260  
   261          assertThat(stepsCalled, hasItems(
   262              'piperPipelineStageInit',
   263              'piperPipelineStageBuild',
   264              'piperPipelineStageAdditionalUnitTests',
   265              'piperPipelineStageIntegration',
   266              'piperPipelineStageAcceptance',
   267              'piperPipelineStageSecurity',
   268              'piperPipelineStagePerformance',
   269              'piperPipelineStageCompliance',
   270              'piperPipelineStageConfirm',
   271              'piperPipelineStagePromote',
   272              'piperPipelineStageRelease',
   273              'piperPipelineStagePost'
   274          ))
   275      }
   276  }