48a6761e3e02746a7db2c0fbcfcc051d6e566642
[yangtools.git] / yang / yang-data-impl / src / test / java / org / opendaylight / yangtools / yang / data / impl / schema / tree / ConcurrentTreeModificationTest.java
1 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
2
3 import static org.junit.Assert.assertFalse;
4 import static org.junit.Assert.assertNotNull;
5 import static org.junit.Assert.assertTrue;
6 import static org.junit.Assert.fail;
7 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
8 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
9
10 import com.google.common.base.Optional;
11 import org.junit.Before;
12 import org.junit.Test;
13 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
14 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
15 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
16 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
17 import org.opendaylight.yangtools.yang.data.api.schema.tree.ConflictingModificationAppliedException;
18 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
19 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
20 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
21 import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
22 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
23 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
24 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 public class ConcurrentTreeModificationTest {
29     private static final Logger LOG = LoggerFactory.getLogger(ConcurrentTreeModificationTest.class);
30
31     private static final Short ONE_ID = 1;
32     private static final Short TWO_ID = 2;
33
34     private static final YangInstanceIdentifier OUTER_LIST_1_PATH = YangInstanceIdentifier.builder(TestModel.OUTER_LIST_PATH)
35             .nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, ONE_ID) //
36             .build();
37
38     private static final YangInstanceIdentifier OUTER_LIST_2_PATH = YangInstanceIdentifier.builder(TestModel.OUTER_LIST_PATH)
39             .nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, TWO_ID) //
40             .build();
41
42     private static final MapEntryNode FOO_NODE = mapEntryBuilder(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, ONE_ID) //
43             .withChild(mapNodeBuilder(TestModel.INNER_LIST_QNAME) //
44                     .build()) //
45             .build();
46
47     private static final MapEntryNode BAR_NODE = mapEntryBuilder(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, TWO_ID) //
48             .withChild(mapNodeBuilder(TestModel.INNER_LIST_QNAME) //
49                     .build()) //
50             .build();
51
52     private SchemaContext schemaContext;
53     private RootModificationApplyOperation rootOper;
54     private InMemoryDataTree inMemoryDataTree;
55
56     @Before
57     public void prepare() {
58         schemaContext = TestModel.createTestContext();
59         assertNotNull("Schema context must not be null.", schemaContext);
60         rootOper = RootModificationApplyOperation.from(SchemaAwareApplyOperation.from(schemaContext,TreeType.OPERATIONAL));
61         inMemoryDataTree = (InMemoryDataTree) InMemoryDataTreeFactory.getInstance().create();
62         inMemoryDataTree.setSchemaContext(schemaContext);
63     }
64
65     private static ContainerNode createFooTestContainerNode() {
66         return ImmutableContainerNodeBuilder
67                 .create()
68                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME))
69                 .withChild(
70                         mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
71                                 .withChild(FOO_NODE).build()).build();
72     }
73
74     private static ContainerNode createBarTestContainerNode() {
75         return ImmutableContainerNodeBuilder
76                 .create()
77                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME))
78                 .withChild(
79                         mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
80                                 .withChild(BAR_NODE).build()).build();
81     }
82
83     private static <T> T assertPresentAndType(final Optional<?> potential, final Class<T> type) {
84         assertNotNull(potential);
85         assertTrue(potential.isPresent());
86         assertTrue(type.isInstance(potential.get()));
87         return type.cast(potential.get());
88     }
89
90     @Test
91     public void writeWrite1stLevelEmptyTreeTest() throws DataValidationFailedException {
92         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
93
94         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
95                 rootOper);
96         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
97                 rootOper);
98
99         modificationTree1.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
100         modificationTree2.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
101
102         inMemoryDataTree.validate(modificationTree1);
103         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
104         inMemoryDataTree.commit(prepare1);
105
106         try {
107             inMemoryDataTree.validate(modificationTree2);
108             fail("Exception should have been thrown.");
109         } catch (final ConflictingModificationAppliedException ex) {
110             LOG.debug("ConflictingModificationAppliedException - '{}' was thrown as expected.");
111         }
112         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
113         inMemoryDataTree.commit(prepare2);
114
115         final Optional<NormalizedNode<?, ?>> testNodeAfterCommits = modificationTree1.readNode(TestModel.TEST_PATH);
116         assertPresentAndType(testNodeAfterCommits, ContainerNode.class);
117     }
118
119     @Test
120     public void writeMerge1stLevelEmptyTreeTest() throws DataValidationFailedException {
121         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
122
123         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
124                 rootOper);
125         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
126                 rootOper);
127
128         modificationTree1.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
129         modificationTree2.merge(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
130
131         inMemoryDataTree.validate(modificationTree1);
132         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
133         inMemoryDataTree.commit(prepare1);
134
135         inMemoryDataTree.validate(modificationTree2);
136         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
137         inMemoryDataTree.commit(prepare2);
138
139         final Optional<NormalizedNode<?, ?>> testNodeAfterCommits = modificationTree1.readNode(TestModel.TEST_PATH);
140         assertPresentAndType(testNodeAfterCommits, ContainerNode.class);
141     }
142
143     @Test
144     public void writeWriteFooBar1stLevelEmptyTreeTest() throws DataValidationFailedException {
145         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
146
147         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
148                 rootOper);
149         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
150                 rootOper);
151
152         modificationTree1.write(TestModel.TEST_PATH, createFooTestContainerNode());
153         modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
154
155         inMemoryDataTree.validate(modificationTree1);
156         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
157         inMemoryDataTree.commit(prepare1);
158
159         try {
160             inMemoryDataTree.validate(modificationTree2);
161             fail("Exception should have been thrown.");
162             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
163             inMemoryDataTree.commit(prepare2);
164         } catch (final ConflictingModificationAppliedException ex) {
165             LOG.debug("ConflictingModificationAppliedException - '{}' was thrown as expected.");
166         }
167
168         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
169         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
170         assertFalse(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH).isPresent());
171     }
172
173     @Test
174     public void writeMergeFooBar1stLevelEmptyTreeTest() throws DataValidationFailedException {
175         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
176
177         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
178                 rootOper);
179         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
180                 rootOper);
181
182         modificationTree1.write(TestModel.TEST_PATH, createFooTestContainerNode());
183         modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
184
185         inMemoryDataTree.validate(modificationTree1);
186         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
187         inMemoryDataTree.commit(prepare1);
188
189         inMemoryDataTree.validate(modificationTree2);
190         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
191         inMemoryDataTree.commit(prepare2);
192
193         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
194         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
195         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
196     }
197
198     @Test
199     public void mergeWriteFooBar1stLevelEmptyTreeTest() throws DataValidationFailedException {
200         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
201
202         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
203                 rootOper);
204         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
205                 rootOper);
206
207         modificationTree1.merge(TestModel.TEST_PATH, createFooTestContainerNode());
208         modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
209
210         inMemoryDataTree.validate(modificationTree1);
211         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
212         inMemoryDataTree.commit(prepare1);
213
214         try {
215             inMemoryDataTree.validate(modificationTree2);
216             fail("Exception should have been thrown.");
217             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
218             inMemoryDataTree.commit(prepare2);
219         } catch (final ConflictingModificationAppliedException ex) {
220             LOG.debug("ConflictingModificationAppliedException - '{}' was thrown as expected.");
221         }
222
223         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
224         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
225         assertFalse(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH).isPresent());
226     }
227
228     @Test
229     public void mergeMergeFooBar1stLevelEmptyTreeTest() throws DataValidationFailedException {
230         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
231
232         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
233                 rootOper);
234         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
235                 rootOper);
236
237         modificationTree1.merge(TestModel.TEST_PATH, createFooTestContainerNode());
238         modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
239
240         inMemoryDataTree.validate(modificationTree1);
241         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
242         inMemoryDataTree.commit(prepare1);
243
244         inMemoryDataTree.validate(modificationTree2);
245         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
246         inMemoryDataTree.commit(prepare2);
247
248         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
249         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
250         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
251     }
252
253     @Test
254     public void writeWriteFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
255         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
256         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
257         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
258         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
259
260         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
261                 rootOper);
262         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
263                 rootOper);
264
265         modificationTree1.write(TestModel.TEST_PATH, createFooTestContainerNode());
266         modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
267
268         inMemoryDataTree.validate(modificationTree1);
269         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
270         inMemoryDataTree.commit(prepare1);
271
272         try {
273             inMemoryDataTree.validate(modificationTree2);
274             fail("Exception should have been thrown.");
275             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
276             inMemoryDataTree.commit(prepare2);
277         } catch (final ConflictingModificationAppliedException ex) {
278             LOG.debug("ConflictingModificationAppliedException - '{}' was thrown as expected.");
279         }
280
281         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
282         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
283         assertFalse(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH).isPresent());
284     }
285
286     @Test
287     public void writeMergeFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
288         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
289         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
290         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
291         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
292
293         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
294                 rootOper);
295         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
296                 rootOper);
297
298         modificationTree1.write(TestModel.TEST_PATH, createFooTestContainerNode());
299         modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
300
301         inMemoryDataTree.validate(modificationTree1);
302         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
303         inMemoryDataTree.commit(prepare1);
304
305         inMemoryDataTree.validate(modificationTree2);
306         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
307         inMemoryDataTree.commit(prepare2);
308
309         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
310         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
311         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
312     }
313
314
315     @Test
316     public void mergeWriteFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
317         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
318         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
319         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
320         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
321
322         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
323                 rootOper);
324         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
325                 rootOper);
326
327         modificationTree1.merge(TestModel.TEST_PATH, createFooTestContainerNode());
328         modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
329
330         inMemoryDataTree.validate(modificationTree1);
331         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
332         inMemoryDataTree.commit(prepare1);
333
334         try {
335             inMemoryDataTree.validate(modificationTree2);
336             fail("Exception should have been thrown.");
337             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
338             inMemoryDataTree.commit(prepare2);
339         } catch (final ConflictingModificationAppliedException ex) {
340             LOG.debug("ConflictingModificationAppliedException - '{}' was thrown as expected.");
341         }
342
343
344         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
345         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
346         assertFalse(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH).isPresent());
347     }
348
349     @Test
350     public void mergeMergeFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
351         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
352         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
353         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
354         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
355
356         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
357                 rootOper);
358         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
359                 rootOper);
360
361         modificationTree1.merge(TestModel.TEST_PATH, createFooTestContainerNode());
362         modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
363
364         inMemoryDataTree.validate(modificationTree1);
365         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
366         inMemoryDataTree.commit(prepare1);
367
368         inMemoryDataTree.validate(modificationTree2);
369         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
370         inMemoryDataTree.commit(prepare2);
371
372         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
373         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
374         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
375     }
376
377     @Test
378     public void deleteWriteFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
379         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
380         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
381         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
382         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
383
384         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
385                 rootOper);
386         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
387                 rootOper);
388
389         modificationTree1.delete(TestModel.TEST_PATH);
390         modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
391
392         inMemoryDataTree.validate(modificationTree1);
393         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
394         inMemoryDataTree.commit(prepare1);
395
396         try {
397             inMemoryDataTree.validate(modificationTree2);
398             fail("Exception should have been thrown.");
399             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
400             inMemoryDataTree.commit(prepare2);
401         } catch (final ConflictingModificationAppliedException ex) {
402             LOG.debug("ConflictingModificationAppliedException - '{}' was thrown as expected.");
403         }
404
405
406         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
407         assertFalse(snapshotAfterCommits.readNode(TestModel.TEST_PATH).isPresent());
408     }
409
410     @Test
411     public void deleteMergeFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
412         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
413         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
414         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
415         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
416
417         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
418                 rootOper);
419         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
420                 rootOper);
421
422         modificationTree1.delete(TestModel.TEST_PATH);
423         modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
424
425         inMemoryDataTree.validate(modificationTree1);
426         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
427         inMemoryDataTree.commit(prepare1);
428
429         inMemoryDataTree.validate(modificationTree2);
430         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
431         inMemoryDataTree.commit(prepare2);
432
433         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
434         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
435     }
436
437     @Test
438     public void writeWriteFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
439         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
440         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
441         initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
442         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
443         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
444
445         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
446                 rootOper);
447         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
448                 rootOper);
449
450         modificationTree1.write(OUTER_LIST_1_PATH, FOO_NODE);
451         modificationTree2.write(OUTER_LIST_2_PATH, BAR_NODE);
452
453         inMemoryDataTree.validate(modificationTree1);
454         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
455         inMemoryDataTree.commit(prepare1);
456
457         inMemoryDataTree.validate(modificationTree2);
458         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
459         inMemoryDataTree.commit(prepare2);
460
461         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
462         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
463         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
464     }
465
466     @Test
467     public void writeMergeFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
468         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
469         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
470         initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
471         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
472         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
473
474         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
475                 rootOper);
476         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
477                 rootOper);
478
479         modificationTree1.write(OUTER_LIST_1_PATH, FOO_NODE);
480         modificationTree2.merge(OUTER_LIST_2_PATH, BAR_NODE);
481
482         inMemoryDataTree.validate(modificationTree1);
483         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
484         inMemoryDataTree.commit(prepare1);
485
486         inMemoryDataTree.validate(modificationTree2);
487         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
488         inMemoryDataTree.commit(prepare2);
489
490         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
491         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
492         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
493     }
494
495     @Test
496     public void mergeWriteFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
497         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
498         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
499         initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
500         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
501         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
502
503         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
504                 rootOper);
505         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
506                 rootOper);
507
508         modificationTree1.merge(OUTER_LIST_1_PATH, FOO_NODE);
509         modificationTree2.write(OUTER_LIST_2_PATH, BAR_NODE);
510
511         inMemoryDataTree.validate(modificationTree1);
512         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
513         inMemoryDataTree.commit(prepare1);
514
515         inMemoryDataTree.validate(modificationTree2);
516         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
517         inMemoryDataTree.commit(prepare2);
518
519         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
520         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
521         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
522     }
523
524     @Test
525     public void mergeMergeFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
526         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
527         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
528         initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
529         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
530         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
531
532         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
533                 rootOper);
534         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
535                 rootOper);
536
537         modificationTree1.merge(OUTER_LIST_1_PATH, FOO_NODE);
538         modificationTree2.merge(OUTER_LIST_2_PATH, BAR_NODE);
539
540         inMemoryDataTree.validate(modificationTree1);
541         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
542         inMemoryDataTree.commit(prepare1);
543
544         inMemoryDataTree.validate(modificationTree2);
545         final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
546         inMemoryDataTree.commit(prepare2);
547
548         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
549         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
550         assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
551     }
552
553     @Test
554     public void deleteWriteFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
555         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
556         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
557         initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
558         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
559         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
560
561         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
562                 rootOper);
563         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
564                 rootOper);
565
566         modificationTree1.delete(TestModel.TEST_PATH);
567         modificationTree2.merge(OUTER_LIST_2_PATH, BAR_NODE);
568
569         inMemoryDataTree.validate(modificationTree1);
570         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
571         inMemoryDataTree.commit(prepare1);
572
573         try {
574             inMemoryDataTree.validate(modificationTree2);
575             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
576             inMemoryDataTree.commit(prepare2);
577             fail("Exception should have been thrown");
578         } catch (final Exception e) {
579             LOG.debug("Exception was thrown because path no longer exist in tree");
580         }
581
582         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
583         assertFalse(snapshotAfterCommits.readNode(TestModel.TEST_PATH).isPresent());
584     }
585
586     @Test
587     public void deleteMergeFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
588         final DataTreeModification initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
589         initialDataTreeModification.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
590         initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
591         inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
592         final InMemoryDataTreeSnapshot initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
593
594         final DataTreeModification modificationTree1 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
595                 rootOper);
596         final DataTreeModification modificationTree2 = new InMemoryDataTreeModification(initialDataTreeSnapshot,
597                 rootOper);
598
599         modificationTree1.delete(TestModel.TEST_PATH);
600         modificationTree2.merge(OUTER_LIST_2_PATH, BAR_NODE);
601
602         inMemoryDataTree.validate(modificationTree1);
603         final DataTreeCandidate prepare1 = inMemoryDataTree.prepare(modificationTree1);
604         inMemoryDataTree.commit(prepare1);
605
606         try {
607             inMemoryDataTree.validate(modificationTree2);
608             final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
609             inMemoryDataTree.commit(prepare2);
610             fail("Exception should have been thrown");
611         } catch (final Exception e) {
612             LOG.debug("Exception was thrown because path no longer exist in tree");
613         }
614
615         final InMemoryDataTreeSnapshot snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
616         assertFalse(snapshotAfterCommits.readNode(TestModel.TEST_PATH).isPresent());
617     }
618 }