github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/test/groovy/util/JenkinsShellCallRule.groovy (about)

     1  package util
     2  
     3  import com.lesfurets.jenkins.unit.BasePipelineTest
     4  import org.junit.rules.TestRule
     5  import org.junit.runner.Description
     6  import org.junit.runners.model.Statement
     7  
     8  class JenkinsShellCallRule implements TestRule {
     9  
    10      enum Type { PLAIN, REGEX }
    11  
    12      class Command {
    13  
    14          final Type type
    15          final String script
    16  
    17          Command(Type type, String script) {
    18              this.type = type
    19              this.script = script
    20          }
    21  
    22          String toString() {
    23              return "${type} : ${script}"
    24          }
    25  
    26          @Override
    27          public int hashCode() {
    28              return type.hashCode() * script.hashCode()
    29          }
    30  
    31          @Override
    32          public boolean equals(Object obj) {
    33  
    34              if (obj == null || !obj instanceof Command) return false
    35              Command other = (Command) obj
    36              return type == other.type && script == other.script
    37          }
    38      }
    39  
    40      final BasePipelineTest testInstance
    41  
    42      List shell = []
    43  
    44      Map<Command, String> returnValues = [:]
    45  
    46      JenkinsShellCallRule(BasePipelineTest testInstance) {
    47          this.testInstance = testInstance
    48      }
    49  
    50      def setReturnValue(script, value) {
    51          setReturnValue(Type.PLAIN, script, value)
    52      }
    53  
    54      def setReturnValue(type, script, value) {
    55          returnValues[new Command(type, script)] = value
    56      }
    57  
    58      def handleShellCall(Map parameters) {
    59  
    60          def unifiedScript = unify(parameters.script)
    61  
    62          shell.add(unifiedScript)
    63  
    64          def result = null
    65  
    66          for(def e : returnValues.entrySet()) {
    67              if(e.key.type == Type.REGEX && unifiedScript =~ e.key.script) {
    68                  result =  e.value
    69                  break
    70          } else if(e.key.type == Type.PLAIN && unifiedScript.equals(e.key.script)) {
    71                  result = e.value
    72                  break
    73              }
    74          }
    75          if(result instanceof Closure) result = result()
    76          if (!result && parameters.returnStatus) result = 0
    77  
    78          if(! parameters.returnStdout && ! parameters.returnStatus) return
    79          return result
    80      }
    81  
    82      @Override
    83      Statement apply(Statement base, Description description) {
    84          return statement(base)
    85      }
    86  
    87      private Statement statement(final Statement base) {
    88          return new Statement() {
    89              @Override
    90              void evaluate() throws Throwable {
    91  
    92                  testInstance.helper.registerAllowedMethod("sh", [String.class], {
    93                      command -> handleShellCall([
    94                          script: command,
    95                          returnStdout: false,
    96                          returnStatus: false
    97                      ])
    98                  })
    99  
   100                  testInstance.helper.registerAllowedMethod("sh", [Map.class], {
   101                      m -> handleShellCall(m)
   102                  })
   103  
   104                  base.evaluate()
   105              }
   106          }
   107      }
   108  
   109      private static String unify(String s) {
   110          s.replaceAll(/\s+/," ").trim()
   111      }
   112  }