我有一个在我的jenkinsfile中使用的类,这里是其简化版本:
class TestBuild { def build(jenkins) { jenkins.script { jenkins.sh(returnStdout: true, script: "echo build") } } }
我提供this的詹金斯在jenkinsfile使用时参数。在这里模拟具有脚本和sh的jenkins对象的最佳方法是什么?谢谢你的帮助
this
前一周我遇到了类似的问题,我想到了:
import org.jenkinsci.plugins.workflow.cps.CpsScript def mockCpsScript() { return [ 'sh': { arg -> def script def returnStdout // depending on sh is called arg is either a map or a string vector with arguments if (arg.length == 1 && arg[0] instanceof Map) { script = arg[0]['script'] returnStdout = arg[0]['returnStdout'] } else { script = arg[0] } println "Calling sh with script: ${script}" }, 'script' : { arg -> arg[0]() }, ] as CpsScript }
并与您的脚本一起使用(以未命名的sh调用扩展):
class TestBuild { def build(jenkins) { jenkins.script { jenkins.sh(returnStdout: true, script: "echo build") jenkins.sh("echo no named arguments") } } } def obj = new TestBuild() obj.build(mockCpsScript())
它输出:
[Pipeline] echo Calling sh with script: echo build [Pipeline] echo Calling sh with script: echo no named arguments
现在,它本身并不是很有用,但是很容易添加定义模拟方法行为的逻辑,例如,此版本根据要读取的目录和文件来控制readFile返回的内容:
import org.jenkinsci.plugins.workflow.cps.CpsScript def mockCpsScript(Map<String, String> readFileMap) { def currentDir = null return [ 'dir' : { arg -> def dir = arg[0] def subClosure = arg[1] if (currentDir != null) { throw new IllegalStateException("Dir '${currentDir}' is already open, trying to open '${dir}'") } currentDir = dir try { subClosure() } finally { currentDir = null } }, 'echo': { arg -> println(arg[0]) }, 'readFile' : { arg -> def file = arg[0] if (currentDir != null) { file = currentDir + '/' + file } def contents = readFileMap[file] if (contents == null) { throw new IllegalStateException("There is no mapped file '${file}'!") } return contents }, 'script' : { arg -> arg[0]() }, ] as CpsScript } class TestBuild { def build(jenkins) { jenkins.script { jenkins.dir ('a') { jenkins.echo(jenkins.readFile('some.file')) } jenkins.echo(jenkins.readFile('another.file')) } } } def obj = new TestBuild() obj.build(mockCpsScript(['a/some.file' : 'Contents of first file', 'another.file' : 'Some other contents']))
输出:
[Pipeline] echo Contents of first file [Pipeline] echo Some other contents
如果需要使用currentBuild或类似的属性,则可以在闭包强制之后分配这些属性:
import org.jenkinsci.plugins.workflow.cps.CpsScript def mockCpsScript() { def jenkins = [ // same as above ] as CpsScript jenkins.currentBuild = [ // Add attributes you need here. E.g. result: result:null, ] return jenkins }