JenkinsPipelineUnit icon indicating copy to clipboard operation
JenkinsPipelineUnit copied to clipboard

Support to withEnv em file .jenkins

Open AnselmoPfeifer opened this issue 8 years ago • 4 comments

I am using JenkinsPipelineUtil to tests our files de pipeline. I am not having success used withEnv. Is this implementation possible?

AnselmoPfeifer avatar Jul 29 '17 23:07 AnselmoPfeifer

Hi, did you try to mock it?

stchar avatar Jul 31 '17 14:07 stchar

Hi @AnselmoPfeifer I don't know in which context are you using withEnv.

In most cases, the variables you are binding in the scope of the withEnv will be run by a mocked sh or mocked bat, and a simple mock like this will be enough: helper.registerAllowedMethod('env', [List, Closure], null) In this case, env is never really used in the test context. The withEnv step will then be known as an existing step in your pipelines, and you won't get any error when calling this. The closure you pass as parameter in your pipeline will be executed. I would suppose, this change in env variable is used for sh or bat step execution, which are both supposed to be mocked. Then that should be fine.

However, you can go further and use this kind of mock:

// Just in case it has never been set:
binding.setVariable('env', [:])
// 
helper.registerAllowedMethod('withEnv', [List, Closure], { List additionalVariables, Closure closure ->
            // Make a copy of the current environment variables into previousEnv
            def previousEnv = new HashMap(env ?: [:])
            additionalVariables.each { String additionalVariable ->
                // Bind every additionnal variable to the current environment
                int equalsIndex = additionalVariable.indexOf('=')
                String variableName = additionalVariable[0..equalsIndex-1]
                String variableValue = additionalVariable[equalsIndex+1..-1]
                println "binding $variableName to $variableValue"
                env[variableName] = variableValue
            }
            // Executes the closure with the extended environment
            closure()
            // Rollback to the previous environment
            env = previousEnv
        })

Note env is usually an instance of EnvActionImpl but use a map in your pipeline test should work fine.

I hope it helps.

EQuincerot avatar Sep 01 '17 21:09 EQuincerot

Hey, guys, tks for helpers.

To we are work withwithEnv, we created one new helper and implemented on Interceptor:

helper.registerAllowedMethod("withEnv", [List, Closure], withEnvInterceptor)
def withEnvInterceptor = { list, closure ->
        def env = binding.getVariable('env')

        for (String pair : list) {
            int split = pair.indexOf('=')
            if (split !=-1)
                env.put(pair.substring(0, split), pair.substring(split +1))
        }
        binding.setVariable('env', env)
        def res = closure.call()
        return res
    }

anspfeifer avatar Sep 19 '17 14:09 anspfeifer

@anspfeifer can be simplified further:

    def withEnvInterceptor = { list, closure ->
        def env = binding.getVariable('env')
        list.each { pair ->
            def (k, v) = pair.split('=')
            env.put(k, v)
        }
        binding.setVariable('env', env)
        closure.call()
    }

jsok avatar Sep 28 '17 23:09 jsok