Use NodeIdentifier to identify datastores
[netconf.git] / netconf / sal-netconf-connector / src / test / java / org / opendaylight / netconf / sal / connect / netconf / util / NetconfBaseOpsTest.java
index 84dd65b6b951b0eef2c85fe971ad6d6dba99b192..2254ee652616fc8a84b8db86518024bbd2f23ee2 100644 (file)
@@ -5,70 +5,90 @@
  * 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.netconf.sal.connect.netconf.util;
 
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import com.google.common.base.Optional;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ExecutionException;
 import org.custommonkey.xmlunit.Diff;
 import org.custommonkey.xmlunit.XMLUnit;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.opendaylight.mdsal.dom.api.DOMRpcService;
+import org.opendaylight.netconf.api.ModifyAction;
 import org.opendaylight.netconf.api.NetconfMessage;
+import org.opendaylight.netconf.api.xml.XmlUtil;
 import org.opendaylight.netconf.sal.connect.api.MessageTransformer;
 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceCommunicator;
+import org.opendaylight.netconf.sal.connect.netconf.AbstractTestModelTest;
 import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc;
 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
+import org.opendaylight.netconf.util.NetconfUtil;
+import org.opendaylight.yangtools.rfc8528.data.util.EmptyMountPointContext;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.common.XMLNamespace;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.xml.sax.SAXException;
 
