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.tree.impl;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.fail;
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.SystemMapNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
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.data.tree.api.DataTree;
28 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
29 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
30 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
31 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
32 import org.opendaylight.yangtools.yang.data.tree.impl.di.InMemoryDataTreeFactory;
33 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
34 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
36 public class Bug5968Test {
37 private static final String NS = "bug5968";
38 private static final String REV = "2016-07-28";
39 private static final QName ROOT = QName.create(NS, REV, "root");
40 private static final QName MY_LIST = QName.create(NS, REV, "my-list");
41 private static final QName LIST_ID = QName.create(NS, REV, "list-id");
42 private static final QName MANDATORY_LEAF = QName.create(NS, REV, "mandatory-leaf");
43 private static final QName COMMON_LEAF = QName.create(NS, REV, "common-leaf");
45 private static EffectiveModelContext SCHEMA_CONTEXT;
48 public static void beforeClass() {
49 SCHEMA_CONTEXT = YangParserTestUtils.parseYang("""
78 public static void afterClass() {
79 SCHEMA_CONTEXT = null;
82 private static DataTree initDataTree(final EffectiveModelContext schemaContext, final boolean withMapNode)
83 throws DataValidationFailedException {
84 final DataTree inMemoryDataTree = new InMemoryDataTreeFactory().create(
85 DataTreeConfiguration.DEFAULT_CONFIGURATION, schemaContext);
87 final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> root = Builders.containerBuilder()
88 .withNodeIdentifier(new NodeIdentifier(ROOT));
89 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
90 modificationTree.write(
91 YangInstanceIdentifier.of(ROOT),
92 withMapNode ? root.withChild(
93 Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST)).build()).build() : root
95 modificationTree.ready();
97 inMemoryDataTree.validate(modificationTree);
98 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
99 inMemoryDataTree.commit(prepare);
101 return inMemoryDataTree;
104 private static DataTree emptyDataTree(final EffectiveModelContext schemaContext)
105 throws DataValidationFailedException {
106 return new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_CONFIGURATION, schemaContext);
110 public void writeInvalidContainerTest() throws DataValidationFailedException {
111 final DataTree inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
113 final SystemMapNode myList = createMap(true);
114 final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> root = Builders.containerBuilder()
115 .withNodeIdentifier(new NodeIdentifier(ROOT)).withChild(myList);
117 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
118 modificationTree.write(YangInstanceIdentifier.of(ROOT), root.build());
121 modificationTree.ready();
122 inMemoryDataTree.validate(modificationTree);
123 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
124 inMemoryDataTree.commit(prepare);
125 fail("Should fail due to missing mandatory leaf.");
126 } catch (final IllegalArgumentException e) {
127 assertEquals("Node (bug5968?revision=2016-07-28)my-list[{(bug5968?revision=2016-07-28)list-id=1}] is "
128 + "missing mandatory descendant /(bug5968?revision=2016-07-28)mandatory-leaf", e.getMessage());
133 public void writeInvalidMapTest() throws DataValidationFailedException {
134 final DataTree inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
135 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
136 writeMap(modificationTree, true);
139 modificationTree.ready();
140 inMemoryDataTree.validate(modificationTree);
141 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
142 inMemoryDataTree.commit(prepare);
143 fail("Should fail due to missing mandatory leaf.");
144 } catch (final IllegalArgumentException e) {
145 assertEquals("Node (bug5968?revision=2016-07-28)my-list[{(bug5968?revision=2016-07-28)list-id=1}] is "
146 + "missing mandatory descendant /(bug5968?revision=2016-07-28)mandatory-leaf", e.getMessage());
151 public void writeInvalidMapEntryTest() throws DataValidationFailedException {
152 final DataTree inMemoryDataTree = initDataTree(SCHEMA_CONTEXT, true);
153 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
155 writeMapEntry(modificationTree, "1", null, "common-value");
158 modificationTree.ready();
159 inMemoryDataTree.validate(modificationTree);
160 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
161 inMemoryDataTree.commit(prepare);
162 fail("Should fail due to missing mandatory leaf.");
163 } catch (final IllegalArgumentException e) {
164 assertEquals("Node (bug5968?revision=2016-07-28)my-list[{(bug5968?revision=2016-07-28)list-id=1}] is "
165 + "missing mandatory descendant /(bug5968?revision=2016-07-28)mandatory-leaf", e.getMessage());
169 private static void writeMap(final DataTreeModification modificationTree, final boolean mandatoryDataMissing) {
170 modificationTree.write(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMap(mandatoryDataMissing));
173 private static SystemMapNode createMap(final boolean mandatoryDataMissing) {
174 return Builders.mapBuilder()
175 .withNodeIdentifier(new NodeIdentifier(MY_LIST))
176 .withChild(mandatoryDataMissing ? createMapEntry("1", "common-value")
177 : createMapEntry("1", "mandatory-value", "common-value"))
181 private static void writeMapEntry(final DataTreeModification modificationTree, final Object listIdValue,
182 final Object mandatoryLeafValue, final Object commonLeafValue) throws DataValidationFailedException {
183 final MapEntryNode taskEntryNode = mandatoryLeafValue == null ? createMapEntry(listIdValue, commonLeafValue)
184 : createMapEntry(listIdValue, mandatoryLeafValue, commonLeafValue);
186 modificationTree.write(
187 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
188 .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue))),
192 private static MapEntryNode createMapEntry(final Object listIdValue, final Object mandatoryLeafValue,
193 final Object commonLeafValue) {
194 return Builders.mapEntryBuilder()
195 .withNodeIdentifier(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
196 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue))
197 .withChild(ImmutableNodes.leafNode(MANDATORY_LEAF, mandatoryLeafValue))
198 .withChild(ImmutableNodes.leafNode(COMMON_LEAF, commonLeafValue)).build();
201 private static MapEntryNode createMapEntry(final Object listIdValue, final Object commonLeafValue) {
202 return Builders.mapEntryBuilder()
203 .withNodeIdentifier(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
204 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue))
205 .withChild(ImmutableNodes.leafNode(COMMON_LEAF, commonLeafValue)).build();
209 public void writeValidContainerTest() throws DataValidationFailedException {
210 final DataTree inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
212 final SystemMapNode myList = createMap(false);
213 final DataContainerNodeBuilder<NodeIdentifier, ContainerNode> root = Builders.containerBuilder()
214 .withNodeIdentifier(new NodeIdentifier(ROOT)).withChild(myList);
216 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
217 modificationTree.write(YangInstanceIdentifier.of(ROOT), root.build());
218 modificationTree.ready();
219 inMemoryDataTree.validate(modificationTree);
220 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
221 inMemoryDataTree.commit(prepare);
225 public void writeValidMapTest() throws DataValidationFailedException {
226 final DataTree inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
227 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
228 writeMap(modificationTree, false);
230 modificationTree.ready();
231 inMemoryDataTree.validate(modificationTree);
232 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
233 inMemoryDataTree.commit(prepare);
237 public void writeValidMapEntryTest() throws DataValidationFailedException {
238 final DataTree inMemoryDataTree = initDataTree(SCHEMA_CONTEXT, true);
239 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
241 writeMapEntry(modificationTree, "1", "mandatory-value", "common-value");
243 modificationTree.ready();
244 inMemoryDataTree.validate(modificationTree);
245 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
246 inMemoryDataTree.commit(prepare);