mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-14 11:03:09 +02:00
e954e3b629
* Ensure closure gets called when neither returnStdout nor returnStatus are set In this case we do not have a return value, but in case we execute a closure we should execute the closure. With that it is possible to raise an exception from the closure. * [refactoring] unify usage of unify method call * Remove dead code. Coding after uncondition throw exception statement does not get executed. * Ensure script rule behaves the same whan called with string and with map.
127 lines
3.4 KiB
Groovy
127 lines
3.4 KiB
Groovy
package util
|
|
|
|
import com.lesfurets.jenkins.unit.BasePipelineTest
|
|
import org.junit.rules.TestRule
|
|
import org.junit.runner.Description
|
|
import org.junit.runners.model.Statement
|
|
|
|
class JenkinsShellCallRule implements TestRule {
|
|
|
|
enum Type { PLAIN, REGEX }
|
|
|
|
class Command {
|
|
|
|
final Type type
|
|
final String script
|
|
|
|
Command(Type type, String script) {
|
|
this.type = type
|
|
this.script = script
|
|
}
|
|
|
|
String toString() {
|
|
return "${type} : ${script}"
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return type.hashCode() * script.hashCode()
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
|
|
if (obj == null || !obj instanceof Command) return false
|
|
Command other = (Command) obj
|
|
return type == other.type && script == other.script
|
|
}
|
|
}
|
|
|
|
final BasePipelineTest testInstance
|
|
|
|
List shell = []
|
|
|
|
Map<Command, String> returnValues = [:]
|
|
List<Command> failingCommands = []
|
|
|
|
JenkinsShellCallRule(BasePipelineTest testInstance) {
|
|
this.testInstance = testInstance
|
|
}
|
|
|
|
def setReturnValue(script, value) {
|
|
setReturnValue(Type.PLAIN, script, value)
|
|
}
|
|
|
|
def setReturnValue(type, script, value) {
|
|
returnValues[new Command(type, script)] = value
|
|
}
|
|
|
|
def failExecution(type, script) {
|
|
failingCommands.add(new Command(type, script))
|
|
}
|
|
|
|
def handleShellCall(Map parameters) {
|
|
|
|
def unifiedScript = unify(parameters.script)
|
|
|
|
shell.add(unifiedScript)
|
|
|
|
for (Command failingCommand: failingCommands){
|
|
if(failingCommand.type == Type.REGEX && unifiedScript =~ failingCommand.script) {
|
|
throw new Exception("Script execution failed!")
|
|
} else if(failingCommand.type == Type.PLAIN && unifiedScript.equals(failingCommand.script)) {
|
|
throw new Exception("Script execution failed!")
|
|
}
|
|
}
|
|
|
|
|
|
def result = null
|
|
|
|
for(def e : returnValues.entrySet()) {
|
|
if(e.key.type == Type.REGEX && unifiedScript =~ e.key.script) {
|
|
result = e.value
|
|
break
|
|
} else if(e.key.type == Type.PLAIN && unifiedScript.equals(e.key.script)) {
|
|
result = e.value
|
|
break
|
|
}
|
|
}
|
|
if(result instanceof Closure) result = result()
|
|
if (!result && parameters.returnStatus) result = 0
|
|
|
|
if(! parameters.returnStdout && ! parameters.returnStatus) return
|
|
return result
|
|
}
|
|
|
|
@Override
|
|
Statement apply(Statement base, Description description) {
|
|
return statement(base)
|
|
}
|
|
|
|
private Statement statement(final Statement base) {
|
|
return new Statement() {
|
|
@Override
|
|
void evaluate() throws Throwable {
|
|
|
|
testInstance.helper.registerAllowedMethod("sh", [String.class], {
|
|
command -> handleShellCall([
|
|
script: command,
|
|
returnStdout: false,
|
|
returnStatus: false
|
|
])
|
|
})
|
|
|
|
testInstance.helper.registerAllowedMethod("sh", [Map.class], {
|
|
m -> handleShellCall(m)
|
|
})
|
|
|
|
base.evaluate()
|
|
}
|
|
}
|
|
}
|
|
|
|
private static String unify(String s) {
|
|
s.replaceAll(/\s+/," ").trim()
|
|
}
|
|
}
|