| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.brooklyn.util.yaml; |
| |
| import static org.testng.Assert.assertEquals; |
| import static org.testng.Assert.assertFalse; |
| |
| import java.util.Date; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.apache.brooklyn.test.Asserts; |
| import org.apache.brooklyn.util.collections.MutableList; |
| import org.apache.brooklyn.util.exceptions.UserFacingException; |
| import org.apache.brooklyn.util.internal.BrooklynSystemProperties; |
| import org.apache.brooklyn.util.yaml.Yamls.YamlExtract; |
| import org.testng.Assert; |
| import org.testng.TestNG; |
| import org.testng.annotations.Test; |
| import org.yaml.snakeyaml.constructor.ConstructorException; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import org.yaml.snakeyaml.error.MarkedYAMLException; |
| |
| public class YamlsTest { |
| |
| @Test |
| public void testGetAs() throws Exception { |
| MutableList<String> list = MutableList.of("x"); |
| assertEquals(Yamls.getAs(list.iterator(), List.class), list); |
| assertEquals(Yamls.getAs(list.iterator(), Iterable.class), list); |
| assertEquals(Yamls.getAs(list.iterator(), Iterator.class), list.iterator()); |
| assertEquals(Yamls.getAs(list.iterator(), String.class), "x"); |
| } |
| |
| @Test |
| public void testGetAt() throws Exception { |
| // leaf of map |
| assertEquals(Yamls.getAt("k1: v", ImmutableList.of("k1")), "v"); |
| assertEquals(Yamls.getAt("k1: {k2: v}", ImmutableList.of("k1", "k2")), "v"); |
| |
| // get list |
| assertEquals(Yamls.getAt("k1: [v1, v2]", ImmutableList.<String>of("k1")), ImmutableList.of("v1", "v2")); |
| |
| // get map |
| assertEquals(Yamls.getAt("k1: v", ImmutableList.<String>of()), ImmutableMap.of("k1", "v")); |
| assertEquals(Yamls.getAt("k1: {k2: v}", ImmutableList.of("k1")), ImmutableMap.of("k2", "v")); |
| |
| // get array index |
| assertEquals(Yamls.getAt("k1: [v1, v2]", ImmutableList.<String>of("k1", "[0]")), "v1"); |
| assertEquals(Yamls.getAt("k1: [v1, v2]", ImmutableList.<String>of("k1", "[1]")), "v2"); |
| } |
| |
| |
| @Test |
| public void testExtractMap() { |
| String sample = "#before\nk1:\n- v1\nk2:\n # comment\n k21: v21\nk3: v3\n#after\n"; |
| |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, "k1").withKeyIncluded(true).getMatchedYamlText(), |
| sample.substring(0, sample.indexOf("k2"))); |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, "k3").withKeyIncluded(true).getMatchedYamlText(), |
| sample.substring(sample.indexOf("k3"))); |
| |
| // comments and no key, outdented - the default |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, "k2", "k21").getMatchedYamlText(), |
| "# comment\nv21"); |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, "k2", "k21").getMatchedYamlText(), |
| "# comment\nv21"); |
| // comments and key |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, "k2", "k21").withKeyIncluded(true).getMatchedYamlText(), |
| "# comment\nk21: v21"); |
| // no comments |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, "k2", "k21").withKeyIncluded(true).withPrecedingCommentsIncluded(false).getMatchedYamlText(), |
| "k21: v21"); |
| // no comments and no key |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, "k2", "k21").withPrecedingCommentsIncluded(false).getMatchedYamlText(), |
| "v21"); |
| |
| // comments and no key, not outdented |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, "k2", "k21").withOriginalIndentation(true).getMatchedYamlText(), |
| " # comment\n v21"); |
| // comments and key |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, "k2", "k21").withKeyIncluded(true).withOriginalIndentation(true).getMatchedYamlText(), |
| " # comment\n k21: v21"); |
| // no comments |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, "k2", "k21").withKeyIncluded(true).withPrecedingCommentsIncluded(false).withOriginalIndentation(true).getMatchedYamlText(), |
| " k21: v21"); |
| // no comments and no key |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, "k2", "k21").withPrecedingCommentsIncluded(false).withOriginalIndentation(true).getMatchedYamlText(), |
| " v21"); |
| } |
| |
| @Test |
| public void testExtractInList() { |
| String sample = |
| "- a\n" + |
| "- b: 2\n" + |
| "- # c\n" + |
| " c1:\n" + |
| " 1\n" + |
| " c2:\n" + |
| " 2\n" + |
| "-\n" + |
| " - a # for a\n" + |
| " # for b\n" + |
| " - b\n"; |
| |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, 0).getMatchedYamlText(), "a"); |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, 1, "b").getMatchedYamlText(), "2"); |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, 3, 0).getMatchedYamlText(), |
| "a" |
| // TODO comments after on same line not yet included - would be nice to add |
| // "a # for a" |
| ); |
| |
| // out-dent |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, 2).getMatchedYamlText(), "c1:\n 1\nc2:\n 2\n"); |
| // don't outdent |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, 2).withOriginalIndentation(true).getMatchedYamlText(), " c1:\n 1\n c2:\n 2\n"); |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, 3, 0).withOriginalIndentation(true).getMatchedYamlText(), |
| " a" |
| // as above, comments after not included |
| // " a # for a" |
| ); |
| |
| // with preceding comments |
| // TODO final item includes newline (and comments) after - this behaviour might change, it's inconsistent, |
| // but it means the final comments aren't lost |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, 3, 1).getMatchedYamlText(), "# for b\nb\n"); |
| |
| // exclude preceding comments |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, 3, 1).withPrecedingCommentsIncluded(false).getMatchedYamlText(), "b\n"); |
| } |
| |
| @Test |
| public void testExtractMapIgnoringPreviousComments() { |
| String sample = "a: 1 # one\n" |
| + "b: 2 # two"; |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath(sample, "b").getMatchedYamlText(), |
| "2 # two"); |
| } |
| |
| @Test |
| public void testExtractMapWithOddWhitespace() { |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath("x: a\n bc", "x").getMatchedYamlText(), |
| "a\n bc"); |
| } |
| |
| @Test |
| public void testReplace() { |
| Assert.assertEquals(Yamls.getTextOfYamlAtPath("x: a\n bc", "x").getFullYamlTextWithExtractReplaced("\nc: 1\nd: 2"), |
| "x: \n c: 1\n d: 2"); |
| } |
| |
| @Test |
| public void testExtractNoOOBE() { |
| // this might log a warning, as item not found, but won't throw |
| YamlExtract r1 = Yamls.getTextOfYamlAtPath( |
| "items:\n- id: sample2\n itemType: location\n item:\n type: jclouds:aws-ec2\n brooklyn.config:\n key2: value2\n\n", |
| "item"); |
| |
| // won't throw |
| r1.getMatchedYamlTextOrWarn(); |
| // will throw |
| try { |
| r1.getMatchedYamlText(); |
| Assert.fail(); |
| } catch (UserFacingException e) { |
| // expected, it should give a vaguely explanatory exception and no trace |
| } |
| } |
| |
| @Test |
| public void testSafeYaml() throws Exception { |
| assertFalse(BrooklynSystemProperties.YAML_TYPE_INSTANTIATION.isEnabled(), |
| "Set property to false (or do not set at all): " + BrooklynSystemProperties.YAML_TYPE_INSTANTIATION.getPropertyName()); |
| |
| try { |
| Yamls.parseAll("!!java.util.Date\n" + |
| "date: 25\n" + |
| "month: 12\n" + |
| "year: 2016"); |
| Asserts.shouldHaveFailedPreviously("Expected exception: " + ConstructorException.class.getCanonicalName()); |
| } catch (MarkedYAMLException e) { |
| Asserts.expectedFailureContains(e, |
| // with 2.2: |
| "Global tag is not allowed", "tag:yaml.org,2002:java.util.Date" |
| // with 1.33: "could not determine a constructor" |
| ); |
| } |
| } |
| |
| @Test |
| public void testUnsafeYaml() throws Exception { |
| assertFalse(BrooklynSystemProperties.YAML_TYPE_INSTANTIATION.isEnabled(), |
| "Set property to false (or do not set at all): " + BrooklynSystemProperties.YAML_TYPE_INSTANTIATION.getPropertyName()); |
| |
| try { |
| System.setProperty(BrooklynSystemProperties.YAML_TYPE_INSTANTIATION.getPropertyName(), "true"); |
| Asserts.assertTrue(BrooklynSystemProperties.YAML_TYPE_INSTANTIATION.isEnabled()); |
| |
| Object d = Yamls.parseAll("!!java.util.Date\n" + |
| "date: 25\n" + |
| "month: 12\n" + |
| "year: 2016").iterator().next(); |
| Asserts.assertInstanceOf(d, Date.class); |
| |
| } finally { |
| System.clearProperty(BrooklynSystemProperties.YAML_TYPE_INSTANTIATION.getPropertyName()); |
| |
| assertFalse(BrooklynSystemProperties.YAML_TYPE_INSTANTIATION.isEnabled(), |
| "Set property to false (or do not set at all): " + BrooklynSystemProperties.YAML_TYPE_INSTANTIATION.getPropertyName()); |
| } |
| } |
| |
| @Test |
| public void testLastDocument() { |
| Asserts.assertEquals(Yamls.lastDocumentFunction().apply("foo\n---\nbar"), "bar"); |
| Asserts.assertEquals(Yamls.lastDocumentFunction().apply("foo\n--- \nbar"), "foo\n--- \nbar"); |
| Asserts.assertEquals(Yamls.lastDocumentFunction().apply("foo"), "foo"); |
| Asserts.assertEquals(Yamls.lastDocumentFunction().apply(null), null); |
| } |
| |
| @Test |
| public void testCommentsAtEnd() { |
| String input = " item: x\n#comment"; |
| Asserts.assertEquals(Yamls.getTextOfYamlAtPath(input, "item").getMatchedYamlTextOrWarn(), "x\n#comment"); |
| } |
| |
| // convenience, since running with older TestNG IDE plugin will fail (older snakeyaml dependency); |
| // if you run as a java app it doesn't bring in the IDE TestNG jar version, and it works |
| public static void main(String[] args) { |
| TestNG testng = new TestNG(); |
| testng.setTestClasses(new Class[] { YamlsTest.class }); |
| // testng.setVerbose(9); |
| testng.run(); |
| } |
| |
| } |