-public class NetconfBaseOpsTest {
+@RunWith(MockitoJUnitRunner.StrictStubs.class)
+public class NetconfBaseOpsTest extends AbstractTestModelTest {
+    private static final QNameModule TEST_MODULE = QNameModule.create(
+            XMLNamespace.of("test:namespace"), Revision.of("2013-07-22"));
+
+    private static final QName CONTAINER_C_QNAME = QName.create(TEST_MODULE, "c");
+    private static final NodeIdentifier CONTAINER_C_NID = NodeIdentifier.create(CONTAINER_C_QNAME);
+    private static final QName LEAF_A_QNAME = QName.create(TEST_MODULE, "a");
+    private static final NodeIdentifier LEAF_A_NID = NodeIdentifier.create(LEAF_A_QNAME);
+    private static final QName LEAF_B_QNAME = QName.create(TEST_MODULE, "b");
+    private static final NodeIdentifier LEAF_B_NID = NodeIdentifier.create(LEAF_B_QNAME);
+    private static final QName CONTAINER_D_QNAME = QName.create(TEST_MODULE, "d");
+    private static final NodeIdentifier CONTAINER_D_NID = NodeIdentifier.create(CONTAINER_D_QNAME);
+    private static final QName LEAF_X_QNAME = QName.create(TEST_MODULE, "x");
+    private static final NodeIdentifier LEAF_X_NID = NodeIdentifier.create(LEAF_X_QNAME);
+
+    private static final QName CONTAINER_E_QNAME = QName.create(TEST_MODULE, "e");
+    private static final NodeIdentifier CONTAINER_E_NID = NodeIdentifier.create(CONTAINER_E_QNAME);
+    private static final QName LEAF_Z_QNAME = QName.create(TEST_MODULE, "z");
+    private static final NodeIdentifier LEAF_Z_NID = NodeIdentifier.create(LEAF_Z_QNAME);
 
     static {
         XMLUnit.setIgnoreWhitespace(true);
         XMLUnit.setIgnoreComments(true);
     }
 
-    private static final QName CONTAINER_Q_NAME = QName.create("test:namespace", "2013-07-22", "c");
-
     @Mock
-    private RemoteDeviceCommunicator<NetconfMessage> listener;
+    private RemoteDeviceCommunicator listener;
     private NetconfRpcFutureCallback callback;
     private NetconfBaseOps baseOps;
 
     @Before
     public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
         final InputStream okStream = getClass().getResourceAsStream("/netconfMessages/rpc-reply_ok.xml");
         final InputStream dataStream = getClass().getResourceAsStream("/netconfMessages/rpc-reply_get.xml");
         final NetconfMessage ok = new NetconfMessage(XmlUtil.readXmlToDocument(okStream));
@@ -91,19 +111,17 @@ public class NetconfBaseOpsTest {
                 .thenReturn(RpcResultBuilder.success(ok).buildFuture());
         when(listener.sendRequest(any(), eq(NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME)))
                 .thenReturn(RpcResultBuilder.success(ok).buildFuture());
-        final SchemaContext schemaContext =
-                YangParserTestUtils.parseYangStreams(getClass().getResourceAsStream("/schemas/test-module.yang"));
-        final MessageTransformer<NetconfMessage> transformer = new NetconfMessageTransformer(schemaContext, true);
-        final DOMRpcService rpc = new NetconfDeviceRpc(schemaContext, listener, transformer);
-        final RemoteDeviceId id =
-                new RemoteDeviceId("device-1", InetSocketAddress.createUnresolved("localhost", 17830));
-        callback = new NetconfRpcFutureCallback("prefix", id);
-        baseOps = new NetconfBaseOps(rpc, schemaContext);
+        final MessageTransformer transformer = new NetconfMessageTransformer(new EmptyMountPointContext(SCHEMA_CONTEXT),
+            true, BASE_SCHEMAS.getBaseSchema());
+        final DOMRpcService rpc = new NetconfDeviceRpc(SCHEMA_CONTEXT, listener, transformer);
+        callback = new NetconfRpcFutureCallback("prefix",
+            new RemoteDeviceId("device-1", InetSocketAddress.createUnresolved("localhost", 17830)));
+        baseOps = new NetconfBaseOps(rpc, new EmptyMountPointContext(SCHEMA_CONTEXT));
     }
 
     @Test
     public void testLock() throws Exception {
-        baseOps.lock(callback, NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME);
+        baseOps.lock(callback, NetconfMessageTransformUtil.NETCONF_CANDIDATE_NODEID);
         verifyMessageSent("lock", NetconfMessageTransformUtil.NETCONF_LOCK_QNAME);
     }
 
@@ -115,7 +133,7 @@ public class NetconfBaseOpsTest {
 
     @Test
     public void testUnlock() throws Exception {
-        baseOps.unlock(callback, NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME);
+        baseOps.unlock(callback, NetconfMessageTransformUtil.NETCONF_CANDIDATE_NODEID);
         verifyMessageSent("unlock", NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME);
     }
 
@@ -164,8 +182,8 @@ public class NetconfBaseOpsTest {
 
     @Test
     public void testCopyConfig() throws Exception {
-        baseOps.copyConfig(callback, NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME,
-                NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME);
+        baseOps.copyConfig(callback, NetconfMessageTransformUtil.NETCONF_RUNNING_NODEID,
+                NetconfMessageTransformUtil.NETCONF_CANDIDATE_NODEID);
         verifyMessageSent("copy-config", NetconfMessageTransformUtil.NETCONF_COPY_CONFIG_QNAME);
     }
 
@@ -175,85 +193,151 @@ public class NetconfBaseOpsTest {
         verifyMessageSent("copy-config", NetconfMessageTransformUtil.NETCONF_COPY_CONFIG_QNAME);
     }
 
-
     @Test
     public void testGetConfigRunningData() throws Exception {
-        final Optional<NormalizedNode<?, ?>> dataOpt =
-                baseOps.getConfigRunningData(callback, Optional.of(YangInstanceIdentifier.EMPTY)).get();
-        Assert.assertTrue(dataOpt.isPresent());
-        Assert.assertEquals(NetconfMessageTransformUtil.NETCONF_DATA_QNAME, dataOpt.get().getNodeType());
+        final var dataOpt = baseOps.getConfigRunningData(callback, Optional.of(YangInstanceIdentifier.empty())).get();
+        assertTrue(dataOpt.isPresent());
+        assertEquals(NetconfUtil.NETCONF_DATA_QNAME, dataOpt.orElseThrow().getIdentifier().getNodeType());
     }
 
     @Test
     public void testGetData() throws Exception {
-        final Optional<NormalizedNode<?, ?>> dataOpt =
-                baseOps.getData(callback, Optional.of(YangInstanceIdentifier.EMPTY)).get();
-        Assert.assertTrue(dataOpt.isPresent());
-        Assert.assertEquals(NetconfMessageTransformUtil.NETCONF_DATA_QNAME, dataOpt.get().getNodeType());
+        final var dataOpt = baseOps.getData(callback, Optional.of(YangInstanceIdentifier.empty())).get();
+        assertTrue(dataOpt.isPresent());
+        assertEquals(NetconfUtil.NETCONF_DATA_QNAME, dataOpt.orElseThrow().getIdentifier().getNodeType());
     }
 
     @Test
     public void testGetConfigRunning() throws Exception {
-        baseOps.getConfigRunning(callback, Optional.absent());
+        baseOps.getConfigRunning(callback, Optional.empty());
         verifyMessageSent("getConfig", NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME);
     }
 
     @Test
     public void testGetConfigCandidate() throws Exception {
-        baseOps.getConfigCandidate(callback, Optional.absent());
+        baseOps.getConfigCandidate(callback, Optional.empty());
         verifyMessageSent("getConfig_candidate", NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME);
     }
 
     @Test
     public void testGetConfigCandidateWithFilter() throws Exception {
-        final YangInstanceIdentifier id = YangInstanceIdentifier.builder()
-                .node(CONTAINER_Q_NAME)
-                .build();
-        baseOps.getConfigCandidate(callback, Optional.of(id));
+        baseOps.getConfigCandidate(callback, Optional.of(YangInstanceIdentifier.of(CONTAINER_C_QNAME)));
         verifyMessageSent("getConfig_candidate-filter", NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME);
     }
 
     @Test
     public void testGet() throws Exception {
-        baseOps.get(callback, Optional.absent());
+        baseOps.get(callback, Optional.empty());
         verifyMessageSent("get", NetconfMessageTransformUtil.NETCONF_GET_QNAME);
     }
 
     @Test
     public void testEditConfigCandidate() throws Exception {
-        final QName leafQName = QName.create(CONTAINER_Q_NAME, "a");
-        final LeafNode<Object> leaf = Builders.leafBuilder()
-                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(leafQName))
-                .withValue("leaf-value")
-                .build();
-        final YangInstanceIdentifier leafId = YangInstanceIdentifier.builder()
-                .node(CONTAINER_Q_NAME)
-                .node(leafQName)
-                .build();
-        final DataContainerChild<?, ?> structure = baseOps.createEditConfigStrcture(Optional.of(leaf),
-                Optional.of(ModifyAction.REPLACE), leafId);
-        baseOps.editConfigCandidate(callback, structure, true);
+        baseOps.editConfigCandidate(callback, baseOps.createEditConfigStructure(
+            Optional.of(ImmutableNodes.leafNode(LEAF_A_NID, "leaf-value")),
+            Optional.of(ModifyAction.REPLACE), YangInstanceIdentifier.builder()
+            .node(CONTAINER_C_QNAME)
+            .node(LEAF_A_NID)
+            .build()), true);
         verifyMessageSent("edit-config-test-module", NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME);
     }
 
+    @Test
+    public void testDeleteContainerNodeCandidate() throws Exception {
+        baseOps.editConfigCandidate(callback, baseOps.createEditConfigStructure(Optional.empty(),
+            Optional.of(ModifyAction.DELETE), YangInstanceIdentifier.of(CONTAINER_C_QNAME)), true);
+        verifyMessageSent("edit-config-delete-container-node-candidate",
+                NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME);
+    }
+
+    @Test
+    public void testDeleteLeafNodeCandidate() throws Exception {
+        baseOps.editConfigCandidate(callback, baseOps.createEditConfigStructure(Optional.empty(),
+            Optional.of(ModifyAction.DELETE),
+            YangInstanceIdentifier.builder().node(CONTAINER_C_QNAME).node(LEAF_A_NID).build()), true);
+        verifyMessageSent("edit-config-delete-leaf-node-candidate",
+                NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME);
+    }
+
     @Test
     public void testEditConfigRunning() throws Exception {
-        final QName containerQName = QName.create("test:namespace", "2013-07-22", "c");
-        final QName leafQName = QName.create(containerQName, "a");
-        final LeafNode<Object> leaf = Builders.leafBuilder()
-                .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(leafQName))
-                .withValue("leaf-value")
-                .build();
-        final YangInstanceIdentifier leafId = YangInstanceIdentifier.builder()
-                .node(containerQName)
-                .node(leafQName)
-                .build();
-        final DataContainerChild<?, ?> structure = baseOps.createEditConfigStrcture(Optional.of(leaf),
-                Optional.of(ModifyAction.REPLACE), leafId);
-        baseOps.editConfigRunning(callback, structure, ModifyAction.MERGE, true);
+        baseOps.editConfigRunning(callback, baseOps.createEditConfigStructure(
+            Optional.of(ImmutableNodes.leafNode(LEAF_A_NID, "leaf-value")),
+            Optional.of(ModifyAction.REPLACE),
+            YangInstanceIdentifier.builder().node(CONTAINER_C_NID).node(LEAF_A_NID).build()), ModifyAction.MERGE, true);
         verifyMessageSent("edit-config-test-module-running", NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME);
     }
 
+    @Test
+    public void testGetWithFields() throws ExecutionException, InterruptedException {
+        final YangInstanceIdentifier path = YangInstanceIdentifier.create(CONTAINER_C_NID);
+        final YangInstanceIdentifier leafAField = YangInstanceIdentifier.create(LEAF_A_NID);
+        final YangInstanceIdentifier leafBField = YangInstanceIdentifier.create(LEAF_B_NID);
+
+        baseOps.getData(callback, Optional.of(path), List.of(leafAField, leafBField)).get();
+        verify(listener).sendRequest(msg("/netconfMessages/get-fields-request.xml"),
+                eq(NetconfMessageTransformUtil.NETCONF_GET_QNAME));
+    }
+
+    @Test
+    public void testGetConfigWithFields() throws ExecutionException, InterruptedException {
+        final YangInstanceIdentifier path = YangInstanceIdentifier.create(CONTAINER_C_NID);
+        final YangInstanceIdentifier leafAField = YangInstanceIdentifier.create(LEAF_A_NID);
+        final YangInstanceIdentifier leafBField = YangInstanceIdentifier.create(LEAF_B_NID);
+
+        baseOps.getConfigRunningData(callback, Optional.of(path), List.of(leafAField, leafBField)).get();
+        verify(listener).sendRequest(msg("/netconfMessages/get-config-fields-request.xml"),
+                eq(NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME));
+    }
+
+    @Test
+    public void testGetDataWithoutFields() {
+        assertThrows(ExecutionException.class, () -> baseOps.getData(callback,
+                Optional.of(YangInstanceIdentifier.empty()), List.of()).get());
+    }
+
+    @Test
+    public void getConfigRunningDataWithoutFields() {
+        assertThrows(ExecutionException.class, () -> baseOps.getConfigRunningData(callback,
+                Optional.of(YangInstanceIdentifier.empty()), List.of()).get());
+    }
+
+    @Test
+    public void testGetWithFieldsAndEmptyParentPath() throws ExecutionException, InterruptedException {
+        final YangInstanceIdentifier leafAField = YangInstanceIdentifier.create(CONTAINER_C_NID, LEAF_A_NID);
+        final YangInstanceIdentifier leafXField = YangInstanceIdentifier.create(
+                CONTAINER_C_NID, CONTAINER_D_NID, LEAF_X_NID);
+        final YangInstanceIdentifier leafZField = YangInstanceIdentifier.create(CONTAINER_E_NID, LEAF_Z_NID);
+
+        baseOps.getData(callback, Optional.of(YangInstanceIdentifier.empty()),
+                List.of(leafAField, leafXField, leafZField)).get();
+        verify(listener).sendRequest(msg("/netconfMessages/get-with-multiple-subtrees.xml"),
+                eq(NetconfMessageTransformUtil.NETCONF_GET_QNAME));
+    }
+
+    @Test
+    public void testGetConfigWithFieldsAndEmptyParentPath() throws ExecutionException, InterruptedException {
+        final YangInstanceIdentifier leafAField = YangInstanceIdentifier.create(CONTAINER_C_NID, LEAF_A_NID);
+        final YangInstanceIdentifier leafXField = YangInstanceIdentifier.create(
+                CONTAINER_C_NID, CONTAINER_D_NID, LEAF_X_NID);
+        final YangInstanceIdentifier leafZField = YangInstanceIdentifier.create(CONTAINER_E_NID, LEAF_Z_NID);
+
+        baseOps.getConfigRunningData(callback, Optional.of(YangInstanceIdentifier.empty()),
+                List.of(leafAField, leafXField, leafZField)).get();
+        verify(listener).sendRequest(msg("/netconfMessages/get-config-with-multiple-subtrees.xml"),
+                eq(NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME));
+    }
+
+    @Test
+    public void testGetWithRootFieldsAndEmptyParentPath() throws ExecutionException, InterruptedException {
+        final YangInstanceIdentifier contCField = YangInstanceIdentifier.create(CONTAINER_C_NID);
+        final YangInstanceIdentifier contDField = YangInstanceIdentifier.create(CONTAINER_E_NID);
+
+        baseOps.getData(callback, Optional.of(YangInstanceIdentifier.empty()), List.of(contCField, contDField)).get();
+        verify(listener).sendRequest(msg("/netconfMessages/get-with-multiple-root-subtrees.xml"),
+                eq(NetconfMessageTransformUtil.NETCONF_GET_QNAME));
+    }
+
     private void verifyMessageSent(final String fileName, final QName name) {
         final String path = "/netconfMessages/" + fileName + ".xml";
         verify(listener).sendRequest(msg(path), eq(name));
@@ -268,20 +352,16 @@ public class NetconfBaseOpsTest {
         }
     }
 
-    private static class NetconfMessageMatcher extends BaseMatcher<NetconfMessage> {
+    private static class NetconfMessageMatcher implements ArgumentMatcher<NetconfMessage> {
 
         private final Document expected;
 
-        private NetconfMessageMatcher(final Document expected) {
+        NetconfMessageMatcher(final Document expected) {
             this.expected = removeAttrs(expected);
         }
 
         @Override
-        public boolean matches(final Object item) {
-            if (!(item instanceof NetconfMessage)) {
-                return false;
-            }
-            final NetconfMessage message = (NetconfMessage) item;
+        public boolean matches(final NetconfMessage message) {
             final Document actualDoc = removeAttrs(message.getDocument());
             actualDoc.normalizeDocument();
             expected.normalizeDocument();
@@ -289,11 +369,6 @@ public class NetconfBaseOpsTest {
             return diff.similar();
         }
 
-        @Override
-        public void describeTo(final Description description) {
-            description.appendText(XmlUtil.toString(expected));
-        }
-
         private static Document removeAttrs(final Document input) {
             final Document copy = XmlUtil.newDocument();
             copy.appendChild(copy.importNode(input.getDocumentElement(), true));
@@ -312,4 +387,4 @@ public class NetconfBaseOpsTest {
         }
     }
 
-}
\ No newline at end of file
+}