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