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