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