Node One
Node One

Reputation: 33

Groovy - readYaml() expecting java.util.LinkedHashMap instead of a file

As a part of our Jenkins solutions, we use Groovy in our pipelines. In one of our groovy file I want to update a docker-stack.yaml.

To do so I'm using readYaml():

stage("Write docker-stack.yaml") {
        def dockerStackYamlToWrite = readFile 'docker-stack.yaml'

        def dockerStackYaml = readYaml file: "docker-stack.yaml"
        def imageOrigin = dockerStackYaml.services[domain].image
        def versionSource = imageOrigin.substring(imageOrigin.lastIndexOf(":") + 1, imageOrigin.length())
        def imageWithNewVersion = imageOrigin.replace(versionSource, imageTag)

        dockerStackYamlToWrite = dockerStackYamlToWrite.replace(imageOrigin, imageWithNewVersion)

        sh "rm docker-stack.yaml"
        writeFile file: "docker-stack.yaml", text: dockerStackYamlToWrite
        sh "git add docker-stack.yaml"
        sh "git commit -m 'promote dockerStack to ${envname}'"
        sh "git push origin ${envname}"
}

I am using test to validate my code:

import org.junit.Before
import org.junit.Test

class TestUpdateVersionInDockerStack extends JenkinsfileBaseTest {

    @Before
    void setUp() throws Exception {
        helper.registerAllowedMethod("build", [Map.class], null)
        helper.registerAllowedMethod("steps", [Object.class], null)

        super.setUp()
    }

    @Test void success() throws Exception {
        def script = loadScript("src/test/jenkins/updateVersionInDockerStack/success.jenkins")
        script.execute()
    }
}

Here is the success.jenkins:

def execute() {
    node() {
        stage("Build") {
            def version = buildVersion()
            updateVersionInDockerStack([
                DOMAIN      : "security-package",
                IMAGE_TAG   : version,
                GITHUB_ORGA : "Bla",
                TARGET_ENV  : "int"
            ])
        }
    }
}

return this

When I run my test I get this message:

groovy.lang.MissingMethodException: No signature of method: updateVersionInDockerStack.readYaml() is applicable for argument types: (java.util.LinkedHashMap) values: [[file:docker-stack.yaml]]

At this point I'm lost. For what I understand from the documentation readYaml() can I a file as an argument.

Can you help to understand why it is expecting a LinkedHashMap? Do you have to convert my value in a LinkedHashMap?

Thank you

Upvotes: 2

Views: 5142

Answers (1)

Szymon Stepniak
Szymon Stepniak

Reputation: 42214

Your pipeline unit test fails, because there is no readYaml method registered in pipeline's allowed methods. In your TestUpdateVersionInDockerStack test class simply add to the setUp method following line:

helper.registerAllowedMethod("readYaml", [Map.class], null)

This will instruct Jenkins pipeline unit environment that the method readYaml that accepts a single argument of type Map is allowed to use in the pipeline and invocation of this method will be registered in the unit test result stack. You can add a method printCallStack() call to your test method to see the stack of all executed steps during the test:

@Test void success() throws Exception {
    def script = loadScript("src/test/jenkins/updateVersionInDockerStack/success.jenkins")
    script.execute()
    printCallStack()
}

Upvotes: 1

Related Questions