2 * Copyright (c) 2015 Pantheon Technologies s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
10 import static junit.framework.TestCase.assertFalse;
11 import static org.hamcrest.CoreMatchers.containsString;
12 import static org.hamcrest.MatcherAssert.assertThat;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertTrue;
15 import static org.junit.Assert.fail;
17 import com.google.common.collect.ImmutableMap;
18 import java.util.Collection;
19 import java.util.HashMap;
21 import java.util.Optional;
22 import org.junit.AfterClass;
23 import org.junit.Before;
24 import org.junit.BeforeClass;
25 import org.junit.Test;
26 import org.opendaylight.yangtools.yang.common.QName;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
30 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
31 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
33 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
39 import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
40 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
41 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
42 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
43 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
44 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
45 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
46 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
47 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
48 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
49 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
50 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
51 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
53 public class Bug4454Test {
55 private static final QName MASTER_CONTAINER_QNAME = QName
56 .create("urn:opendaylight:params:xml:ns:yang:list-constraints-validation-test-model", "2015-02-02",
58 private static final QName MIN_MAX_LIST_QNAME = QName.create(MASTER_CONTAINER_QNAME, "min-max-list");
59 private static final QName MIN_MAX_LEAF_LIST_QNAME = QName.create(MASTER_CONTAINER_QNAME, "min-max-leaf-list");
60 private static final QName MIN_MAX_LIST_QNAME_NO_MINMAX = QName
61 .create(MASTER_CONTAINER_QNAME, "min-max-list-no-minmax");
62 private static final QName MIN_MAX_KEY_LEAF_QNAME = QName.create(MASTER_CONTAINER_QNAME, "min-max-key-leaf");
63 private static final QName MIN_MAX_VALUE_LEAF_QNAME = QName.create(MASTER_CONTAINER_QNAME, "min-max-value-leaf");
64 private static final QName PRESENCE_QNAME = QName.create(MASTER_CONTAINER_QNAME, "presence");
66 private static final YangInstanceIdentifier MASTER_CONTAINER_PATH = YangInstanceIdentifier
67 .of(MASTER_CONTAINER_QNAME);
68 private static final YangInstanceIdentifier MIN_MAX_LIST_PATH = YangInstanceIdentifier
69 .builder(MASTER_CONTAINER_PATH)
70 .node(MIN_MAX_LIST_QNAME).build();
71 private static final YangInstanceIdentifier PRESENCE_PATH = YangInstanceIdentifier.of(PRESENCE_QNAME);
72 private static final YangInstanceIdentifier PRESENCE_MIN_MAX_LIST_PATH = PRESENCE_PATH.node(MIN_MAX_LIST_QNAME);
73 private static final YangInstanceIdentifier MIN_MAX_LIST_NO_MINMAX_PATH = YangInstanceIdentifier
74 .builder(MASTER_CONTAINER_PATH)
75 .node(MIN_MAX_LIST_QNAME_NO_MINMAX).build();
76 private static final YangInstanceIdentifier MIN_MAX_LEAF_LIST_PATH = YangInstanceIdentifier
77 .builder(MASTER_CONTAINER_PATH).node(MIN_MAX_LEAF_LIST_QNAME).build();
79 private static final Map<QName, Object> FOO_PREDICATES = ImmutableMap.of(MIN_MAX_KEY_LEAF_QNAME, "foo");
80 private static final Map<QName, Object> BAZ_PREDICATES = ImmutableMap.of(MIN_MAX_KEY_LEAF_QNAME, "baz");
82 private final MapEntryNode fooEntryNodeWithValue = ImmutableMapEntryNodeBuilder.create().withNodeIdentifier(
83 NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME, FOO_PREDICATES))
84 .withChild(ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "footest")).build();
85 private final MapEntryNode bazEntryNodeWithValue = ImmutableMapEntryNodeBuilder.create().withNodeIdentifier(
86 NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME, BAZ_PREDICATES))
87 .withChild(ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "baztest")).build();
88 private final MapEntryNode fooEntryNode = ImmutableNodes.mapEntry(MIN_MAX_LIST_QNAME, MIN_MAX_KEY_LEAF_QNAME,
90 private final MapEntryNode barEntryNode = ImmutableNodes.mapEntry(MIN_MAX_LIST_QNAME, MIN_MAX_KEY_LEAF_QNAME,
92 private final MapEntryNode bazEntryNode = ImmutableNodes.mapEntry(MIN_MAX_LIST_QNAME, MIN_MAX_KEY_LEAF_QNAME,
94 private final SystemMapNode mapNodeBazFuzWithNodes = ImmutableNodes.mapNodeBuilder()
95 .withNodeIdentifier(new NodeIdentifier(MIN_MAX_LIST_QNAME))
96 .withChild(bazEntryNode).withChild(bazEntryNodeWithValue).withChild(fooEntryNode)
98 private final SystemMapNode mapNodeFooWithNodes = ImmutableNodes.mapNodeBuilder()
99 .withNodeIdentifier(new NodeIdentifier(MIN_MAX_LIST_QNAME))
100 .withChild(fooEntryNode).withChild(fooEntryNodeWithValue).withChild(barEntryNode).withChild(bazEntryNode)
102 private final SystemMapNode mapNodeBar = ImmutableNodes.mapNodeBuilder()
103 .withNodeIdentifier(new NodeIdentifier(MIN_MAX_LIST_QNAME))
104 .withChild(barEntryNode).build();
105 private final SystemMapNode mapNodeBaz = ImmutableNodes.mapNodeBuilder()
106 .withNodeIdentifier(new NodeIdentifier(MIN_MAX_LIST_QNAME))
107 .withChild(bazEntryNode).build();
109 private static EffectiveModelContext schemaContext;
111 private DataTree inMemoryDataTree;
114 public static void beforeClass() {
115 schemaContext = YangParserTestUtils.parseYangResource("/bug-4454-test.yang");
119 public static void afterClass() {
120 schemaContext = null;
124 public void prepare() throws DataValidationFailedException {
125 inMemoryDataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_OPERATIONAL,
127 final DataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
128 final DataTreeModification modificationTree = initialDataTreeSnapshot.newModification();
130 modificationTree.write(MASTER_CONTAINER_PATH, ImmutableNodes.containerNode(MASTER_CONTAINER_QNAME));
131 modificationTree.ready();
132 inMemoryDataTree.commit(inMemoryDataTree.prepare(modificationTree));
136 public void minMaxListDeleteWriteTest() throws DataValidationFailedException {
137 final DataTreeModification modificationTree1 = inMemoryDataTree.takeSnapshot().newModification();
139 Map<QName, Object> key = new HashMap<>();
140 key.put(MIN_MAX_KEY_LEAF_QNAME, "foo");
142 NodeIdentifierWithPredicates mapEntryPath2 = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME , key);
144 final YangInstanceIdentifier minMaxLeafFoo = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
145 .node(MIN_MAX_LIST_QNAME).node(mapEntryPath2).build();
148 key.put(MIN_MAX_KEY_LEAF_QNAME, "NON-EXISTING-LEAF");
150 mapEntryPath2 = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME, key);
152 final YangInstanceIdentifier minMaxLeafNel = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
153 .node(MIN_MAX_LIST_QNAME).node(mapEntryPath2).build();
155 final Map<QName, Object> keyTemp = new HashMap<>();
156 keyTemp.put(MIN_MAX_KEY_LEAF_QNAME, "baz");
158 NodeIdentifierWithPredicates mapEntryPathTest = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME , keyTemp);
160 final YangInstanceIdentifier pathToBaz = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
161 .node(MIN_MAX_LIST_QNAME).node(mapEntryPathTest).node(MIN_MAX_VALUE_LEAF_QNAME).build();
164 keyTemp.put(MIN_MAX_KEY_LEAF_QNAME, "bar");
166 mapEntryPathTest = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME , keyTemp);
168 final YangInstanceIdentifier pathToBar = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
169 .node(MIN_MAX_LIST_QNAME).node(mapEntryPathTest).node(MIN_MAX_VALUE_LEAF_QNAME).build();
172 keyTemp.put(MIN_MAX_KEY_LEAF_QNAME, "foo");
174 final NodeIdentifierWithPredicates mapEntryPathTestKey = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME,
177 final YangInstanceIdentifier pathToKeyFoo = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
178 .node(MIN_MAX_LIST_QNAME).node(mapEntryPathTestKey).node(MIN_MAX_KEY_LEAF_QNAME).build();
180 final LeafNode<String> newNode = ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "test");
181 final LeafNode<String> newNode1 = ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "test1");
182 final LeafNode<String> newNode2 = ImmutableNodes.leafNode(MIN_MAX_VALUE_LEAF_QNAME, "test2");
183 final LeafNode<String> newNodekey = ImmutableNodes.leafNode(MIN_MAX_KEY_LEAF_QNAME, "foo");
185 assertFalse(inMemoryDataTree.toString().contains("list"));
187 DataTreeSnapshot snapshotAfterCommit = inMemoryDataTree.takeSnapshot();
188 Optional<NormalizedNode> minMaxListRead = snapshotAfterCommit.readNode(MIN_MAX_LIST_PATH);
189 assertTrue(!minMaxListRead.isPresent());
191 modificationTree1.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
192 modificationTree1.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
193 modificationTree1.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
194 modificationTree1.merge(MIN_MAX_LIST_PATH, mapNodeBar);
195 modificationTree1.merge(MIN_MAX_LIST_PATH, mapNodeBaz);
196 modificationTree1.write(pathToKeyFoo, newNodekey);
197 modificationTree1.write(pathToBaz, newNode2);
198 modificationTree1.write(pathToBaz, newNode1);
199 modificationTree1.write(pathToBaz, newNode);
200 modificationTree1.delete(minMaxLeafFoo);
201 modificationTree1.delete(minMaxLeafNel);
203 modificationTree1.ready();
204 inMemoryDataTree.validate(modificationTree1);
205 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree1);
206 inMemoryDataTree.commit(prepare);
208 DataTreeSnapshot test = inMemoryDataTree.takeSnapshot();
209 testLoop(test, "bar", "test");
211 DataTreeModification tempMod = test.newModification();
212 tempMod.write(pathToBaz, newNode2);
213 tempMod.write(pathToBaz, newNode1);
214 tempMod.merge(pathToBaz, newNode2);
215 tempMod.write(pathToBaz, newNode1);
218 inMemoryDataTree.validate(tempMod);
219 final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(tempMod);
220 inMemoryDataTree.commit(prepare1);
222 DataTreeSnapshot test1 = inMemoryDataTree.takeSnapshot();
223 testLoop(test1, "bar", "test1");
225 DataTreeModification tempMod1 = test1.newModification();
226 tempMod1.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
229 inMemoryDataTree.validate(tempMod1);
230 final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(tempMod1);
231 inMemoryDataTree.commit(prepare2);
233 DataTreeSnapshot test2 = inMemoryDataTree.takeSnapshot();
234 minMaxListRead = test2.readNode(MIN_MAX_LIST_PATH);
235 assertTrue(minMaxListRead.isPresent());
236 assertEquals(3, ((NormalizedNodeContainer<?>) minMaxListRead.get()).size());
238 DataTreeModification tempMod2 = test2.newModification();
239 tempMod2.write(MIN_MAX_LIST_PATH, mapNodeBaz);
240 tempMod2.write(pathToBaz, newNode2);
243 inMemoryDataTree.validate(tempMod2);
244 final DataTreeCandidate prepare3 = inMemoryDataTree.prepare(tempMod2);
245 inMemoryDataTree.commit(prepare3);
247 DataTreeSnapshot test3 = inMemoryDataTree.takeSnapshot();
248 minMaxListRead = test3.readNode(MIN_MAX_LIST_PATH);
249 assertTrue(minMaxListRead.isPresent());
250 assertEquals(1, ((NormalizedNodeContainer<?>) minMaxListRead.get()).size());
251 assertThat(minMaxListRead.get().body().toString(), containsString("test2"));
253 DataTreeModification tempMod3 = test3.newModification();
254 tempMod3.merge(MIN_MAX_LIST_PATH, mapNodeBar);
255 tempMod3.merge(pathToBar, newNode1);
258 inMemoryDataTree.validate(tempMod3);
259 final DataTreeCandidate prepare4 = inMemoryDataTree.prepare(tempMod3);
260 inMemoryDataTree.commit(prepare4);
262 DataTreeSnapshot test4 = inMemoryDataTree.takeSnapshot();
263 testLoop(test4, "test1", "test2");
267 public void minMaxLeafListPass() throws DataValidationFailedException {
268 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
270 final NodeWithValue<?> barPath = new NodeWithValue<>(MIN_MAX_LIST_QNAME, "bar");
271 final NodeWithValue<?> gooPath = new NodeWithValue<>(MIN_MAX_LIST_QNAME, "goo");
273 final LeafSetEntryNode<Object> barLeafSetEntry = ImmutableLeafSetEntryNodeBuilder.create()
274 .withNodeIdentifier(barPath)
275 .withValue("bar").build();
276 final LeafSetEntryNode<Object> gooLeafSetEntry = ImmutableLeafSetEntryNodeBuilder.create()
277 .withNodeIdentifier(gooPath)
278 .withValue("goo").build();
280 final LeafSetNode<Object> fooLeafSetNode = ImmutableLeafSetNodeBuilder.create()
281 .withNodeIdentifier(new NodeIdentifier(MIN_MAX_LEAF_LIST_QNAME))
282 .withChildValue("foo")
285 modificationTree.write(MIN_MAX_LEAF_LIST_PATH, fooLeafSetNode);
286 modificationTree.write(MIN_MAX_LEAF_LIST_PATH.node(barPath), barLeafSetEntry);
287 modificationTree.ready();
289 inMemoryDataTree.validate(modificationTree);
290 final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree);
291 inMemoryDataTree.commit(prepare1);
293 DataTreeSnapshot test1 = inMemoryDataTree.takeSnapshot();
295 DataTreeModification tempMod1 = test1.newModification();
296 tempMod1.write(MIN_MAX_LEAF_LIST_PATH.node(gooPath), gooLeafSetEntry);
297 tempMod1.write(MIN_MAX_LEAF_LIST_PATH.node(barPath), barLeafSetEntry);
300 inMemoryDataTree.validate(tempMod1);
301 final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(tempMod1);
302 inMemoryDataTree.commit(prepare2);
304 final DataTreeSnapshot snapshotAfterCommit = inMemoryDataTree.takeSnapshot();
305 final Optional<NormalizedNode> masterContainer = snapshotAfterCommit.readNode(MASTER_CONTAINER_PATH);
306 assertTrue(masterContainer.isPresent());
307 final Optional<NormalizedNodeContainer<?>> leafList = ((DistinctNodeContainer) masterContainer.get())
308 .findChildByArg(new NodeIdentifier(MIN_MAX_LEAF_LIST_QNAME));
309 assertTrue(leafList.isPresent());
310 assertEquals(3, leafList.get().size());
314 public void minMaxListDeleteTest() throws DataValidationFailedException {
315 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
318 NodeIdentifierWithPredicates mapEntryPath2 = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME,
319 ImmutableMap.of(MIN_MAX_KEY_LEAF_QNAME, "foo"));
321 final YangInstanceIdentifier minMaxLeafFoo = MASTER_CONTAINER_PATH
322 .node(MIN_MAX_LIST_QNAME).node(mapEntryPath2);
324 mapEntryPath2 = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME,
325 ImmutableMap.of(MIN_MAX_KEY_LEAF_QNAME, "bar"));
327 final YangInstanceIdentifier minMaxLeafBar = MASTER_CONTAINER_PATH
328 .node(MIN_MAX_LIST_QNAME).node(mapEntryPath2);
330 mapEntryPath2 = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME,
331 ImmutableMap.of(MIN_MAX_KEY_LEAF_QNAME, "baz"));
333 final YangInstanceIdentifier minMaxLeafBaz = MASTER_CONTAINER_PATH
334 .node(MIN_MAX_LIST_QNAME).node(mapEntryPath2);
336 modificationTree.write(MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
337 modificationTree.merge(MIN_MAX_LIST_PATH, mapNodeBar);
338 modificationTree.merge(MIN_MAX_LIST_PATH, mapNodeBaz);
339 modificationTree.delete(minMaxLeafFoo);
340 modificationTree.delete(minMaxLeafBar);
341 modificationTree.delete(minMaxLeafBaz);
343 modificationTree.ready();
345 inMemoryDataTree.validate(modificationTree);
346 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
347 inMemoryDataTree.commit(prepare);
349 // Empty list should have disappeared, along with the container, as we are not enforcing root
350 final NormalizedNode data = inMemoryDataTree.takeSnapshot()
351 .readNode(YangInstanceIdentifier.empty()).get();
352 assertTrue(data instanceof ContainerNode);
353 assertEquals(0, ((ContainerNode) data).size());
357 public void minMaxListDeleteExceptionTest() throws DataValidationFailedException {
358 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
360 NodeIdentifierWithPredicates mapEntryPath2 = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME,
361 ImmutableMap.of(MIN_MAX_KEY_LEAF_QNAME, "foo"));
363 final YangInstanceIdentifier minMaxLeafFoo = PRESENCE_PATH.node(MIN_MAX_LIST_QNAME).node(mapEntryPath2);
365 mapEntryPath2 = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME,
366 ImmutableMap.of(MIN_MAX_KEY_LEAF_QNAME, "bar"));
368 final YangInstanceIdentifier minMaxLeafBar = PRESENCE_PATH.node(MIN_MAX_LIST_QNAME).node(mapEntryPath2);
370 mapEntryPath2 = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME,
371 ImmutableMap.of(MIN_MAX_KEY_LEAF_QNAME, "baz"));
373 final YangInstanceIdentifier minMaxLeafBaz = PRESENCE_PATH.node(MIN_MAX_LIST_QNAME).node(mapEntryPath2);
375 modificationTree.write(PRESENCE_PATH, ImmutableNodes.containerNode(PRESENCE_QNAME));
376 modificationTree.write(PRESENCE_MIN_MAX_LIST_PATH, mapNodeFooWithNodes);
377 modificationTree.merge(PRESENCE_MIN_MAX_LIST_PATH, mapNodeBar);
378 modificationTree.merge(PRESENCE_MIN_MAX_LIST_PATH, mapNodeBaz);
379 modificationTree.delete(minMaxLeafFoo);
380 modificationTree.delete(minMaxLeafBar);
381 modificationTree.delete(minMaxLeafBaz);
384 // Unlike minMaxListDeleteTest(), presence container enforces the list to be present
385 modificationTree.ready();
386 fail("Should have failed with IAE");
387 } catch (IllegalArgumentException e) {
388 assertEquals("Node (urn:opendaylight:params:xml:ns:yang:list-constraints-validation-test-model?"
389 + "revision=2015-02-02)presence is missing mandatory descendant "
390 + "/(urn:opendaylight:params:xml:ns:yang:list-constraints-validation-test-model?"
391 + "revision=2015-02-02)min-max-list", e.getMessage());
396 public void minMaxListNoMinMaxDeleteTest() throws DataValidationFailedException {
397 final MapEntryNode fooEntryNoMinMaxNode =
398 ImmutableNodes.mapEntry(MIN_MAX_LIST_QNAME_NO_MINMAX, MIN_MAX_KEY_LEAF_QNAME, "foo");
399 final SystemMapNode mapNode1 = ImmutableNodes.mapNodeBuilder()
400 .withNodeIdentifier(new NodeIdentifier(MIN_MAX_LIST_QNAME_NO_MINMAX))
401 .withChild(fooEntryNoMinMaxNode).build();
403 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
405 Map<QName, Object> key = new HashMap<>();
406 key.put(MIN_MAX_KEY_LEAF_QNAME, "foo");
408 NodeIdentifierWithPredicates mapEntryPath2 = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME_NO_MINMAX, key);
410 final YangInstanceIdentifier minMaxLeafFoo = MASTER_CONTAINER_PATH
411 .node(MIN_MAX_LIST_QNAME_NO_MINMAX).node(mapEntryPath2);
414 key.put(MIN_MAX_KEY_LEAF_QNAME, "non-existing-leaf");
416 mapEntryPath2 = NodeIdentifierWithPredicates.of(MIN_MAX_LIST_QNAME_NO_MINMAX, key);
418 YangInstanceIdentifier minMaxLeafNel = YangInstanceIdentifier.builder(MASTER_CONTAINER_PATH)
419 .node(MIN_MAX_LIST_QNAME_NO_MINMAX).node(mapEntryPath2).build();
421 modificationTree.write(MIN_MAX_LIST_NO_MINMAX_PATH, mapNode1);
422 modificationTree.delete(minMaxLeafFoo);
423 modificationTree.delete(minMaxLeafNel);
425 modificationTree.ready();
427 inMemoryDataTree.validate(modificationTree);
428 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
429 inMemoryDataTree.commit(prepare);
431 final DataTreeSnapshot snapshotAfterCommit = inMemoryDataTree.takeSnapshot();
432 final Optional<NormalizedNode> minMaxListRead = snapshotAfterCommit.readNode(MIN_MAX_LIST_NO_MINMAX_PATH);
434 // Empty list should have disappeared
435 assertFalse(minMaxListRead.isPresent());
438 private static void testLoop(final DataTreeSnapshot snapshot, final String first, final String second) {
439 Optional<NormalizedNode> minMaxListRead = snapshot.readNode(MIN_MAX_LIST_PATH);
440 assertTrue(minMaxListRead.isPresent());
441 assertEquals(2, ((NormalizedNodeContainer<?>) minMaxListRead.get()).size());
443 for (Object collectionChild : (Collection<?>) minMaxListRead.get().body()) {
444 if (collectionChild.toString().contains(first)) {
445 assertTrue(collectionChild.toString().contains(first));
447 assertTrue(collectionChild.toString().contains(second));