2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
15 import com.google.common.collect.ImmutableMap;
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.DataContainerChild;
23 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
25 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
26 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
27 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
28 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
29 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
30 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
31 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
32 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
33 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
35 public class Bug5830Test {
36 private static final String NS = "foo";
37 private static final String REV = "2016-05-17";
38 private static final QName TASK_CONTAINER = QName.create(NS, REV, "task-container");
39 private static final QName TASK = QName.create(NS, REV, "task");
40 private static final QName TASK_ID = QName.create(NS, REV, "task-id");
41 private static final QName TASK_DATA = QName.create(NS, REV, "task-data");
42 private static final QName OTHER_DATA = QName.create(NS, REV, "other-data");
43 private static final QName MANDATORY_DATA = QName.create(NS, REV, "mandatory-data");
44 private static final QName TASK_MANDATORY_LEAF = QName.create(NS, REV, "task-mandatory-leaf");
45 private static final QName NON_PRESENCE_CONTAINER = QName.create(NS, REV, "non-presence-container");
46 private static final QName NON_PRESENCE_CONTAINER_2 = QName.create(NS, REV, "non-presence-container-2");
47 private static final QName PRESENCE_CONTAINER_2 = QName.create(NS, REV, "presence-container-2");
48 private static final QName MANDATORY_LEAF_2 = QName.create(NS, REV, "mandatory-leaf-2");
50 private static DataTree initDataTree(final SchemaContext schemaContext)
51 throws DataValidationFailedException {
52 DataTree inMemoryDataTree = new InMemoryDataTreeFactory().create(
53 DataTreeConfiguration.DEFAULT_CONFIGURATION, schemaContext);
55 final MapNode taskNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(TASK)).build();
56 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
57 modificationTree.write(YangInstanceIdentifier.of(TASK_CONTAINER).node(TASK), taskNode);
58 modificationTree.ready();
60 inMemoryDataTree.validate(modificationTree);
61 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
62 inMemoryDataTree.commit(prepare);
63 return inMemoryDataTree;
67 public void testMandatoryNodes() throws DataValidationFailedException {
68 testPresenceContainer();
69 testNonPresenceContainer();
70 testMultipleContainers();
73 private static void testPresenceContainer() throws DataValidationFailedException {
74 final SchemaContext schemaContext = TestModel.createTestContext("/bug5830/foo-presence.yang");
75 assertNotNull("Schema context must not be null.", schemaContext);
77 testContainerIsNotPresent(schemaContext);
79 testContainerIsPresent(schemaContext);
80 fail("Should fail due to missing mandatory node under present presence container.");
81 } catch (IllegalArgumentException e) {
83 "Node (foo?revision=2016-05-17)task-data is missing mandatory descendant /(foo?revision=2016-05-17)"
84 + "mandatory-data", e.getMessage());
86 testMandatoryDataLeafIsPresent(schemaContext);
89 private static void testNonPresenceContainer() throws DataValidationFailedException {
90 final SchemaContext schemaContext = TestModel.createTestContext("/bug5830/foo-non-presence.yang");
91 assertNotNull("Schema context must not be null.", schemaContext);
94 testContainerIsNotPresent(schemaContext);
95 fail("Should fail due to missing mandatory node.");
96 } catch (IllegalArgumentException e) {
98 "Node (foo?revision=2016-05-17)task[{(foo?revision=2016-05-17)task-id=123}] is missing mandatory "
99 + "descendant /(foo?revision=2016-05-17)task-data/mandatory-data", e.getMessage());
103 testContainerIsPresent(schemaContext);
104 fail("Should fail due to missing mandatory node.");
105 } catch (IllegalArgumentException e) {
107 "Node (foo?revision=2016-05-17)task[{(foo?revision=2016-05-17)task-id=123}] is missing mandatory "
108 + "descendant /(foo?revision=2016-05-17)task-data/mandatory-data", e.getMessage());
110 testMandatoryDataLeafIsPresent(schemaContext);
113 private static void testMultipleContainers() throws DataValidationFailedException {
114 final SchemaContext schemaContext = TestModel.createTestContext("/bug5830/foo-multiple.yang");
115 assertNotNull("Schema context must not be null.", schemaContext);
117 testContainerIsNotPresent(schemaContext);
120 testContainerIsPresent(schemaContext);
121 fail("Should fail due to missing mandatory node under present presence container.");
122 } catch (IllegalArgumentException e) {
123 assertTrue(e.getMessage().startsWith(
124 "Node (foo?revision=2016-05-17)task-data is missing mandatory descendant"));
128 testMandatoryDataLeafIsPresent(schemaContext);
129 fail("Should fail due to missing mandatory node under present presence container.");
130 } catch (IllegalArgumentException e) {
131 assertEquals("Node (foo?revision=2016-05-17)task-data "
132 + "is missing mandatory descendant /(foo?revision=2016-05-17)non-presence-container/"
133 + "non-presence-container-2/mandatory-leaf-2", e.getMessage());
136 testMandatoryLeaf2IsPresent(schemaContext, false);
139 testMandatoryLeaf2IsPresent(schemaContext, true);
140 fail("Should fail due to missing mandatory node under present presence container.");
141 } catch (IllegalArgumentException e) {
143 "Node (foo?revision=2016-05-17)presence-container-2 is missing mandatory "
144 + "descendant /(foo?revision=2016-05-17)mandatory-leaf-3", e.getMessage());
148 private static void testContainerIsNotPresent(final SchemaContext schemaContext)
149 throws DataValidationFailedException {
150 final DataTree inMemoryDataTree = initDataTree(schemaContext);
151 final MapEntryNode taskEntryNode = Builders.mapEntryBuilder()
152 .withNodeIdentifier(NodeIdentifierWithPredicates.of(TASK, ImmutableMap.of(TASK_ID, "123")))
153 .withChild(ImmutableNodes.leafNode(TASK_ID, "123"))
154 .withChild(ImmutableNodes.leafNode(TASK_MANDATORY_LEAF, "mandatory data")).build();
156 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
157 modificationTree.write(
158 YangInstanceIdentifier.of(TASK_CONTAINER).node(TASK)
159 .node(NodeIdentifierWithPredicates.of(TASK, ImmutableMap.of(TASK_ID, "123"))), taskEntryNode);
160 modificationTree.ready();
162 inMemoryDataTree.validate(modificationTree);
163 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
164 inMemoryDataTree.commit(prepare);
167 private static void testContainerIsPresent(final SchemaContext schemaContext) throws DataValidationFailedException {
168 final DataTree inMemoryDataTree = initDataTree(schemaContext);
170 final MapEntryNode taskEntryNode = Builders.mapEntryBuilder()
171 .withNodeIdentifier(NodeIdentifierWithPredicates.of(TASK, ImmutableMap.of(TASK_ID, "123")))
172 .withChild(ImmutableNodes.leafNode(TASK_ID, "123"))
173 .withChild(ImmutableNodes.leafNode(TASK_MANDATORY_LEAF, "mandatory data"))
174 .withChild(createTaskDataContainer(false)).build();
176 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
177 modificationTree.write(
178 YangInstanceIdentifier.of(TASK_CONTAINER).node(TASK)
179 .node(NodeIdentifierWithPredicates.of(TASK, ImmutableMap.of(TASK_ID, "123"))), taskEntryNode);
180 modificationTree.ready();
182 inMemoryDataTree.validate(modificationTree);
183 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
184 inMemoryDataTree.commit(prepare);
187 private static void testMandatoryDataLeafIsPresent(final SchemaContext schemaContext)
188 throws DataValidationFailedException {
189 final DataTree inMemoryDataTree = initDataTree(schemaContext);
191 final MapEntryNode taskEntryNode = Builders.mapEntryBuilder()
192 .withNodeIdentifier(NodeIdentifierWithPredicates.of(TASK, ImmutableMap.of(TASK_ID, "123")))
193 .withChild(ImmutableNodes.leafNode(TASK_ID, "123"))
194 .withChild(ImmutableNodes.leafNode(TASK_MANDATORY_LEAF, "mandatory data"))
195 .withChild(createTaskDataContainer(true)).build();
197 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
198 modificationTree.write(
199 YangInstanceIdentifier.of(TASK_CONTAINER).node(TASK)
200 .node(NodeIdentifierWithPredicates.of(TASK, ImmutableMap.of(TASK_ID, "123"))), taskEntryNode);
201 modificationTree.ready();
203 inMemoryDataTree.validate(modificationTree);
204 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
205 inMemoryDataTree.commit(prepare);
208 private static void testMandatoryLeaf2IsPresent(final SchemaContext schemaContext,
209 final boolean withPresenceContianer) throws DataValidationFailedException {
210 final DataTree inMemoryDataTree = initDataTree(schemaContext);
212 final MapEntryNode taskEntryNode = Builders.mapEntryBuilder()
213 .withNodeIdentifier(NodeIdentifierWithPredicates.of(TASK, ImmutableMap.of(TASK_ID, "123")))
214 .withChild(ImmutableNodes.leafNode(TASK_ID, "123"))
215 .withChild(ImmutableNodes.leafNode(TASK_MANDATORY_LEAF, "mandatory data"))
216 .withChild(createTaskDataMultipleContainer(withPresenceContianer)).build();
218 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
219 modificationTree.write(
220 YangInstanceIdentifier.of(TASK_CONTAINER).node(TASK)
221 .node(NodeIdentifierWithPredicates.of(TASK, ImmutableMap.of(TASK_ID, "123"))), taskEntryNode);
222 modificationTree.ready();
224 inMemoryDataTree.validate(modificationTree);
225 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
226 inMemoryDataTree.commit(prepare);
229 private static DataContainerChild<?, ?> createTaskDataContainer(final boolean withMandatoryNode) {
230 DataContainerNodeBuilder<NodeIdentifier, ContainerNode> taskDataBuilder = Builders.containerBuilder()
231 .withNodeIdentifier(new NodeIdentifier(TASK_DATA))
232 .withChild(ImmutableNodes.leafNode(OTHER_DATA, "foo"));
233 if (withMandatoryNode) {
234 taskDataBuilder.withChild(ImmutableNodes.leafNode(MANDATORY_DATA, "mandatory-data-value"));
236 return taskDataBuilder.build();
239 private static DataContainerChild<?, ?> createTaskDataMultipleContainer(final boolean withPresenceContianer) {
240 DataContainerNodeBuilder<NodeIdentifier, ContainerNode> nonPresenceContainerBuilder = Builders
242 .withNodeIdentifier(new NodeIdentifier(NON_PRESENCE_CONTAINER))
244 Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(NON_PRESENCE_CONTAINER_2))
245 .withChild(ImmutableNodes.leafNode(MANDATORY_LEAF_2, "mandatory leaf data 2")).build());
247 if (withPresenceContianer) {
248 nonPresenceContainerBuilder.withChild(Builders.containerBuilder()
249 .withNodeIdentifier(new NodeIdentifier(PRESENCE_CONTAINER_2)).build());
252 DataContainerNodeBuilder<NodeIdentifier, ContainerNode> taskDataBuilder = Builders.containerBuilder()
253 .withNodeIdentifier(new NodeIdentifier(TASK_DATA))
254 .withChild(ImmutableNodes.leafNode(OTHER_DATA, "foo"));
255 taskDataBuilder.withChild(ImmutableNodes.leafNode(MANDATORY_DATA, "mandatory-data-value"));
256 taskDataBuilder.withChild(nonPresenceContainerBuilder.build());
258 return taskDataBuilder.build();