Fix mandatory enforcer failure on augmented nodes
[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.api.schema.tree.DataTree;
22 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
23 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
24 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
25 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
26 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
27 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
28 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
29
30 public class YT1276Test {
31     private static final QName FOO = QName.create("foo", "foo");
32     private static final QName BAR = QName.create(FOO, "bar");
33     private static final QName BAZ = QName.create(FOO, "baz");
34     private static final QName XYZZY_LEAF = QName.create(FOO, "xyzzy-leaf");
35     private static final QName XYZZY_AUGMENT = QName.create(FOO, "xyzzy-augment");
36
37     private static EffectiveModelContext MODEL;
38
39     private final DataTree tree = new InMemoryDataTreeFactory()
40         .create(DataTreeConfiguration.DEFAULT_CONFIGURATION, MODEL);
41
42     @BeforeClass
43     public static void beforeClass() {
44         MODEL = YangParserTestUtils.parseYangResource("/yt1276.yang");
45     }
46
47     @Test
48     public void testFooWithBar() throws DataValidationFailedException {
49         applyOperation(mod -> {
50             mod.write(YangInstanceIdentifier.of(FOO), Builders.containerBuilder()
51                 .withNodeIdentifier(new NodeIdentifier(FOO))
52                 .withChild(Builders.augmentationBuilder()
53                     .withNodeIdentifier(new AugmentationIdentifier(Set.of(BAR)))
54                     .withChild(ImmutableNodes.leafNode(BAR, "xyzzy"))
55                     .build())
56                 .build());
57         });
58     }
59
60     @Test
61     @Deprecated
62     public void testFooWithBarLegacy() throws DataValidationFailedException {
63         applyOperation(mod -> {
64             mod.write(YangInstanceIdentifier.of(FOO), Builders.containerBuilder()
65                 .withNodeIdentifier(new NodeIdentifier(FOO))
66                 .withChild(ImmutableNodes.leafNode(BAR, "xyzzy"))
67                 .build());
68         });
69     }
70
71     @Test
72     public void testFooWithoutBar() {
73         final IllegalArgumentException ex = assertFailsReady(mod -> {
74             mod.write(YangInstanceIdentifier.of(FOO), Builders.containerBuilder()
75                 .withNodeIdentifier(new NodeIdentifier(FOO))
76                 .build());
77         });
78         assertEquals(
79             "Node (foo)foo is missing mandatory descendant /AugmentationIdentifier{childNames=[(foo)bar]}/(foo)bar",
80             ex.getMessage());
81     }
82
83     @Test
84     public void testBarWithXyzzy() throws DataValidationFailedException {
85         applyOperation(mod -> {
86             mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
87                 .withNodeIdentifier(new NodeIdentifier(BAR))
88                 .withChild(Builders.choiceBuilder()
89                     .withNodeIdentifier(new NodeIdentifier(BAZ))
90                     .withChild(ImmutableNodes.leafNode(XYZZY_LEAF, "xyzzy"))
91                     .withChild(Builders.augmentationBuilder()
92                         .withNodeIdentifier(new AugmentationIdentifier(Set.of(XYZZY_AUGMENT)))
93                         .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT, "xyzzy"))
94                         .build())
95                     .build())
96                 .build());
97         });
98     }
99
100     @Test
101     @Deprecated
102     public void testBarWithXyzzyLegacy() throws DataValidationFailedException {
103         applyOperation(mod -> {
104             mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
105                 .withNodeIdentifier(new NodeIdentifier(BAR))
106                 .withChild(Builders.choiceBuilder()
107                     .withNodeIdentifier(new NodeIdentifier(BAZ))
108                     .withChild(ImmutableNodes.leafNode(XYZZY_LEAF, "xyzzy"))
109                     .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT, "xyzzy"))
110                     .build())
111                 .build());
112         });
113     }
114
115     @Test
116     public void testBarWithoutXyzzyLeaf() {
117         final IllegalArgumentException ex = assertFailsReady(mod -> {
118             mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
119                 .withNodeIdentifier(new NodeIdentifier(BAR))
120                 .withChild(Builders.choiceBuilder()
121                     .withNodeIdentifier(new NodeIdentifier(BAZ))
122                     .withChild(Builders.augmentationBuilder()
123                         .withNodeIdentifier(new AugmentationIdentifier(Set.of(XYZZY_AUGMENT)))
124                         .withChild(ImmutableNodes.leafNode(XYZZY_AUGMENT, "xyzzy"))
125                         .build())
126                     .build())
127                 .build());
128         });
129         assertEquals(
130             "Node (foo)baz is missing mandatory descendant /(foo)xyzzy-leaf",
131             ex.getMessage());
132     }
133
134     @Test
135     public void testBarWithoutXyzzyAugment() {
136         final IllegalArgumentException ex = assertFailsReady(mod -> {
137             mod.write(YangInstanceIdentifier.of(BAR), Builders.containerBuilder()
138                 .withNodeIdentifier(new NodeIdentifier(BAR))
139                 .withChild(Builders.choiceBuilder()
140                     .withNodeIdentifier(new NodeIdentifier(BAZ))
141                     .withChild(ImmutableNodes.leafNode(XYZZY_LEAF, "xyzzy"))
142                     .build())
143                 .build());
144         });
145         assertEquals("Node (foo)baz is missing mandatory descendant "
146             + "/AugmentationIdentifier{childNames=[(foo)xyzzy-augment]}/(foo)xyzzy-augment",
147             ex.getMessage());
148
149     }
150
151     private IllegalArgumentException assertFailsReady(final Consumer<DataTreeModification> operation) {
152         return assertThrows(IllegalArgumentException.class, () -> applyOperation(operation));
153     }
154
155     private void applyOperation(final Consumer<DataTreeModification> operation)
156             throws DataValidationFailedException {
157         final DataTreeModification mod = tree.takeSnapshot().newModification();
158         operation.accept(mod);
159         mod.ready();
160         tree.commit(tree.prepare(mod));
161     }
162 }