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