Rename opendaylight.mdsal.binding.runtime.spi
[yangtools.git] / data / yang-data-tree-ri / src / test / java / org / opendaylight / yangtools / yang / data / tree / impl / 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.tree.impl;
9
10 import static org.junit.jupiter.api.Assertions.assertEquals;
11 import static org.junit.jupiter.api.Assertions.assertThrows;
12
13 import java.util.function.Consumer;
14 import org.junit.jupiter.api.BeforeAll;
15 import org.junit.jupiter.api.Test;
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
19 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
20 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
21 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
22 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
23 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
24 import org.opendaylight.yangtools.yang.data.tree.impl.di.InMemoryDataTreeFactory;
25 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
26 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
27
28 class YT1276Test {
29     private static final QName FOO = QName.create("foo", "foo");
30     private static final QName BAR = QName.create(FOO, "bar");
31     private static final QName BAZ = QName.create(FOO, "baz");
32     private static final QName XYZZY_LEAF = QName.create(FOO, "xyzzy-leaf");
33     private static final QName XYZZY_AUGMENT = QName.create(FOO, "xyzzy-augment");
34     private static final QName XYZZY_AUGMENT_CONT = QName.create(FOO, "xyzzy-augment-container");
35     private static final QName XYZZY_AUGMENT_CONT_INNER = QName.create(FOO, "xyzzy-augment-container-inner");
36     private static final QName XYZZY_AUGMENT_CONT_LEAF = QName.create(FOO, "xyzzy-augment-container-leaf");
37     private static final QName BAZ_AUG_CASE_MANDAT_LEAF = QName.create(FOO, "augmented-case-mandatory");
38     private static final QName BAZ_AUG_CASE_NON_MANDAT_LEAF = QName.create(FOO, "augmented-case-non-mandatory");
39     private static final QName NESTED_BAZ_CHOICE = QName.create(FOO, "nested-baz");
40     private static final QName NESTED_BAZ_XYZ_CASE_MANDATORY = QName.create(FOO, "nested-xyz-mandatory");
41     private static final QName NESTED_BAZ_XYZ_CASE_NON_MANDATORY = QName.create(FOO, "nested-xyz-non-mandatory");
42
43     private static EffectiveModelContext MODEL;
44
45     private final DataTree tree = new InMemoryDataTreeFactory()
46         .create(DataTreeConfiguration.DEFAULT_CONFIGURATION, MODEL);
47
48     @BeforeAll
49     static void beforeClass() {
50         MODEL = YangParserTestUtils.parseYangResource("/yt1276.yang");
51     }
52
53     @Test
54     void testFooWithBar() throws DataValidationFailedException {
55         applyOperation(mod -> {
56             mod.write(YangInstanceIdentifier.of(FOO), ImmutableNodes.newContainerBuilder()
57                 .withNodeIdentifier(new NodeIdentifier(FOO))
58                 .withChild(ImmutableNodes.leafNode(BAR, "xyzzy"))
59                 .build());
60         });
61     }
62
63     @Test
64     @Deprecated
65     void testFooWithBarLegacy() throws DataValidationFailedException {
66         applyOperation(mod -> {
67             mod.write(YangInstanceIdentifier.of(FOO), ImmutableNodes.newContainerBuilder()
68                 .withNodeIdentifier(new NodeIdentifier(FOO))
69                 .withChild(ImmutableNodes.leafNode(BAR, "xyzzy"))
70                 .build());
71         });
72     }
73
74     @Test
75     void testFooWithoutBar() {
76         final IllegalArgumentException ex = assertFailsReady(mod -> {
77             mod.write(YangInstanceIdentifier.of(FOO), ImmutableNodes.newContainerBuilder()
78                 .withNodeIdentifier(new NodeIdentifier(FOO))
79                 .build());
80         });
81         assertEquals("Node (foo)foo is missing mandatory descendant /(foo)bar", ex.getMessage());
82     }
83
84     @Test
85     void testBarWithXyzzyWithSubtree() throws DataValidationFailedException {
86         applyOperation(mod -> {
87             mod.write(YangInstanceIdentifier.of(BAR), ImmutableNodes.newContainerBuilder()
88                 .withNodeIdentifier(new NodeIdentifier(BAR))
89                 .withChild(ImmutableNodes.newChoiceBuilder()
90                     .withNodeIdentifier(new NodeIdentifier(BAZ))
91                     .withChild(ImmutableNodes.leafNode(XYZZY_LEAF, "xyzzy"))
92                     .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT, "xyzzy"))
93                     .withChild(ImmutableNodes.newContainerBuilder()
94                         .withNodeIdentifier(new NodeIdentifier(XYZZY_AUGMENT_CONT))
95                         .withChild(ImmutableNodes.newContainerBuilder()
96                             .withNodeIdentifier(new NodeIdentifier(XYZZY_AUGMENT_CONT_INNER))
97                             .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT_CONT_LEAF, "aug-cont-leaf"))
98                             .build())
99                         .build())
100                     .build())
101                 .build());
102         });
103     }
104
105     @Test
106     void testBazWithAugmentedCaseWithMandatoryLeaf() throws DataValidationFailedException {
107         applyOperation(mod -> {
108             mod.write(YangInstanceIdentifier.of(BAR), ImmutableNodes.newContainerBuilder()
109                 .withNodeIdentifier(new NodeIdentifier(BAR))
110                 .withChild(ImmutableNodes.newChoiceBuilder()
111                     .withNodeIdentifier(new NodeIdentifier(BAZ))
112                     .withChild(ImmutableNodes.leafNode(BAZ_AUG_CASE_MANDAT_LEAF, "augmentedCaseMandatory"))
113                     .withChild(ImmutableNodes.leafNode(BAZ_AUG_CASE_NON_MANDAT_LEAF, "augmentedCaseNonMandatory"))
114                     .build())
115                 .build());
116         });
117     }
118
119     @Test
120     void testBazWithAugmentedCaseWithoutMandatoryLeaf() throws DataValidationFailedException {
121         assertThrows(IllegalArgumentException.class, () -> {
122             applyOperation(mod -> {
123                 mod.write(YangInstanceIdentifier.of(BAR), ImmutableNodes.newContainerBuilder()
124                     .withNodeIdentifier(new NodeIdentifier(BAR))
125                     .withChild(ImmutableNodes.newChoiceBuilder()
126                         .withNodeIdentifier(new NodeIdentifier(BAZ))
127                         .withChild(ImmutableNodes.leafNode(BAZ_AUG_CASE_NON_MANDAT_LEAF, "augmentedCaseNonMandatory"))
128                         .build())
129                     .build());
130             });
131         });
132     }
133
134     @Test
135     void testWithAugmentedNestedBazWithMandatoryLeaf() throws DataValidationFailedException {
136         applyOperation(mod -> {
137             mod.write(YangInstanceIdentifier.of(BAR), ImmutableNodes.newContainerBuilder()
138                 .withNodeIdentifier(new NodeIdentifier(BAR))
139                 .withChild(ImmutableNodes.newChoiceBuilder()
140                     .withNodeIdentifier(new NodeIdentifier(BAZ))
141                     .withChild(ImmutableNodes.newChoiceBuilder()
142                         .withNodeIdentifier(new NodeIdentifier(NESTED_BAZ_CHOICE))
143                         .withChild(ImmutableNodes.leafNode(NESTED_BAZ_XYZ_CASE_MANDATORY, "nestedMandatory"))
144                         .withChild(ImmutableNodes.leafNode(NESTED_BAZ_XYZ_CASE_NON_MANDATORY, "nestedNonMandatory"))
145                     .build())
146                     .build())
147                 .build());
148         });
149     }
150
151     @Test
152     void testWithAugmentedNestedBazWithhoutMandatoryLeaf() throws DataValidationFailedException {
153         assertThrows(IllegalArgumentException.class, () -> {
154             applyOperation(mod -> {
155                 mod.write(YangInstanceIdentifier.of(BAR), ImmutableNodes.newContainerBuilder()
156                     .withNodeIdentifier(new NodeIdentifier(BAR))
157                     .withChild(ImmutableNodes.newChoiceBuilder()
158                         .withNodeIdentifier(new NodeIdentifier(BAZ))
159                         .withChild(ImmutableNodes.newChoiceBuilder()
160                             .withNodeIdentifier(new NodeIdentifier(NESTED_BAZ_CHOICE))
161                             .withChild(ImmutableNodes.leafNode(NESTED_BAZ_XYZ_CASE_NON_MANDATORY, "nestedNonMandatory"))
162                             .build())
163                         .build())
164                     .build());
165             });
166         });
167     }
168
169     @Test
170     @Deprecated
171     void testBarWithXyzzyLegacy() throws DataValidationFailedException {
172         applyOperation(mod -> {
173             mod.write(YangInstanceIdentifier.of(BAR), ImmutableNodes.newContainerBuilder()
174                 .withNodeIdentifier(new NodeIdentifier(BAR))
175                 .withChild(ImmutableNodes.newChoiceBuilder()
176                     .withNodeIdentifier(new NodeIdentifier(BAZ))
177                     .withChild(ImmutableNodes.leafNode(XYZZY_LEAF, "xyzzy"))
178                     .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT, "xyzzy"))
179                     .withChild(ImmutableNodes.newContainerBuilder()
180                         .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT))
181                         .withChild(ImmutableNodes.newContainerBuilder()
182                             .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT_INNER))
183                             .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT_CONT_LEAF, "aug-cont-leaf"))
184                             .build())
185                         .build())
186                     .build())
187                 .build());
188         });
189     }
190
191     @Test
192     void testBarWithoutXyzzyLeaf() {
193         final var ex = assertFailsReady(mod -> {
194             mod.write(YangInstanceIdentifier.of(BAR), ImmutableNodes.newContainerBuilder()
195                 .withNodeIdentifier(new NodeIdentifier(BAR))
196                 .withChild(ImmutableNodes.newChoiceBuilder()
197                     .withNodeIdentifier(new NodeIdentifier(BAZ))
198                     .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT, "xyzzy"))
199                     .withChild(ImmutableNodes.newContainerBuilder()
200                         .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT))
201                         .withChild(ImmutableNodes.newContainerBuilder()
202                             .withNodeIdentifier(NodeIdentifier.create(XYZZY_AUGMENT_CONT_INNER))
203                             .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT_CONT_LEAF, "aug-cont-leaf"))
204                             .build())
205                         .build())
206                     .build())
207                 .build());
208         });
209         assertEquals(
210             "Node (foo)baz is missing mandatory descendant /(foo)xyzzy-leaf",
211             ex.getMessage());
212     }
213
214     @Test
215     void testBarWithoutXyzzyAugment() {
216         final var ex = assertFailsReady(mod -> {
217             mod.write(YangInstanceIdentifier.of(BAR), ImmutableNodes.newContainerBuilder()
218                 .withNodeIdentifier(new NodeIdentifier(BAR))
219                 .withChild(ImmutableNodes.newChoiceBuilder()
220                     .withNodeIdentifier(new NodeIdentifier(BAZ))
221                     .withChild(ImmutableNodes.leafNode(XYZZY_LEAF, "xyzzy"))
222                     .build())
223                 .build());
224         });
225         assertEquals("Node (foo)baz is missing mandatory descendant /(foo)xyzzy-augment", ex.getMessage());
226
227     }
228
229     private IllegalArgumentException assertFailsReady(final Consumer<DataTreeModification> operation) {
230         return assertThrows(IllegalArgumentException.class, () -> applyOperation(operation));
231     }
232
233     private void applyOperation(final Consumer<DataTreeModification> operation)
234             throws DataValidationFailedException {
235         final var mod = tree.takeSnapshot().newModification();
236         operation.accept(mod);
237         mod.ready();
238         tree.commit(tree.prepare(mod));
239     }
240 }