BUG-4355: mandatory node presence enforcement
[yangtools.git] / yang / yang-data-impl / src / test / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / MandatoryLeafTest.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.leafNode;
13
14 import org.junit.Before;
15 import org.junit.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.ChoiceNode;
19 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
20 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
21 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
22 import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
23 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
24 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
25 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
26
27 public class MandatoryLeafTest {
28
29     private SchemaContext schemaContext;
30
31     @Before
32     public void prepare() throws ReactorException {
33         schemaContext = RetestModel.createTestContext("/mandatory-leaf-test.yang");
34         assertNotNull("Schema context must not be null.", schemaContext);
35     }
36
37     private InMemoryDataTree initDataTree() {
38         InMemoryDataTree inMemoryDataTree = (InMemoryDataTree) InMemoryDataTreeFactory.getInstance().create(
39                 TreeType.CONFIGURATION);
40         inMemoryDataTree.setSchemaContext(schemaContext);
41         return inMemoryDataTree;
42     }
43
44     @Test
45     public void testCorrectMandatoryLeafWrite() throws DataValidationFailedException {
46         final InMemoryDataTree inMemoryDataTree = initDataTree();
47         final NodeIdentifier choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
48
49         final ContainerNode container = Builders
50                 .containerBuilder()
51                 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
52                 .withChild(
53                         Builders.choiceBuilder()
54                                 .withNodeIdentifier(choice1Id)
55                                 .withChild(
56                                         Builders.containerBuilder()
57                                                 .withNodeIdentifier(
58                                                         new NodeIdentifier(QName.create(TestModel.TEST_QNAME,
59                                                                 "case2-cont")))
60                                                 .withChild(
61                                                         leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf1"),
62                                                                 "leaf-value"))
63                                                 .withChild(
64                                                         leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf2"),
65                                                                 "leaf-value2")).build()).build()).build();
66
67         final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
68         modificationTree.write(TestModel.TEST_PATH, container);
69         modificationTree.ready();
70
71         inMemoryDataTree.validate(modificationTree);
72         final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
73         inMemoryDataTree.commit(prepare);
74     }
75
76     @Test
77     public void testCorrectMandatoryLeafChoiceWrite() throws DataValidationFailedException {
78         final InMemoryDataTree inMemoryDataTree = initDataTree();
79         // Container write
80         final ContainerNode container = Builders.containerBuilder()
81                 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME)).build();
82
83         final InMemoryDataTreeModification modificationTree1 = inMemoryDataTree.takeSnapshot().newModification();
84         modificationTree1.write(TestModel.TEST_PATH, container);
85         modificationTree1.ready();
86
87         inMemoryDataTree.validate(modificationTree1);
88         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
89         inMemoryDataTree.commit(prepare1);
90
91         // Choice write
92         final NodeIdentifier choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
93         final ChoiceNode choice = Builders
94                 .choiceBuilder()
95                 .withNodeIdentifier(choice1Id)
96                 .withChild(
97                         Builders.containerBuilder()
98                                 .withNodeIdentifier(
99                                         new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
100                                 .withChild(leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf1"), "leaf-value"))
101                                 .withChild(leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf2"), "leaf-value2"))
102                                 .build()).build();
103
104         final InMemoryDataTreeModification modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
105         modificationTree2.write(TestModel.TEST_PATH.node(choice1Id), choice);
106         modificationTree2.ready();
107
108         inMemoryDataTree.validate(modificationTree2);
109         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
110         inMemoryDataTree.commit(prepare2);
111     }
112
113     @Test(expected = IllegalArgumentException.class)
114     public void testMandatoryLeafViolation() throws DataValidationFailedException {
115         final InMemoryDataTree inMemoryDataTree = initDataTree();
116         final NodeIdentifier choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
117
118         final ContainerNode container = Builders
119                 .containerBuilder()
120                 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
121                 .withChild(
122                         Builders.choiceBuilder()
123                                 .withNodeIdentifier(choice1Id)
124                                 .withChild(
125                                         Builders.containerBuilder()
126                                                 .withNodeIdentifier(
127                                                         new NodeIdentifier(QName.create(TestModel.TEST_QNAME,
128                                                                 "case2-cont")))
129                                                 .withChild(
130                                                         leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf2"),
131                                                                 "leaf-value2")).build()).build()).build();
132         try {
133             final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
134             modificationTree.write(TestModel.TEST_PATH, container);
135             modificationTree.ready();
136
137             inMemoryDataTree.validate(modificationTree);
138             final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
139             inMemoryDataTree.commit(prepare);
140         } catch (IllegalArgumentException e) {
141             assertEquals(
142                     "Node (urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)choice1 is missing mandatory descendant /(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)case2-cont/case2-leaf1",
143                     e.getMessage());
144             throw e;
145         }
146     }
147
148     @Test(expected = IllegalArgumentException.class)
149     public void testMandatoryLeafViolationChoiceWrite() throws DataValidationFailedException {
150         final InMemoryDataTree inMemoryDataTree = initDataTree();
151         // Container write
152         final ContainerNode container = Builders.containerBuilder()
153                 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME)).build();
154
155         final InMemoryDataTreeModification modificationTree1 = inMemoryDataTree.takeSnapshot().newModification();
156         modificationTree1.write(TestModel.TEST_PATH, container);
157         modificationTree1.ready();
158
159         inMemoryDataTree.validate(modificationTree1);
160         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
161         inMemoryDataTree.commit(prepare1);
162
163         // Choice write
164         final NodeIdentifier choice1Id = new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "choice1"));
165         final ChoiceNode choice = Builders
166                 .choiceBuilder()
167                 .withNodeIdentifier(choice1Id)
168                 .withChild(
169                         Builders.containerBuilder()
170                                 .withNodeIdentifier(
171                                         new NodeIdentifier(QName.create(TestModel.TEST_QNAME, "case2-cont")))
172                                 .withChild(leafNode(QName.create(TestModel.TEST_QNAME, "case2-leaf2"), "leaf-value2"))
173                                 .build()).build();
174
175         try {
176             final InMemoryDataTreeModification modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
177             modificationTree2.write(TestModel.TEST_PATH.node(choice1Id), choice);
178             modificationTree2.ready();
179             inMemoryDataTree.validate(modificationTree2);
180             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
181             inMemoryDataTree.commit(prepare2);
182         } catch (IllegalArgumentException e) {
183             assertEquals(
184                     "Node (urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)choice1 is missing mandatory descendant /(urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test?revision=2014-03-13)case2-cont/case2-leaf1",
185                     e.getMessage());
186             throw e;
187         }
188     }
189 }