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;
12 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.leafNode;
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.NodeIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
20 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
21 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
22 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
23 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
24 import org.opendaylight.yangtools.yang.data.tree.api.TreeType;
25 import org.opendaylight.yangtools.yang.data.tree.impl.di.InMemoryDataTreeFactory;
26 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
28 class MandatoryLeafTest {
29 private static EffectiveModelContext SCHEMA_CONTEXT;
32 static void beforeClass() {
33 SCHEMA_CONTEXT = TestModel.createTestContext("/mandatory-leaf-test.yang");
37 static void afterClass() {
38 SCHEMA_CONTEXT = null;
41 private static DataTree initDataTree(final boolean enableValidation) {
42 return new InMemoryDataTreeFactory().create(new DataTreeConfiguration.Builder(TreeType.CONFIGURATION)
43 .setMandatoryNodesValidation(enableValidation)
44 .build(), SCHEMA_CONTEXT);
48 void testCorrectMandatoryLeafWrite() throws DataValidationFailedException {
49 final var inMemoryDataTree = initDataTree(true);
50 final var choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
52 final var container = Builders.containerBuilder()
53 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
54 .withChild(Builders.choiceBuilder()
55 .withNodeIdentifier(choice1Id)
56 .withChild(Builders.containerBuilder()
57 .withNodeIdentifier(new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
58 .withChild(leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf1"), "leaf-value"))
59 .withChild(leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf2"), "leaf-value2"))
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 = Builders.containerBuilder()
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 = Builders.choiceBuilder()
92 .withNodeIdentifier(choice1Id)
93 .withChild(Builders.containerBuilder()
94 .withNodeIdentifier(new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
95 .withChild(leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf1"), "leaf-value"))
96 .withChild(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 = Builders.containerBuilder()
116 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
117 .withChild(Builders.choiceBuilder()
118 .withNodeIdentifier(choice1Id)
119 .withChild(Builders.containerBuilder()
120 .withNodeIdentifier(new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
121 .withChild(leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf2"), "leaf-value2"))
126 final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
127 modificationTree.write(TestModel.TEST_PATH, container);
128 modificationTree.ready();
130 inMemoryDataTree.validate(modificationTree);
131 final var prepare = inMemoryDataTree.prepare(modificationTree);
132 inMemoryDataTree.commit(prepare);
133 } catch (final IllegalArgumentException e) {
134 assertEquals("Node (urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?"
135 + "revision=2014-03-13)choice1 is missing mandatory descendant /(urn:opendaylight:params:xml:ns:"
136 + "yang:controller:md:sal:dom:store:test?revision=2014-03-13)case2-cont/case2-leaf1",
144 void testDisabledValidation() throws DataValidationFailedException {
145 final var inMemoryDataTree = initDataTree(false);
146 final var choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
148 final ContainerNode container = Builders.containerBuilder()
149 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
150 .withChild(Builders.choiceBuilder()
151 .withNodeIdentifier(choice1Id)
152 .withChild(Builders.containerBuilder()
153 .withNodeIdentifier(new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
154 .withChild(leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf2"), "leaf-value2"))
158 final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
159 modificationTree.write(TestModel.TEST_PATH, container);
160 modificationTree.ready();
162 inMemoryDataTree.validate(modificationTree);
163 final var prepare = inMemoryDataTree.prepare(modificationTree);
164 inMemoryDataTree.commit(prepare);
168 void testMandatoryLeafViolationChoiceWrite() {
169 assertThrows(IllegalArgumentException.class, () -> {
170 final var inMemoryDataTree = initDataTree(true);
172 final var container = Builders.containerBuilder()
173 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME)).build();
175 final var modificationTree1 = inMemoryDataTree.takeSnapshot().newModification();
176 modificationTree1.write(TestModel.TEST_PATH, container);
177 modificationTree1.ready();
179 inMemoryDataTree.validate(modificationTree1);
180 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
181 inMemoryDataTree.commit(prepare1);
184 final var choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
185 final var choice = Builders.choiceBuilder()
186 .withNodeIdentifier(choice1Id)
187 .withChild(Builders.containerBuilder()
188 .withNodeIdentifier(new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
189 .withChild(leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf2"), "leaf-value2"))
194 final var modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
195 modificationTree2.write(TestModel.TEST_PATH.node(choice1Id), choice);
196 modificationTree2.ready();
197 inMemoryDataTree.validate(modificationTree2);
198 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
199 inMemoryDataTree.commit(prepare2);
200 } catch (final IllegalArgumentException e) {
201 assertEquals("Node (urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?"
202 + "revision=2014-03-13)choice1 is missing mandatory descendant /(urn:opendaylight:params:xml:ns:"
203 + "yang:controller:md:sal:dom:store:test?revision=2014-03-13)case2-cont/case2-leaf1",
211 void testDisabledValidationChoiceWrite() throws DataValidationFailedException {
212 final var inMemoryDataTree = initDataTree(false);
214 final var container = Builders.containerBuilder()
215 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME)).build();
217 final var modificationTree1 = inMemoryDataTree.takeSnapshot().newModification();
218 modificationTree1.write(TestModel.TEST_PATH, container);
219 modificationTree1.ready();
221 inMemoryDataTree.validate(modificationTree1);
222 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
223 inMemoryDataTree.commit(prepare1);
226 final var choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
227 final var choice = Builders.choiceBuilder()
228 .withNodeIdentifier(choice1Id)
229 .withChild(Builders.containerBuilder()
230 .withNodeIdentifier(new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
231 .withChild(leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf2"), "leaf-value2"))
235 final var modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
236 modificationTree2.write(TestModel.TEST_PATH.node(choice1Id), choice);
237 modificationTree2.ready();
238 inMemoryDataTree.validate(modificationTree2);
239 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
240 inMemoryDataTree.commit(prepare2);