2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.data.tree.impl;
10 import static org.junit.jupiter.api.Assertions.assertFalse;
11 import static org.junit.jupiter.api.Assertions.assertNotNull;
12 import static org.junit.jupiter.api.Assertions.assertTrue;
13 import static org.junit.jupiter.api.Assertions.fail;
15 import java.util.Optional;
16 import org.junit.jupiter.api.BeforeEach;
17 import org.junit.jupiter.api.Test;
18 import org.opendaylight.yangtools.yang.common.QName;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
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.spi.node.ImmutableNodes;
25 import org.opendaylight.yangtools.yang.data.tree.api.ConflictingModificationAppliedException;
26 import org.opendaylight.yangtools.yang.data.tree.api.DataTree;
27 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
28 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeConfiguration;
29 import org.opendaylight.yangtools.yang.data.tree.api.DataValidationFailedException;
30 import org.opendaylight.yangtools.yang.data.tree.impl.di.InMemoryDataTreeFactory;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 class ConcurrentTreeModificationTest extends AbstractTestModelTest {
35 private static final Logger LOG = LoggerFactory.getLogger(ConcurrentTreeModificationTest.class);
37 private static final Short ONE_ID = 1;
38 private static final Short TWO_ID = 2;
40 private static final YangInstanceIdentifier OUTER_LIST_1_PATH = YangInstanceIdentifier.builder(
41 TestModel.OUTER_LIST_PATH)
42 .nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, ONE_ID)
45 private static final YangInstanceIdentifier OUTER_LIST_2_PATH = YangInstanceIdentifier.builder(
46 TestModel.OUTER_LIST_PATH)
47 .nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, TWO_ID)
50 private static final MapEntryNode FOO_NODE = ImmutableNodes.newMapEntryBuilder()
51 .withNodeIdentifier(NodeIdentifierWithPredicates.of(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, ONE_ID))
52 .withChild(ImmutableNodes.leafNode(TestModel.ID_QNAME, ONE_ID))
53 .withChild(ImmutableNodes.newSystemMapBuilder()
54 .withNodeIdentifier(new NodeIdentifier(TestModel.INNER_LIST_QNAME))
58 private static final MapEntryNode BAR_NODE = ImmutableNodes.newMapEntryBuilder()
59 .withNodeIdentifier(NodeIdentifierWithPredicates.of(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, TWO_ID))
60 .withChild(ImmutableNodes.leafNode(TestModel.ID_QNAME, TWO_ID))
61 .withChild(ImmutableNodes.newSystemMapBuilder()
62 .withNodeIdentifier(new NodeIdentifier(TestModel.INNER_LIST_QNAME))
66 private DataTree inMemoryDataTree;
71 inMemoryDataTree = new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_OPERATIONAL,
75 private static ContainerNode createFooTestContainerNode() {
76 return ImmutableNodes.newContainerBuilder()
77 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
78 .withChild(ImmutableNodes.newSystemMapBuilder()
79 .withNodeIdentifier(new NodeIdentifier(TestModel.OUTER_LIST_QNAME))
85 private static ContainerNode createBarTestContainerNode() {
86 return ImmutableNodes.newContainerBuilder()
87 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
88 .withChild(ImmutableNodes.newSystemMapBuilder()
89 .withNodeIdentifier(new NodeIdentifier(TestModel.OUTER_LIST_QNAME))
95 private static <T> T assertPresentAndType(final Optional<?> potential, final Class<T> type) {
96 assertNotNull(potential);
97 assertTrue(potential.isPresent());
98 assertTrue(type.isInstance(potential.orElseThrow()));
99 return type.cast(potential.orElseThrow());
103 void writeWrite1stLevelEmptyTreeTest() throws DataValidationFailedException {
104 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
106 final var modificationTree1 = initialDataTreeSnapshot.newModification();
107 final var modificationTree2 = initialDataTreeSnapshot.newModification();
109 modificationTree1.write(TestModel.TEST_PATH,
110 ImmutableNodes.newContainerBuilder().withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME)).build());
111 modificationTree2.write(TestModel.TEST_PATH,
112 ImmutableNodes.newContainerBuilder().withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME)).build());
114 modificationTree1.ready();
115 modificationTree2.ready();
116 inMemoryDataTree.validate(modificationTree1);
117 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
118 inMemoryDataTree.commit(prepare1);
121 inMemoryDataTree.validate(modificationTree2);
122 fail("Exception should have been thrown.");
123 } catch (final ConflictingModificationAppliedException ex) {
124 LOG.debug("ConflictingModificationAppliedException - was thrown as expected", ex);
126 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
127 inMemoryDataTree.commit(prepare2);
129 final var testNodeAfterCommits = modificationTree1.readNode(TestModel.TEST_PATH);
130 assertPresentAndType(testNodeAfterCommits, ContainerNode.class);
134 void writeMerge1stLevelEmptyTreeTest() throws DataValidationFailedException {
135 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
137 final var modificationTree1 = initialDataTreeSnapshot.newModification();
138 final var modificationTree2 = initialDataTreeSnapshot.newModification();
140 modificationTree1.write(TestModel.TEST_PATH,
141 ImmutableNodes.newContainerBuilder().withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME)).build());
142 modificationTree2.merge(TestModel.TEST_PATH,
143 ImmutableNodes.newContainerBuilder().withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME)).build());
145 modificationTree1.ready();
146 modificationTree2.ready();
148 inMemoryDataTree.validate(modificationTree1);
149 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
150 inMemoryDataTree.commit(prepare1);
152 inMemoryDataTree.validate(modificationTree2);
153 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
154 inMemoryDataTree.commit(prepare2);
156 final var testNodeAfterCommits = modificationTree1.readNode(TestModel.TEST_PATH);
157 assertPresentAndType(testNodeAfterCommits, ContainerNode.class);
161 void writeWriteFooBar1stLevelEmptyTreeTest() throws DataValidationFailedException {
162 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
164 final var modificationTree1 = initialDataTreeSnapshot.newModification();
165 final var modificationTree2 = initialDataTreeSnapshot.newModification();
167 modificationTree1.write(TestModel.TEST_PATH, createFooTestContainerNode());
168 modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
169 modificationTree1.ready();
170 modificationTree2.ready();
172 inMemoryDataTree.validate(modificationTree1);
173 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
174 inMemoryDataTree.commit(prepare1);
177 inMemoryDataTree.validate(modificationTree2);
178 fail("Exception should have been thrown.");
179 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
180 inMemoryDataTree.commit(prepare2);
181 } catch (final ConflictingModificationAppliedException ex) {
182 LOG.debug("ConflictingModificationAppliedException - was thrown as expected", ex);
185 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
186 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
187 assertFalse(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH).isPresent());
191 void writeMergeFooBar1stLevelEmptyTreeTest() throws DataValidationFailedException {
192 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
194 final var modificationTree1 = initialDataTreeSnapshot.newModification();
195 final var modificationTree2 = initialDataTreeSnapshot.newModification();
197 modificationTree1.write(TestModel.TEST_PATH, createFooTestContainerNode());
198 modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
199 modificationTree1.ready();
200 modificationTree2.ready();
202 inMemoryDataTree.validate(modificationTree1);
203 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
204 inMemoryDataTree.commit(prepare1);
206 inMemoryDataTree.validate(modificationTree2);
207 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
208 inMemoryDataTree.commit(prepare2);
210 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
211 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
212 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
216 void mergeWriteFooBar1stLevelEmptyTreeTest() throws DataValidationFailedException {
217 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
219 final var modificationTree1 = initialDataTreeSnapshot.newModification();
220 final var modificationTree2 = initialDataTreeSnapshot.newModification();
222 modificationTree1.merge(TestModel.TEST_PATH, createFooTestContainerNode());
223 modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
224 modificationTree1.ready();
225 modificationTree2.ready();
227 inMemoryDataTree.validate(modificationTree1);
228 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
229 inMemoryDataTree.commit(prepare1);
232 inMemoryDataTree.validate(modificationTree2);
233 fail("Exception should have been thrown.");
234 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
235 inMemoryDataTree.commit(prepare2);
236 } catch (final ConflictingModificationAppliedException ex) {
237 LOG.debug("ConflictingModificationAppliedException - was thrown as expected", ex);
240 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
241 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
242 assertFalse(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH).isPresent());
246 void mergeMergeFooBar1stLevelEmptyTreeTest() throws DataValidationFailedException {
247 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
249 final var modificationTree1 = initialDataTreeSnapshot.newModification();
250 final var modificationTree2 = initialDataTreeSnapshot.newModification();
252 modificationTree1.merge(TestModel.TEST_PATH, createFooTestContainerNode());
253 modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
254 modificationTree1.ready();
255 modificationTree2.ready();
257 inMemoryDataTree.validate(modificationTree1);
258 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
259 inMemoryDataTree.commit(prepare1);
261 inMemoryDataTree.validate(modificationTree2);
262 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
263 inMemoryDataTree.commit(prepare2);
265 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
266 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
267 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
271 void writeWriteFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
272 final var initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
273 initialDataTreeModification.write(TestModel.TEST_PATH, emptyContainer(TestModel.TEST_QNAME));
274 initialDataTreeModification.ready();
275 inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
276 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
278 final var modificationTree1 = initialDataTreeSnapshot.newModification();
279 final var modificationTree2 = initialDataTreeSnapshot.newModification();
281 modificationTree1.write(TestModel.TEST_PATH, createFooTestContainerNode());
282 modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
283 modificationTree1.ready();
284 modificationTree2.ready();
286 inMemoryDataTree.validate(modificationTree1);
287 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
288 inMemoryDataTree.commit(prepare1);
291 inMemoryDataTree.validate(modificationTree2);
292 fail("Exception should have been thrown.");
293 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
294 inMemoryDataTree.commit(prepare2);
295 } catch (final ConflictingModificationAppliedException ex) {
296 LOG.debug("ConflictingModificationAppliedException was thrown as expected", ex);
299 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
300 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
301 assertFalse(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH).isPresent());
305 void writeMergeFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
306 final var initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
307 initialDataTreeModification.write(TestModel.TEST_PATH, emptyContainer(TestModel.TEST_QNAME));
308 initialDataTreeModification.ready();
309 inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
310 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
312 final var modificationTree1 = initialDataTreeSnapshot.newModification();
313 final var modificationTree2 = initialDataTreeSnapshot.newModification();
315 modificationTree1.write(TestModel.TEST_PATH, createFooTestContainerNode());
316 modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
317 modificationTree1.ready();
318 modificationTree2.ready();
320 inMemoryDataTree.validate(modificationTree1);
321 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
322 inMemoryDataTree.commit(prepare1);
324 inMemoryDataTree.validate(modificationTree2);
325 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
326 inMemoryDataTree.commit(prepare2);
328 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
329 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
330 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
334 void mergeWriteFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
335 final var initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
336 initialDataTreeModification.write(TestModel.TEST_PATH, emptyContainer(TestModel.TEST_QNAME));
337 initialDataTreeModification.ready();
338 inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
339 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
341 final var modificationTree1 = initialDataTreeSnapshot.newModification();
342 final var modificationTree2 = initialDataTreeSnapshot.newModification();
344 modificationTree1.merge(TestModel.TEST_PATH, createFooTestContainerNode());
345 modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
346 modificationTree1.ready();
347 modificationTree2.ready();
349 inMemoryDataTree.validate(modificationTree1);
350 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
351 inMemoryDataTree.commit(prepare1);
354 inMemoryDataTree.validate(modificationTree2);
355 fail("Exception should have been thrown.");
356 final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
357 inMemoryDataTree.commit(prepare2);
358 } catch (final ConflictingModificationAppliedException ex) {
359 LOG.debug("ConflictingModificationAppliedException was thrown as expected", ex);
363 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
364 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
365 assertFalse(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH).isPresent());
369 void mergeMergeFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
370 final var initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
371 initialDataTreeModification.write(TestModel.TEST_PATH, emptyContainer(TestModel.TEST_QNAME));
372 initialDataTreeModification.ready();
373 inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
374 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
376 final var modificationTree1 = initialDataTreeSnapshot.newModification();
377 final var modificationTree2 = initialDataTreeSnapshot.newModification();
379 modificationTree1.merge(TestModel.TEST_PATH, createFooTestContainerNode());
380 modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
381 modificationTree1.ready();
382 modificationTree2.ready();
384 inMemoryDataTree.validate(modificationTree1);
385 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
386 inMemoryDataTree.commit(prepare1);
388 inMemoryDataTree.validate(modificationTree2);
389 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
390 inMemoryDataTree.commit(prepare2);
392 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
393 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
394 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
398 void deleteWriteFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
399 final var initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
400 initialDataTreeModification.write(TestModel.TEST_PATH, emptyContainer(TestModel.TEST_QNAME));
401 initialDataTreeModification.ready();
402 inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
403 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
405 final var modificationTree1 = initialDataTreeSnapshot.newModification();
406 final var modificationTree2 = initialDataTreeSnapshot.newModification();
408 modificationTree1.delete(TestModel.TEST_PATH);
409 modificationTree2.write(TestModel.TEST_PATH, createBarTestContainerNode());
410 modificationTree1.ready();
411 modificationTree2.ready();
413 inMemoryDataTree.validate(modificationTree1);
414 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
415 inMemoryDataTree.commit(prepare1);
418 inMemoryDataTree.validate(modificationTree2);
419 fail("Exception should have been thrown.");
420 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
421 inMemoryDataTree.commit(prepare2);
422 } catch (final ConflictingModificationAppliedException ex) {
423 LOG.debug("ConflictingModificationAppliedException was thrown as expected", ex);
427 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
428 assertFalse(snapshotAfterCommits.readNode(TestModel.TEST_PATH).isPresent());
432 void deleteMergeFooBar1stLevelEmptyContainerTest() throws DataValidationFailedException {
433 final var initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
434 initialDataTreeModification.write(TestModel.TEST_PATH, emptyContainer(TestModel.TEST_QNAME));
435 initialDataTreeModification.ready();
436 inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
437 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
439 final var modificationTree1 = initialDataTreeSnapshot.newModification();
440 final var modificationTree2 = initialDataTreeSnapshot.newModification();
442 modificationTree1.delete(TestModel.TEST_PATH);
443 modificationTree2.merge(TestModel.TEST_PATH, createBarTestContainerNode());
444 modificationTree1.ready();
445 modificationTree2.ready();
447 inMemoryDataTree.validate(modificationTree1);
448 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
449 inMemoryDataTree.commit(prepare1);
451 inMemoryDataTree.validate(modificationTree2);
452 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
453 inMemoryDataTree.commit(prepare2);
455 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
456 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
460 void writeWriteFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
461 final var initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
462 initialDataTreeModification.write(TestModel.TEST_PATH, emptyContainer(TestModel.TEST_QNAME));
463 initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, ImmutableNodes.newSystemMapBuilder()
464 .withNodeIdentifier(new NodeIdentifier(TestModel.OUTER_LIST_QNAME))
466 initialDataTreeModification.ready();
467 inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
468 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
470 final var modificationTree1 = initialDataTreeSnapshot.newModification();
471 final var modificationTree2 = initialDataTreeSnapshot.newModification();
473 modificationTree1.write(OUTER_LIST_1_PATH, FOO_NODE);
474 modificationTree2.write(OUTER_LIST_2_PATH, BAR_NODE);
475 modificationTree1.ready();
476 modificationTree2.ready();
478 inMemoryDataTree.validate(modificationTree1);
479 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
480 inMemoryDataTree.commit(prepare1);
482 inMemoryDataTree.validate(modificationTree2);
483 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
484 inMemoryDataTree.commit(prepare2);
486 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
487 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
488 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
492 void writeMergeFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
493 final var initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
494 initialDataTreeModification.write(TestModel.TEST_PATH, emptyContainer(TestModel.TEST_QNAME));
495 initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, ImmutableNodes.newSystemMapBuilder()
496 .withNodeIdentifier(new NodeIdentifier(TestModel.OUTER_LIST_QNAME))
498 initialDataTreeModification.ready();
499 inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
500 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
502 final var modificationTree1 = initialDataTreeSnapshot.newModification();
503 final var modificationTree2 = initialDataTreeSnapshot.newModification();
505 modificationTree1.write(OUTER_LIST_1_PATH, FOO_NODE);
506 modificationTree2.merge(OUTER_LIST_2_PATH, BAR_NODE);
507 modificationTree1.ready();
508 modificationTree2.ready();
510 inMemoryDataTree.validate(modificationTree1);
511 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
512 inMemoryDataTree.commit(prepare1);
514 inMemoryDataTree.validate(modificationTree2);
515 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
516 inMemoryDataTree.commit(prepare2);
518 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
519 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
520 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
524 void mergeWriteFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
525 final var initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
526 initialDataTreeModification.write(TestModel.TEST_PATH, emptyContainer(TestModel.TEST_QNAME));
527 initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, ImmutableNodes.newSystemMapBuilder()
528 .withNodeIdentifier(new NodeIdentifier(TestModel.OUTER_LIST_QNAME))
530 initialDataTreeModification.ready();
531 inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
532 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
534 final var modificationTree1 = initialDataTreeSnapshot.newModification();
535 final var modificationTree2 = initialDataTreeSnapshot.newModification();
537 modificationTree1.merge(OUTER_LIST_1_PATH, FOO_NODE);
538 modificationTree2.write(OUTER_LIST_2_PATH, BAR_NODE);
539 modificationTree1.ready();
540 modificationTree2.ready();
542 inMemoryDataTree.validate(modificationTree1);
543 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
544 inMemoryDataTree.commit(prepare1);
546 inMemoryDataTree.validate(modificationTree2);
547 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
548 inMemoryDataTree.commit(prepare2);
550 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
551 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
552 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
556 void mergeMergeFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
557 final var initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
558 initialDataTreeModification.write(TestModel.TEST_PATH, emptyContainer(TestModel.TEST_QNAME));
559 initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, ImmutableNodes.newSystemMapBuilder()
560 .withNodeIdentifier(new NodeIdentifier(TestModel.OUTER_LIST_QNAME))
562 initialDataTreeModification.ready();
563 inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
564 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
566 final var modificationTree1 = initialDataTreeSnapshot.newModification();
567 final var modificationTree2 = initialDataTreeSnapshot.newModification();
569 modificationTree1.merge(OUTER_LIST_1_PATH, FOO_NODE);
570 modificationTree2.merge(OUTER_LIST_2_PATH, BAR_NODE);
571 modificationTree1.ready();
572 modificationTree2.ready();
574 inMemoryDataTree.validate(modificationTree1);
575 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
576 inMemoryDataTree.commit(prepare1);
578 inMemoryDataTree.validate(modificationTree2);
579 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
580 inMemoryDataTree.commit(prepare2);
582 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
583 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_1_PATH), MapEntryNode.class);
584 assertPresentAndType(snapshotAfterCommits.readNode(OUTER_LIST_2_PATH), MapEntryNode.class);
588 void deleteWriteFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
589 final var initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
590 initialDataTreeModification.write(TestModel.TEST_PATH, emptyContainer(TestModel.TEST_QNAME));
591 initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, ImmutableNodes.newSystemMapBuilder()
592 .withNodeIdentifier(new NodeIdentifier(TestModel.OUTER_LIST_QNAME))
594 initialDataTreeModification.ready();
595 inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
596 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
598 final var modificationTree1 = initialDataTreeSnapshot.newModification();
599 final var modificationTree2 = initialDataTreeSnapshot.newModification();
601 modificationTree1.delete(TestModel.TEST_PATH);
602 modificationTree2.write(OUTER_LIST_2_PATH, BAR_NODE);
603 modificationTree1.ready();
604 modificationTree2.ready();
606 inMemoryDataTree.validate(modificationTree1);
607 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
608 inMemoryDataTree.commit(prepare1);
611 inMemoryDataTree.validate(modificationTree2);
612 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
613 inMemoryDataTree.commit(prepare2);
614 fail("Exception should have been thrown");
615 } catch (final ConflictingModificationAppliedException e) {
616 LOG.debug("Exception was thrown because path no longer exist in tree", e);
619 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
620 assertFalse(snapshotAfterCommits.readNode(TestModel.TEST_PATH).isPresent());
624 void deleteMergeFooBar2ndLevelEmptyContainerTest() throws DataValidationFailedException {
625 final var initialDataTreeModification = inMemoryDataTree.takeSnapshot().newModification();
626 initialDataTreeModification.write(TestModel.TEST_PATH, emptyContainer(TestModel.TEST_QNAME));
627 initialDataTreeModification.write(TestModel.OUTER_LIST_PATH, ImmutableNodes.newSystemMapBuilder()
628 .withNodeIdentifier(new NodeIdentifier(TestModel.OUTER_LIST_QNAME))
630 initialDataTreeModification.ready();
631 inMemoryDataTree.commit(inMemoryDataTree.prepare(initialDataTreeModification));
632 final var initialDataTreeSnapshot = inMemoryDataTree.takeSnapshot();
634 final var modificationTree1 = initialDataTreeSnapshot.newModification();
635 final var modificationTree2 = initialDataTreeSnapshot.newModification();
637 modificationTree1.delete(TestModel.TEST_PATH);
638 modificationTree2.merge(OUTER_LIST_2_PATH, BAR_NODE);
639 modificationTree1.ready();
640 modificationTree2.ready();
642 inMemoryDataTree.validate(modificationTree1);
643 final var prepare1 = inMemoryDataTree.prepare(modificationTree1);
644 inMemoryDataTree.commit(prepare1);
647 inMemoryDataTree.validate(modificationTree2);
648 final var prepare2 = inMemoryDataTree.prepare(modificationTree2);
649 inMemoryDataTree.commit(prepare2);
650 fail("Exception should have been thrown");
651 } catch (final ConflictingModificationAppliedException e) {
652 LOG.debug("Exception was thrown because path no longer exist in tree", e);
655 final var snapshotAfterCommits = inMemoryDataTree.takeSnapshot();
656 assertFalse(snapshotAfterCommits.readNode(TestModel.TEST_PATH).isPresent());
659 private static ContainerNode emptyContainer(final QName name) {
660 return ImmutableNodes.newContainerBuilder().withNodeIdentifier(new NodeIdentifier(name)).build();