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.jupiter.api.Assertions.assertEquals;
11 import static org.junit.jupiter.api.Assertions.fail;
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;
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");
41 private static EffectiveModelContext SCHEMA_CONTEXT;
44 static void beforeClass() {
45 SCHEMA_CONTEXT = YangParserTestUtils.parseYang("""
74 static void afterClass() {
75 SCHEMA_CONTEXT = null;
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);
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))
92 modificationTree.ready();
94 inMemoryDataTree.validate(modificationTree);
95 final var prepare = inMemoryDataTree.prepare(modificationTree);
96 inMemoryDataTree.commit(prepare);
98 return inMemoryDataTree;
101 private static DataTree emptyDataTree(final EffectiveModelContext schemaContext) {
102 return new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_CONFIGURATION, schemaContext);
106 void writeInvalidContainerTest() throws DataValidationFailedException {
107 final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
109 final var myList = createMap(true);
110 final var root = ImmutableNodes.newContainerBuilder()
111 .withNodeIdentifier(new NodeIdentifier(ROOT)).withChild(myList);
113 final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
114 modificationTree.write(YangInstanceIdentifier.of(ROOT), root.build());
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());
129 void writeInvalidMapTest() throws DataValidationFailedException {
130 final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
131 final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
132 writeMap(modificationTree, true);
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());
147 void writeInvalidMapEntryTest() throws DataValidationFailedException {
148 final var inMemoryDataTree = initDataTree(SCHEMA_CONTEXT, true);
149 final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
151 writeMapEntry(modificationTree, "1", null, "common-value");
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());
165 private static void writeMap(final DataTreeModification modificationTree, final boolean mandatoryDataMissing) {
166 modificationTree.write(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMap(mandatoryDataMissing));
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"))
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);
182 modificationTree.write(
183 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
184 .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue))),
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();
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();
205 void writeValidContainerTest() throws DataValidationFailedException {
206 final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
208 final var myList = createMap(false);
209 final var root = ImmutableNodes.newContainerBuilder()
210 .withNodeIdentifier(new NodeIdentifier(ROOT)).withChild(myList);
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);
221 void writeValidMapTest() throws DataValidationFailedException {
222 final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
223 final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
224 writeMap(modificationTree, false);
226 modificationTree.ready();
227 inMemoryDataTree.validate(modificationTree);
228 final var prepare = inMemoryDataTree.prepare(modificationTree);
229 inMemoryDataTree.commit(prepare);
233 void writeValidMapEntryTest() throws DataValidationFailedException {
234 final var inMemoryDataTree = initDataTree(SCHEMA_CONTEXT, true);
235 final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
237 writeMapEntry(modificationTree, "1", "mandatory-value", "common-value");
239 modificationTree.ready();
240 inMemoryDataTree.validate(modificationTree);
241 final var prepare = inMemoryDataTree.prepare(modificationTree);
242 inMemoryDataTree.commit(prepare);