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%2FNetconfDeviceTest.java;h=863f1027acbc796a2b1bb4cf61cf339673517763;hb=68d52ef8ea8ee2ee6cda8bbc4a864c3fa897297e;hp=a7e0de26dbd283ee8b2e429e1e8c4df493f9c9d1;hpb=c1868b25648677e5834bc6823a7a4aa8ce1dd2c8;p=netconf.git diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceTest.java index a7e0de26db..863f1027ac 100644 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceTest.java +++ b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceTest.java @@ -8,19 +8,22 @@ package org.opendaylight.netconf.sal.connect.netconf; import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyCollectionOf; -import static org.mockito.Matchers.eq; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyCollection; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.after; 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.spy; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; @@ -31,66 +34,48 @@ import com.google.common.util.concurrent.SettableFuture; import java.io.IOException; import java.net.InetSocketAddress; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.Executors; import org.junit.Test; import org.mockito.ArgumentCaptor; -import org.mockito.Mockito; -import org.opendaylight.controller.md.sal.dom.api.DOMActionService; -import org.opendaylight.controller.md.sal.dom.api.DOMNotification; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; -import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; -import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult; +import org.opendaylight.mdsal.dom.api.DOMNotification; import org.opendaylight.netconf.api.NetconfMessage; import org.opendaylight.netconf.api.xml.XmlNetconfConstants; import org.opendaylight.netconf.api.xml.XmlUtil; -import org.opendaylight.netconf.sal.connect.api.MessageTransformer; import org.opendaylight.netconf.sal.connect.api.NetconfDeviceSchemasResolver; import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler; +import org.opendaylight.netconf.sal.connect.api.RemoteDeviceServices; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCommunicator; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences; -import org.opendaylight.netconf.sal.connect.netconf.sal.NetconfDeviceRpc; import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability.CapabilityOrigin; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.Revision; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.repo.api.EffectiveModelContextFactory; import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException; -import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier; -import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory; import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository; import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException; -import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation; import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; 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.test.util.YangParserTestUtils; import org.xml.sax.SAXException; -@SuppressWarnings("checkstyle:IllegalCatch") -public class NetconfDeviceTest { - +public class NetconfDeviceTest extends AbstractTestModelTest { private static final NetconfMessage NOTIFICATION; - private static final ContainerNode COMPOSITE_NODE; - static { - try { - COMPOSITE_NODE = mockClass(ContainerNode.class); - } catch (final Exception e) { - throw new RuntimeException(e); - } try { NOTIFICATION = new NetconfMessage(XmlUtil .readXmlToDocument(NetconfDeviceTest.class.getResourceAsStream("/notification-payload.xml"))); @@ -99,31 +84,27 @@ public class NetconfDeviceTest { } } - private static final DOMRpcResult RPC_RESULT = new DefaultDOMRpcResult(COMPOSITE_NODE); - 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 = - RevisionSourceIdentifier.create(TEST_MODULE, Revision.of(TEST_REVISION)); + public static final SourceIdentifier TEST_SID = new SourceIdentifier(TEST_MODULE, TEST_REVISION); public static final String TEST_CAPABILITY = TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION; - public static final SourceIdentifier TEST_SID2 = - RevisionSourceIdentifier.create(TEST_MODULE + "2", Revision.of(TEST_REVISION)); + public static final SourceIdentifier TEST_SID2 = new SourceIdentifier(TEST_MODULE + "2", TEST_REVISION); public static final String TEST_CAPABILITY2 = TEST_NAMESPACE + "?module=" + TEST_MODULE + "2" + "&revision=" + TEST_REVISION; private static final NetconfDeviceSchemasResolver STATE_SCHEMAS_RESOLVER = - (deviceRpc, remoteSessionCapabilities, id) -> NetconfStateSchemas.EMPTY; + (deviceRpc, remoteSessionCapabilities, id, schemaContext) -> NetconfStateSchemas.EMPTY; + @Test public void testNetconfDeviceFlawedModelFailedResolution() throws Exception { - final RemoteDeviceHandler facade = getFacade(); + final RemoteDeviceHandler facade = getFacade(); final NetconfDeviceCommunicator listener = getListener(); - final SchemaContextFactory schemaFactory = getSchemaFactory(); - final SchemaContext schema = getSchema(); + final EffectiveModelContextFactory schemaFactory = getSchemaFactory(); final SchemaRepository schemaRepository = getSchemaRepository(); final SchemaResolutionException schemaResolutionException = @@ -132,12 +113,13 @@ public class NetconfDeviceTest { if (((Collection) invocation.getArguments()[0]).size() == 2) { return Futures.immediateFailedFuture(schemaResolutionException); } else { - return Futures.immediateFuture(schema); + return Futures.immediateFuture(SCHEMA_CONTEXT); } - }).when(schemaFactory).createSchemaContext(anyCollectionOf(SourceIdentifier.class)); + }).when(schemaFactory).createEffectiveModelContext(anyCollection()); - final NetconfDeviceSchemasResolver stateSchemasResolver = (deviceRpc, remoteSessionCapabilities, id) -> { - final Module first = Iterables.getFirst(schema.getModules(), null); + final NetconfDeviceSchemasResolver stateSchemasResolver = (deviceRpc, remoteSessionCapabilities, id, + schemaContext) -> { + final Module first = Iterables.getFirst(SCHEMA_CONTEXT.getModules(), null); final QName qName = QName.create(first.getQNameModule(), first.getName()); final NetconfStateSchemas.RemoteYangSchema source1 = new NetconfStateSchemas.RemoteYangSchema(qName); final NetconfStateSchemas.RemoteYangSchema source2 = @@ -154,34 +136,33 @@ public class NetconfDeviceTest { .setGlobalProcessingExecutor(getExecutor()) .setId(getId()) .setSalFacade(facade) + .setBaseSchemas(BASE_SCHEMAS) .build(); // 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(NetconfDeviceRpc.class), - any(DOMActionService.class)); - Mockito.verify(schemaFactory, times(2)).createSchemaContext(anyCollectionOf(SourceIdentifier.class)); + verify(facade, timeout(5000)).onDeviceConnected(any(NetconfDeviceSchema.class), + any(NetconfSessionPreferences.class), any(RemoteDeviceServices.class)); + verify(schemaFactory, times(2)).createEffectiveModelContext(anyCollection()); } @Test public void testNetconfDeviceFailFirstSchemaFailSecondEmpty() throws Exception { final ArrayList capList = Lists.newArrayList(TEST_CAPABILITY); - final RemoteDeviceHandler facade = getFacade(); + final RemoteDeviceHandler facade = getFacade(); final NetconfDeviceCommunicator listener = getListener(); - final SchemaContextFactory schemaFactory = getSchemaFactory(); + final EffectiveModelContextFactory schemaFactory = getSchemaFactory(); final SchemaRepository schemaRepository = getSchemaRepository(); // Make fallback attempt to fail due to empty resolved sources - final SchemaResolutionException schemaResolutionException - = new SchemaResolutionException("fail first", - Collections.emptyList(), HashMultimap.create()); + final SchemaResolutionException schemaResolutionException = new SchemaResolutionException("fail first", + List.of(), ImmutableMultimap.of()); doReturn(Futures.immediateFailedFuture(schemaResolutionException)) - .when(schemaFactory).createSchemaContext(anyCollectionOf(SourceIdentifier.class)); + .when(schemaFactory).createEffectiveModelContext(anyCollection()); final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice .SchemaResourcesDTO(getSchemaRegistry(), schemaRepository, schemaFactory, STATE_SCHEMAS_RESOLVER); @@ -191,24 +172,24 @@ public class NetconfDeviceTest { .setGlobalProcessingExecutor(getExecutor()) .setId(getId()) .setSalFacade(facade) + .setBaseSchemas(BASE_SCHEMAS) .build(); // 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)); + verify(facade, timeout(5000)).onDeviceDisconnected(); + verify(listener, timeout(5000)).close(); + verify(schemaFactory, times(1)).createEffectiveModelContext(anyCollection()); } @Test public void testNetconfDeviceMissingSource() throws Exception { - final RemoteDeviceHandler facade = getFacade(); + final RemoteDeviceHandler facade = getFacade(); final NetconfDeviceCommunicator listener = getListener(); - final SchemaContext schema = getSchema(); - final SchemaContextFactory schemaFactory = getSchemaFactory(); + final EffectiveModelContextFactory schemaFactory = getSchemaFactory(); final SchemaRepository schemaRepository = getSchemaRepository(); // Make fallback attempt to fail due to empty resolved sources @@ -220,12 +201,13 @@ public class NetconfDeviceTest { if (((Collection) invocation.getArguments()[0]).size() == 2) { return Futures.immediateFailedFuture(schemaResolutionException); } else { - return Futures.immediateFuture(schema); + return Futures.immediateFuture(SCHEMA_CONTEXT); } - }).when(schemaFactory).createSchemaContext(anyCollectionOf(SourceIdentifier.class)); + }).when(schemaFactory).createEffectiveModelContext(anyCollection()); - final NetconfDeviceSchemasResolver stateSchemasResolver = (deviceRpc, remoteSessionCapabilities, id) -> { - final Module first = Iterables.getFirst(schema.getModules(), null); + final NetconfDeviceSchemasResolver stateSchemasResolver = (deviceRpc, remoteSessionCapabilities, id, + schemaContext) -> { + final Module first = Iterables.getFirst(SCHEMA_CONTEXT.getModules(), null); final QName qName = QName.create(first.getQNameModule(), first.getName()); final NetconfStateSchemas.RemoteYangSchema source1 = new NetconfStateSchemas.RemoteYangSchema(qName); final NetconfStateSchemas.RemoteYangSchema source2 = @@ -240,18 +222,18 @@ public class NetconfDeviceTest { .setReconnectOnSchemasChange(true) .setSchemaResourcesDTO(schemaResourcesDTO) .setGlobalProcessingExecutor(getExecutor()) + .setBaseSchemas(BASE_SCHEMAS) .setId(getId()) .setSalFacade(facade) .build(); // Monitoring supported final NetconfSessionPreferences sessionCaps = - getSessionCaps(true, Lists.newArrayList(TEST_CAPABILITY, TEST_CAPABILITY2)); + getSessionCaps(true, List.of(TEST_CAPABILITY, TEST_CAPABILITY2)); device.onRemoteSessionUp(sessionCaps, listener); - Mockito.verify(facade, Mockito.timeout(5000)).onDeviceConnected( - any(SchemaContext.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class), - any(DOMActionService.class)); - Mockito.verify(schemaFactory, times(1)).createSchemaContext(anyCollectionOf(SourceIdentifier.class)); + verify(facade, timeout(5000)).onDeviceConnected(any(NetconfDeviceSchema.class), + any(NetconfSessionPreferences.class), any(RemoteDeviceServices.class)); + verify(schemaFactory, times(1)).createEffectiveModelContext(anyCollection()); } private static SchemaSourceRegistry getSchemaRegistry() { @@ -266,7 +248,7 @@ public class NetconfDeviceTest { private static SchemaRepository getSchemaRepository() { final SchemaRepository mock = mock(SchemaRepository.class); - final SchemaSourceRepresentation mockRep = mock(SchemaSourceRepresentation.class); + final YangTextSchemaSource mockRep = mock(YangTextSchemaSource.class); doReturn(Futures.immediateFuture(mockRep)) .when(mock).getSchemaSource(any(SourceIdentifier.class), eq(YangTextSchemaSource.class)); return mock; @@ -274,11 +256,11 @@ public class NetconfDeviceTest { @Test public void testNotificationBeforeSchema() throws Exception { - final RemoteDeviceHandler facade = getFacade(); + final RemoteDeviceHandler facade = getFacade(); final NetconfDeviceCommunicator listener = getListener(); - final SchemaContextFactory schemaContextProviderFactory = mock(SchemaContextFactory.class); + final EffectiveModelContextFactory schemaContextProviderFactory = mock(EffectiveModelContextFactory.class); final SettableFuture schemaFuture = SettableFuture.create(); - doReturn(schemaFuture).when(schemaContextProviderFactory).createSchemaContext(any(Collection.class)); + doReturn(schemaFuture).when(schemaContextProviderFactory).createEffectiveModelContext(any(Collection.class)); final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER); @@ -288,6 +270,7 @@ public class NetconfDeviceTest { .setGlobalProcessingExecutor(getExecutor()) .setId(getId()) .setSalFacade(facade) + .setBaseSchemas(BASE_SCHEMAS) .build(); final NetconfSessionPreferences sessionCaps = getSessionCaps(true, @@ -308,10 +291,10 @@ public class NetconfDeviceTest { @Test public void testNetconfDeviceReconnect() throws Exception { - final RemoteDeviceHandler facade = getFacade(); + final RemoteDeviceHandler facade = getFacade(); final NetconfDeviceCommunicator listener = getListener(); - final SchemaContextFactory schemaContextProviderFactory = getSchemaFactory(); + final EffectiveModelContextFactory schemaContextProviderFactory = getSchemaFactory(); final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO( getSchemaRegistry(), getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER); @@ -321,34 +304,33 @@ public class NetconfDeviceTest { .setGlobalProcessingExecutor(getExecutor()) .setId(getId()) .setSalFacade(facade) + .setBaseSchemas(BASE_SCHEMAS) .build(); final NetconfSessionPreferences sessionCaps = getSessionCaps(true, Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION)); device.onRemoteSessionUp(sessionCaps, listener); - verify(schemaContextProviderFactory, timeout(5000)).createSchemaContext(any(Collection.class)); + verify(schemaContextProviderFactory, timeout(5000)).createEffectiveModelContext(any(Collection.class)); verify(facade, timeout(5000)).onDeviceConnected( - any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class), - any(DOMActionService.class)); + any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(RemoteDeviceServices.class)); device.onRemoteSessionDown(); verify(facade, timeout(5000)).onDeviceDisconnected(); device.onRemoteSessionUp(sessionCaps, listener); - verify(schemaContextProviderFactory, timeout(5000).times(2)).createSchemaContext(any(Collection.class)); + verify(schemaContextProviderFactory, timeout(5000).times(2)).createEffectiveModelContext(any(Collection.class)); verify(facade, timeout(5000).times(2)).onDeviceConnected( - any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class), - any(DOMActionService.class)); + any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(RemoteDeviceServices.class)); } @Test public void testNetconfDeviceDisconnectListenerCallCancellation() throws Exception { - final RemoteDeviceHandler facade = getFacade(); + final RemoteDeviceHandler facade = getFacade(); final NetconfDeviceCommunicator listener = getListener(); - final SchemaContextFactory schemaContextProviderFactory = mock(SchemaContextFactory.class); + final EffectiveModelContextFactory schemaContextProviderFactory = mock(EffectiveModelContextFactory.class); final SettableFuture schemaFuture = SettableFuture.create(); - doReturn(schemaFuture).when(schemaContextProviderFactory).createSchemaContext(any(Collection.class)); + doReturn(schemaFuture).when(schemaContextProviderFactory).createEffectiveModelContext(any(Collection.class)); final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER); @@ -358,6 +340,7 @@ public class NetconfDeviceTest { .setGlobalProcessingExecutor(getExecutor()) .setId(getId()) .setSalFacade(facade) + .setBaseSchemas(BASE_SCHEMAS) .build(); final NetconfSessionPreferences sessionCaps = getSessionCaps(true, Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION)); @@ -367,17 +350,17 @@ public class NetconfDeviceTest { device.onRemoteSessionDown(); verify(facade, timeout(5000)).onDeviceDisconnected(); //complete schema setup - schemaFuture.set(getSchema()); + schemaFuture.set(SCHEMA_CONTEXT); //facade.onDeviceDisconnected() was called, so facade.onDeviceConnected() shouldn't be called anymore - verify(facade, after(1000).never()).onDeviceConnected(any(), any(), any(), any(DOMActionService.class)); + verify(facade, after(1000).never()).onDeviceConnected(any(), any(), any(RemoteDeviceServices.class)); } @Test public void testNetconfDeviceAvailableCapabilitiesBuilding() throws Exception { - final RemoteDeviceHandler facade = getFacade(); + final RemoteDeviceHandler facade = getFacade(); final NetconfDeviceCommunicator listener = getListener(); - final SchemaContextFactory schemaContextProviderFactory = getSchemaFactory(); + final EffectiveModelContextFactory schemaContextProviderFactory = getSchemaFactory(); final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO( getSchemaRegistry(), getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER); @@ -387,48 +370,161 @@ public class NetconfDeviceTest { .setGlobalProcessingExecutor(getExecutor()) .setId(getId()) .setSalFacade(facade) + .setBaseSchemas(BASE_SCHEMAS) .build(); - final NetconfDevice netconfSpy = Mockito.spy(device); + final NetconfDevice netconfSpy = spy(device); final NetconfSessionPreferences sessionCaps = getSessionCaps(true, Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION)); - final Map moduleBasedCaps = new HashMap<>(); - moduleBasedCaps.putAll(sessionCaps.getModuleBasedCapsOrigin()); + final Map moduleBasedCaps = new HashMap<>(); + moduleBasedCaps.putAll(sessionCaps.moduleBasedCaps()); moduleBasedCaps - .put(QName.create("(test:qname:side:loading)test"), AvailableCapability.CapabilityOrigin.UserDefined); + .put(QName.create("(test:qname:side:loading)test"), CapabilityOrigin.UserDefined); netconfSpy.onRemoteSessionUp(sessionCaps.replaceModuleCaps(moduleBasedCaps), listener); - final ArgumentCaptor argument = - ArgumentCaptor.forClass(NetconfSessionPreferences.class); - verify(facade, timeout(5000)) - .onDeviceConnected(any(SchemaContext.class), argument.capture(), any(DOMRpcService.class), - any(DOMActionService.class)); - final NetconfDeviceCapabilities netconfDeviceCaps = argument.getValue().getNetconfDeviceCapabilities(); - - netconfDeviceCaps.getResolvedCapabilities() + final ArgumentCaptor argument = ArgumentCaptor.forClass(NetconfDeviceSchema.class); + verify(facade, timeout(5000)).onDeviceConnected(argument.capture(), any(NetconfSessionPreferences.class), + any(RemoteDeviceServices.class)); + argument.getValue().capabilities().resolvedCapabilities() .forEach(entry -> assertEquals("Builded 'AvailableCapability' schemas should match input capabilities.", moduleBasedCaps.get( QName.create(entry.getCapability())).getName(), entry.getCapabilityOrigin().getName())); } - private static SchemaContextFactory getSchemaFactory() throws Exception { - final SchemaContextFactory schemaFactory = mockClass(SchemaContextFactory.class); - doReturn(Futures.immediateFuture(getSchema())) - .when(schemaFactory).createSchemaContext(any(Collection.class)); - return schemaFactory; + @Test + public void testNetconfDeviceNotificationsModelNotPresentWithCapability() throws Exception { + final RemoteDeviceHandler facade = getFacade(); + final NetconfDeviceCommunicator listener = getListener(); + final EffectiveModelContextFactory schemaContextProviderFactory = getSchemaFactory(); + + final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO( + getSchemaRegistry(), getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER); + final NetconfDevice device = new NetconfDeviceBuilder() + .setSchemaResourcesDTO(schemaResourcesDTO) + .setGlobalProcessingExecutor(getExecutor()) + .setId(getId()) + .setSalFacade(facade) + .setBaseSchemas(BASE_SCHEMAS) + .build(); + final NetconfDevice netconfSpy = spy(device); + + final NetconfSessionPreferences sessionCaps = getSessionCaps(false, + Lists.newArrayList(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_NOTIFICATION_1_0)); + + netconfSpy.onRemoteSessionUp(sessionCaps, listener); + + final ArgumentCaptor argument = ArgumentCaptor.forClass(NetconfDeviceSchema.class); + verify(facade, timeout(5000)).onDeviceConnected(argument.capture(), any(NetconfSessionPreferences.class), + any(RemoteDeviceServices.class)); + + List notificationModulesName = Arrays.asList( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714 + .$YangModuleInfoImpl.getInstance().getName().toString(), + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715 + .$YangModuleInfoImpl.getInstance().getName().toString()); + + final Set resolvedCapabilities = argument.getValue().capabilities().resolvedCapabilities(); + + assertEquals(2, resolvedCapabilities.size()); + assertTrue(resolvedCapabilities.stream().anyMatch(entry -> notificationModulesName + .contains(entry.getCapability()))); + } + + @Test + public void testNetconfDeviceNotificationsCapabilityIsNotPresent() throws Exception { + final RemoteDeviceHandler facade = getFacade(); + final NetconfDeviceCommunicator listener = getListener(); + final EffectiveModelContextFactory schemaContextProviderFactory = getSchemaFactory(); + + final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO( + getSchemaRegistry(), getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER); + final NetconfDevice device = new NetconfDeviceBuilder() + .setSchemaResourcesDTO(schemaResourcesDTO) + .setGlobalProcessingExecutor(getExecutor()) + .setId(getId()) + .setSalFacade(facade) + .setBaseSchemas(BASE_SCHEMAS) + .build(); + final NetconfDevice netconfSpy = spy(device); + + final NetconfSessionPreferences sessionCaps = getSessionCaps(false, + Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION)); + + netconfSpy.onRemoteSessionUp(sessionCaps, listener); + + final ArgumentCaptor argument = ArgumentCaptor.forClass(NetconfDeviceSchema.class); + verify(facade, timeout(5000)).onDeviceConnected(argument.capture(), any(NetconfSessionPreferences.class), + any(RemoteDeviceServices.class)); + final NetconfDeviceCapabilities netconfDeviceCaps = argument.getValue().capabilities(); + + List notificationModulesName = List.of( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714 + .$YangModuleInfoImpl.getInstance().getName().toString(), + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715 + .$YangModuleInfoImpl.getInstance().getName().toString()); + + assertFalse(netconfDeviceCaps.resolvedCapabilities().stream() + .anyMatch(entry -> notificationModulesName.contains(entry.getCapability()))); } - public static SchemaContext getSchema() { - return YangParserTestUtils.parseYangResource("/schemas/test-module.yang"); + @Test + public void testNetconfDeviceNotificationsModelIsPresent() throws Exception { + final RemoteDeviceHandler facade = getFacade(); + final NetconfDeviceCommunicator listener = getListener(); + final EffectiveModelContextFactory schemaContextProviderFactory = getSchemaFactory(); + + final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO = new NetconfDevice.SchemaResourcesDTO( + getSchemaRegistry(), getSchemaRepository(), schemaContextProviderFactory, STATE_SCHEMAS_RESOLVER); + final NetconfDevice device = new NetconfDeviceBuilder() + .setSchemaResourcesDTO(schemaResourcesDTO) + .setGlobalProcessingExecutor(getExecutor()) + .setId(getId()) + .setSalFacade(facade) + .setBaseSchemas(BASE_SCHEMAS) + .build(); + final NetconfDevice netconfSpy = spy(device); + + final NetconfSessionPreferences sessionCaps = getSessionCaps(false, Collections.emptyList()); + + final Map moduleBasedCaps = new HashMap<>(); + moduleBasedCaps.put(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714 + .$YangModuleInfoImpl.getInstance().getName(), + CapabilityOrigin.DeviceAdvertised); + moduleBasedCaps.put(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715 + .$YangModuleInfoImpl.getInstance().getName(), + CapabilityOrigin.DeviceAdvertised); + + + netconfSpy.onRemoteSessionUp(sessionCaps.replaceModuleCaps(moduleBasedCaps), listener); + + final ArgumentCaptor argument = ArgumentCaptor.forClass(NetconfDeviceSchema.class); + verify(facade, timeout(5000)).onDeviceConnected(argument.capture(), any(NetconfSessionPreferences.class), + any(RemoteDeviceServices.class)); + final Set resolvedCapabilities = argument.getValue().capabilities().resolvedCapabilities(); + + List notificationModulesName = List.of( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714 + .$YangModuleInfoImpl.getInstance().getName().toString(), + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715 + .$YangModuleInfoImpl.getInstance().getName().toString()); + + assertEquals(2, resolvedCapabilities.size()); + assertTrue(resolvedCapabilities.stream().anyMatch(entry -> notificationModulesName + .contains(entry.getCapability()))); + } + + private static EffectiveModelContextFactory getSchemaFactory() throws Exception { + final EffectiveModelContextFactory schemaFactory = mockClass(EffectiveModelContextFactory.class); + doReturn(Futures.immediateFuture(SCHEMA_CONTEXT)) + .when(schemaFactory).createEffectiveModelContext(any(Collection.class)); + return schemaFactory; } - private static RemoteDeviceHandler getFacade() throws Exception { - final RemoteDeviceHandler remoteDeviceHandler = - mockCloseableClass(RemoteDeviceHandler.class); + private static RemoteDeviceHandler getFacade() throws Exception { + final RemoteDeviceHandler remoteDeviceHandler = mockCloseableClass(RemoteDeviceHandler.class); doNothing().when(remoteDeviceHandler).onDeviceConnected( - any(SchemaContext.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class), - any(DOMActionService.class)); + any(NetconfDeviceSchema.class), any(NetconfSessionPreferences.class), any(RemoteDeviceServices.class)); doNothing().when(remoteDeviceHandler).onDeviceDisconnected(); doNothing().when(remoteDeviceHandler).onNotification(any(DOMNotification.class)); return remoteDeviceHandler; @@ -443,7 +539,7 @@ public class NetconfDeviceTest { private static T mockClass(final Class remoteDeviceHandlerClass) { final T mock = mock(remoteDeviceHandlerClass); - Mockito.doReturn(remoteDeviceHandlerClass.getSimpleName()).when(mock).toString(); + doReturn(remoteDeviceHandlerClass.getSimpleName()).when(mock).toString(); return mock; } @@ -455,14 +551,6 @@ public class NetconfDeviceTest { return MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()); } - public MessageTransformer getMessageTransformer() throws Exception { - final MessageTransformer messageTransformer = mockClass(MessageTransformer.class); - doReturn(NOTIFICATION).when(messageTransformer).toRpcRequest(any(SchemaPath.class), any(NormalizedNode.class)); - doReturn(RPC_RESULT).when(messageTransformer).toRpcResult(any(NetconfMessage.class), any(SchemaPath.class)); - doReturn(COMPOSITE_NODE).when(messageTransformer).toNotification(any(NetconfMessage.class)); - return messageTransformer; - } - public NetconfSessionPreferences getSessionCaps(final boolean addMonitor, final Collection additionalCapabilities) { final ArrayList capabilities = Lists.newArrayList(