0

We have been stuck with this problem for a week now though we have been working with pipelines for past few months. Our goal is to spin-up as many containers as many feature files in our cucumber test suite and run those tests in parallel (one per container). Here is the error we are getting with the pipeline code below:

java.lang.UnsupportedOperationException: Calling public static java.util.List org.codehaus.groovy.runtime.DefaultGroovyMethods.each(java.util.List,groovy.lang.Closure) on a CPS-transformed closure is not yet supported (JENKINS-26481); encapsulate in a @NonCPS method, or use Java-style loops

pipeline code:

def cucumberTestImage
pipeline {
    agent any
    options {
         echo "options stuff"
    }

  stages {
    stage('Build & Deploy'){
            steps {
        parallel (
                SPA: {
            script {
                  echo "deploying SPA app"
                }
              }
            } 
                    echo 'SPA JOB COMPLETED!!'
          },
          Tests: {
            script {
              }    
              //building docker image name cucumberTestImage

            }
          }
        )
      }
    }

     stage('Test') {
     steps {
         script {    
            def tests = [:]
            getFeatures().each {stage -> tests[stage] = {
                    cucumberTestImage.inside{sh "echo ${stage}"}
                }}
            parallel tests;
        }
     }
    }

  }
}

@NonCPS
def getFeatures() {
            return sh(script: 'cd testfolder && find features -type f -name \'*.feature\'', returnStdout: true).tokenize()
    }
Cœur
  • 37,241
  • 25
  • 195
  • 267
Ram
  • 1
  • 1

2 Answers2

0

The error seems to indicate that this block is causing the problem:

getFeatures().each {stage -> tests[stage] = {
                    cucumberTestImage.inside{sh "echo ${stage}"}
                }}

It seems that the each method is not support in the jenkins version you are using, you can change it to the following:

def features = getFeatures()
for(def stage: features) {
   tests[stage] = {cucumberTestImage.inside{sh "echo ${stage}"}}}
}

Alternatively, you may want to upgrade jenkins as the stated jenkins issue JENKINS-26481 is resolved.

yamenk
  • 46,736
  • 10
  • 93
  • 87
  • Thanks for the quick response. it did resolved the error, however the stage value inside the Image.Inside block is retaining the final value from the list so when parallel statement kicks in the output shows all the echo statements with the final value from the list! this seems like docker specific issue? – Ram Nov 17 '17 at 18:50
  • @Ram I don't think the problem is docker related. This is a jenkins pipeline issue. You may want to give https://stackoverflow.com/questions/40195720/how-to-print-each-element-of-multi-line-string-parameter a shot. Also try to disable pipeline sandbox. – yamenk Nov 17 '17 at 18:59
0

As my original issue is resolved and i was able to run the jenkins pipeline twice successfully, all of sudden the other issue popped-up without any code change done by me.. weird!! The issue is that variable inside the dockerimage.inside block holds the same value for all parallel runs. .I don't know why its happening.. it doesn't make any sense. The below code is in question!

stage('Test') {
     steps {
         script {    
            def tests = [:]
            def features = getFeatures()
            for(def stage: features) {
               tests[stage] = {cucumberTestImage.inside{
                   sh "echo running test --- ${stage}"
                   //sh "cd /app && ./bin/cucumber ${stage}"
               }}}
             parallel tests;
        }
     }
    }

def getFeatures() {
            return sh(script: 'cd frameworkfolder && find features -type f -name \'*.feature\'', returnStdout: true).tokenize()
    }
Ram
  • 1
  • 1