Split out yang-data-tree-{api,spi}
[yangtools.git] / data / yang-data-impl / src / test / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / YT1276Test.java
1 /*
2  * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertThrows;
12
13 import java.util.Set;
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.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
24 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
25 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
26 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
27 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
28 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
29 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
30
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");
45
46     private static EffectiveModelContext MODEL;
47
48     private final DataTree tree = new InMemoryDataTreeFactory()
49         .create(DataTreeConfiguration.DEFAULT_CONFIGURATION, MODEL);
50
51     @BeforeClass
52     public static void beforeClass() {
53         MODEL = YangParserTestUtils.parseYangResource("/yt1276.yang");
54     }
55
56     @Test
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"))
64                     .build())
65                 .build());
66         });
67     }
68
69     @Test
70     @Deprecated
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"))
76                 .build());
77         });
78     }
79
80     @Test
81     public void testFooWithoutBar() {
82         final IllegalArgumentException ex = assertFailsReady(mod -> {
83             mod.write(YangInstanceIdentifier.of(FOO), Builders.containerBuilder()
84                 .withNodeIdentifier(new NodeIdentifier(FOO))
85                 .build());
86         });
87         assertEquals(
88             "Node (foo)foo is missing mandatory descendant /AugmentationIdentifier{childNames=[(foo)bar]}/(foo)bar",
89             ex.getMessage());
90     }
91
92     @Test
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(ImmutableContainerNodeBuilder.create()
104                             .withNodeIdentifier(new NodeIdentifier(XYZZY_AUGMENT_CONT))
105                             .withChild(ImmutableContainerNodeBuilder.create()
106                                 .withNodeIdentifier(new NodeIdentifier(XYZZY_AUGMENT_CONT_INNER))
107                                 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT_CONT_LEAF, "aug-cont-leaf"))
108                                 .build())
109                             .build())
110                         .build())
111                     .build())
112                 .build());
113         });
114     }
115
116     @Test
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"))
125                     .build())
126                 .build());
127         });
128     }
129
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"))
138                     .build())
139                 .build());
140         });
141     }
142
143     @Test
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"))
154                     .build())
155                     .build())
156                 .build());
157         });
158     }
159
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"))
170                         .build())
171                     .build())
172                 .build());
173         });
174     }
175
176     @Test
177     @Deprecated
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(ImmutableContainerNodeBuilder.create()
187                         .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT))
188                         .withChild(ImmutableContainerNodeBuilder.create()
189                             .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT_INNER))
190                             .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT_CONT_LEAF, "aug-cont-leaf"))
191                             .build())
192                         .build())
193                     .build())
194                 .build());
195         });
196     }
197
198     @Test
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(ImmutableContainerNodeBuilder.create()
209                             .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT))
210                             .withChild(ImmutableContainerNodeBuilder.create()
211                                 .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT_INNER))
212                                 .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT_CONT_LEAF, "aug-cont-leaf"))
213                                 .build())
214                             .build())
215                         .build())
216                     .build())
217                 .build());
218         });
219         assertEquals(
220             "Node (foo)baz is missing mandatory descendant /(foo)xyzzy-leaf",
221             ex.getMessage());
222     }
223
224     @Test
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"))
232                     .build())
233                 .build());
234         });
235         assertEquals("Node (foo)baz is missing mandatory descendant /AugmentationIdentifier{childNames="
236                 + "[(foo)xyzzy-augment, (foo)xyzzy-augment-container]}/(foo)xyzzy-augment", ex.getMessage());
237
238     }
239
240     private IllegalArgumentException assertFailsReady(final Consumer<DataTreeModification> operation) {
241         return assertThrows(IllegalArgumentException.class, () -> applyOperation(operation));
242     }
243
244     private void applyOperation(final Consumer<DataTreeModification> operation)
245             throws DataValidationFailedException {
246         final DataTreeModification mod = tree.takeSnapshot().newModification();
247         operation.accept(mod);
248         mod.ready();
249         tree.commit(tree.prepare(mod));
250     }
251 }