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