2 * Copyright (c) 2015 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.assertThrows;
13 import org.junit.jupiter.api.AfterAll;
14 import org.junit.jupiter.api.BeforeAll;
15 import org.junit.jupiter.api.Test;
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
18 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
19 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
20 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
21 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
22 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
23 import org.opendaylight.yangtools.yang.data.tree.api.TreeType;
24 import org.opendaylight.yangtools.yang.data.tree.impl.di.InMemoryDataTreeFactory;
25 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
27 class MandatoryLeafTest {
28 private static EffectiveModelContext SCHEMA_CONTEXT;
31 static void beforeClass() {
32 SCHEMA_CONTEXT = TestModel.createTestContext("/mandatory-leaf-test.yang");
36 static void afterClass() {
37 SCHEMA_CONTEXT = null;
40 private static DataTree initDataTree(final boolean enableValidation) {
41 return new InMemoryDataTreeFactory().create(new DataTreeConfiguration.Builder(TreeType.CONFIGURATION)
42 .setMandatoryNodesValidation(enableValidation)
43 .build(), SCHEMA_CONTEXT);
47 void testCorrectMandatoryLeafWrite() throws DataValidationFailedException {
48 final var inMemoryDataTree = initDataTree(true);
49 final var choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
51 final var container = ImmutableNodes.newContainerBuilder()
52 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
53 .withChild(ImmutableNodes.newChoiceBuilder()
54 .withNodeIdentifier(choice1Id)
55 .withChild(ImmutableNodes.newContainerBuilder()
56 .withNodeIdentifier(new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
57 .withChild(ImmutableNodes.leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf1"), "leaf-value"))
58 .withChild(ImmutableNodes.leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf2"),
64 final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
65 modificationTree.write(TestModel.TEST_PATH, container);
66 modificationTree.ready();
68 inMemoryDataTree.validate(modificationTree);
69 final var prepare = inMemoryDataTree.prepare(modificationTree);
70 inMemoryDataTree.commit(prepare);
74 void testCorrectMandatoryLeafChoiceWrite() throws DataValidationFailedException {
75 final var inMemoryDataTree = initDataTree(true);
77 final var container = ImmutableNodes.newContainerBuilder()
78 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
81 final var modificationTree1 = inMemoryDataTree.takeSnapshot().newModification();
82 modificationTree1.write(TestModel.TEST_PATH, container);
83 modificationTree1.ready();
85 inMemoryDataTree.validate(modificationTree1);
86 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
87 inMemoryDataTree.commit(prepare1);
90 final var choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
91 final var choice = ImmutableNodes.newChoiceBuilder()
92 .withNodeIdentifier(choice1Id)
93 .withChild(ImmutableNodes.newContainerBuilder()
94 .withNodeIdentifier(new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
95 .withChild(ImmutableNodes.leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf1"), "leaf-value"))
96 .withChild(ImmutableNodes.leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf2"), "leaf-value2"))
100 final var modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
101 modificationTree2.write(TestModel.TEST_PATH.node(choice1Id), choice);
102 modificationTree2.ready();
104 inMemoryDataTree.validate(modificationTree2);
105 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
106 inMemoryDataTree.commit(prepare2);
110 void testMandatoryLeafViolation() {
111 assertThrows(IllegalArgumentException.class, () -> {
112 final var inMemoryDataTree = initDataTree(true);
113 final var choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
115 final var container = ImmutableNodes.newContainerBuilder()
116 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
117 .withChild(ImmutableNodes.newChoiceBuilder()
118 .withNodeIdentifier(choice1Id)
119 .withChild(ImmutableNodes.newContainerBuilder()
120 .withNodeIdentifier(new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
121 .withChild(ImmutableNodes.leafNode(
122 QName.create(TestModel.TEST_QNAME, "case2-leaf2"), "leaf-value2"))
127 final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
128 modificationTree.write(TestModel.TEST_PATH, container);
129 modificationTree.ready();
131 inMemoryDataTree.validate(modificationTree);
132 final var prepare = inMemoryDataTree.prepare(modificationTree);
133 inMemoryDataTree.commit(prepare);
134 } catch (final IllegalArgumentException e) {
135 assertEquals("Node (urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?"
136 + "revision=2014-03-13)choice1 is missing mandatory descendant /(urn:opendaylight:params:xml:ns:"
137 + "yang:controller:md:sal:dom:store:test?revision=2014-03-13)case2-cont/case2-leaf1",
145 void testDisabledValidation() throws DataValidationFailedException {
146 final var inMemoryDataTree = initDataTree(false);
147 final var choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
149 final ContainerNode container = ImmutableNodes.newContainerBuilder()
150 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
151 .withChild(ImmutableNodes.newChoiceBuilder()
152 .withNodeIdentifier(choice1Id)
153 .withChild(ImmutableNodes.newContainerBuilder()
154 .withNodeIdentifier(new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
155 .withChild(ImmutableNodes.leafNode(
156 QName.create(TestModel.TEST_QNAME, "case2-leaf2"), "leaf-value2"))
160 final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
161 modificationTree.write(TestModel.TEST_PATH, container);
162 modificationTree.ready();
164 inMemoryDataTree.validate(modificationTree);
165 final var prepare = inMemoryDataTree.prepare(modificationTree);
166 inMemoryDataTree.commit(prepare);
170 void testMandatoryLeafViolationChoiceWrite() {
171 assertThrows(IllegalArgumentException.class, () -> {
172 final var inMemoryDataTree = initDataTree(true);
174 final var container = ImmutableNodes.newContainerBuilder()
175 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME)).build();
177 final var modificationTree1 = inMemoryDataTree.takeSnapshot().newModification();
178 modificationTree1.write(TestModel.TEST_PATH, container);
179 modificationTree1.ready();
181 inMemoryDataTree.validate(modificationTree1);
182 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
183 inMemoryDataTree.commit(prepare1);
186 final var choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
187 final var choice = ImmutableNodes.newChoiceBuilder()
188 .withNodeIdentifier(choice1Id)
189 .withChild(ImmutableNodes.newContainerBuilder()
190 .withNodeIdentifier(new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
191 .withChild(ImmutableNodes.leafNode(
192 QName.create(TestModel.TEST_QNAME, "case2-leaf2"), "leaf-value2"))
197 final var modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
198 modificationTree2.write(TestModel.TEST_PATH.node(choice1Id), choice);
199 modificationTree2.ready();
200 inMemoryDataTree.validate(modificationTree2);
201 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
202 inMemoryDataTree.commit(prepare2);
203 } catch (final IllegalArgumentException e) {
204 assertEquals("Node (urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?"
205 + "revision=2014-03-13)choice1 is missing mandatory descendant /(urn:opendaylight:params:xml:ns:"
206 + "yang:controller:md:sal:dom:store:test?revision=2014-03-13)case2-cont/case2-leaf1",
214 void testDisabledValidationChoiceWrite() throws DataValidationFailedException {
215 final var inMemoryDataTree = initDataTree(false);
217 final var container = ImmutableNodes.newContainerBuilder()
218 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME)).build();
220 final var modificationTree1 = inMemoryDataTree.takeSnapshot().newModification();
221 modificationTree1.write(TestModel.TEST_PATH, container);
222 modificationTree1.ready();
224 inMemoryDataTree.validate(modificationTree1);
225 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
226 inMemoryDataTree.commit(prepare1);
229 final var choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
230 final var choice = ImmutableNodes.newChoiceBuilder()
231 .withNodeIdentifier(choice1Id)
232 .withChild(ImmutableNodes.newContainerBuilder()
233 .withNodeIdentifier(new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
234 .withChild(ImmutableNodes.leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf2"), "leaf-value2"))
238 final var modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
239 modificationTree2.write(TestModel.TEST_PATH.node(choice1Id), choice);
240 modificationTree2.ready();
241 inMemoryDataTree.validate(modificationTree2);
242 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
243 inMemoryDataTree.commit(prepare2);