X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=netconf%2Fsal-netconf-connector%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Fsal%2Fconnect%2Fnetconf%2Futil%2FNetconfBaseOpsTest.java;h=567fa744d767dffe5e4eda1f9594ca7412f3f119;hb=14323f32667c16d5206e73bfe34eea48d4e2272f;hp=84dd65b6b951b0eef2c85fe971ad6d6dba99b192;hpb=9c56fbbb1c62243df9baa3b95140153f91ffdde9;p=netconf.git diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfBaseOpsTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfBaseOpsTest.java index 84dd65b6b9..567fa744d7 100644 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfBaseOpsTest.java +++ b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfBaseOpsTest.java @@ -5,62 +5,87 @@ * 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.Collections; 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.YangInstanceIdentifier.NodeIdentifier; 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.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 listener; private NetconfRpcFutureCallback callback; @@ -68,7 +93,6 @@ public class NetconfBaseOpsTest { @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,14 +115,13 @@ 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 transformer = new NetconfMessageTransformer(schemaContext, true); - final DOMRpcService rpc = new NetconfDeviceRpc(schemaContext, listener, transformer); + final MessageTransformer transformer = new NetconfMessageTransformer( + new EmptyMountPointContext(SCHEMA_CONTEXT), true, BASE_SCHEMAS.getBaseSchema()); + final DOMRpcService rpc = new NetconfDeviceRpc(SCHEMA_CONTEXT, listener, transformer); final RemoteDeviceId id = new RemoteDeviceId("device-1", InetSocketAddress.createUnresolved("localhost", 17830)); callback = new NetconfRpcFutureCallback("prefix", id); - baseOps = new NetconfBaseOps(rpc, schemaContext); + baseOps = new NetconfBaseOps(rpc, new EmptyMountPointContext(SCHEMA_CONTEXT)); } @Test @@ -175,39 +198,38 @@ public class NetconfBaseOpsTest { verifyMessageSent("copy-config", NetconfMessageTransformUtil.NETCONF_COPY_CONFIG_QNAME); } - @Test public void testGetConfigRunningData() throws Exception { - final Optional> dataOpt = - baseOps.getConfigRunningData(callback, Optional.of(YangInstanceIdentifier.EMPTY)).get(); - Assert.assertTrue(dataOpt.isPresent()); - Assert.assertEquals(NetconfMessageTransformUtil.NETCONF_DATA_QNAME, dataOpt.get().getNodeType()); + final Optional dataOpt = + baseOps.getConfigRunningData(callback, Optional.of(YangInstanceIdentifier.empty())).get(); + assertTrue(dataOpt.isPresent()); + assertEquals(NetconfUtil.NETCONF_DATA_QNAME, dataOpt.get().getIdentifier().getNodeType()); } @Test public void testGetData() throws Exception { - final Optional> dataOpt = - baseOps.getData(callback, Optional.of(YangInstanceIdentifier.EMPTY)).get(); - Assert.assertTrue(dataOpt.isPresent()); - Assert.assertEquals(NetconfMessageTransformUtil.NETCONF_DATA_QNAME, dataOpt.get().getNodeType()); + final Optional dataOpt = + baseOps.getData(callback, Optional.of(YangInstanceIdentifier.empty())).get(); + assertTrue(dataOpt.isPresent()); + assertEquals(NetconfUtil.NETCONF_DATA_QNAME, dataOpt.get().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) + .node(CONTAINER_C_QNAME) .build(); baseOps.getConfigCandidate(callback, Optional.of(id)); verifyMessageSent("getConfig_candidate-filter", NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME); @@ -215,45 +237,137 @@ public class NetconfBaseOpsTest { @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 leaf = Builders.leafBuilder() - .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(leafQName)) + .withNodeIdentifier(LEAF_A_NID) .withValue("leaf-value") .build(); final YangInstanceIdentifier leafId = YangInstanceIdentifier.builder() - .node(CONTAINER_Q_NAME) - .node(leafQName) + .node(CONTAINER_C_QNAME) + .node(LEAF_A_NID) .build(); - final DataContainerChild structure = baseOps.createEditConfigStrcture(Optional.of(leaf), + final DataContainerChild structure = baseOps.createEditConfigStructure(Optional.of(leaf), Optional.of(ModifyAction.REPLACE), leafId); baseOps.editConfigCandidate(callback, structure, true); verifyMessageSent("edit-config-test-module", NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME); } + @Test + public void testDeleteContainerNodeCandidate() throws Exception { + final YangInstanceIdentifier containerId = YangInstanceIdentifier.builder() + .node(CONTAINER_C_QNAME) + .build(); + final DataContainerChild structure = baseOps.createEditConfigStructure(Optional.empty(), + Optional.of(ModifyAction.DELETE), containerId); + baseOps.editConfigCandidate(callback, structure, true); + verifyMessageSent("edit-config-delete-container-node-candidate", + NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME); + } + + @Test + public void testDeleteLeafNodeCandidate() throws Exception { + final YangInstanceIdentifier leafId = YangInstanceIdentifier.builder() + .node(CONTAINER_C_QNAME) + .node(LEAF_A_NID) + .build(); + final DataContainerChild structure = baseOps.createEditConfigStructure(Optional.empty(), + Optional.of(ModifyAction.DELETE), leafId); + baseOps.editConfigCandidate(callback, structure, 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 leaf = Builders.leafBuilder() - .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(leafQName)) + .withNodeIdentifier(LEAF_A_NID) .withValue("leaf-value") .build(); final YangInstanceIdentifier leafId = YangInstanceIdentifier.builder() - .node(containerQName) - .node(leafQName) + .node(CONTAINER_C_NID) + .node(LEAF_A_NID) .build(); - final DataContainerChild structure = baseOps.createEditConfigStrcture(Optional.of(leaf), + final DataContainerChild structure = baseOps.createEditConfigStructure(Optional.of(leaf), Optional.of(ModifyAction.REPLACE), leafId); baseOps.editConfigRunning(callback, structure, 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()), Collections.emptyList()).get()); + } + + @Test + public void getConfigRunningDataWithoutFields() { + assertThrows(ExecutionException.class, () -> baseOps.getConfigRunningData(callback, + Optional.of(YangInstanceIdentifier.empty()), Collections.emptyList()).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 +382,16 @@ public class NetconfBaseOpsTest { } } - private static class NetconfMessageMatcher extends BaseMatcher { + private static class NetconfMessageMatcher implements ArgumentMatcher { 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 +399,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 +417,4 @@ public class NetconfBaseOpsTest { } } -} \ No newline at end of file +}