blob: b80e8d0ba45453ca7548d1ff8610d52a1fc6fb7a [file] [log] [blame]
/*
* 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();
}
}