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