X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-netconf-connector%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fconnect%2Fnetconf%2FNetconfDeviceTest.java;h=ec945e050bc54e89d8a9c5ec3d4fd835913dfbd1;hp=defaab629f3684de2be6a5b1d7a578749cd493e0;hb=b5c49b7c32cae050b9a91ff07c0a001d7dfb0042;hpb=79202e1fd05d2606b35e163f608fad9cce84b5d4 diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java index defaab629f..ec945e050b 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTest.java @@ -8,13 +8,20 @@ package org.opendaylight.controller.sal.connect.netconf; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyCollectionOf; import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import com.google.common.base.Optional; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.Futures; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; @@ -23,17 +30,18 @@ import java.util.List; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; - import org.junit.Test; import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants; import org.opendaylight.controller.sal.connect.api.MessageTransformer; -import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator; import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler; -import org.opendaylight.controller.sal.connect.api.SchemaContextProviderFactory; import org.opendaylight.controller.sal.connect.api.SchemaSourceProviderFactory; -import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionCapabilities; +import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator; +import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences; +import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceRpc; import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.controller.sal.connect.util.RemoteDeviceId; import org.opendaylight.controller.sal.core.api.RpcImplementation; @@ -42,15 +50,18 @@ import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.ModuleImport; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider; +import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException; +import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory; +import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException; +import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; +import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource; +import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration; +import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry; import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider; import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; -import com.google.common.base.Optional; -import com.google.common.collect.Lists; -import com.google.common.util.concurrent.Futures; - public class NetconfDeviceTest { private static final NetconfMessage netconfMessage; @@ -71,83 +82,150 @@ public class NetconfDeviceTest { public static final String TEST_NAMESPACE = "test:namespace"; public static final String TEST_MODULE = "test-module"; public static final String TEST_REVISION = "2013-07-22"; + public static final SourceIdentifier TEST_SID = new SourceIdentifier(TEST_MODULE, Optional.of(TEST_REVISION)); + public static final String TEST_CAPABILITY = TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION; - @Test - public void testNetconfDeviceWithoutMonitoring() throws Exception { - final RemoteDeviceHandler facade = getFacade(); - final RemoteDeviceCommunicator listener = getListener(); + public static final SourceIdentifier TEST_SID2 = new SourceIdentifier(TEST_MODULE + "2", Optional.of(TEST_REVISION)); + public static final String TEST_CAPABILITY2 = TEST_NAMESPACE + "?module=" + TEST_MODULE + "2" + "&revision=" + TEST_REVISION; + + private static final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver = new NetconfStateSchemas.NetconfStateSchemasResolver() { + + @Override + public NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id) { + return NetconfStateSchemas.EMPTY; + } + }; - final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), getMessageTransformer(), getSchemaContextProviderFactory(), getSourceProviderFactory()); - device.onRemoteSessionUp(getSessionCaps(false, Collections.emptyList()), listener); + @Test + public void testNetconfDeviceFailFirstSchemaFailSecondEmpty() throws Exception { + final ArrayList capList = Lists.newArrayList(TEST_CAPABILITY); + + final RemoteDeviceHandler facade = getFacade(); + final NetconfDeviceCommunicator listener = getListener(); + + final SchemaContextFactory schemaFactory = getSchemaFactory(); + + // Make fallback attempt to fail due to empty resolved sources + final SchemaResolutionException schemaResolutionException + = new SchemaResolutionException("fail first", + Collections.emptyList(), HashMultimap.create()); + doReturn(Futures.immediateFailedCheckedFuture( + schemaResolutionException)) + .when(schemaFactory).createSchemaContext(anyCollectionOf(SourceIdentifier.class)); + + final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO + = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), schemaFactory, stateSchemasResolver); + final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, getId(), facade, getExecutor(), getMessageTransformer(), true); + // Monitoring not supported + final NetconfSessionPreferences sessionCaps = getSessionCaps(false, capList); + device.onRemoteSessionUp(sessionCaps, listener); Mockito.verify(facade, Mockito.timeout(5000)).onDeviceDisconnected(); + Mockito.verify(listener, Mockito.timeout(5000)).close(); + Mockito.verify(schemaFactory, times(1)).createSchemaContext(anyCollectionOf(SourceIdentifier.class)); + } + + @Test + public void testNetconfDeviceMissingSource() throws Exception { + final RemoteDeviceHandler facade = getFacade(); + final NetconfDeviceCommunicator listener = getListener(); + + final SchemaContextFactory schemaFactory = getSchemaFactory(); + + // Make fallback attempt to fail due to empty resolved sources + final MissingSchemaSourceException schemaResolutionException = new MissingSchemaSourceException("fail first", TEST_SID); + doAnswer(new Answer() { + @Override + public Object answer(final InvocationOnMock invocation) throws Throwable { + if(((Collection) invocation.getArguments()[0]).size() == 2) { + return Futures.immediateFailedCheckedFuture(schemaResolutionException); + } else { + return Futures.immediateCheckedFuture(getSchema()); + } + } + }).when(schemaFactory).createSchemaContext(anyCollectionOf(SourceIdentifier.class)); + + final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO + = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), schemaFactory, stateSchemasResolver); + final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, getId(), facade, getExecutor(), getMessageTransformer(), true); + // Monitoring supported + final NetconfSessionPreferences sessionCaps = getSessionCaps(true, Lists.newArrayList(TEST_CAPABILITY, TEST_CAPABILITY2)); + device.onRemoteSessionUp(sessionCaps, listener); + + Mockito.verify(facade, Mockito.timeout(5000)).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(RpcImplementation.class)); + Mockito.verify(schemaFactory, times(2)).createSchemaContext(anyCollectionOf(SourceIdentifier.class)); + } + + private SchemaSourceRegistry getSchemaRegistry() { + final SchemaSourceRegistry mock = mock(SchemaSourceRegistry.class); + final SchemaSourceRegistration mockReg = mock(SchemaSourceRegistration.class); + doNothing().when(mockReg).close(); + doReturn(mockReg).when(mock).registerSchemaSource(any(org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider.class), any(PotentialSchemaSource.class)); + return mock; } @Test public void testNotificationBeforeSchema() throws Exception { - final RemoteDeviceHandler facade = getFacade(); - final RemoteDeviceCommunicator listener = getListener(); + final RemoteDeviceHandler facade = getFacade(); + final NetconfDeviceCommunicator listener = getListener(); final MessageTransformer messageTransformer = getMessageTransformer(); - final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), messageTransformer, getSchemaContextProviderFactory(), getSourceProviderFactory()); + + final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO + = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), getSchemaFactory(), stateSchemasResolver); + final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, getId(), facade, getExecutor(), messageTransformer, true); device.onNotification(netconfMessage); device.onNotification(netconfMessage); verify(facade, times(0)).onNotification(any(CompositeNode.class)); - final NetconfSessionCapabilities sessionCaps = getSessionCaps(true, - Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION)); + final NetconfSessionPreferences sessionCaps = getSessionCaps(true, + Lists.newArrayList(TEST_CAPABILITY)); device.onRemoteSessionUp(sessionCaps, listener); verify(messageTransformer, timeout(10000).times(2)).toNotification(netconfMessage); - verify(facade, times(2)).onNotification(compositeNode); + verify(facade, timeout(10000).times(2)).onNotification(compositeNode); device.onNotification(netconfMessage); - verify(messageTransformer, times(3)).toNotification(netconfMessage); - verify(facade, times(3)).onNotification(compositeNode); + verify(messageTransformer, timeout(10000).times(3)).toNotification(netconfMessage); + verify(facade, timeout(10000).times(3)).onNotification(compositeNode); } @Test public void testNetconfDeviceReconnect() throws Exception { - final RemoteDeviceHandler facade = getFacade(); - final RemoteDeviceCommunicator listener = getListener(); + final RemoteDeviceHandler facade = getFacade(); + final NetconfDeviceCommunicator listener = getListener(); - final SchemaContextProviderFactory schemaContextProviderFactory = getSchemaContextProviderFactory(); - final SchemaSourceProviderFactory sourceProviderFactory = getSourceProviderFactory(); + final SchemaContextFactory schemaContextProviderFactory = getSchemaFactory(); final MessageTransformer messageTransformer = getMessageTransformer(); - final NetconfDevice device = new NetconfDevice(getId(), facade, getExecutor(), messageTransformer, schemaContextProviderFactory, sourceProviderFactory); - final NetconfSessionCapabilities sessionCaps = getSessionCaps(true, + final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO + = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), schemaContextProviderFactory, stateSchemasResolver); + final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, getId(), facade, getExecutor(), messageTransformer, true); + final NetconfSessionPreferences sessionCaps = getSessionCaps(true, Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION)); device.onRemoteSessionUp(sessionCaps, listener); - verify(sourceProviderFactory, timeout(5000)).createSourceProvider(any(RpcImplementation.class)); - verify(schemaContextProviderFactory, timeout(5000)).createContextProvider(any(Collection.class), any(SchemaSourceProvider.class)); + verify(schemaContextProviderFactory, timeout(5000)).createSchemaContext(any(Collection.class)); verify(messageTransformer, timeout(5000)).onGlobalContextUpdated(any(SchemaContext.class)); - verify(facade, timeout(5000)).onDeviceConnected(any(SchemaContextProvider.class), any(NetconfSessionCapabilities.class), any(RpcImplementation.class)); + verify(facade, timeout(5000)).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(RpcImplementation.class)); device.onRemoteSessionDown(); verify(facade, timeout(5000)).onDeviceDisconnected(); device.onRemoteSessionUp(sessionCaps, listener); - verify(sourceProviderFactory, timeout(5000).times(2)).createSourceProvider(any(RpcImplementation.class)); - verify(schemaContextProviderFactory, timeout(5000).times(2)).createContextProvider(any(Collection.class), any(SchemaSourceProvider.class)); - verify(messageTransformer, timeout(5000).times(2)).onGlobalContextUpdated(any(SchemaContext.class)); - verify(facade, timeout(5000).times(2)).onDeviceConnected(any(SchemaContextProvider.class), any(NetconfSessionCapabilities.class), any(RpcImplementation.class)); + verify(schemaContextProviderFactory, timeout(5000).times(2)).createSchemaContext(any(Collection.class)); + verify(messageTransformer, timeout(5000).times(3)).onGlobalContextUpdated(any(SchemaContext.class)); + verify(facade, timeout(5000).times(2)).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(RpcImplementation.class)); } - private SchemaContextProviderFactory getSchemaContextProviderFactory() { - final SchemaContextProviderFactory schemaContextProviderFactory = mockClass(SchemaContextProviderFactory.class); - doReturn(new SchemaContextProvider() { - @Override - public SchemaContext getSchemaContext() { - return getSchema(); - } - }).when(schemaContextProviderFactory).createContextProvider(any(Collection.class), any(SchemaSourceProvider.class)); - return schemaContextProviderFactory; + private SchemaContextFactory getSchemaFactory() { + final SchemaContextFactory schemaFactory = mockClass(SchemaContextFactory.class); + doReturn(Futures.immediateCheckedFuture(getSchema())).when(schemaFactory).createSchemaContext(any(Collection.class)); + return schemaFactory; } public static SchemaContext getSchema() { @@ -159,9 +237,9 @@ public class NetconfDeviceTest { return parser.resolveSchemaContext(models); } - private RemoteDeviceHandler getFacade() throws Exception { - final RemoteDeviceHandler remoteDeviceHandler = mockCloseableClass(RemoteDeviceHandler.class); - doNothing().when(remoteDeviceHandler).onDeviceConnected(any(SchemaContextProvider.class), any(NetconfSessionCapabilities.class), any(RpcImplementation.class)); + private RemoteDeviceHandler getFacade() throws Exception { + final RemoteDeviceHandler remoteDeviceHandler = mockCloseableClass(RemoteDeviceHandler.class); + doNothing().when(remoteDeviceHandler).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(RpcImplementation.class)); doNothing().when(remoteDeviceHandler).onDeviceDisconnected(); doNothing().when(remoteDeviceHandler).onNotification(any(CompositeNode.class)); return remoteDeviceHandler; @@ -184,7 +262,7 @@ public class NetconfDeviceTest { } private static T mockClass(final Class remoteDeviceHandlerClass) { - final T mock = Mockito.mock(remoteDeviceHandlerClass); + final T mock = mock(remoteDeviceHandlerClass); Mockito.doReturn(remoteDeviceHandlerClass.getSimpleName()).when(mock).toString(); return mock; } @@ -206,7 +284,7 @@ public class NetconfDeviceTest { return messageTransformer; } - public NetconfSessionCapabilities getSessionCaps(final boolean addMonitor, final Collection additionalCapabilities) { + public NetconfSessionPreferences getSessionCaps(final boolean addMonitor, final Collection additionalCapabilities) { final ArrayList capabilities = Lists.newArrayList( XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0, XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1); @@ -217,12 +295,12 @@ public class NetconfDeviceTest { capabilities.addAll(additionalCapabilities); - return NetconfSessionCapabilities.fromStrings( + return NetconfSessionPreferences.fromStrings( capabilities); } - public RemoteDeviceCommunicator getListener() throws Exception { - final RemoteDeviceCommunicator remoteDeviceCommunicator = mockCloseableClass(RemoteDeviceCommunicator.class); + public NetconfDeviceCommunicator getListener() throws Exception { + final NetconfDeviceCommunicator remoteDeviceCommunicator = mockCloseableClass(NetconfDeviceCommunicator.class); doReturn(Futures.immediateFuture(rpcResult)).when(remoteDeviceCommunicator).sendRequest(any(NetconfMessage.class), any(QName.class)); return remoteDeviceCommunicator; }