2 * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.data.tree.impl;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertThrows;
14 import java.util.function.Consumer;
15 import org.junit.BeforeClass;
16 import org.junit.Test;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
21 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
22 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
23 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
24 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
25 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
26 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
27 import org.opendaylight.yangtools.yang.data.tree.impl.di.InMemoryDataTreeFactory;
28 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
29 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
31 public class YT1276Test {
32 private static final QName FOO = QName.create("foo", "foo");
33 private static final QName BAR = QName.create(FOO, "bar");
34 private static final QName BAZ = QName.create(FOO, "baz");
35 private static final QName XYZZY_LEAF = QName.create(FOO, "xyzzy-leaf");
36 private static final QName XYZZY_AUGMENT = QName.create(FOO, "xyzzy-augment");
37 private static final QName XYZZY_AUGMENT_CONT = QName.create(FOO, "xyzzy-augment-container");
38 private static final QName XYZZY_AUGMENT_CONT_INNER = QName.create(FOO, "xyzzy-augment-container-inner");
39 private static final QName XYZZY_AUGMENT_CONT_LEAF = QName.create(FOO, "xyzzy-augment-container-leaf");
40 private static final QName BAZ_AUG_CASE_MANDAT_LEAF = QName.create(FOO, "augmented-case-mandatory");
41 private static final QName BAZ_AUG_CASE_NON_MANDAT_LEAF = QName.create(FOO, "augmented-case-non-mandatory");
42 private static final QName NESTED_BAZ_CHOICE = QName.create(FOO, "nested-baz");
43 private static final QName NESTED_BAZ_XYZ_CASE_MANDATORY = QName.create(FOO, "nested-xyz-mandatory");
44 private static final QName NESTED_BAZ_XYZ_CASE_NON_MANDATORY = QName.create(FOO, "nested-xyz-non-mandatory");
46 private static EffectiveModelContext MODEL;
48 private final DataTree tree = new InMemoryDataTreeFactory()
49 .create(DataTreeConfiguration.DEFAULT_CONFIGURATION, MODEL);
52 public static void beforeClass() {
53 MODEL = YangParserTestUtils.parseYangResource("/yt1276.yang");
57 public void testFooWithBar() throws DataValidationFailedException {
58 applyOperation(mod -> {
59 mod.write(YangInstanceIdentifier.of(FOO), Builders.containerBuilder()
60 .withNodeIdentifier(new NodeIdentifier(FOO))
61 .withChild(Builders.augmentationBuilder()
62 .withNodeIdentifier(new AugmentationIdentifier(Set.of(BAR)))
63 .withChild(ImmutableNodes.leafNode(BAR, "xyzzy"))
71 public void testFooWithBarLegacy() throws DataValidationFailedException {
72 applyOperation(mod -> {
73 mod.write(YangInstanceIdentifier.of(FOO), Builders.containerBuilder()
74 .withNodeIdentifier(new NodeIdentifier(FOO))
75 .withChild(ImmutableNodes.leafNode(BAR, "xyzzy"))
81 public void testFooWithoutBar() {
82 final IllegalArgumentException ex = assertFailsReady(mod -> {
83 mod.write(YangInstanceIdentifier.of(FOO), Builders.containerBuilder()
84 .withNodeIdentifier(new NodeIdentifier(FOO))
88 "Node (foo)foo is missing mandatory descendant /AugmentationIdentifier{childNames=[(foo)bar]}/(foo)bar",
93 public void testBarWithXyzzyWithSubtree() throws DataValidationFailedException {
94 applyOperation(mod -> {
95 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
96 .withNodeIdentifier(new NodeIdentifier(BAR))
97 .withChild(Builders.choiceBuilder()
98 .withNodeIdentifier(new NodeIdentifier(BAZ))
99 .withChild(ImmutableNodes.leafNode(XYZZY_LEAF, "xyzzy"))
100 .withChild(Builders.augmentationBuilder()
101 .withNodeIdentifier(new AugmentationIdentifier(Set.of(XYZZY_AUGMENT, XYZZY_AUGMENT_CONT)))
102 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT, "xyzzy"))
103 .withChild(Builders.containerBuilder()
104 .withNodeIdentifier(new NodeIdentifier(XYZZY_AUGMENT_CONT))
105 .withChild(Builders.containerBuilder()
106 .withNodeIdentifier(new NodeIdentifier(XYZZY_AUGMENT_CONT_INNER))
107 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT_CONT_LEAF, "aug-cont-leaf"))
117 public void testBazWithAugmentedCaseWithMandatoryLeaf() throws DataValidationFailedException {
118 applyOperation(mod -> {
119 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
120 .withNodeIdentifier(new NodeIdentifier(BAR))
121 .withChild(Builders.choiceBuilder()
122 .withNodeIdentifier(new NodeIdentifier(BAZ))
123 .withChild(ImmutableNodes.leafNode(BAZ_AUG_CASE_MANDAT_LEAF, "augmentedCaseMandatory"))
124 .withChild(ImmutableNodes.leafNode(BAZ_AUG_CASE_NON_MANDAT_LEAF, "augmentedCaseNonMandatory"))
130 @Test(expected = IllegalArgumentException.class)
131 public void testBazWithAugmentedCaseWithoutMandatoryLeaf() throws DataValidationFailedException {
132 applyOperation(mod -> {
133 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
134 .withNodeIdentifier(new NodeIdentifier(BAR))
135 .withChild(Builders.choiceBuilder()
136 .withNodeIdentifier(new NodeIdentifier(BAZ))
137 .withChild(ImmutableNodes.leafNode(BAZ_AUG_CASE_NON_MANDAT_LEAF, "augmentedCaseNonMandatory"))
144 public void testWithAugmentedNestedBazWithMandatoryLeaf() throws DataValidationFailedException {
145 applyOperation(mod -> {
146 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
147 .withNodeIdentifier(new NodeIdentifier(BAR))
148 .withChild(Builders.choiceBuilder()
149 .withNodeIdentifier(new NodeIdentifier(BAZ))
150 .withChild(Builders.choiceBuilder()
151 .withNodeIdentifier(new NodeIdentifier(NESTED_BAZ_CHOICE))
152 .withChild(ImmutableNodes.leafNode(NESTED_BAZ_XYZ_CASE_MANDATORY, "nestedMandatory"))
153 .withChild(ImmutableNodes.leafNode(NESTED_BAZ_XYZ_CASE_NON_MANDATORY, "nestedNonMandatory"))
160 @Test(expected = IllegalArgumentException.class)
161 public void testWithAugmentedNestedBazWithhoutMandatoryLeaf() throws DataValidationFailedException {
162 applyOperation(mod -> {
163 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
164 .withNodeIdentifier(new NodeIdentifier(BAR))
165 .withChild(Builders.choiceBuilder()
166 .withNodeIdentifier(new NodeIdentifier(BAZ))
167 .withChild(Builders.choiceBuilder()
168 .withNodeIdentifier(new NodeIdentifier(NESTED_BAZ_CHOICE))
169 .withChild(ImmutableNodes.leafNode(NESTED_BAZ_XYZ_CASE_NON_MANDATORY, "nestedNonMandatory"))
178 public void testBarWithXyzzyLegacy() throws DataValidationFailedException {
179 applyOperation(mod -> {
180 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
181 .withNodeIdentifier(new NodeIdentifier(BAR))
182 .withChild(Builders.choiceBuilder()
183 .withNodeIdentifier(new NodeIdentifier(BAZ))
184 .withChild(ImmutableNodes.leafNode(XYZZY_LEAF, "xyzzy"))
185 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT, "xyzzy"))
186 .withChild(Builders.containerBuilder()
187 .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT))
188 .withChild(Builders.containerBuilder()
189 .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT_INNER))
190 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT_CONT_LEAF, "aug-cont-leaf"))
199 public void testBarWithoutXyzzyLeaf() {
200 final IllegalArgumentException ex = assertFailsReady(mod -> {
201 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
202 .withNodeIdentifier(new NodeIdentifier(BAR))
203 .withChild(Builders.choiceBuilder()
204 .withNodeIdentifier(new NodeIdentifier(BAZ))
205 .withChild(Builders.augmentationBuilder()
206 .withNodeIdentifier(new AugmentationIdentifier(Set.of(XYZZY_AUGMENT, XYZZY_AUGMENT_CONT)))
207 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT, "xyzzy"))
208 .withChild(Builders.containerBuilder()
209 .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT))
210 .withChild(Builders.containerBuilder()
211 .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT_INNER))
212 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT_CONT_LEAF, "aug-cont-leaf"))
220 "Node (foo)baz is missing mandatory descendant /(foo)xyzzy-leaf",
225 public void testBarWithoutXyzzyAugment() {
226 final IllegalArgumentException ex = assertFailsReady(mod -> {
227 mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
228 .withNodeIdentifier(new NodeIdentifier(BAR))
229 .withChild(Builders.choiceBuilder()
230 .withNodeIdentifier(new NodeIdentifier(BAZ))
231 .withChild(ImmutableNodes.leafNode(XYZZY_LEAF, "xyzzy"))
235 assertEquals("Node (foo)baz is missing mandatory descendant /AugmentationIdentifier{childNames="
236 + "[(foo)xyzzy-augment, (foo)xyzzy-augment-container]}/(foo)xyzzy-augment", ex.getMessage());
240 private IllegalArgumentException assertFailsReady(final Consumer<DataTreeModification> operation) {
241 return assertThrows(IllegalArgumentException.class, () -> applyOperation(operation));
244 private void applyOperation(final Consumer<DataTreeModification> operation)
245 throws DataValidationFailedException {
246 final DataTreeModification mod = tree.takeSnapshot().newModification();
247 operation.accept(mod);
249 tree.commit(tree.prepare(mod));