Rename opendaylight.mdsal.binding.runtime.spi
[yangtools.git] / data / yang-data-tree-ri / src / test / java / org / opendaylight / yangtools / yang / data / tree / impl / Bug5968Test.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. 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.fail;
12
13 import com.google.common.collect.ImmutableMap;
14 import org.junit.jupiter.api.AfterAll;
15 import org.junit.jupiter.api.BeforeAll;
16 import org.junit.jupiter.api.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.NodeIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
21 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
22 import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
23 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
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.data.tree.impl.di.InMemoryDataTreeFactory;
29 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
30 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
31
32 class Bug5968Test {
33     private static final String NS = "bug5968";
34     private static final String REV = "2016-07-28";
35     private static final QName ROOT = QName.create(NS, REV, "root");
36     private static final QName MY_LIST = QName.create(NS, REV, "my-list");
37     private static final QName LIST_ID = QName.create(NS, REV, "list-id");
38     private static final QName MANDATORY_LEAF = QName.create(NS, REV, "mandatory-leaf");
39     private static final QName COMMON_LEAF = QName.create(NS, REV, "common-leaf");
40
41     private static EffectiveModelContext SCHEMA_CONTEXT;
42
43     @BeforeAll
44     static void beforeClass() {
45         SCHEMA_CONTEXT = YangParserTestUtils.parseYang("""
46             module bug5968 {
47               yang-version 1;
48               namespace bug5968;
49               prefix bug5968;
50
51               revision 2016-07-28 {
52                 description "test";
53               }
54
55               container root {
56                 list my-list {
57                   key "list-id";
58                   leaf list-id {
59                     type string;
60                   }
61                   leaf mandatory-leaf {
62                     type string;
63                     mandatory true;
64                   }
65                   leaf common-leaf {
66                     type string;
67                   }
68                 }
69               }
70             }""");
71     }
72
73     @AfterAll
74     static void afterClass() {
75         SCHEMA_CONTEXT = null;
76     }
77
78     private static DataTree initDataTree(final EffectiveModelContext schemaContext, final boolean withMapNode)
79             throws DataValidationFailedException {
80         final var inMemoryDataTree = new InMemoryDataTreeFactory().create(
81                 DataTreeConfiguration.DEFAULT_CONFIGURATION, schemaContext);
82
83         final var root = ImmutableNodes.newContainerBuilder()
84                 .withNodeIdentifier(new NodeIdentifier(ROOT));
85         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
86         modificationTree.write(YangInstanceIdentifier.of(ROOT), withMapNode
87             ? root.withChild(ImmutableNodes.newSystemMapBuilder()
88                 .withNodeIdentifier(new NodeIdentifier(MY_LIST))
89                 .build())
90                 .build()
91                 : root.build());
92         modificationTree.ready();
93
94         inMemoryDataTree.validate(modificationTree);
95         final var prepare = inMemoryDataTree.prepare(modificationTree);
96         inMemoryDataTree.commit(prepare);
97
98         return inMemoryDataTree;
99     }
100
101     private static DataTree emptyDataTree(final EffectiveModelContext schemaContext) {
102         return new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_CONFIGURATION, schemaContext);
103     }
104
105     @Test
106     void writeInvalidContainerTest() throws DataValidationFailedException {
107         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
108
109         final var myList = createMap(true);
110         final var root = ImmutableNodes.newContainerBuilder()
111                 .withNodeIdentifier(new NodeIdentifier(ROOT)).withChild(myList);
112
113         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
114         modificationTree.write(YangInstanceIdentifier.of(ROOT), root.build());
115
116         try {
117             modificationTree.ready();
118             inMemoryDataTree.validate(modificationTree);
119             final var prepare = inMemoryDataTree.prepare(modificationTree);
120             inMemoryDataTree.commit(prepare);
121             fail("Should fail due to missing mandatory leaf.");
122         } catch (final IllegalArgumentException e) {
123             assertEquals("Node (bug5968?revision=2016-07-28)my-list[{(bug5968?revision=2016-07-28)list-id=1}] is "
124                 + "missing mandatory descendant /(bug5968?revision=2016-07-28)mandatory-leaf", e.getMessage());
125         }
126     }
127
128     @Test
129     void writeInvalidMapTest() throws DataValidationFailedException {
130         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
131         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
132         writeMap(modificationTree, true);
133
134         try {
135             modificationTree.ready();
136             inMemoryDataTree.validate(modificationTree);
137             final var prepare = inMemoryDataTree.prepare(modificationTree);
138             inMemoryDataTree.commit(prepare);
139             fail("Should fail due to missing mandatory leaf.");
140         } catch (final IllegalArgumentException e) {
141             assertEquals("Node (bug5968?revision=2016-07-28)my-list[{(bug5968?revision=2016-07-28)list-id=1}] is "
142                 + "missing mandatory descendant /(bug5968?revision=2016-07-28)mandatory-leaf", e.getMessage());
143         }
144     }
145
146     @Test
147     void writeInvalidMapEntryTest() throws DataValidationFailedException {
148         final var inMemoryDataTree = initDataTree(SCHEMA_CONTEXT, true);
149         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
150
151         writeMapEntry(modificationTree, "1", null, "common-value");
152
153         try {
154             modificationTree.ready();
155             inMemoryDataTree.validate(modificationTree);
156             final var prepare = inMemoryDataTree.prepare(modificationTree);
157             inMemoryDataTree.commit(prepare);
158             fail("Should fail due to missing mandatory leaf.");
159         } catch (final IllegalArgumentException e) {
160             assertEquals("Node (bug5968?revision=2016-07-28)my-list[{(bug5968?revision=2016-07-28)list-id=1}] is "
161                 + "missing mandatory descendant /(bug5968?revision=2016-07-28)mandatory-leaf", e.getMessage());
162         }
163     }
164
165     private static void writeMap(final DataTreeModification modificationTree, final boolean mandatoryDataMissing) {
166         modificationTree.write(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMap(mandatoryDataMissing));
167     }
168
169     private static SystemMapNode createMap(final boolean mandatoryDataMissing) {
170         return ImmutableNodes.newSystemMapBuilder()
171             .withNodeIdentifier(new NodeIdentifier(MY_LIST))
172             .withChild(mandatoryDataMissing ? createMapEntry("1", "common-value")
173                 : createMapEntry("1", "mandatory-value", "common-value"))
174             .build();
175     }
176
177     private static void writeMapEntry(final DataTreeModification modificationTree, final Object listIdValue,
178             final Object mandatoryLeafValue, final Object commonLeafValue) throws DataValidationFailedException {
179         final var taskEntryNode = mandatoryLeafValue == null ? createMapEntry(listIdValue, commonLeafValue)
180                 : createMapEntry(listIdValue, mandatoryLeafValue, commonLeafValue);
181
182         modificationTree.write(
183                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
184                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue))),
185                 taskEntryNode);
186     }
187
188     private static MapEntryNode createMapEntry(final Object listIdValue, final Object mandatoryLeafValue,
189             final Object commonLeafValue) {
190         return ImmutableNodes.newMapEntryBuilder()
191                 .withNodeIdentifier(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
192                 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue))
193                 .withChild(ImmutableNodes.leafNode(MANDATORY_LEAF, mandatoryLeafValue))
194                 .withChild(ImmutableNodes.leafNode(COMMON_LEAF, commonLeafValue)).build();
195     }
196
197     private static MapEntryNode createMapEntry(final Object listIdValue, final Object commonLeafValue) {
198         return ImmutableNodes.newMapEntryBuilder()
199                 .withNodeIdentifier(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
200                 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue))
201                 .withChild(ImmutableNodes.leafNode(COMMON_LEAF, commonLeafValue)).build();
202     }
203
204     @Test
205     void writeValidContainerTest() throws DataValidationFailedException {
206         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
207
208         final var myList = createMap(false);
209         final var root = ImmutableNodes.newContainerBuilder()
210                 .withNodeIdentifier(new NodeIdentifier(ROOT)).withChild(myList);
211
212         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
213         modificationTree.write(YangInstanceIdentifier.of(ROOT), root.build());
214         modificationTree.ready();
215         inMemoryDataTree.validate(modificationTree);
216         final var prepare = inMemoryDataTree.prepare(modificationTree);
217         inMemoryDataTree.commit(prepare);
218     }
219
220     @Test
221     void writeValidMapTest() throws DataValidationFailedException {
222         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
223         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
224         writeMap(modificationTree, false);
225
226         modificationTree.ready();
227         inMemoryDataTree.validate(modificationTree);
228         final var prepare = inMemoryDataTree.prepare(modificationTree);
229         inMemoryDataTree.commit(prepare);
230     }
231
232     @Test
233     void writeValidMapEntryTest() throws DataValidationFailedException {
234         final var inMemoryDataTree = initDataTree(SCHEMA_CONTEXT, true);
235         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
236
237         writeMapEntry(modificationTree, "1", "mandatory-value", "common-value");
238
239         modificationTree.ready();
240         inMemoryDataTree.validate(modificationTree);
241         final var prepare = inMemoryDataTree.prepare(modificationTree);
242         inMemoryDataTree.commit(prepare);
243     }
244 }