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