Expand DataTreeCandidatesTest 78/80278/1
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 8 Feb 2019 13:01:18 +0000 (14:01 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 12 Feb 2019 09:35:04 +0000 (10:35 +0100)
This expands the test suite with some assertions around merge
operations turning into unmodified nodes.

Change-Id: I385848837d01d3adc242661ddc50dc9098cd4f34
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/Bug2690Test.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/DataTreeCandidatesTest.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/StructuralApplyModificationTest.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/TestModel.java

index 2dbe0b45b38f9e1cc45fc7ff8b055d18ca6c96b4..d22a68fca5690de81db6c5372dfa273715520c8a 100644 (file)
@@ -13,7 +13,6 @@ import static org.junit.Assert.assertTrue;
 import java.util.Optional;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
@@ -30,9 +29,6 @@ import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 
 public class Bug2690Test extends AbstractTestModelTest {
-    private static final YangInstanceIdentifier NAME_PATH = YangInstanceIdentifier.of(TestModel.NON_PRESENCE_QNAME)
-            .node(TestModel.NAME_QNAME);
-
     private DataTree inMemoryDataTree;
 
     @Before
@@ -87,14 +83,13 @@ public class Bug2690Test extends AbstractTestModelTest {
 
     private DataTreeModification setupTestDeleteStructuralAndWriteChild() {
         final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
-        modificationTree.delete(YangInstanceIdentifier.of(TestModel.NON_PRESENCE_QNAME));
-        modificationTree.write(NAME_PATH, Builders.leafBuilder()
-            .withNodeIdentifier(new NodeIdentifier(TestModel.NAME_QNAME)).withValue("abc").build());
+        modificationTree.delete(TestModel.NON_PRESENCE_PATH);
+        modificationTree.write(TestModel.NAME_PATH, ImmutableNodes.leafNode(TestModel.NAME_QNAME, "abc"));
         return modificationTree;
     }
 
     private static void verifyTestDeleteStructuralAndWriteChild(final DataTreeSnapshot snapshot) {
-        final Optional<NormalizedNode<?, ?>> readNode = snapshot.readNode(NAME_PATH);
+        final Optional<NormalizedNode<?, ?>> readNode = snapshot.readNode(TestModel.NAME_PATH);
         assertTrue(readNode.isPresent());
     }
 
index 084e4418d71bfae87b3254613f5e9611d4db3d4f..eb816d1c1596e21fb9d196f9bc117b208b87eb5f 100644 (file)
@@ -10,19 +10,24 @@ package org.opendaylight.yangtools.yang.data.impl.schema.tree;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
+import java.util.Collection;
 import org.junit.Before;
 import org.junit.Test;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -70,8 +75,7 @@ public class DataTreeCandidatesTest extends AbstractTestModelTest {
                 .withValue("testing-value")
                 .build();
 
-        final InMemoryDataTreeModification modification = (InMemoryDataTreeModification) innerDataTree.takeSnapshot()
-                .newModification();
+        final DataTreeModification modification = innerDataTree.takeSnapshot().newModification();
         modification.write(TestModel.VALUE_PATH, leaf);
 
         modification.ready();
@@ -98,4 +102,84 @@ public class DataTreeCandidatesTest extends AbstractTestModelTest {
         final LeafNode<?> readLeaf = (LeafNode<?>) newModification.readNode(TestModel.INNER_VALUE_PATH).get();
         assertEquals(readLeaf, leaf);
     }
+
+    @Test
+    public void testEmptyMergeOnContainer() throws DataValidationFailedException {
+        DataTreeModification modification = dataTree.takeSnapshot().newModification();
+        modification.merge(TestModel.NON_PRESENCE_PATH, ImmutableNodes.containerNode(TestModel.NON_PRESENCE_QNAME));
+        modification.ready();
+        dataTree.validate(modification);
+
+        // The entire transaction needs to fizzle to a no-op
+        DataTreeCandidate candidate = dataTree.prepare(modification);
+        DataTreeCandidateNode node = candidate.getRootNode();
+        assertEquals(ModificationType.UNMODIFIED, node.getModificationType());
+
+        // 'test'
+        assertUnmodified(1, node.getChildNodes());
+    }
+
+    @Test
+    public void testEmptyWriteOnContainer() throws DataValidationFailedException {
+        DataTreeModification modification = dataTree.takeSnapshot().newModification();
+        modification.write(TestModel.NON_PRESENCE_PATH, ImmutableNodes.containerNode(TestModel.NON_PRESENCE_QNAME));
+        modification.ready();
+        dataTree.validate(modification);
+
+        // The entire transaction needs to fizzle to a no-op
+        DataTreeCandidate candidate = dataTree.prepare(modification);
+        DataTreeCandidateNode node = candidate.getRootNode();
+        assertEquals(ModificationType.UNMODIFIED, node.getModificationType());
+
+        // 'test'
+        assertUnmodified(1, node.getChildNodes());
+    }
+
+    @Test
+    public void testEmptyMergesOnDeleted() throws DataValidationFailedException {
+        DataTreeModification modification = dataTree.takeSnapshot().newModification();
+        modification.delete(TestModel.NON_PRESENCE_PATH);
+        modification.merge(TestModel.DEEP_CHOICE_PATH, ImmutableNodes.choiceNode(TestModel.DEEP_CHOICE_QNAME));
+        modification.ready();
+        dataTree.validate(modification);
+
+        final DataTreeCandidate candidate = dataTree.prepare(modification);
+        assertEquals(YangInstanceIdentifier.EMPTY, candidate.getRootPath());
+        final DataTreeCandidateNode node = candidate.getRootNode();
+        assertEquals(ModificationType.UNMODIFIED, node.getModificationType());
+
+        // 'test'
+        assertUnmodified(1, node.getChildNodes());
+    }
+
+    @Test
+    public void testEmptyMergesOnExisting() throws DataValidationFailedException {
+        // Make sure 'non-presence' is present
+        DataTreeModification modification = dataTree.takeSnapshot().newModification();
+        modification.write(TestModel.NAME_PATH, ImmutableNodes.leafNode(TestModel.NAME_QNAME, "foo"));
+        modification.ready();
+        dataTree.validate(modification);
+        dataTree.commit(dataTree.prepare(modification));
+
+        // Issue an empty merge on it and a child choice
+        modification = dataTree.takeSnapshot().newModification();
+        modification.merge(TestModel.NON_PRESENCE_PATH, ImmutableNodes.containerNode(TestModel.NON_PRESENCE_QNAME));
+        modification.merge(TestModel.DEEP_CHOICE_PATH, ImmutableNodes.choiceNode(TestModel.DEEP_CHOICE_QNAME));
+        modification.ready();
+        dataTree.validate(modification);
+
+        // The entire transaction needs to fizzle to a no-op
+        final DataTreeCandidate candidate = dataTree.prepare(modification);
+        assertEquals(YangInstanceIdentifier.EMPTY, candidate.getRootPath());
+        final DataTreeCandidateNode node = candidate.getRootNode();
+        assertEquals(ModificationType.UNMODIFIED, node.getModificationType());
+
+        // 'non-presence' and 'test'
+        assertUnmodified(2, node.getChildNodes());
+    }
+
+    private static void assertUnmodified(final int expSize, final Collection<DataTreeCandidateNode> nodes) {
+        assertEquals(expSize, nodes.size());
+        nodes.forEach(node -> assertEquals(ModificationType.UNMODIFIED, node.getModificationType()));
+    }
 }
index d4cbb259404293d8f75b09e4b7df5763699b5d3c..5e0389b5512cc19f938038913cfa96461cc42920 100644 (file)
@@ -109,12 +109,8 @@ public final class StructuralApplyModificationTest extends AbstractTestModelTest
     public void testNestedStrucutralNodes() throws DataValidationFailedException {
         final DataTreeModification addListEntryModification = inMemoryDataTree.takeSnapshot().newModification();
 
-        final YangInstanceIdentifier path = YangInstanceIdentifier.create(
-            getNId(TestModel.NON_PRESENCE_QNAME),
-            getNId(TestModel.DEEP_CHOICE_QNAME),
-            getNId(TestModel.A_LIST_QNAME),
-            getNId(TestModel.A_LIST_QNAME, TestModel.A_NAME_QNAME, "1")
-        );
+        final YangInstanceIdentifier path = TestModel.DEEP_CHOICE_PATH.node(TestModel.A_LIST_QNAME)
+            .node(getNId(TestModel.A_LIST_QNAME, TestModel.A_NAME_QNAME, "1"));
 
         addListEntryModification.write(path,
             Builders.mapEntryBuilder()
@@ -127,9 +123,8 @@ public final class StructuralApplyModificationTest extends AbstractTestModelTest
 
         // Check parent structure auto created
         assertNodeExistence(path, true);
-        assertNodeExistence(YangInstanceIdentifier.create(getNId(TestModel.NON_PRESENCE_QNAME)), true);
-        assertNodeExistence(YangInstanceIdentifier.create(
-            getNId(TestModel.NON_PRESENCE_QNAME), getNId(TestModel.DEEP_CHOICE_QNAME)), true);
+        assertNodeExistence(TestModel.NON_PRESENCE_PATH, true);
+        assertNodeExistence(TestModel.DEEP_CHOICE_PATH, true);
     }
 
     private void assertNodeExistence(final YangInstanceIdentifier outerListParentPath, final boolean shouldBePresent) {
index f98d9d2bb041192af4a93fcf98eabaa9daf4e23e..df20968ba6d4d9410f56fb2ae8d6cfd5d1bc2bbe 100644 (file)
@@ -36,6 +36,10 @@ public final class TestModel {
     public static final YangInstanceIdentifier INNER_CONTAINER_PATH = TEST_PATH.node(INNER_CONTAINER_QNAME);
     public static final YangInstanceIdentifier VALUE_PATH = YangInstanceIdentifier.of(VALUE_QNAME);
     public static final YangInstanceIdentifier INNER_VALUE_PATH = INNER_CONTAINER_PATH.node(VALUE_QNAME);
+    public static final YangInstanceIdentifier NON_PRESENCE_PATH = YangInstanceIdentifier.of(NON_PRESENCE_QNAME);
+    public static final YangInstanceIdentifier DEEP_CHOICE_PATH = NON_PRESENCE_PATH.node(DEEP_CHOICE_QNAME);
+    public static final YangInstanceIdentifier NAME_PATH = NON_PRESENCE_PATH.node(NAME_QNAME);
+
     public static final QName TWO_QNAME = QName.create(TEST_QNAME, "two");
     public static final QName THREE_QNAME = QName.create(TEST_QNAME, "three");