322e6837a9ab19867e850013039e3db8768c1f7b
[yangtools.git] / yang / yang-data-impl / src / test / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / YT776Test.java
1 /*
2  * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.fail;
12 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.containerBuilder;
13 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.leafBuilder;
14 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.leafSetBuilder;
15 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.mapBuilder;
16 import static org.opendaylight.yangtools.yang.data.impl.schema.Builders.mapEntryBuilder;
17
18 import com.google.common.collect.ImmutableMap;
19 import org.junit.AfterClass;
20 import org.junit.Before;
21 import org.junit.BeforeClass;
22 import org.junit.Test;
23 import org.opendaylight.yangtools.yang.common.QName;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
27 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
30 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
31 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
32 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
33 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
34
35 public class YT776Test {
36     private static final QName MODULE = QName.create("yt776", "yt776");
37     private static final NodeIdentifier BOX = new NodeIdentifier(QName.create(MODULE, "box"));
38     private static final QName OBJECT = QName.create(MODULE, "object");
39     private static final QName OBJECT_ID = QName.create(MODULE, "object-id");
40     private static final NodeIdentifier OBJECT_LIST = new NodeIdentifier(OBJECT);
41     private static final NodeIdentifierWithPredicates OBJECT_ITEM = new NodeIdentifierWithPredicates(OBJECT,
42         ImmutableMap.of(OBJECT_ID, "1"));
43     private static final LeafNode<?> OBJECT_ID_LEAF = leafBuilder().withNodeIdentifier(new NodeIdentifier(OBJECT_ID))
44             .withValue("1").build();
45     private static final NodeIdentifier ATTRIBUTES = new NodeIdentifier(QName.create(MODULE, "attributes"));
46
47     private static final QName NESTED = QName.create(MODULE, "nested");
48     private static final QName NESTED_ATTRIBUTE = QName.create(MODULE, "nested-attribute");
49     private static final NodeIdentifier NESTED_LIST = new NodeIdentifier(NESTED);
50     private static final NodeIdentifierWithPredicates NESTED_ITEM = new NodeIdentifierWithPredicates(NESTED,
51         ImmutableMap.of(NESTED_ATTRIBUTE, "foo"));
52
53     private static SchemaContext SCHEMA_CONTEXT;
54
55     private DataTree dataTree;
56
57     @BeforeClass
58     public static void beforeClass() {
59         SCHEMA_CONTEXT = TestModel.createTestContext("/yt776/yt776.yang");
60     }
61
62     @AfterClass
63     public static void afterClass() {
64         SCHEMA_CONTEXT = null;
65     }
66
67     @Before
68     public void init() {
69         dataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_CONFIGURATION, SCHEMA_CONTEXT);
70     }
71
72     @Test
73     public void testNoAttributes() {
74         final DataTreeModification mod = dataTree.takeSnapshot().newModification();
75         mod.write(YangInstanceIdentifier.create(BOX), containerBuilder().withNodeIdentifier(BOX)
76             .withChild(mapBuilder().withNodeIdentifier(OBJECT_LIST)
77                 .addChild(mapEntryBuilder().withNodeIdentifier(OBJECT_ITEM)
78                     .withChild(OBJECT_ID_LEAF)
79                     .build())
80                 .build())
81             .build());
82
83         try {
84             mod.ready();
85             fail("Should fail with IAE");
86         } catch (IllegalArgumentException e) {
87             // FIXME: This is actually mandatory leaf enforcer kicking in: attributes have to be present. This is
88             //        most probably not what we want.
89             assertEquals("Node (yt776)object[{(yt776)object-id=1}] is missing mandatory descendant /(yt776)attributes",
90                 e.getMessage());
91         }
92     }
93
94     @Test
95     public void testEmptyAttributes() throws DataValidationFailedException {
96         final DataTreeModification mod = write(containerBuilder().withNodeIdentifier(BOX)
97             .withChild(mapBuilder().withNodeIdentifier(OBJECT_LIST)
98                 .addChild(mapEntryBuilder().withNodeIdentifier(OBJECT_ITEM)
99                     .withChild(OBJECT_ID_LEAF)
100                     .withChild(leafSetBuilder().withNodeIdentifier(ATTRIBUTES).build())
101                     .build())
102                 .build())
103             .build());
104
105         try {
106             mod.ready();
107             fail("Should fail with IAE");
108         } catch (IllegalArgumentException e) {
109             assertEquals("Node (yt776)attributes does not have enough elements (0), needs at least 1", e.getMessage());
110         }
111     }
112
113     @Test
114     public void testOneAttribute() throws DataValidationFailedException {
115         writeAndCommit(containerBuilder().withNodeIdentifier(BOX)
116             .withChild(mapBuilder().withNodeIdentifier(OBJECT_LIST)
117                 .addChild(mapEntryBuilder().withNodeIdentifier(OBJECT_ITEM)
118                     .withChild(OBJECT_ID_LEAF)
119                     .withChild(leafSetBuilder().withNodeIdentifier(ATTRIBUTES)
120                         .withChildValue("object1")
121                         .build())
122                     .build())
123                 .build())
124             .build());
125     }
126
127     @Test
128     public void testTwoAttributes() throws DataValidationFailedException {
129         writeAndCommit(containerBuilder().withNodeIdentifier(BOX)
130             .withChild(mapBuilder().withNodeIdentifier(OBJECT_LIST)
131                 .addChild(mapEntryBuilder().withNodeIdentifier(OBJECT_ITEM)
132                     .withChild(OBJECT_ID_LEAF)
133                     .withChild(leafSetBuilder().withNodeIdentifier(ATTRIBUTES)
134                         .withChildValue("object1")
135                         .withChildValue("object2")
136                         .build())
137                     .build())
138                 .build())
139             .build());
140     }
141
142     @Test
143     public void testThreeAttributes() throws DataValidationFailedException {
144         final DataTreeModification mod = write(containerBuilder().withNodeIdentifier(BOX)
145             .withChild(mapBuilder().withNodeIdentifier(OBJECT_LIST)
146                 .addChild(mapEntryBuilder().withNodeIdentifier(OBJECT_ITEM)
147                     .withChild(OBJECT_ID_LEAF)
148                     .withChild(leafSetBuilder().withNodeIdentifier(ATTRIBUTES)
149                         .withChildValue("object1")
150                         .withChildValue("object2")
151                         .withChildValue("object3")
152                         .build())
153                     .build())
154                 .build())
155             .build());
156
157         try {
158             mod.ready();
159             fail("Should fail with IAE");
160         } catch (IllegalArgumentException e) {
161             assertEquals("Node (yt776)attributes has too many elements (3), can have at most 2", e.getMessage());
162         }
163     }
164
165     @Test
166     public void testEmptyAndMergeOne() throws DataValidationFailedException {
167         final DataTreeModification mod = dataTree.takeSnapshot().newModification();
168         mod.write(YangInstanceIdentifier.create(BOX), containerBuilder().withNodeIdentifier(BOX)
169             .withChild(mapBuilder().withNodeIdentifier(OBJECT_LIST)
170                 .addChild(mapEntryBuilder().withNodeIdentifier(OBJECT_ITEM)
171                     .withChild(OBJECT_ID_LEAF)
172                     .build())
173                 .build())
174             .build());
175         mod.merge(YangInstanceIdentifier.create(BOX), containerBuilder().withNodeIdentifier(BOX)
176             .withChild(mapBuilder().withNodeIdentifier(OBJECT_LIST)
177                 .addChild(mapEntryBuilder().withNodeIdentifier(OBJECT_ITEM)
178                     .withChild(OBJECT_ID_LEAF)
179                     .withChild(leafSetBuilder().withNodeIdentifier(ATTRIBUTES)
180                         .withChildValue("object1")
181                         .build())
182                     .build())
183                 .build())
184             .build());
185
186         commit(mod);
187     }
188
189     @Test
190     public void testEmptyAndMergeOneWithListTouched() throws DataValidationFailedException {
191         final DataTreeModification mod = dataTree.takeSnapshot().newModification();
192         mod.write(YangInstanceIdentifier.create(BOX), containerBuilder().withNodeIdentifier(BOX)
193             .withChild(mapBuilder().withNodeIdentifier(OBJECT_LIST)
194                 .addChild(mapEntryBuilder().withNodeIdentifier(OBJECT_ITEM)
195                     .withChild(OBJECT_ID_LEAF)
196                     .build())
197                 .build())
198             .build());
199         mod.merge(YangInstanceIdentifier.create(BOX), containerBuilder().withNodeIdentifier(BOX)
200             .withChild(mapBuilder().withNodeIdentifier(OBJECT_LIST)
201                 .addChild(mapEntryBuilder().withNodeIdentifier(OBJECT_ITEM)
202                     .withChild(OBJECT_ID_LEAF)
203                     .withChild(leafSetBuilder().withNodeIdentifier(ATTRIBUTES)
204                         .withChildValue("object1")
205                         .build())
206                     .build())
207                 .build())
208             .build());
209
210         mod.delete(YangInstanceIdentifier.create(BOX, OBJECT_LIST, OBJECT_ITEM, NESTED_LIST, NESTED_ITEM));
211
212         commit(mod);
213     }
214
215     private DataTreeModification write(final ContainerNode data) throws DataValidationFailedException {
216         final DataTreeModification mod = dataTree.takeSnapshot().newModification();
217         mod.write(YangInstanceIdentifier.create(BOX), data);
218         return mod;
219     }
220
221     private void writeAndCommit(final ContainerNode data) throws DataValidationFailedException {
222         final DataTreeModification mod = dataTree.takeSnapshot().newModification();
223         mod.write(YangInstanceIdentifier.create(BOX), data);
224         commit(mod);
225     }
226
227     private void commit(final DataTreeModification mod) throws DataValidationFailedException {
228         mod.ready();
229         dataTree.validate(mod);
230         dataTree.commit(dataTree.prepare(mod));
231     }
232 }