92906c6e722154f578b906cc7456b6b4c55cc63d
[yangtools.git] / yang / yang-data-impl / src / test / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / Bug4454Test.java
1 /*
2  * Copyright (c) 2015 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 junit.framework.TestCase.assertFalse;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import com.google.common.base.Optional;
14 import java.io.IOException;
15 import java.util.HashMap;
16 import java.util.Map;
17 import org.junit.Before;
18 import org.junit.Test;
19 import org.opendaylight.yangtools.util.UnmodifiableCollection;
20 import org.opendaylight.yangtools.yang.common.QName;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
23 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
25 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
26 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
27 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
29 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
30 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
31 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
32 import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
33 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
34 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
35 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
36 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
37 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
38 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
39 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
40 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
41 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
42 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
43
44 public class Bug4454Test {
45     private static final YangStatementSourceImpl source = new YangStatementSourceImpl("/bug-4454-test.yang", false);
46
47     private static final QName MASTER_CONTAINER_QNAME = QName
48             .create("urn:opendaylight:params:xml:ns:yang:list-constraints-validation-test-model", "2015-02-02",
49                     "master-container");
50     private static final QName MIN_MAX_LIST_QNAME = QName.create(MASTER_CONTAINER_QNAME, "min-max-list");
51     private static final QName MIN_MAX_LEAF_LIST_QNAME = QName.create(MASTER_CONTAINER_QNAME, "min-max-leaf-list");
52     private static final QName MIN_MAX_LIST_QNAME_NO_MINMAX = QName
53             .create(MASTER_CONTAINER_QNAME, "min-max-list-no-minmax");
54     private static final QName MIN_MAX_KEY_LEAF_QNAME = QName.create(MASTER_CONTAINER_QNAME, "min-max-key-leaf");
55     private static final QName MIN_MAX_VALUE_LEAF_QNAME = QName.create(MASTER_CONTAINER_QNAME, "min-max-value-leaf");
56
57     private static final YangInstanceIdentifier MASTER_CONTAINER_PATH = YangInstanceIdentifier
58             .of(MASTER_CONTAINER_QNAME);
59     private static final YangInstanceIdentifier MIN_MAX_LIST_PATH = YangInstanceIdentifier
60             .builder(MASTER_CONTAINER_PATH)
61             .node(MIN_MAX_LIST_QNAME).build();
62     private static final YangInstanceIdentifier MIN_MAX_LIST_NO_MINMAX_PATH = YangInstanceIdentifier
63             .builder(MASTER_CONTAINER_PATH)
64             .node(MIN_MAX_LIST_QNAME_NO_MINMAX).build();
65     private static final YangInstanceIdentifier MIN_MAX_LEAF_LIST_PATH = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
66             .node(MIN_MAX_LEAF_LIST_QNAME).build();
67
68     private static Map<QName,Object> fooPredicates = new HashMap<>();
69     static {
70         fooPredicates.put(MIN_MAX_KEY_LEAF_QNAME,"foo");
71     }
72
73     private static Map<QName,Object> bazPredicates = new HashMap<>();
74     static {
75         bazPredicates.put(MIN_MAX_KEY_LEAF_QNAME,"baz");
76     }
77
78     private final MapEntryNode fooEntryNodeWithValue = ImmutableMapEntryNodeBuilder.create().withNodeIdentifier(new
79             YangInstanceIdentifier.NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME, fooPredicates)).
80             withChild(ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "footest")).build();
81     private final MapEntryNode BazEntryNodeWithValue = ImmutableMapEntryNodeBuilder.create().withNodeIdentifier(new
82             YangInstanceIdentifier.NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME, bazPredicates)).
83             withChild(ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "baztest")).build();
84     private final MapEntryNode fooEntryNode = ImmutableNodes.mapEntry(MIN_MAX_LIST_QNAME, MIN_MAX_KEY_LEAF_QNAME,
85             "foo");
86     private final MapEntryNode barEntryNode = ImmutableNodes.mapEntry(MIN_MAX_LIST_QNAME, MIN_MAX_KEY_LEAF_QNAME,
87             "bar");
88     private final MapEntryNode bazEntryNode = ImmutableNodes.mapEntry(MIN_MAX_LIST_QNAME, MIN_MAX_KEY_LEAF_QNAME,
89             "baz");
90     private final MapNode mapNodeBazFuzWithNodes = ImmutableNodes.mapNodeBuilder()
91             .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(MIN_MAX_LIST_QNAME))
92             .withChild(bazEntryNode).withChild(BazEntryNodeWithValue).withChild(fooEntryNode)
93             .build();
94     private final MapNode mapNodeFooWithNodes = ImmutableNodes.mapNodeBuilder()
95             .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(MIN_MAX_LIST_QNAME))
96             .withChild(fooEntryNode).withChild(fooEntryNodeWithValue).withChild(barEntryNode).withChild(bazEntryNode)
97             .build();
98     private final MapNode mapNodeBar = ImmutableNodes.mapNodeBuilder()
99             .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(MIN_MAX_LIST_QNAME))
100             .withChild(barEntryNode).build();
101     private final MapNode mapNodeBaz = ImmutableNodes.mapNodeBuilder()
102             .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(MIN_MAX_LIST_QNAME))
103             .withChild(bazEntryNode).build();
104
105     private InMemoryDataTree inMemoryDataTree;
106
107     @Before
108     public void prepare() throws IOException, YangSyntaxErrorException, ReactorException {
109         SchemaContext schemaContext = createTestContext();
110         assertNotNull("Schema context must not be null.", schemaContext);
111         inMemoryDataTree =  (InMemoryDataTree) InMemoryDataTreeFactory.getInstance().create(TreeType.OPERATIONAL);
112         inMemoryDataTree.setSchemaContext(schemaContext);
113         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
114         final DataTreeModification modificationTree = initialDataTreeSnapshot.newModification();
115
116         modificationTree.write(MASTER_CONTAINER_PATH, ImmutableNodes.containerNode(MASTER_CONTAINER_QNAME));
117         modificationTree.ready();
118         inMemoryDataTree.commit(inMemoryDataTree.prepare(modificationTree));
119     }
120
121     public static SchemaContext createTestContext() throws IOException, YangSyntaxErrorException, ReactorException {
122         CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
123         reactor.addSources(source);
124
125         return reactor.buildEffective();
126     }
127
128     @Test
129     public void minMaxListDeleteWriteTest() throws DataValidationFailedException {
130         final InMemoryDataTreeModification modificationTree1 = inMemoryDataTree.takeSnapshot().newModification();
131
132         Map<QName, Object> key = new HashMap<>();
133         key.put(MIN_MAX_KEY_LEAF_QNAME, "foo");
134
135         YangInstanceIdentifier.NodeIdentifierWithPredicates mapEntryPath2 = new YangInstanceIdentifier
136                 .NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME , key);
137
138         YangInstanceIdentifier MIN_MAX_LEAF_FOO = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
139                 .node(MIN_MAX_LIST_QNAME).node(mapEntryPath2).build();
140
141         key.clear();
142         key.put(MIN_MAX_KEY_LEAF_QNAME, "NON-EXISTING-LEAF");
143
144         mapEntryPath2 = new YangInstanceIdentifier.NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME, key);
145
146         YangInstanceIdentifier MIN_MAX_LEAF_NEL = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH).node
147                 (MIN_MAX_LIST_QNAME).node(mapEntryPath2).build();
148
149         final Map<QName, Object> keyTemp = new HashMap<>();
150         keyTemp.put(MIN_MAX_KEY_LEAF_QNAME, "baz");
151
152         YangInstanceIdentifier.NodeIdentifierWithPredicates mapEntryPathTest = new YangInstanceIdentifier
153                 .NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME , keyTemp);
154
155         final YangInstanceIdentifier pathToBaz = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
156                 .node(MIN_MAX_LIST_QNAME).node(mapEntryPathTest).node(MIN_MAX_VALUE_LEAF_QNAME).build();
157
158         keyTemp.clear();
159         keyTemp.put(MIN_MAX_KEY_LEAF_QNAME, "bar");
160
161         mapEntryPathTest = new YangInstanceIdentifier.NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME , keyTemp);
162
163         final YangInstanceIdentifier pathToBar = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
164                 .node(MIN_MAX_LIST_QNAME).node(mapEntryPathTest).node(MIN_MAX_VALUE_LEAF_QNAME).build();
165
166         keyTemp.clear();
167         keyTemp.put(MIN_MAX_KEY_LEAF_QNAME, "foo");
168
169         final YangInstanceIdentifier.NodeIdentifierWithPredicates mapEntryPathTestKey = new YangInstanceIdentifier
170                 .NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME , keyTemp);
171
172         final YangInstanceIdentifier pathToKeyFoo = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
173                 .node(MIN_MAX_LIST_QNAME).node(mapEntryPathTestKey).node(MIN_MAX_KEY_LEAF_QNAME).build();
174
175         final LeafNode<String> newNode = ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "test");
176         final LeafNode<String> newNode1 = ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "test1");
177         final LeafNode<String> newNode2 = ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "test2");
178         final LeafNode<String> newNodekey = ImmutableNodes.leafNode(MIN_MAX_KEY_LEAF_QNAME, "foo");
179
180         assertFalse(inMemoryDataTree.toString().contains("list"));
181
182         InMemoryDataTreeSnapshot snapshotAfterCommit = inMemoryDataTree.takeSnapshot();
183         Optional<NormalizedNode<?, ?>> minMaxListRead = snapshotAfterCommit.readNode(MIN_MAX_LIST_PATH);
184         assertTrue(!minMaxListRead.isPresent());
185
186         modificationTree1.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
187         modificationTree1.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
188         modificationTree1.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
189         modificationTree1.merge(MIN_MAX_LIST_PATH, mapNodeBar);
190         modificationTree1.merge(MIN_MAX_LIST_PATH, mapNodeBaz);
191         modificationTree1.write(pathToKeyFoo, newNodekey);
192         modificationTree1.write(pathToBaz, newNode2);
193         modificationTree1.write(pathToBaz, newNode1);
194         modificationTree1.write(pathToBaz, newNode);
195         modificationTree1.delete(MIN_MAX_LEAF_FOO);
196         modificationTree1.delete(MIN_MAX_LEAF_NEL);
197
198         modificationTree1.ready();
199         inMemoryDataTree.validate(modificationTree1);
200         final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree1);
201         inMemoryDataTree.commit(prepare);
202
203         InMemoryDataTreeSnapshot test = inMemoryDataTree.takeSnapshot();
204         testLoop(test, "bar", "test");
205
206         InMemoryDataTreeModification tempMod = test.newModification();
207         tempMod.write(pathToBaz, newNode2);
208         tempMod.write(pathToBaz, newNode1);
209         tempMod.merge(pathToBaz, newNode2);
210         tempMod.write(pathToBaz, newNode1);
211
212         tempMod.ready();
213         inMemoryDataTree.validate(tempMod);
214         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(tempMod);
215         inMemoryDataTree.commit(prepare1);
216
217         InMemoryDataTreeSnapshot test1 = inMemoryDataTree.takeSnapshot();
218         testLoop(test1, "bar", "test1");
219
220         InMemoryDataTreeModification tempMod1 = test1.newModification();
221         tempMod1.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
222
223         tempMod1.ready();
224         inMemoryDataTree.validate(tempMod1);
225         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(tempMod1);
226         inMemoryDataTree.commit(prepare2);
227
228         InMemoryDataTreeSnapshot test2 = inMemoryDataTree.takeSnapshot();
229         minMaxListRead = test2.readNode(MIN_MAX_LIST_PATH);
230         assertTrue(minMaxListRead.isPresent());
231         assertTrue(((NormalizedNodeContainer<?, ?, ?>) minMaxListRead.get()).getValue().size() == 3);
232
233         InMemoryDataTreeModification tempMod2 = test2.newModification();
234         tempMod2.write(MIN_MAX_LIST_PATH, mapNodeBaz);
235         tempMod2.write(pathToBaz, newNode2);
236
237         tempMod2.ready();
238         inMemoryDataTree.validate(tempMod2);
239         final DataTreeCandidate prepare3 = inMemoryDataTree.prepare(tempMod2);
240         inMemoryDataTree.commit(prepare3);
241
242         InMemoryDataTreeSnapshot test3 = inMemoryDataTree.takeSnapshot();
243         minMaxListRead = test3.readNode(MIN_MAX_LIST_PATH);
244         assertTrue(minMaxListRead.isPresent());
245         assertTrue(((NormalizedNodeContainer<?, ?, ?>) minMaxListRead.get()).getValue().size() == 1);
246         assertTrue(minMaxListRead.get().getValue().toString().contains("test2"));
247
248         InMemoryDataTreeModification tempMod3 = test3.newModification();
249         tempMod3.merge(MIN_MAX_LIST_PATH, mapNodeBar);
250         tempMod3.merge(pathToBar, newNode1);
251
252         tempMod3.ready();
253         inMemoryDataTree.validate(tempMod3);
254         final DataTreeCandidate prepare4 = inMemoryDataTree.prepare(tempMod3);
255         inMemoryDataTree.commit(prepare4);
256
257         InMemoryDataTreeSnapshot test4 = inMemoryDataTree.takeSnapshot();
258         testLoop(test4, "test1", "test2");
259     }
260
261     @Test
262     public void minMaxLeafListPass() throws DataValidationFailedException {
263         final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
264
265         final YangInstanceIdentifier.NodeWithValue barPath = new YangInstanceIdentifier.NodeWithValue(MIN_MAX_LIST_QNAME, "bar");
266         final YangInstanceIdentifier.NodeWithValue gooPath = new YangInstanceIdentifier.NodeWithValue(MIN_MAX_LIST_QNAME, "goo");
267
268         final LeafSetEntryNode<Object> barLeafSetEntry = ImmutableLeafSetEntryNodeBuilder.create()
269                 .withNodeIdentifier(barPath)
270                 .withValue("bar").build();
271         final LeafSetEntryNode<Object> gooLeafSetEntry = ImmutableLeafSetEntryNodeBuilder.create()
272                 .withNodeIdentifier(gooPath)
273                 .withValue("goo").build();
274
275         final LeafSetNode<Object> fooLeafSetNode = ImmutableLeafSetNodeBuilder.create()
276                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(MIN_MAX_LEAF_LIST_QNAME))
277                 .withChildValue("foo").build();
278
279         modificationTree.write(MIN_MAX_LEAF_LIST_PATH, fooLeafSetNode);
280         modificationTree.write(MIN_MAX_LEAF_LIST_PATH.node(barPath), barLeafSetEntry);
281         modificationTree.ready();
282
283         inMemoryDataTree.validate(modificationTree);
284         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree);
285         inMemoryDataTree.commit(prepare1);
286
287         InMemoryDataTreeSnapshot test1 = inMemoryDataTree.takeSnapshot();
288
289         InMemoryDataTreeModification tempMod1 = test1.newModification();
290         tempMod1.write(MIN_MAX_LEAF_LIST_PATH.node(gooPath), gooLeafSetEntry);
291         tempMod1.write(MIN_MAX_LEAF_LIST_PATH.node(barPath), barLeafSetEntry);
292         tempMod1.ready();
293
294         inMemoryDataTree.validate(tempMod1);
295         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(tempMod1);
296         inMemoryDataTree.commit(prepare2);
297
298         final InMemoryDataTreeSnapshot snapshotAfterCommit = inMemoryDataTree.takeSnapshot();
299         final Optional<NormalizedNode<?, ?>> masterContainer = snapshotAfterCommit.readNode(MASTER_CONTAINER_PATH);
300         assertTrue(masterContainer.isPresent());
301         final Optional<NormalizedNodeContainer<?, ?, ?>> leafList = ((NormalizedNodeContainer) masterContainer.get()).getChild(
302                 new YangInstanceIdentifier.NodeIdentifier(MIN_MAX_LEAF_LIST_QNAME));
303         assertTrue(leafList.isPresent());
304         assertTrue(leafList.get().getValue().size() == 3);
305     }
306
307
308     @Test(expected = DataValidationFailedException.class)
309     public void minMaxListDeleteExceptionTest() throws DataValidationFailedException {
310         final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
311
312         Map<QName, Object> key = new HashMap<>();
313         key.put(MIN_MAX_KEY_LEAF_QNAME, "foo");
314
315         YangInstanceIdentifier.NodeIdentifierWithPredicates mapEntryPath2 = new YangInstanceIdentifier
316                 .NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME , key);
317
318         YangInstanceIdentifier MIN_MAX_LEAF_FOO = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
319                 .node(MIN_MAX_LIST_QNAME).node(mapEntryPath2).build();
320
321         key.clear();
322         key.put(MIN_MAX_KEY_LEAF_QNAME, "bar");
323
324         mapEntryPath2 = new YangInstanceIdentifier.NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME, key);
325
326         YangInstanceIdentifier MIN_MAX_LEAF_BAR = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH).node
327                 (MIN_MAX_LIST_QNAME)
328                 .node(mapEntryPath2).build();
329
330         key.clear();
331         key.put(MIN_MAX_KEY_LEAF_QNAME, "bar");
332
333         mapEntryPath2 = new YangInstanceIdentifier.NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME, key);
334
335         YangInstanceIdentifier MIN_MAX_LEAF_BAZ = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH).node
336                 (MIN_MAX_LIST_QNAME)
337                 .node(mapEntryPath2).build();
338
339         modificationTree.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
340         modificationTree.merge(MIN_MAX_LIST_PATH, mapNodeBar);
341         modificationTree.merge(MIN_MAX_LIST_PATH, mapNodeBaz);
342         modificationTree.delete(MIN_MAX_LEAF_FOO);
343         modificationTree.delete(MIN_MAX_LEAF_BAR);
344         modificationTree.delete(MIN_MAX_LEAF_BAZ);
345
346         modificationTree.ready();
347
348         inMemoryDataTree.validate(modificationTree);
349         final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
350         inMemoryDataTree.commit(prepare);
351     }
352
353     @Test
354     public void minMaxListNoMinMaxDeleteTest() throws DataValidationFailedException {
355         final MapEntryNode fooEntryNode = ImmutableNodes.mapEntry(MIN_MAX_LIST_QNAME_NO_MINMAX, MIN_MAX_KEY_LEAF_QNAME
356                 , "foo");
357         final MapNode mapNode1 = ImmutableNodes.mapNodeBuilder()
358                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(MIN_MAX_LIST_QNAME_NO_MINMAX))
359                 .withChild(fooEntryNode).build();
360
361         final InMemoryDataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
362
363         Map<QName, Object> key = new HashMap<>();
364         key.put(MIN_MAX_KEY_LEAF_QNAME, "foo");
365
366         YangInstanceIdentifier.NodeIdentifierWithPredicates mapEntryPath2 = new YangInstanceIdentifier
367                 .NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME_NO_MINMAX , key);
368
369         YangInstanceIdentifier MIN_MAX_LEAF_FOO = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH).node
370                 (MIN_MAX_LIST_QNAME_NO_MINMAX).node(mapEntryPath2).build();
371
372         key.clear();
373         key.put(MIN_MAX_KEY_LEAF_QNAME, "non-existing-leaf");
374
375         mapEntryPath2 = new YangInstanceIdentifier.NodeIdentifierWithPredicates(MIN_MAX_LIST_QNAME_NO_MINMAX, key);
376
377         YangInstanceIdentifier MIN_MAX_LEAF_NEL = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH).node
378                 (MIN_MAX_LIST_QNAME_NO_MINMAX)
379                 .node(mapEntryPath2).build();
380
381         modificationTree.write(MIN_MAX_LIST_NO_MINMAX_PATH, mapNode1);
382         modificationTree.delete(MIN_MAX_LEAF_FOO);
383         modificationTree.delete(MIN_MAX_LEAF_NEL);
384
385         modificationTree.ready();
386
387         inMemoryDataTree.validate(modificationTree);
388         final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
389         inMemoryDataTree.commit(prepare);
390
391         final InMemoryDataTreeSnapshot snapshotAfterCommit = inMemoryDataTree.takeSnapshot();
392         final Optional<NormalizedNode<?, ?>> minMaxListRead = snapshotAfterCommit.readNode(MIN_MAX_LIST_NO_MINMAX_PATH);
393         assertTrue(minMaxListRead.isPresent());
394         assertTrue(((NormalizedNodeContainer<?, ?, ?>) minMaxListRead.get()).getValue().size() == 0);
395     }
396
397     private static void testLoop(final InMemoryDataTreeSnapshot snapshot, final String first, final String second) {
398         Optional<NormalizedNode<?, ?>> minMaxListRead = snapshot.readNode(MIN_MAX_LIST_PATH);
399         assertTrue(minMaxListRead.isPresent());
400         assertTrue(((NormalizedNodeContainer<?, ?, ?>) minMaxListRead.get()).getValue().size() == 2);
401         UnmodifiableCollection<?> collectionChildren = (UnmodifiableCollection<?>) minMaxListRead.get().getValue();
402
403         for (Object collectionChild : collectionChildren) {
404             if(collectionChild.toString().contains(first)){
405                 assertTrue(collectionChild.toString().contains(first));
406             } else {
407                 assertTrue(collectionChild.toString().contains(second));
408             }
409         }
410     }
411 }