Fix DataTreeCandidateNodes handling of deleted nodes 39/102539/1
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 3 Oct 2022 08:42:11 +0000 (10:42 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 3 Oct 2022 10:54:33 +0000 (12:54 +0200)
Recursive candidate should be used only for DistinctNodeContainer,
not all NormalizedNodeContainers. Fix the check so that we do not hit a
ClassCastException.

JIRA: YANGTOOLS-1455
Change-Id: I6a89f8e59a7f8d8b36c5c5d2990290f66f79f529
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit a3bdb0fbc05db361f7c105469ffd73b1e35390be)

data/yang-data-tree-spi/src/main/java/org/opendaylight/yangtools/yang/data/tree/spi/DataTreeCandidateNodes.java
data/yang-data-tree-spi/src/test/java/org/opendaylight/yangtools/yang/data/tree/spi/YT1455Test.java [new file with mode: 0644]

index 4071970bae2696ef0c230b96878de71734e3e620..7ab94e1857c282bba489d12c5529234cb6126c9a 100644 (file)
@@ -230,14 +230,13 @@ public final class DataTreeCandidateNodes {
 
     @SuppressWarnings("unchecked")
     private static @NonNull DataTreeCandidateNode deleteNode(final NormalizedNode data) {
-        if (data instanceof NormalizedNodeContainer) {
+        if (data instanceof DistinctNodeContainer) {
             return new RecursiveDeleteCandidateNode(
                 (DistinctNodeContainer<PathArgument, NormalizedNode>) data);
         }
         return new DeleteLeafCandidateNode(data);
     }
 
-
     @SuppressWarnings("unchecked")
     private static @NonNull DataTreeCandidateNode replaceNode(final NormalizedNode oldData,
             final NormalizedNode newData) {
diff --git a/data/yang-data-tree-spi/src/test/java/org/opendaylight/yangtools/yang/data/tree/spi/YT1455Test.java b/data/yang-data-tree-spi/src/test/java/org/opendaylight/yangtools/yang/data/tree/spi/YT1455Test.java
new file mode 100644 (file)
index 0000000..1328823
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.tree.spi;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doReturn;
+
+import java.util.List;
+import java.util.Optional;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.DistinctNodeContainer;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+import org.opendaylight.yangtools.yang.data.tree.api.ModificationType;
+
+@RunWith(MockitoJUnitRunner.StrictStubs.class)
+public class YT1455Test {
+    @Mock
+    public DistinctNodeContainer<PathArgument, NormalizedNode> oldData;
+    @Mock
+    public DistinctNodeContainer<PathArgument, NormalizedNode> newData;
+    @Mock
+    public UnkeyedListNode child;
+
+    @Test
+    public void testDeleteUnkeyedList() {
+        final var childId = new NodeIdentifier(QName.create("foo", "foo"));
+        doReturn(childId).when(child).getIdentifier();
+        doReturn(List.of(child)).when(oldData).body();
+        doReturn(List.of()).when(newData).body();
+        doReturn(null).when(newData).childByArg(childId);
+
+        final var delta = DataTreeCandidateNodes.containerDelta(oldData, newData);
+        assertEquals(1, delta.size());
+
+        final var first = delta.iterator().next();
+        assertEquals(childId, first.getIdentifier());
+        assertEquals(ModificationType.DELETE, first.getModificationType());
+        assertEquals(Optional.of(child), first.getDataBefore());
+        assertEquals(Optional.empty(), first.getDataAfter());
+        assertEquals(0, first.getChildNodes().size());
+    }
+}