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