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