github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/test/groovy/com/sap/piper/variablesubstitution/YamlUtilsTest.groovy (about)

     1  package com.sap.piper.variablesubstitution
     2  
     3  import org.junit.Before
     4  
     5  import static org.junit.Assert.*
     6  import org.junit.Rule
     7  import org.junit.Test
     8  import org.junit.rules.ExpectedException;
     9  import org.junit.rules.RuleChain;
    10  import util.BasePiperTest
    11  import util.JenkinsEnvironmentRule
    12  import util.JenkinsErrorRule
    13  import util.JenkinsLoggingRule
    14  import util.JenkinsReadYamlRule
    15  import util.JenkinsWriteYamlRule
    16  import util.Rules
    17  
    18  class YamlUtilsTest extends BasePiperTest {
    19  
    20      private JenkinsReadYamlRule readYamlRule = new JenkinsReadYamlRule(this)
    21      private JenkinsWriteYamlRule writeYamlRule = new JenkinsWriteYamlRule(this)
    22      private JenkinsErrorRule errorRule = new JenkinsErrorRule(this)
    23      private JenkinsEnvironmentRule environmentRule = new JenkinsEnvironmentRule(this)
    24      private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this)
    25      private ExpectedException expectedExceptionRule = ExpectedException.none()
    26  
    27      private YamlUtils yamlUtils
    28  
    29      @Rule
    30      public RuleChain rules = Rules
    31          .getCommonRules(this)
    32          .around(readYamlRule)
    33          .around(writeYamlRule)
    34          .around(errorRule)
    35          .around(environmentRule)
    36          .around(loggingRule)
    37          .around(expectedExceptionRule)
    38  
    39      @Before
    40      public void setup() {
    41          yamlUtils = new YamlUtils(nullScript)
    42  
    43          readYamlRule.registerYaml("manifest.yml", new FileInputStream(new File("test/resources/variableSubstitution/manifest.yml")))
    44                      .registerYaml("manifest-variables.yml", new FileInputStream(new File("test/resources/variableSubstitution/manifest-variables.yml")))
    45                      .registerYaml("test/resources/variableSubstitution/manifest.yml", new FileInputStream(new File("test/resources/variableSubstitution/manifest.yml")))
    46                      .registerYaml("test/resources/variableSubstitution/manifest-variables.yml", new FileInputStream(new File("test/resources/variableSubstitution/manifest-variables.yml")))
    47                      .registerYaml("test/resources/variableSubstitution/invalid_manifest.yml", new FileInputStream(new File("test/resources/variableSubstitution/invalid_manifest.yml")))
    48                      .registerYaml("test/resources/variableSubstitution/novars_manifest.yml", new FileInputStream(new File("test/resources/variableSubstitution/novars_manifest.yml")))
    49                      .registerYaml("test/resources/variableSubstitution/multi_manifest.yml", new FileInputStream(new File("test/resources/variableSubstitution/multi_manifest.yml")))
    50                      .registerYaml("test/resources/variableSubstitution/datatypes_manifest.yml", new FileInputStream(new File("test/resources/variableSubstitution/datatypes_manifest.yml")))
    51                      .registerYaml("test/resources/variableSubstitution/datatypes_manifest-variables.yml", new FileInputStream(new File("test/resources/variableSubstitution/datatypes_manifest-variables.yml")))
    52      }
    53  
    54      @Test
    55      public void substituteVariables_Fails_If_InputYamlIsNullOrEmpty() throws Exception {
    56  
    57          expectedExceptionRule.expect(IllegalArgumentException)
    58          expectedExceptionRule.expectMessage("[YamlUtils] Input Yaml data must not be null or empty.")
    59  
    60          yamlUtils.substituteVariables(null, null)
    61      }
    62  
    63      @Test
    64      public void substituteVariables_Fails_If_VariablesYamlIsNullOrEmpty() throws Exception {
    65          String manifestFileName = "test/resources/variableSubstitution/manifest.yml"
    66  
    67          expectedExceptionRule.expect(IllegalArgumentException)
    68          expectedExceptionRule.expectMessage("[YamlUtils] Variables Yaml data must not be null or empty.")
    69  
    70          Object input = nullScript.readYaml file: manifestFileName
    71  
    72          // execute step
    73          yamlUtils.substituteVariables(input, null)
    74      }
    75  
    76      @Test
    77      public void substituteVariables_Throws_If_InputYamlIsInvalid() throws Exception {
    78          String manifestFileName = "test/resources/variableSubstitution/invalid_manifest.yml"
    79          String variablesFileName = "test/resources/variableSubstitution/invalid_manifest.yml"
    80  
    81          //check that exception is thrown and that it has the correct message.
    82          expectedExceptionRule.expect(org.yaml.snakeyaml.scanner.ScannerException)
    83          expectedExceptionRule.expectMessage("found character '%' that cannot start any token. (Do not use % for indentation)")
    84  
    85          Object input = nullScript.readYaml file: manifestFileName
    86          Object variables = nullScript.readYaml file: variablesFileName
    87  
    88          // execute step
    89          yamlUtils.substituteVariables(input, variables)
    90      }
    91  
    92      @Test
    93      public void substituteVariables_Throws_If_VariablesYamlInvalid() throws Exception {
    94          String manifestFileName = "test/resources/variableSubstitution/manifest.yml"
    95          String variablesFileName = "test/resources/variableSubstitution/invalid_manifest.yml"
    96  
    97          //check that exception is thrown and that it has the correct message.
    98          expectedExceptionRule.expect(org.yaml.snakeyaml.scanner.ScannerException)
    99          expectedExceptionRule.expectMessage("found character '%' that cannot start any token. (Do not use % for indentation)")
   100  
   101          Object input = nullScript.readYaml file: manifestFileName
   102          Object variables = nullScript.readYaml file: variablesFileName
   103  
   104          // execute step
   105          yamlUtils.substituteVariables(input, variables)
   106      }
   107  
   108      @Test
   109      public void substituteVariables_ReplacesVariablesProperly_InSingleYamlFiles() throws Exception {
   110          String manifestFileName = "test/resources/variableSubstitution/manifest.yml"
   111          String variablesFileName = "test/resources/variableSubstitution/manifest-variables.yml"
   112  
   113          Object input = nullScript.readYaml file: manifestFileName
   114          Object variables = nullScript.readYaml file: variablesFileName
   115  
   116          // execute step
   117          Map<String, Object> manifestDataAfterReplacement = yamlUtils.substituteVariables(input, variables)
   118  
   119          //Check that something was written
   120          assertNotNull(manifestDataAfterReplacement)
   121  
   122          // check that resolved variables have expected values
   123          assertCorrectVariableResolution(manifestDataAfterReplacement)
   124  
   125          // check that the step was marked as a success (even if it did do nothing).
   126          assertJobStatusSuccess()
   127      }
   128  
   129      private void assertAllVariablesReplaced(String yamlStringAfterReplacement) {
   130          assertFalse(yamlStringAfterReplacement.contains("(("))
   131          assertFalse(yamlStringAfterReplacement.contains("))"))
   132      }
   133  
   134      private void assertCorrectVariableResolution(Map<String, Object> manifestDataAfterReplacement) {
   135          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("name").equals("uniquePrefix-catalog-service-odatav2-0.0.1"))
   136          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("routes").get(0).get("route").equals("uniquePrefix-catalog-service-odatav2-001.cfapps.eu10.hana.ondemand.com"))
   137          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("services").get(0).equals("uniquePrefix-catalog-service-odatav2-xsuaa"))
   138          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("services").get(1).equals("uniquePrefix-catalog-service-odatav2-hana"))
   139          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("xsuaa-instance-name").equals("uniquePrefix-catalog-service-odatav2-xsuaa"))
   140          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("db_service_instance_name").equals("uniquePrefix-catalog-service-odatav2-hana"))
   141      }
   142  
   143      @Test
   144      public void substituteVariables_ReplacesVariablesProperly_InMultiYamlData() throws Exception {
   145          String manifestFileName = "test/resources/variableSubstitution/multi_manifest.yml"
   146          String variablesFileName = "test/resources/variableSubstitution/manifest-variables.yml"
   147  
   148          Object input = nullScript.readYaml file: manifestFileName
   149          Object variables = nullScript.readYaml file: variablesFileName
   150  
   151          // execute step
   152          List<Object> manifestDataAfterReplacement = yamlUtils.substituteVariables(input, variables)
   153  
   154          //Check that something was written
   155          assertNotNull(manifestDataAfterReplacement)
   156  
   157          //check that result still is a multi-YAML file.
   158          assertEquals("Dumped YAML after replacement should still be a multi-YAML file.",2, manifestDataAfterReplacement.size())
   159  
   160          // check that resolved variables have expected values
   161          manifestDataAfterReplacement.each { yaml ->
   162              assertCorrectVariableResolution(yaml as Map<String, Object>)
   163          }
   164  
   165          // check that the step was marked as a success (even if it did do nothing).
   166          assertJobStatusSuccess()
   167      }
   168  
   169      @Test
   170      public void substituteVariables_ReturnsOriginalIfNoVariablesPresent() throws Exception {
   171          // This test makes sure that, if no variables are found in a manifest that need
   172          // to be replaced, the execution is eventually skipped and the manifest remains
   173          // untouched.
   174  
   175          String manifestFileName = "test/resources/variableSubstitution/novars_manifest.yml"
   176          String variablesFileName = "test/resources/variableSubstitution/manifest-variables.yml"
   177  
   178          Object input = nullScript.readYaml file: manifestFileName
   179          Object variables = nullScript.readYaml file: variablesFileName
   180  
   181          // execute step
   182          ExecutionContext context = new ExecutionContext()
   183          Object result = yamlUtils.substituteVariables(input, variables, context)
   184  
   185          //Check that nothing was written
   186          assertNotNull(result)
   187          assertFalse(context.variablesReplaced)
   188  
   189          // check that the step was marked as a success (even if it did do nothing).
   190          assertJobStatusSuccess()
   191      }
   192  
   193      @Test
   194      public void substituteVariables_SupportsAllDataTypes() throws Exception {
   195          // This test makes sure that, all datatypes supported by YAML are also
   196          // properly substituted by the substituteVariables step.
   197          // In particular this includes variables of type:
   198          // Integer, Boolean, String, Float and inline JSON documents (which are parsed as multi-line strings)
   199          // and complex types (like other YAML objects).
   200          // The test also checks the differing behaviour when substituting nodes that only consist of a
   201          // variable reference and nodes that contains several variable references or additional string constants.
   202  
   203          String manifestFileName = "test/resources/variableSubstitution/datatypes_manifest.yml"
   204          String variablesFileName = "test/resources/variableSubstitution/datatypes_manifest-variables.yml"
   205  
   206          Object input = nullScript.readYaml file: manifestFileName
   207          Object variables = nullScript.readYaml file: variablesFileName
   208  
   209          // execute step
   210          ExecutionContext context = new ExecutionContext()
   211          Map<String, Object> manifestDataAfterReplacement = yamlUtils.substituteVariables(input, variables, context)
   212  
   213          //Check that something was written
   214          assertNotNull(manifestDataAfterReplacement)
   215  
   216          assertCorrectVariableResolution(manifestDataAfterReplacement)
   217  
   218          assertDataTypeAndSubstitutionCorrectness(manifestDataAfterReplacement)
   219  
   220          // check that the step was marked as a success (even if it did do nothing).
   221          assertJobStatusSuccess()
   222      }
   223  
   224      private void assertDataTypeAndSubstitutionCorrectness(Map<String, Object> manifestDataAfterReplacement) {
   225          // See datatypes_manifest.yml and datatypes_manifest-variables.yml.
   226          // Note: For debugging consider turning on YAML writing to a file in JenkinsWriteYamlRule to see the
   227          // actual outcome of replacing variables (for visual inspection).
   228  
   229          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("instances").equals(1))
   230          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("instances") instanceof Integer)
   231  
   232          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("services").get(0) instanceof String)
   233  
   234          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("booleanVariableTrue").equals(true))
   235          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("booleanVariableTrue") instanceof Boolean)
   236  
   237          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("booleanVariableFalse").equals(false))
   238          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("booleanVariableFalse") instanceof Boolean)
   239  
   240          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("floatVariable") == 0.25)
   241          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("floatVariable") instanceof Double)
   242  
   243          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("json-variable") instanceof String)
   244  
   245          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("object-variable") instanceof Map)
   246  
   247          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("string-variable").startsWith("true-0.25-1-"))
   248          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("string-variable") instanceof String)
   249  
   250          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("single-var-with-string-constants").equals("true-with-some-more-text"))
   251          assertTrue(manifestDataAfterReplacement.get("applications").get(0).get("env").get("single-var-with-string-constants") instanceof String)
   252      }
   253  
   254      @Test
   255      public void substituteVariables_DoesNotFail_If_ExecutionContextIsNull() throws Exception {
   256          String manifestFileName = "test/resources/variableSubstitution/manifest.yml"
   257          String variablesFileName = "test/resources/variableSubstitution/manifest-variables.yml"
   258  
   259          Object input = nullScript.readYaml file: manifestFileName
   260          Object variables = nullScript.readYaml file: variablesFileName
   261  
   262          // execute step
   263          Map<String, Object> manifestDataAfterReplacement = yamlUtils.substituteVariables(input, variables, null)
   264  
   265          //Check that something was written
   266          assertNotNull(manifestDataAfterReplacement)
   267  
   268          // check that resolved variables have expected values
   269          assertCorrectVariableResolution(manifestDataAfterReplacement)
   270  
   271          // check that the step was marked as a success (even if it did do nothing).
   272          assertJobStatusSuccess()
   273      }
   274  }