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