X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fnetconf-it%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fit%2FNetconfITTest.java;h=4c0730863fd0d0058281f468ec245c45c25e8fd6;hp=e99e51e92f67c14e28c06a7b52dc65b64894ac28;hb=510f3bd2d25c0e667a60ff5ef18cfbd40534cec0;hpb=87e068952fe9207ccccbcebdaac2de09743e2403 diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index e99e51e92f..4c0730863f 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -8,215 +8,106 @@ package org.opendaylight.controller.netconf.it; -import static java.util.Collections.emptyList; +import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyString; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import com.google.common.base.Function; +import com.google.common.base.Throwables; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import java.io.IOException; -import java.io.InputStream; -import java.lang.management.ManagementFactory; import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; - import javax.management.ObjectName; import javax.xml.parsers.ParserConfigurationException; - -import junit.framework.Assert; - -import org.apache.commons.io.IOUtils; -import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; -import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; -import org.opendaylight.controller.config.spi.ModuleFactory; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory; +import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleFactory; +import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleMXBean; import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory; import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean; -import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory; -import org.opendaylight.controller.netconf.StubUserManager; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; -import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl; -import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; -import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl; -import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException; -import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; -import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; -import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl; -import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; -import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; -import org.opendaylight.controller.netconf.ssh.NetconfSSHServer; -import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider; +import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.netconf.client.TestingNetconfClient; import org.opendaylight.controller.netconf.util.test.XmlFileLoader; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2; +import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry; +import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.xml.sax.SAXException; -import ch.ethz.ssh2.Connection; -import ch.ethz.ssh2.Session; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import io.netty.channel.ChannelFuture; - public class NetconfITTest extends AbstractNetconfConfigTest { - // TODO refactor, pull common code up to AbstractNetconfITTest - - private static final Logger logger = LoggerFactory.getLogger(NetconfITTest.class); - - private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023); - private static final InetSocketAddress sshAddress = new InetSocketAddress("127.0.0.1", 10830); - private static final String USERNAME = "netconf"; - private static final String PASSWORD = "netconf"; - - private NetconfMessage getConfig, getConfigCandidate, editConfig, - closeSession, startExi, stopExi; - private DefaultCommitNotificationProducer commitNot; - private NetconfServerDispatcher dispatch; + public static final int PORT = 12023; + public static final InetSocketAddress TCP_ADDRESS = new InetSocketAddress(LOOPBACK_ADDRESS, PORT); - private NetconfClientDispatcherImpl clientDispatcher; + private NetconfMessage getConfigCandidate, editConfig, closeSession; + private NetconfClientDispatcher clientDispatcher; @Before public void setUp() throws Exception { - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,getModuleFactories().toArray( - new ModuleFactory[0]))); - loadMessages(); - - NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl(); - factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore())); - - - commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer()); - - dispatch = createDispatcher(factoriesListener); - ChannelFuture s = dispatch.createServer(tcpAddress); - s.await(); - - clientDispatcher = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer()); - } - - private NetconfServerDispatcher createDispatcher(NetconfOperationServiceFactoryListenerImpl factoriesListener) { - return super.createDispatcher(factoriesListener, getNetconfMonitoringListenerService(), commitNot); - } - - static NetconfMonitoringServiceImpl getNetconfMonitoringListenerService() { - NetconfOperationProvider netconfOperationProvider = mock(NetconfOperationProvider.class); - NetconfOperationServiceSnapshotImpl snap = mock(NetconfOperationServiceSnapshotImpl.class); - doReturn(Collections.emptySet()).when(snap).getServices(); - doReturn(snap).when(netconfOperationProvider).openSnapshot(anyString()); - return new NetconfMonitoringServiceImpl(netconfOperationProvider); + clientDispatcher = getClientDispatcher(); } - @After - public void tearDown() throws Exception { - commitNot.close(); - clientDispatcher.close(); + @Override + protected InetSocketAddress getTcpServerAddress() { + return TCP_ADDRESS; } private void loadMessages() throws IOException, SAXException, ParserConfigurationException { this.editConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/edit_config.xml"); - this.getConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml"); this.getConfigCandidate = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig_candidate.xml"); - this.startExi = XmlFileLoader - .xmlFileToNetconfMessage("netconfMessages/startExi.xml"); - this.stopExi = XmlFileLoader - .xmlFileToNetconfMessage("netconfMessages/stopExi.xml"); this.closeSession = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/closeSession.xml"); } - private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException { - final Collection yangDependencies = getBasicYangs(); - return new HardcodedYangStoreService(yangDependencies); - } - - static Collection getBasicYangs() throws IOException { - - List paths = Arrays.asList("/META-INF/yang/config.yang", "/META-INF/yang/rpc-context.yang", - "/META-INF/yang/config-test.yang", "/META-INF/yang/config-test-impl.yang", "/META-INF/yang/test-types.yang", - "/META-INF/yang/ietf-inet-types.yang"); - final Collection yangDependencies = new ArrayList<>(); - List failedToFind = new ArrayList<>(); - for (String path : paths) { - InputStream resourceAsStream = NetconfITTest.class.getResourceAsStream(path); - if (resourceAsStream == null) { - failedToFind.add(path); - } else { - yangDependencies.add(resourceAsStream); - } - } - assertEquals("Some yang files were not found", emptyList(), failedToFind); - return yangDependencies; - } - - protected List getModuleFactories() { - return getModuleFactoriesS(); - } - - static List getModuleFactoriesS() { - return Lists.newArrayList(new TestImplModuleFactory(), new DepTestImplModuleFactory(), - new NetconfTestImplModuleFactory()); - } - @Test public void testNetconfClientDemonstration() throws Exception { - try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", clientDispatcher, getClientConfiguration(tcpAddress, 4000))) { + try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", clientDispatcher, getClientConfiguration(TCP_ADDRESS, 4000))) { - Set capabilitiesFromNetconfServer = netconfClient.getCapabilities(); - long sessionId = netconfClient.getSessionId(); + final Set capabilitiesFromNetconfServer = netconfClient.getCapabilities(); + final long sessionId = netconfClient.getSessionId(); // NetconfMessage can be created : // new NetconfMessage(XmlUtil.readXmlToDocument("")); - NetconfMessage response = netconfClient.sendMessage(getConfig); + final NetconfMessage response = netconfClient.sendMessage(getGetConfig()); response.getDocument(); } } @Test public void testTwoSessions() throws Exception { - try (TestingNetconfClient netconfClient = new TestingNetconfClient("1", clientDispatcher, getClientConfiguration(tcpAddress, 10000))) { - try (TestingNetconfClient netconfClient2 = new TestingNetconfClient("2", clientDispatcher, getClientConfiguration(tcpAddress, 10000))) { + try (TestingNetconfClient netconfClient = new TestingNetconfClient("1", clientDispatcher, getClientConfiguration(TCP_ADDRESS, 10000))) { + try (TestingNetconfClient netconfClient2 = new TestingNetconfClient("2", clientDispatcher, getClientConfiguration(TCP_ADDRESS, 10000))) { + assertNotNull(netconfClient2.getCapabilities()); } } } - @Ignore - @Test - public void waitingTest() throws Exception { - final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction(); - transaction.createModule(DepTestImplModuleFactory.NAME, "eb"); - transaction.commit(); - Thread.currentThread().suspend(); - } - @Test public void rpcReplyContainsAllAttributesTest() throws Exception { - try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { - final String rpc = "" - + "" + ""; + try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) { + final String rpc = "" + ""; final Document doc = XmlUtil.readXmlToDocument(rpc); final NetconfMessage message = netconfClient.sendMessage(new NetconfMessage(doc)); assertNotNull(message); @@ -242,9 +133,8 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void rpcReplyErrorContainsAllAttributesTest() throws Exception { - try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { - final String rpc = "" - + "" + ""; + try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) { + final String rpc = "" + ""; final Document doc = XmlUtil.readXmlToDocument(rpc); final NetconfMessage message = netconfClient.sendMessage(new NetconfMessage(doc)); final NamedNodeMap expectedAttributes = doc.getDocumentElement().getAttributes(); @@ -257,16 +147,16 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void rpcOutputContainsCorrectNamespace() throws Exception { final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction(); - ObjectName dep = transaction.createModule(DepTestImplModuleFactory.NAME, "instanceD"); - ObjectName impl = transaction.createModule(NetconfTestImplModuleFactory.NAME, "instance"); - NetconfTestImplModuleMXBean proxy = configRegistryClient + final ObjectName dep = transaction.createModule(DepTestImplModuleFactory.NAME, "instanceD"); + final ObjectName impl = transaction.createModule(NetconfTestImplModuleFactory.NAME, "instance"); + final NetconfTestImplModuleMXBean proxy = configRegistryClient .newMXBeanProxy(impl, NetconfTestImplModuleMXBean.class); proxy.setTestingDep(dep); proxy.setSimpleShort((short) 0); transaction.commit(); - try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) { final String expectedNamespace = "urn:opendaylight:params:xml:ns:yang:controller:test:impl"; final String rpc = "" @@ -289,7 +179,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void testCloseSession() throws Exception { - try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) { // edit config Document rpcReply = netconfClient.sendMessage(this.editConfig) @@ -305,7 +195,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void testEditConfig() throws Exception { - try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) { // send edit_config.xml final Document rpcReply = netconfClient.sendMessage(this.editConfig).getDocument(); assertIsOK(rpcReply); @@ -314,7 +204,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void testValidate() throws Exception { - try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) { // begin transaction Document rpcReply = netconfClient.sendMessage(getConfigCandidate).getDocument(); assertEquals("data", XmlElement.fromDomDocument(rpcReply).getOnlyChildElement().getName()); @@ -332,7 +222,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { } private Document assertGetConfigWorks(final TestingNetconfClient netconfClient) throws InterruptedException, ExecutionException, TimeoutException, NetconfDocumentedException { - return assertGetConfigWorks(netconfClient, this.getConfig); + return assertGetConfigWorks(netconfClient, getGetConfig()); } private Document assertGetConfigWorks(final TestingNetconfClient netconfClient, final NetconfMessage getConfigMessage) @@ -345,14 +235,14 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void testGetConfig() throws Exception { - try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) { assertGetConfigWorks(netconfClient); } } @Test public void createYangTestBasedOnYuma() throws Exception { - try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) { Document rpcReply = netconfClient.sendMessage( XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_merge_yang-test.xml")) .getDocument(); @@ -365,7 +255,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { final ObjectName on = new ObjectName( "org.opendaylight.controller:instanceName=impl-dep-instance,type=Module,moduleFactoryName=impl-dep"); - Set cfgBeans = configRegistryClient.lookupConfigBeans(); + final Set cfgBeans = configRegistryClient.lookupConfigBeans(); assertEquals(cfgBeans, Sets.newHashSet(on)); } } @@ -376,54 +266,96 @@ public class NetconfITTest extends AbstractNetconfConfigTest { return netconfClient; } - private void startSSHServer() throws Exception { - logger.info("Creating SSH server"); - StubUserManager um = new StubUserManager(USERNAME, PASSWORD); - String pem; - try (InputStream is = getClass().getResourceAsStream("/RSA.pk")) { - pem = IOUtils.toString(is); + @Test + public void testIdRef() throws Exception { + final NetconfMessage editId = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_identities.xml"); + final NetconfMessage commit = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml"); + + try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) { + assertIsOK(netconfClient.sendMessage(editId).getDocument()); + assertIsOK(netconfClient.sendMessage(commit).getDocument()); + + final NetconfMessage response = netconfClient.sendMessage(getGetConfig()); + + assertThat(XmlUtil.toString(response.getDocument()), containsString("prefix:test-identity1")); + assertThat(XmlUtil.toString(response.getDocument()), containsString("prefix:test-identity2")); + assertThat(XmlUtil.toString(response.getDocument()), containsString("prefix:test-identity2")); + assertThat(XmlUtil.toString(response.getDocument()), containsString("prefix:test-identity1")); + + } catch (final Exception e) { + fail(Throwables.getStackTraceAsString(e)); } - AuthProvider ap = new AuthProvider(um, pem); - Thread sshServerThread = new Thread(NetconfSSHServer.start(10830, tcpAddress, ap)); - sshServerThread.setDaemon(true); - sshServerThread.start(); - logger.info("SSH server on"); + } + + @Override + protected CodecRegistry getCodecRegistry() { + final IdentityCodec codec = mock(IdentityCodec.class); + doReturn(TestIdentity1.class).when(codec).deserialize(TestIdentity1.QNAME); + doReturn(TestIdentity2.class).when(codec).deserialize(TestIdentity2.QNAME); + + final CodecRegistry ret = super.getCodecRegistry(); + doReturn(codec).when(ret).getIdentityCodec(); + return ret; } @Test - public void sshTest() throws Exception { - startSSHServer(); - logger.info("creating connection"); - Connection conn = new Connection(sshAddress.getHostName(), sshAddress.getPort()); - Assert.assertNotNull(conn); - logger.info("connection created"); - conn.connect(); - boolean isAuthenticated = conn.authenticateWithPassword(USERNAME, PASSWORD); - assertTrue(isAuthenticated); - logger.info("user authenticated"); - final Session sess = conn.openSession(); - sess.startSubSystem("netconf"); - logger.info("user authenticated"); - sess.getStdin().write(XmlUtil.toString(this.getConfig.getDocument()).getBytes()); - - new Thread() { + public void testMultipleDependencies() throws Exception { + // push first xml, should add parent and d1,d2 dependencies + try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) { + final Document rpcReply = netconfClient.sendMessage( + XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_merge_multiple-deps1.xml")) + .getDocument(); + assertIsOK(rpcReply); + commit(netconfClient); + } + // verify that parent.getTestingDeps == d1,d2 + final MultipleDependenciesModuleMXBean parentProxy = configRegistryClient.newMXBeanProxy( + configRegistryClient.lookupConfigBean(MultipleDependenciesModuleFactory.NAME, "parent"), + MultipleDependenciesModuleMXBean.class); + { + final List testingDeps = parentProxy.getTestingDeps(); + assertEquals(2, testingDeps.size()); + final Set actualRefs = getServiceReferences(testingDeps); + assertEquals(Sets.newHashSet("ref_d1", "ref_d2"), actualRefs); + } + + // push second xml, should add d3 to parent's dependencies + mergeD3(parentProxy); + // push second xml again, to test that d3 is not added again + mergeD3(parentProxy); + } + + public void mergeD3(final MultipleDependenciesModuleMXBean parentProxy) throws Exception { + try (TestingNetconfClient netconfClient = new TestingNetconfClient( + "test " + TCP_ADDRESS.toString(), clientDispatcher, getClientConfiguration(TCP_ADDRESS, 5000))) { + + final Document rpcReply = netconfClient.sendMessage( + XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_merge_multiple-deps2.xml")) + .getDocument(); + assertIsOK(rpcReply); + commit(netconfClient); + } + { + final List testingDeps = parentProxy.getTestingDeps(); + assertEquals(3, testingDeps.size()); + final Set actualRefs = getServiceReferences(testingDeps); + assertEquals(Sets.newHashSet("ref_d1", "ref_d2", "ref_d3"), actualRefs); + } + } + + public Set getServiceReferences(final List testingDeps) { + return new HashSet<>(Lists.transform(testingDeps, new Function() { @Override - public void run() { - while (true) { - byte[] bytes = new byte[1024]; - int c = 0; - try { - c = sess.getStdout().read(bytes); - } catch (IOException e) { - throw new IllegalStateException("IO exception while reading data on ssh bridge."); - } - logger.info("got data:" + bytes); - if (c == 0) { - break; - } - } + public String apply(final ObjectName input) { + return ObjectNameUtil.getReferenceName(input); } - }.join(); + })); } + public void commit(final TestingNetconfClient netconfClient) throws Exception { + final Document rpcReply; + rpcReply = netconfClient.sendMessage(XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml")) + .getDocument(); + assertIsOK(rpcReply); + } }