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 }