Deprecate simple DataTreeFactory.create()
[yangtools.git] / data / yang-data-tree-ri / src / test / java / org / opendaylight / yangtools / yang / data / tree / impl / Bug5968MergeTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. 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.tree.impl;
9
10 import static org.junit.jupiter.api.Assertions.assertEquals;
11 import static org.junit.jupiter.api.Assertions.fail;
12
13 import com.google.common.collect.ImmutableMap;
14 import org.junit.jupiter.api.AfterAll;
15 import org.junit.jupiter.api.BeforeAll;
16 import org.junit.jupiter.api.Test;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
21 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
22 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
23 import org.opendaylight.yangtools.yang.data.api.schema.SystemMapNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.builder.CollectionNodeBuilder;
25 import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
26 import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
27 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
28 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
29 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeModification;
30 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
31 import org.opendaylight.yangtools.yang.data.tree.impl.di.InMemoryDataTreeFactory;
32 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
33 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
34
35 class Bug5968MergeTest {
36     private static final String NS = "bug5968";
37     private static final String REV = "2016-07-28";
38     private static final QName ROOT = QName.create(NS, REV, "root");
39     private static final QName MY_LIST = QName.create(NS, REV, "my-list");
40     private static final QName LIST_ID = QName.create(NS, REV, "list-id");
41     private static final QName MANDATORY_LEAF = QName.create(NS, REV, "mandatory-leaf");
42     private static final QName COMMON_LEAF = QName.create(NS, REV, "common-leaf");
43     private static EffectiveModelContext SCHEMA_CONTEXT;
44
45     @BeforeAll
46     static void beforeClass() {
47         SCHEMA_CONTEXT = YangParserTestUtils.parseYang("""
48             module bug5968 {
49               yang-version 1;
50               namespace bug5968;
51               prefix bug5968;
52
53               revision 2016-07-28 {
54                 description "test";
55               }
56
57               container root {
58                 list my-list {
59                   key "list-id";
60                   leaf list-id {
61                     type string;
62                   }
63                   leaf mandatory-leaf {
64                     type string;
65                     mandatory true;
66                   }
67                   leaf common-leaf {
68                     type string;
69                   }
70                 }
71               }
72             }""");
73     }
74
75     @AfterAll
76     static void afterClass() {
77         SCHEMA_CONTEXT = null;
78     }
79
80     private static DataTree initDataTree(final EffectiveModelContext schemaContext, final boolean withMapNode)
81             throws DataValidationFailedException {
82         final var inMemoryDataTree = new InMemoryDataTreeFactory().create(
83                 DataTreeConfiguration.DEFAULT_CONFIGURATION, schemaContext);
84
85         final var root = ImmutableNodes.newContainerBuilder()
86                 .withNodeIdentifier(new NodeIdentifier(ROOT));
87         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
88         modificationTree.merge(YangInstanceIdentifier.of(ROOT),
89             withMapNode ? root.withChild(
90                 ImmutableNodes.newSystemMapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST)).build()).build()
91                 : root.build());
92         modificationTree.ready();
93
94         inMemoryDataTree.validate(modificationTree);
95         final var prepare = inMemoryDataTree.prepare(modificationTree);
96         inMemoryDataTree.commit(prepare);
97
98         return inMemoryDataTree;
99     }
100
101     private static DataTree emptyDataTree(final EffectiveModelContext schemaContext) {
102         return new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_CONFIGURATION, schemaContext);
103     }
104
105     @Test
106     void mergeInvalidContainerTest() throws DataValidationFailedException {
107         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
108
109         final var myList = createMap(true);
110         final var root = ImmutableNodes.newContainerBuilder()
111                 .withNodeIdentifier(new NodeIdentifier(ROOT)).withChild(myList);
112
113         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
114         modificationTree.merge(YangInstanceIdentifier.of(ROOT), root.build());
115
116         try {
117             modificationTree.ready();
118             inMemoryDataTree.validate(modificationTree);
119             final var prepare = inMemoryDataTree.prepare(modificationTree);
120             inMemoryDataTree.commit(prepare);
121             fail("Should fail due to missing mandatory leaf.");
122         } catch (final IllegalArgumentException e) {
123             assertEquals("Node (bug5968?revision=2016-07-28)my-list[{(bug5968?revision=2016-07-28)list-id=1}] is "
124                 + "missing mandatory descendant /(bug5968?revision=2016-07-28)mandatory-leaf", e.getMessage());
125         }
126     }
127
128     @Test
129     void mergeInvalidMapTest() throws DataValidationFailedException {
130         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
131         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
132         mergeMap(modificationTree, true);
133
134         try {
135             modificationTree.ready();
136             inMemoryDataTree.validate(modificationTree);
137             final var prepare = inMemoryDataTree.prepare(modificationTree);
138             inMemoryDataTree.commit(prepare);
139             fail("Should fail due to missing mandatory leaf.");
140         } catch (final IllegalArgumentException e) {
141             assertEquals("Node (bug5968?revision=2016-07-28)my-list[{(bug5968?revision=2016-07-28)list-id=1}] is "
142                 + "missing mandatory descendant /(bug5968?revision=2016-07-28)mandatory-leaf", e.getMessage());
143         }
144     }
145
146     @Test
147     void mergeInvalidMapEntryTest() throws DataValidationFailedException {
148         final var inMemoryDataTree = initDataTree(SCHEMA_CONTEXT, true);
149         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
150
151         mergeMapEntry(modificationTree, "1", null, "common-value");
152
153         try {
154             modificationTree.ready();
155             inMemoryDataTree.validate(modificationTree);
156             final var prepare = inMemoryDataTree.prepare(modificationTree);
157             inMemoryDataTree.commit(prepare);
158             fail("Should fail due to missing mandatory leaf.");
159         } catch (final IllegalArgumentException e) {
160             assertEquals("Node (bug5968?revision=2016-07-28)my-list[{(bug5968?revision=2016-07-28)list-id=1}] is "
161                 + "missing mandatory descendant /(bug5968?revision=2016-07-28)mandatory-leaf", e.getMessage());
162         }
163     }
164
165     private static void mergeMap(final DataTreeModification modificationTree,
166             final boolean mandatoryDataMissing) throws DataValidationFailedException {
167         modificationTree.merge(YangInstanceIdentifier.of(ROOT, MY_LIST), createMap(mandatoryDataMissing));
168     }
169
170     private static SystemMapNode createMap(final boolean mandatoryDataMissing) throws DataValidationFailedException {
171         return ImmutableNodes.newSystemMapBuilder()
172             .withNodeIdentifier(new NodeIdentifier(MY_LIST))
173             .withChild(mandatoryDataMissing ? createMapEntry("1", "common-value")
174                 : createMapEntry("1", "mandatory-value", "common-value"))
175             .build();
176     }
177
178     private static void mergeMapEntry(final DataTreeModification modificationTree, final Object listIdValue,
179             final Object mandatoryLeafValue, final Object commonLeafValue) throws DataValidationFailedException {
180         final var taskEntryNode = mandatoryLeafValue == null ? createMapEntry(listIdValue, commonLeafValue)
181                 : createMapEntry(listIdValue, mandatoryLeafValue, commonLeafValue);
182
183         modificationTree.merge(
184             YangInstanceIdentifier.of(ROOT, MY_LIST)
185                 .node(NodeIdentifierWithPredicates.of(MY_LIST, LIST_ID, listIdValue)),
186             taskEntryNode);
187     }
188
189     private static MapEntryNode createMapEntry(final Object listIdValue, final Object mandatoryLeafValue,
190             final Object commonLeafValue) {
191         return ImmutableNodes.newMapEntryBuilder()
192                 .withNodeIdentifier(NodeIdentifierWithPredicates.of(MY_LIST, LIST_ID, listIdValue))
193                 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue))
194                 .withChild(ImmutableNodes.leafNode(MANDATORY_LEAF, mandatoryLeafValue))
195                 .withChild(ImmutableNodes.leafNode(COMMON_LEAF, commonLeafValue)).build();
196     }
197
198     private static MapEntryNode createMapEntry(final Object listIdValue, final Object commonLeafValue) {
199         return ImmutableNodes.newMapEntryBuilder()
200                 .withNodeIdentifier(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
201                 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue))
202                 .withChild(ImmutableNodes.leafNode(COMMON_LEAF, commonLeafValue)).build();
203     }
204
205     private static MapEntryNode createMapEntryM(final Object listIdValue, final Object mandatoryLeafValue) {
206         return ImmutableNodes.newMapEntryBuilder()
207                 .withNodeIdentifier(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
208                 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue))
209                 .withChild(ImmutableNodes.leafNode(MANDATORY_LEAF, mandatoryLeafValue)).build();
210     }
211
212     @Test
213     void mergeValidContainerTest() throws DataValidationFailedException {
214         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
215
216         final var myList = createMap(false);
217         final var root = ImmutableNodes.newContainerBuilder()
218                 .withNodeIdentifier(new NodeIdentifier(ROOT)).withChild(myList);
219
220         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
221         modificationTree.merge(YangInstanceIdentifier.of(ROOT), root.build());
222         modificationTree.ready();
223         inMemoryDataTree.validate(modificationTree);
224         final var prepare = inMemoryDataTree.prepare(modificationTree);
225         inMemoryDataTree.commit(prepare);
226     }
227
228     @Test
229     void mergeValidMapTest() throws DataValidationFailedException {
230         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
231         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
232         mergeMap(modificationTree, false);
233
234         modificationTree.ready();
235         inMemoryDataTree.validate(modificationTree);
236         final var prepare = inMemoryDataTree.prepare(modificationTree);
237         inMemoryDataTree.commit(prepare);
238     }
239
240     @Test
241     void mergeValidMapEntryTest() throws DataValidationFailedException {
242         final var inMemoryDataTree = initDataTree(SCHEMA_CONTEXT, true);
243         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
244
245         mergeMapEntry(modificationTree, "1", "mandatory-value", "common-value");
246
247         modificationTree.ready();
248         inMemoryDataTree.validate(modificationTree);
249         final var prepare = inMemoryDataTree.prepare(modificationTree);
250         inMemoryDataTree.commit(prepare);
251     }
252
253     @Test
254     void validMultiStepsMergeTest() throws DataValidationFailedException {
255         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
256         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
257
258         modificationTree.merge(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
259         modificationTree.merge(YangInstanceIdentifier.of(ROOT, MY_LIST), createMapBuilder().build());
260         modificationTree.merge(
261             YangInstanceIdentifier.of(ROOT, MY_LIST).node(NodeIdentifierWithPredicates.of(MY_LIST, LIST_ID, "1")),
262             createEmptyMapEntryBuilder("1").build());
263         modificationTree.merge(
264             YangInstanceIdentifier.of(ROOT, MY_LIST).node(NodeIdentifierWithPredicates.of(MY_LIST, LIST_ID, "1")),
265             createMapEntry("1", "mandatory-value", "common-value"));
266
267         modificationTree.ready();
268         inMemoryDataTree.validate(modificationTree);
269         final var prepare = inMemoryDataTree.prepare(modificationTree);
270         inMemoryDataTree.commit(prepare);
271     }
272
273     @Test
274     void invalidMultiStepsMergeTest() throws DataValidationFailedException {
275         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
276         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
277
278         modificationTree.merge(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
279         modificationTree.merge(YangInstanceIdentifier.of(ROOT, MY_LIST), createMapBuilder().build());
280         modificationTree.merge(
281             YangInstanceIdentifier.of(ROOT, MY_LIST).node(NodeIdentifierWithPredicates.of(MY_LIST, LIST_ID, "1")),
282             createEmptyMapEntryBuilder("1").build());
283         modificationTree.merge(
284             YangInstanceIdentifier.of(ROOT, MY_LIST).node(NodeIdentifierWithPredicates.of(MY_LIST, LIST_ID, "1")),
285             createMapEntry("1", "common-value"));
286
287         try {
288             modificationTree.ready();
289             inMemoryDataTree.validate(modificationTree);
290             final var prepare = inMemoryDataTree.prepare(modificationTree);
291             inMemoryDataTree.commit(prepare);
292             fail("Should fail due to missing mandatory leaf.");
293         } catch (final IllegalArgumentException e) {
294             assertEquals("Node (bug5968?revision=2016-07-28)my-list[{(bug5968?revision=2016-07-28)list-id=1}] is "
295                 + "missing mandatory descendant /(bug5968?revision=2016-07-28)mandatory-leaf", e.getMessage());
296         }
297     }
298
299     private static DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> createEmptyMapEntryBuilder(
300             final Object listIdValue) {
301         return ImmutableNodes.newMapEntryBuilder()
302                 .withNodeIdentifier(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
303                 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue));
304     }
305
306     private static CollectionNodeBuilder<MapEntryNode, SystemMapNode> createMapBuilder() {
307         return ImmutableNodes.newSystemMapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST));
308     }
309
310     private static DataContainerNodeBuilder<NodeIdentifier, ContainerNode> createContainerBuilder() {
311         return ImmutableNodes.newContainerBuilder().withNodeIdentifier(new NodeIdentifier(ROOT));
312     }
313
314     @Test
315     void validMultiStepsWriteAndMergeTest() throws DataValidationFailedException {
316         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
317         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
318
319         modificationTree.write(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
320         modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMapBuilder().build());
321         modificationTree.merge(
322                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
323                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
324                 createEmptyMapEntryBuilder("1").build());
325         modificationTree.merge(
326                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
327                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
328                 createMapEntry("1", "mandatory-value", "common-value"));
329
330         modificationTree.ready();
331         inMemoryDataTree.validate(modificationTree);
332         final var prepare = inMemoryDataTree.prepare(modificationTree);
333         inMemoryDataTree.commit(prepare);
334     }
335
336     @Test
337     void invalidMultiStepsWriteAndMergeTest() throws DataValidationFailedException {
338         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
339         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
340
341         modificationTree.write(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
342         modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMapBuilder().build());
343         modificationTree.merge(
344                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
345                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
346                 createEmptyMapEntryBuilder("1").build());
347         modificationTree.merge(
348                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
349                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
350                 createMapEntry("1", "common-value"));
351
352         try {
353             modificationTree.ready();
354             inMemoryDataTree.validate(modificationTree);
355             final var prepare = inMemoryDataTree.prepare(modificationTree);
356             inMemoryDataTree.commit(prepare);
357             fail("Should fail due to missing mandatory leaf.");
358         } catch (final IllegalArgumentException e) {
359             assertEquals("Node (bug5968?revision=2016-07-28)my-list[{(bug5968?revision=2016-07-28)list-id=1}] is "
360                 + "missing mandatory descendant /(bug5968?revision=2016-07-28)mandatory-leaf", e.getMessage());
361         }
362     }
363
364     @Test
365     void validMapEntryMultiCommitMergeTest() throws DataValidationFailedException {
366         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
367         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
368
369         modificationTree.write(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
370         modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMapBuilder().build());
371         modificationTree.merge(
372                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
373                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
374                 createEmptyMapEntryBuilder("1").build());
375         modificationTree.merge(
376                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
377                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
378                 createMapEntryM("1", "mandatory-value"));
379
380         modificationTree.ready();
381         inMemoryDataTree.validate(modificationTree);
382         final var prepare = inMemoryDataTree.prepare(modificationTree);
383         inMemoryDataTree.commit(prepare);
384
385         final var modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
386         modificationTree2.merge(
387                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
388                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
389                 createMapEntry("1", "common-value"));
390         modificationTree2.ready();
391         inMemoryDataTree.validate(modificationTree2);
392         final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
393         inMemoryDataTree.commit(prepare2);
394     }
395
396     @Test
397     void invalidMapEntryMultiCommitMergeTest() throws DataValidationFailedException {
398         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
399         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
400
401         modificationTree.write(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
402         modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMapBuilder().build());
403         modificationTree.merge(
404                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
405                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
406                 createEmptyMapEntryBuilder("1").build());
407         modificationTree.merge(
408                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
409                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
410                 createMapEntryM("1", "mandatory-value"));
411
412         modificationTree.ready();
413         inMemoryDataTree.validate(modificationTree);
414         final var prepare = inMemoryDataTree.prepare(modificationTree);
415         inMemoryDataTree.commit(prepare);
416
417         final var modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
418         modificationTree2.write(
419                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
420                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
421                 createMapEntry("1", "common-value"));
422         modificationTree2.merge(
423                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
424                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
425                 createMapEntryM("1", "mandatory-value"));
426         modificationTree2.merge(
427                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
428                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "2"))),
429                 createMapEntry("2", "common-value"));
430         try {
431             modificationTree2.ready();
432             inMemoryDataTree.validate(modificationTree2);
433             final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
434             inMemoryDataTree.commit(prepare2);
435             fail("Should fail due to missing mandatory leaf.");
436         } catch (final IllegalArgumentException e) {
437             assertEquals("Node (bug5968?revision=2016-07-28)my-list[{(bug5968?revision=2016-07-28)list-id=2}] is "
438                 + "missing mandatory descendant /(bug5968?revision=2016-07-28)mandatory-leaf", e.getMessage());
439         }
440     }
441
442     /*
443      * This test consists of two transactions (i.e. data tree modifications) on
444      * empty data tree. The first one writes mandatory data and second one
445      * writes common data without any mandatory data.
446      */
447     @Test
448     void validMapEntryMultiCommitMergeTest2() throws DataValidationFailedException {
449         final var inMemoryDataTree = emptyDataTree(SCHEMA_CONTEXT);
450         final var modificationTree = inMemoryDataTree.takeSnapshot().newModification();
451         final var modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
452
453         modificationTree.write(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
454         modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMapBuilder().build());
455         modificationTree.merge(
456                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
457                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
458                 createEmptyMapEntryBuilder("1").build());
459         modificationTree.merge(
460                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
461                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
462                 createMapEntryM("1", "mandatory-value"));
463
464         modificationTree.ready();
465         inMemoryDataTree.validate(modificationTree);
466         final var prepare = inMemoryDataTree.prepare(modificationTree);
467         inMemoryDataTree.commit(prepare);
468
469         modificationTree2.merge(
470                 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
471                         .node(NodeIdentifierWithPredicates.of(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
472                 createMapEntry("1", "common-value"));
473         modificationTree2.ready();
474         inMemoryDataTree.validate(modificationTree2);
475         final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
476         inMemoryDataTree.commit(prepare2);
477     }
478 }