summaryrefslogtreecommitdiffstats
path: root/v3po/data-impl/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'v3po/data-impl/src/test')
-rw-r--r--v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataTreeUtilsTest.java68
-rw-r--r--v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java100
-rw-r--r--v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModificationDiffTest.java376
-rw-r--r--v3po/data-impl/src/test/resources/test-diff.yang37
4 files changed, 483 insertions, 98 deletions
diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataTreeUtilsTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataTreeUtilsTest.java
deleted file mode 100644
index 40792a135..000000000
--- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataTreeUtilsTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.data.impl;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-import org.junit.Test;
-import org.mockito.Matchers;
-import org.mockito.Mockito;
-import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-
-public class DataTreeUtilsTest {
-
- @Test
- public void testChildrenFromNormalized() throws Exception {
- final ContainerNode parent = Mockito.mock(ContainerNode.class);
- final BindingNormalizedNodeSerializer serializer = Mockito.mock(BindingNormalizedNodeSerializer.class);
-
- final Collection<DataContainerChild> list = new ArrayList<>();
- Mockito.doReturn(list).when(parent).getValue();
-
- // init child1 (will not be serialized)
- final DataContainerChild child1 = Mockito.mock(DataContainerChild.class);
- Mockito.when(child1.getIdentifier()).thenReturn(Mockito.mock(YangInstanceIdentifier.PathArgument.class));
- Mockito.when(serializer.fromNormalizedNode(Matchers.any(YangInstanceIdentifier.class), Matchers.eq(child1))).thenReturn(null);
- list.add(child1);
-
- // init child 2 (will be serialized)
- final DataContainerChild child2 = Mockito.mock(DataContainerChild.class);
- Mockito.when(child2.getIdentifier()).thenReturn(Mockito.mock(YangInstanceIdentifier.PathArgument.class));
-
- final Map.Entry entry = Mockito.mock(Map.Entry.class);
- final InstanceIdentifier<?> id = Mockito.mock(InstanceIdentifier.class);
- Mockito.doReturn(id).when(entry).getKey();
- final DataObject data = Mockito.mock(DataObject.class);
- Mockito.doReturn(data).when(entry).getValue();
- Mockito.when(serializer.fromNormalizedNode(Matchers.any(YangInstanceIdentifier.class), Matchers.eq(child2))).thenReturn(entry);
-
- list.add(child2);
-
- // run tested method
- final Map<InstanceIdentifier<?>, DataObject> map = DataTreeUtils.childrenFromNormalized(parent, serializer);
- assertEquals(1, map.size());
- assertEquals(data, map.get(id));
- }
-} \ No newline at end of file
diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java
index fed32da8a..086636de6 100644
--- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java
+++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java
@@ -37,9 +37,8 @@ import io.fd.honeycomb.v3po.data.DataModification;
import io.fd.honeycomb.v3po.translate.TranslationException;
import io.fd.honeycomb.v3po.translate.write.WriteContext;
import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.List;
+import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
@@ -58,6 +57,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
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.ModificationType;
public class ModifiableDataTreeDelegatorTest {
@@ -109,7 +109,7 @@ public class ModifiableDataTreeDelegatorTest {
when(dataTree.takeSnapshot()).thenReturn(snapshot);
when(snapshot.newModification()).thenReturn(modification);
- final DataModification dataTreeSnapshot = configDataTree.newModification();
+ configDataTree.newModification();
// Snapshot captured twice, so that original data could be provided to translation layer without any possible
// modification
verify(dataTree, times(2)).takeSnapshot();
@@ -135,12 +135,19 @@ public class ModifiableDataTreeDelegatorTest {
// Prepare modification:
final DataTreeCandidateNode rootNode = mockRootNode();
+ doReturn(ModificationType.SUBTREE_MODIFIED).when(rootNode).getModificationType();
+ doReturn(mock(YangInstanceIdentifier.PathArgument.class)).when(rootNode).getIdentifier();
+ final DataTreeCandidateNode childNode = mock(DataTreeCandidateNode.class);
+ doReturn(mock(YangInstanceIdentifier.PathArgument.class)).when(childNode).getIdentifier();
+ doReturn(Collections.singleton(childNode)).when(rootNode).getChildNodes();
+ doReturn(ModificationType.WRITE).when(childNode).getModificationType();
+
// data before:
final ContainerNode nodeBefore = mockContainerNode(dataBefore);
- when(rootNode.getDataBefore()).thenReturn(Optional.<NormalizedNode<?, ?>>fromNullable(nodeBefore));
+ when(childNode.getDataBefore()).thenReturn(Optional.fromNullable(nodeBefore));
// data after:
final ContainerNode nodeAfter = mockContainerNode(dataAfter);
- when(rootNode.getDataAfter()).thenReturn(Optional.<NormalizedNode<?, ?>>fromNullable(nodeAfter));
+ when(childNode.getDataAfter()).thenReturn(Optional.fromNullable(nodeAfter));
// Run the test
doReturn(rootNode).when(prepare).getRootNode();
@@ -160,9 +167,7 @@ public class ModifiableDataTreeDelegatorTest {
}
private Map<InstanceIdentifier<?>, DataObject> mapOf(final DataObject dataBefore, final Class<Ethernet> type) {
- return eq(
- Collections.<InstanceIdentifier<?>, DataObject>singletonMap(InstanceIdentifier.create(type),
- dataBefore));
+ return eq(Collections.singletonMap(InstanceIdentifier.create(type),dataBefore));
}
private DataObject mockDataObject(final String name, final Class<? extends DataObject> classToMock) {
@@ -194,12 +199,19 @@ public class ModifiableDataTreeDelegatorTest {
// Prepare modification:
final DataTreeCandidateNode rootNode = mockRootNode();
+ doReturn(ModificationType.SUBTREE_MODIFIED).when(rootNode).getModificationType();
+ doReturn(mock(YangInstanceIdentifier.PathArgument.class)).when(rootNode).getIdentifier();
+ final DataTreeCandidateNode childNode = mock(DataTreeCandidateNode.class);
+ doReturn(mock(YangInstanceIdentifier.PathArgument.class)).when(childNode).getIdentifier();
+ doReturn(Collections.singleton(childNode)).when(rootNode).getChildNodes();
+ doReturn(ModificationType.WRITE).when(childNode).getModificationType();
+
// data before:
final ContainerNode nodeBefore = mockContainerNode(dataBefore);
- when(rootNode.getDataBefore()).thenReturn(Optional.<NormalizedNode<?, ?>>fromNullable(nodeBefore));
+ when(childNode.getDataBefore()).thenReturn(Optional.fromNullable(nodeBefore));
// data after:
final ContainerNode nodeAfter = mockContainerNode(dataAfter);
- when(rootNode.getDataAfter()).thenReturn(Optional.<NormalizedNode<?, ?>>fromNullable(nodeAfter));
+ when(childNode.getDataAfter()).thenReturn(Optional.fromNullable(nodeAfter));
// Run the test
try {
@@ -245,12 +257,19 @@ public class ModifiableDataTreeDelegatorTest {
// Prepare modification:
final DataTreeCandidateNode rootNode = mockRootNode();
+ doReturn(ModificationType.SUBTREE_MODIFIED).when(rootNode).getModificationType();
+ doReturn(mock(YangInstanceIdentifier.PathArgument.class)).when(rootNode).getIdentifier();
+ final DataTreeCandidateNode childNode = mock(DataTreeCandidateNode.class);
+ doReturn(mock(YangInstanceIdentifier.PathArgument.class)).when(childNode).getIdentifier();
+ doReturn(Collections.singleton(childNode)).when(rootNode).getChildNodes();
+ doReturn(ModificationType.WRITE).when(childNode).getModificationType();
+
// data before:
final ContainerNode nodeBefore = mockContainerNode(dataBefore);
- when(rootNode.getDataBefore()).thenReturn(Optional.<NormalizedNode<?, ?>>fromNullable(nodeBefore));
+ when(childNode.getDataBefore()).thenReturn(Optional.fromNullable(nodeBefore));
// data after:
final ContainerNode nodeAfter = mockContainerNode(dataAfter);
- when(rootNode.getDataAfter()).thenReturn(Optional.<NormalizedNode<?, ?>>fromNullable(nodeAfter));
+ when(childNode.getDataAfter()).thenReturn(Optional.fromNullable(nodeAfter));
// Run the test
try {
@@ -267,6 +286,37 @@ public class ModifiableDataTreeDelegatorTest {
fail("RevertFailedException was expected");
}
+ @Test
+ public void testChildrenFromNormalized() throws Exception {
+ final BindingNormalizedNodeSerializer serializer = mock(BindingNormalizedNodeSerializer.class);
+
+ final Map<YangInstanceIdentifier, NormalizedNode<?, ?>> map = new HashMap<>();
+
+ // init child1 (will not be serialized)
+ final DataContainerChild child1 = mock(DataContainerChild.class);
+ when(child1.getIdentifier()).thenReturn(mock(YangInstanceIdentifier.PathArgument.class));
+ when(serializer.fromNormalizedNode(any(YangInstanceIdentifier.class), eq(child1))).thenReturn(null);
+ map.put(mock(YangInstanceIdentifier.class), child1);
+
+ // init child 2 (will be serialized)
+ final DataContainerChild child2 = mock(DataContainerChild.class);
+ when(child2.getIdentifier()).thenReturn(mock(YangInstanceIdentifier.PathArgument.class));
+
+ final Map.Entry entry = mock(Map.Entry.class);
+ final InstanceIdentifier<?> id = mock(InstanceIdentifier.class);
+ doReturn(id).when(entry).getKey();
+ final DataObject data = mock(DataObject.class);
+ doReturn(data).when(entry).getValue();
+ when(serializer.fromNormalizedNode(any(YangInstanceIdentifier.class), eq(child2))).thenReturn(entry);
+ map.put(mock(YangInstanceIdentifier.class), child2);
+
+ // run tested method
+ final Map<InstanceIdentifier<?>, DataObject> baMap =
+ ModifiableDataTreeDelegator.toBindingAware(map, serializer);
+ assertEquals(1, baMap.size());
+ assertEquals(data, baMap.get(id));
+ }
+
private DataTreeCandidateNode mockRootNode() {
final DataTreeCandidate candidate = mock(DataTreeCandidate.class);
when(dataTree.prepare(modification)).thenReturn(candidate);
@@ -277,32 +327,22 @@ public class ModifiableDataTreeDelegatorTest {
return rootNode;
}
- private ContainerNode mockContainerNode(DataObject... modifications) {
- final int numberOfChildren = modifications.length;
-
+ private ContainerNode mockContainerNode(DataObject modification) {
final YangInstanceIdentifier.NodeIdentifier identifier =
YangInstanceIdentifier.NodeIdentifier.create(QName.create("/"));
final ContainerNode node = mock(ContainerNode.class);
when(node.getIdentifier()).thenReturn(identifier);
- final List<DataContainerChild> list = new ArrayList<>(numberOfChildren);
- doReturn(list).when(node).getValue();
+ final Map.Entry entry = mock(Map.Entry.class);
+ final Class<? extends DataObject> implementedInterface =
+ (Class<? extends DataObject>) modification.getImplementedInterface();
+ final InstanceIdentifier<?> id = InstanceIdentifier.create(implementedInterface);
- for (DataObject modification : modifications) {
- final DataContainerChild child = mock(DataContainerChild.class);
- when(child.getIdentifier()).thenReturn(mock(YangInstanceIdentifier.PathArgument.class));
- list.add(child);
+ doReturn(id).when(entry).getKey();
+ doReturn(modification).when(entry).getValue();
+ doReturn(entry).when(serializer).fromNormalizedNode(any(YangInstanceIdentifier.class), eq(node));
- final Map.Entry entry = mock(Map.Entry.class);
- final Class<? extends DataObject> implementedInterface =
- (Class<? extends DataObject>) modification.getImplementedInterface();
- final InstanceIdentifier<?> id = InstanceIdentifier.create(implementedInterface);
-
- doReturn(id).when(entry).getKey();
- doReturn(modification).when(entry).getValue();
- doReturn(entry).when(serializer).fromNormalizedNode(any(YangInstanceIdentifier.class), eq(child));
- }
return node;
}
}
diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModificationDiffTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModificationDiffTest.java
new file mode 100644
index 000000000..f5c270618
--- /dev/null
+++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModificationDiffTest.java
@@ -0,0 +1,376 @@
+package io.fd.honeycomb.v3po.data.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateTip;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
+
+public class ModificationDiffTest {
+
+ private static final QName TOP_CONTAINER_QNAME = QName.create("urn:opendaylight:params:xml:ns:yang:test:diff", "2015-01-05", "top-container");
+ private static final QName STRING_LEAF_QNAME = QName.create(TOP_CONTAINER_QNAME, "string");
+ private static final QName NAME_LEAF_QNAME = QName.create(TOP_CONTAINER_QNAME, "name");
+ private static final QName TEXT_LEAF_QNAME = QName.create(TOP_CONTAINER_QNAME, "text");
+ private static final QName NESTED_LIST_QNAME = QName.create(TOP_CONTAINER_QNAME, "nested-list");
+ private static final QName DEEP_LIST_QNAME = QName.create(TOP_CONTAINER_QNAME, "deep-list");
+
+ private YangInstanceIdentifier topContainerId = YangInstanceIdentifier.of(TOP_CONTAINER_QNAME);;
+
+ @Test
+ public void testInitialWrite() throws Exception {
+ final TipProducingDataTree dataTree = getDataTree();
+ final DataTreeSnapshot dataTreeSnapshot = dataTree.takeSnapshot();
+ final DataTreeModification dataTreeModification = dataTreeSnapshot.newModification();
+ final NormalizedNode<?, ?> topContainer = getTopContainer("string1");
+ final YangInstanceIdentifier topContainerId = YangInstanceIdentifier.of(TOP_CONTAINER_QNAME);
+ dataTreeModification.write(topContainerId, topContainer);
+ dataTreeModification.ready();
+ dataTree.validate(dataTreeModification);
+ final DataTreeCandidateTip prepare = dataTree.prepare(dataTreeModification);
+
+ final ModifiableDataTreeDelegator.ModificationDiff modificationDiff =
+ ModifiableDataTreeDelegator.ModificationDiff
+ .recursivelyFromCandidate(YangInstanceIdentifier.EMPTY, prepare.getRootNode());
+
+ assertTrue(modificationDiff.getModificationsBefore().isEmpty());
+ assertAfter(topContainer, topContainerId, modificationDiff);
+ }
+
+ @Test
+ public void testUpdateWrite() throws Exception {
+ final TipProducingDataTree dataTree = getDataTree();
+ final NormalizedNode<?, ?> topContainerBefore = addTopContainer(dataTree);
+
+ final DataTreeSnapshot dataTreeSnapshot = dataTree.takeSnapshot();
+ final DataTreeModification dataTreeModification = dataTreeSnapshot.newModification();
+ final NormalizedNode<?, ?> topContainerAfter = getTopContainer("string2");
+ dataTreeModification.write(topContainerId, topContainerAfter);
+ dataTreeModification.ready();
+ dataTree.validate(dataTreeModification);
+ final DataTreeCandidateTip prepare = dataTree.prepare(dataTreeModification);
+
+ final ModifiableDataTreeDelegator.ModificationDiff modificationDiff =
+ ModifiableDataTreeDelegator.ModificationDiff
+ .recursivelyFromCandidate(YangInstanceIdentifier.EMPTY, prepare.getRootNode());
+
+ assertBefore(topContainerBefore, topContainerId, modificationDiff);
+ assertAfter(topContainerAfter, topContainerId, modificationDiff);
+ }
+
+ @Test
+ public void testUpdateMerge() throws Exception {
+ final TipProducingDataTree dataTree = getDataTree();
+ final NormalizedNode<?, ?> topContainerBefore = addTopContainer(dataTree);
+
+ final DataTreeSnapshot dataTreeSnapshot = dataTree.takeSnapshot();
+ final DataTreeModification dataTreeModification = dataTreeSnapshot.newModification();
+ final NormalizedNode<?, ?> topContainerAfter = getTopContainer("string2");
+ dataTreeModification.merge(topContainerId, topContainerAfter);
+ dataTreeModification.ready();
+ dataTree.validate(dataTreeModification);
+ final DataTreeCandidateTip prepare = dataTree.prepare(dataTreeModification);
+
+ final ModifiableDataTreeDelegator.ModificationDiff modificationDiff =
+ ModifiableDataTreeDelegator.ModificationDiff
+ .recursivelyFromCandidate(YangInstanceIdentifier.EMPTY, prepare.getRootNode());
+
+ assertBefore(topContainerBefore, topContainerId, modificationDiff);
+ assertAfter(topContainerAfter, topContainerId, modificationDiff);
+ }
+
+ @Test
+ public void testUpdateDelete() throws Exception {
+ final TipProducingDataTree dataTree = getDataTree();
+ final NormalizedNode<?, ?> topContainerBefore = addTopContainer(dataTree);
+
+ final DataTreeSnapshot dataTreeSnapshot = dataTree.takeSnapshot();
+ final DataTreeModification dataTreeModification = dataTreeSnapshot.newModification();
+ dataTreeModification.delete(topContainerId);
+ dataTreeModification.ready();
+ dataTree.validate(dataTreeModification);
+ final DataTreeCandidateTip prepare = dataTree.prepare(dataTreeModification);
+
+ final ModifiableDataTreeDelegator.ModificationDiff modificationDiff =
+ ModifiableDataTreeDelegator.ModificationDiff
+ .recursivelyFromCandidate(YangInstanceIdentifier.EMPTY, prepare.getRootNode());
+
+ assertBefore(topContainerBefore, topContainerId, modificationDiff);
+ assertTrue(modificationDiff.getModificationsAfter().isEmpty());
+ }
+
+ @Test
+ public void testWriteAndUpdateInnerList() throws Exception {
+ final TipProducingDataTree dataTree = getDataTree();
+ addTopContainer(dataTree);
+
+ DataTreeSnapshot dataTreeSnapshot = dataTree.takeSnapshot();
+ DataTreeModification dataTreeModification = dataTreeSnapshot.newModification();
+ final YangInstanceIdentifier listId =
+ YangInstanceIdentifier.create(
+ new YangInstanceIdentifier.NodeIdentifier(TOP_CONTAINER_QNAME),
+ new YangInstanceIdentifier.NodeIdentifier(NESTED_LIST_QNAME));
+
+ final MapNode mapNode = getNestedList("name1", "text");
+ dataTreeModification.write(listId, mapNode);
+ dataTreeModification.ready();
+ dataTree.validate(dataTreeModification);
+ DataTreeCandidateTip prepare = dataTree.prepare(dataTreeModification);
+
+ ModifiableDataTreeDelegator.ModificationDiff modificationDiff =
+ ModifiableDataTreeDelegator.ModificationDiff
+ .recursivelyFromCandidate(YangInstanceIdentifier.EMPTY, prepare.getRootNode());
+
+ assertTrue(modificationDiff.getModificationsBefore().isEmpty());
+ assertAfter(mapNode, listId, modificationDiff);
+
+ // Commit so that update can be tested next
+ dataTree.commit(prepare);
+
+ YangInstanceIdentifier listItemId = listId.node(
+ new YangInstanceIdentifier.NodeIdentifierWithPredicates(NESTED_LIST_QNAME, NAME_LEAF_QNAME, "name1"));
+ MapEntryNode mapEntryNode =
+ getNestedList("name1", "text-update").getValue().iterator().next();
+
+ dataTreeSnapshot = dataTree.takeSnapshot();
+ dataTreeModification = dataTreeSnapshot.newModification();
+ dataTreeModification.write(listItemId, mapEntryNode);
+ dataTreeModification.ready();
+ dataTree.validate(dataTreeModification);
+ prepare = dataTree.prepare(dataTreeModification);
+
+ modificationDiff =
+ ModifiableDataTreeDelegator.ModificationDiff
+ .recursivelyFromCandidate(YangInstanceIdentifier.EMPTY, prepare.getRootNode());
+
+ assertBefore(mapNode.getValue().iterator().next(), listItemId, modificationDiff);
+ assertAfter(mapEntryNode, listItemId, modificationDiff);
+ }
+
+ @Test
+ public void testWriteTopContainerAndInnerList() throws Exception {
+ final TipProducingDataTree dataTree = getDataTree();
+
+ DataTreeSnapshot dataTreeSnapshot = dataTree.takeSnapshot();
+ DataTreeModification dataTreeModification = dataTreeSnapshot.newModification();
+
+ final ContainerNode topContainer = getTopContainer("string1");
+ dataTreeModification.write(topContainerId, topContainer);
+
+ final YangInstanceIdentifier listId =
+ YangInstanceIdentifier.create(
+ new YangInstanceIdentifier.NodeIdentifier(TOP_CONTAINER_QNAME),
+ new YangInstanceIdentifier.NodeIdentifier(NESTED_LIST_QNAME));
+
+ final MapNode mapNode = getNestedList("name1", "text");
+ dataTreeModification.write(listId, mapNode);
+
+ dataTreeModification.ready();
+ dataTree.validate(dataTreeModification);
+ final DataTreeCandidateTip prepare = dataTree.prepare(dataTreeModification);
+
+ final ModifiableDataTreeDelegator.ModificationDiff modificationDiff =
+ ModifiableDataTreeDelegator.ModificationDiff
+ .recursivelyFromCandidate(YangInstanceIdentifier.EMPTY, prepare.getRootNode());
+
+ assertTrue(modificationDiff.getModificationsBefore().isEmpty());
+
+ // TODO HONEYCOMB-94 2 after modifications should appear, for top-container and nested-list entry
+ assertAfter(Builders.containerBuilder(topContainer)
+ .withChild(mapNode)
+ .build(),
+ topContainerId, modificationDiff);
+ }
+
+ @Test
+ public void testWriteDeepList() throws Exception {
+ final TipProducingDataTree dataTree = getDataTree();
+ addTopContainer(dataTree);
+
+ DataTreeSnapshot dataTreeSnapshot = dataTree.takeSnapshot();
+ DataTreeModification dataTreeModification = dataTreeSnapshot.newModification();
+
+ YangInstanceIdentifier listId =
+ YangInstanceIdentifier.create(
+ new YangInstanceIdentifier.NodeIdentifier(TOP_CONTAINER_QNAME),
+ new YangInstanceIdentifier.NodeIdentifier(NESTED_LIST_QNAME));
+
+ MapNode mapNode = getNestedList("name1", "text");
+ dataTreeModification.write(listId, mapNode);
+
+ dataTreeModification.ready();
+ dataTree.validate(dataTreeModification);
+ DataTreeCandidateTip prepare = dataTree.prepare(dataTreeModification);
+ dataTree.commit(prepare);
+
+ dataTreeSnapshot = dataTree.takeSnapshot();
+ dataTreeModification = dataTreeSnapshot.newModification();
+
+ final YangInstanceIdentifier.NodeIdentifierWithPredicates nestedListNodeId =
+ new YangInstanceIdentifier.NodeIdentifierWithPredicates(NESTED_LIST_QNAME, NAME_LEAF_QNAME, "name1");
+ listId = YangInstanceIdentifier.create(
+ new YangInstanceIdentifier.NodeIdentifier(TOP_CONTAINER_QNAME),
+ new YangInstanceIdentifier.NodeIdentifier(NESTED_LIST_QNAME),
+ nestedListNodeId);
+ final YangInstanceIdentifier deepListId = listId.node(new YangInstanceIdentifier.NodeIdentifier(DEEP_LIST_QNAME));
+ final YangInstanceIdentifier deepListEntryId = deepListId.node(
+ new YangInstanceIdentifier.NodeIdentifierWithPredicates(DEEP_LIST_QNAME, NAME_LEAF_QNAME,"name1"));
+
+ final MapEntryNode deepListEntry = getDeepList("name1").getValue().iterator().next();
+ // Merge parent list, just to see no modifications on it
+ dataTreeModification.merge(
+ listId,
+ Builders.mapEntryBuilder().withNodeIdentifier(nestedListNodeId).withChild(ImmutableNodes.leafNode(NAME_LEAF_QNAME, "name1")).build());
+ dataTreeModification.merge(
+ deepListId,
+ Builders.mapBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(DEEP_LIST_QNAME)).build());
+ dataTreeModification.merge(
+ deepListEntryId,
+ deepListEntry);
+
+ dataTreeModification.ready();
+ dataTree.validate(dataTreeModification);
+ prepare = dataTree.prepare(dataTreeModification);
+ dataTree.commit(prepare);
+
+ final ModifiableDataTreeDelegator.ModificationDiff modificationDiff = ModifiableDataTreeDelegator.ModificationDiff
+ .recursivelyFromCandidate(YangInstanceIdentifier.EMPTY, prepare.getRootNode());
+
+ assertTrue(modificationDiff.getModificationsBefore().isEmpty());
+ assertAfter(getDeepList("name1"), deepListId, modificationDiff);
+ }
+
+ @Test
+ public void testDeleteInnerListItem() throws Exception {
+ final TipProducingDataTree dataTree = getDataTree();
+ addTopContainer(dataTree);
+
+ DataTreeSnapshot dataTreeSnapshot = dataTree.takeSnapshot();
+ DataTreeModification dataTreeModification = dataTreeSnapshot.newModification();
+ final YangInstanceIdentifier listId =
+ YangInstanceIdentifier.create(
+ new YangInstanceIdentifier.NodeIdentifier(TOP_CONTAINER_QNAME),
+ new YangInstanceIdentifier.NodeIdentifier(NESTED_LIST_QNAME));
+
+ final MapNode mapNode = getNestedList("name1", "text");
+ dataTreeModification.write(listId, mapNode);
+ dataTreeModification.ready();
+ dataTree.validate(dataTreeModification);
+ DataTreeCandidateTip prepare = dataTree.prepare(dataTreeModification);
+
+ // Commit so that update can be tested next
+ dataTree.commit(prepare);
+
+ YangInstanceIdentifier listItemId = listId.node(
+ new YangInstanceIdentifier.NodeIdentifierWithPredicates(NESTED_LIST_QNAME, NAME_LEAF_QNAME, "name1"));
+
+ dataTreeSnapshot = dataTree.takeSnapshot();
+ dataTreeModification = dataTreeSnapshot.newModification();
+ dataTreeModification.delete(listItemId);
+ dataTreeModification.ready();
+ dataTree.validate(dataTreeModification);
+ prepare = dataTree.prepare(dataTreeModification);
+
+ final ModifiableDataTreeDelegator.ModificationDiff modificationDiff =
+ ModifiableDataTreeDelegator.ModificationDiff
+ .recursivelyFromCandidate(YangInstanceIdentifier.EMPTY, prepare.getRootNode());
+
+ assertBefore(mapNode.getValue().iterator().next(), listItemId, modificationDiff);
+ assertTrue(modificationDiff.getModificationsAfter().isEmpty());
+ }
+
+ private NormalizedNode<?, ?> addTopContainer(final TipProducingDataTree dataTree) throws DataValidationFailedException {
+ DataTreeSnapshot dataTreeSnapshot = dataTree.takeSnapshot();
+ DataTreeModification dataTreeModification = dataTreeSnapshot.newModification();
+ final NormalizedNode<?, ?> topContainerBefore = getTopContainer("string1");
+ dataTreeModification.write(topContainerId, topContainerBefore);
+ dataTreeModification.ready();
+ dataTree.validate(dataTreeModification);
+ DataTreeCandidateTip prepare = dataTree.prepare(dataTreeModification);
+ dataTree.commit(prepare);
+ return topContainerBefore;
+ }
+
+ private void assertAfter(final NormalizedNode<?, ?> topContainer, final YangInstanceIdentifier topContainerId,
+ final ModifiableDataTreeDelegator.ModificationDiff modificationDiff) {
+ assertModification(topContainer, topContainerId, modificationDiff.getModificationsAfter());
+ }
+
+ private void assertModification(final NormalizedNode<?, ?> topContainer,
+ final YangInstanceIdentifier topContainerId,
+ final Map<YangInstanceIdentifier, NormalizedNode<?, ?>> modificationMap) {
+ assertEquals(1, modificationMap.keySet().size());
+ assertEquals(topContainerId, modificationMap.keySet().iterator().next());
+ assertEquals(topContainer, modificationMap.values().iterator().next());
+ }
+
+ private void assertBefore(final NormalizedNode<?, ?> topContainerBefore,
+ final YangInstanceIdentifier topContainerId,
+ final ModifiableDataTreeDelegator.ModificationDiff modificationDiff) {
+ assertModification(topContainerBefore, topContainerId, modificationDiff.getModificationsBefore());
+ }
+
+ private TipProducingDataTree getDataTree() throws ReactorException {
+ final TipProducingDataTree dataTree = InMemoryDataTreeFactory.getInstance().create(TreeType.CONFIGURATION);
+ dataTree.setSchemaContext(getSchemaCtx());
+ return dataTree;
+ }
+
+ private ContainerNode getTopContainer(final String stringValue) {
+ return Builders.containerBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TOP_CONTAINER_QNAME))
+ .withChild(ImmutableNodes.leafNode(STRING_LEAF_QNAME, stringValue))
+ .build();
+ }
+
+ private MapNode getNestedList(final String listItemName, final String text) {
+ return Builders.mapBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NESTED_LIST_QNAME))
+ .withChild(
+ Builders.mapEntryBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifierWithPredicates(NESTED_LIST_QNAME, NAME_LEAF_QNAME, listItemName))
+ .withChild(ImmutableNodes.leafNode(NAME_LEAF_QNAME, listItemName))
+ .withChild(ImmutableNodes.leafNode(TEXT_LEAF_QNAME, text))
+ .build()
+ )
+ .build();
+ }
+
+ private MapNode getDeepList(final String listItemName) {
+ return Builders.mapBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(DEEP_LIST_QNAME))
+ .withChild(
+ Builders.mapEntryBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifierWithPredicates(DEEP_LIST_QNAME, NAME_LEAF_QNAME, listItemName))
+ .withChild(ImmutableNodes.leafNode(NAME_LEAF_QNAME, listItemName))
+ .build()
+ )
+ .build();
+ }
+
+ private SchemaContext getSchemaCtx() throws ReactorException {
+ final CrossSourceStatementReactor.BuildAction buildAction = YangInferencePipeline.RFC6020_REACTOR.newBuild();
+ buildAction.addSource(new YangStatementSourceImpl(getClass().getResourceAsStream("/test-diff.yang")));
+ return buildAction.buildEffective();
+ }
+} \ No newline at end of file
diff --git a/v3po/data-impl/src/test/resources/test-diff.yang b/v3po/data-impl/src/test/resources/test-diff.yang
new file mode 100644
index 000000000..7e8721f00
--- /dev/null
+++ b/v3po/data-impl/src/test/resources/test-diff.yang
@@ -0,0 +1,37 @@
+module test-diff {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:test:diff";
+ prefix "td";
+
+ revision "2015-01-05" {
+ description "Initial revision";
+ }
+
+ container top-container {
+ leaf string {
+ type string;
+ }
+
+ list nested-list {
+ key "name";
+
+ leaf name {
+ type string;
+ }
+
+ leaf text {
+ type string;
+ }
+
+ list deep-list {
+ key "name";
+
+ leaf name {
+ type string;
+ }
+
+ }
+ }
+ }
+
+}