From 787d5375bafae2644824daeb31658953e61e6611 Mon Sep 17 00:00:00 2001 From: Vishal Thapar Date: Mon, 4 May 2015 19:22:37 +0530 Subject: [PATCH] Interfacemgr: Added Unit Tests 1. Added some basic Unit Tests 2. Fixed issues found with Unit testing 3. Some refactoring Change-Id: If7dd995f23115a425802c2e0382b8ac8c052702a Signed-off-by: Vishal Thapar --- interfacemgr/interfacemgr-impl/pom.xml | 2 +- .../vpnservice/interfacemgr/IfmConstants.java | 6 +- .../vpnservice/interfacemgr/IfmUtil.java | 44 +++- .../interfacemgr/InterfaceManager.java | 92 +++----- .../interfacemgr/InterfacemgrProvider.java | 16 +- .../interfacemgr/test/IfmUtilTest.java | 31 +++ .../test/InterfaceManagerTest.java | 209 ++++++++++++++++++ .../test/MockDataChangedEvent.java | 53 +++++ 8 files changed, 380 insertions(+), 73 deletions(-) create mode 100644 interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/IfmUtilTest.java create mode 100644 interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/InterfaceManagerTest.java create mode 100644 interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/MockDataChangedEvent.java diff --git a/interfacemgr/interfacemgr-impl/pom.xml b/interfacemgr/interfacemgr-impl/pom.xml index a6c4b08b..fec2ca0d 100644 --- a/interfacemgr/interfacemgr-impl/pom.xml +++ b/interfacemgr/interfacemgr-impl/pom.xml @@ -38,7 +38,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.vpnservice vpnmanager-impl - 1.0-SNAPSHOT + 0.0.1-SNAPSHOT org.opendaylight.vpnservice diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java index 4cfa0005..add3af5b 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmConstants.java @@ -2,8 +2,10 @@ package org.opendaylight.vpnservice.interfacemgr; public class IfmConstants { public static final String IFM_IDPOOL_NAME = "interfaces"; + public static final long IFM_IDPOOL_START = 1L; + public static final String IFM_IDPOOL_SIZE = "65535"; public static final String OF_URI_PREFIX = "openflow:"; - public static final String OF_URI_SEPARATOR = "openflow:"; - public static final int DEFAULT_IFINDEX = 65535; + public static final String OF_URI_SEPARATOR = ":"; + public static final int DEFAULT_IFINDEX = 65536; } diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java index af51d74a..76f0c1ae 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/IfmUtil.java @@ -1,11 +1,20 @@ package org.opendaylight.vpnservice.interfacemgr; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.Pools; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPoolKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; -public class IfmUtil { +public class IfmUtil { - static String getDpnFromNodeConnectorId(NodeConnectorId portId) { + public static String getDpnFromNodeConnectorId(NodeConnectorId portId) { /* * NodeConnectorId is of form 'openflow:dpnid:portnum' */ @@ -14,7 +23,36 @@ public class IfmUtil { } - static NodeId buildDpnNodeId(long dpnId) { + public static NodeId buildDpnNodeId(long dpnId) { return new NodeId(IfmConstants.OF_URI_PREFIX + dpnId); } + + public static InstanceIdentifier buildId(String interfaceName) { + //TODO Make this generic and move to AbstractDataChangeListener or Utils. + InstanceIdentifierBuilder idBuilder = + InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new InterfaceKey(interfaceName)); + InstanceIdentifier id = idBuilder.build(); + return id; + } + + public static InstanceIdentifier buildStateInterfaceId(String interfaceName) { + InstanceIdentifierBuilder idBuilder = + InstanceIdentifier.builder(InterfacesState.class) + .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class, + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName)); + InstanceIdentifier id = idBuilder.build(); + return id; + } + + public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName( + String name) { + return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(name); + } + + public static InstanceIdentifier getPoolId(String poolName){ + InstanceIdentifier.InstanceIdentifierBuilder idBuilder = + InstanceIdentifier.builder(Pools.class).child(IdPool.class, new IdPoolKey(poolName)); + InstanceIdentifier id = idBuilder.build(); + return id; + } } diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java index 8f0a4aa3..a1cc4972 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfaceManager.java @@ -7,18 +7,15 @@ */ package org.opendaylight.vpnservice.interfacemgr; - import com.google.common.base.Optional; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; - import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; - import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; @@ -34,7 +31,6 @@ import org.opendaylight.vpnservice.mdsalutil.MatchInfo; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus; @@ -49,9 +45,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.GetUniqueIdOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.Pools; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool; -import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPoolKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.id.pool.GeneratedIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfL2vlan; @@ -140,18 +134,6 @@ public class InterfaceManager extends AbstractDataChangeListener impl return id; } - private InstanceIdentifier - - buildStateInterfaceId(String interfaceName) { - //TODO Make this generic and move to AbstractDataChangeListener or Utils. - InstanceIdentifierBuilder - - idBuilder = InstanceIdentifier.builder(InterfacesState.class) - .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class, - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(interfaceName)); - InstanceIdentifier id = idBuilder.build(); - return id; - } private void addInterface(final InstanceIdentifier identifier, final Interface interf) { @@ -164,7 +146,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl ncId = nodeConn.getId(); } mapNcToInterfaceName.put(ncId, interf.getName()); - if(interf.getType().getClass().isInstance(L3tunnel.class)) { + if(interf.getType().isAssignableFrom(L3tunnel.class)) { NodeId nodeId = getNodeIdFromNodeConnectorId(ncId); IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class); dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue()); @@ -184,7 +166,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl * if-index = interface-id */ InstanceIdentifier id = - buildStateInterfaceId(interf.getName()); + IfmUtil.buildStateInterfaceId(interf.getName()); Optional stateIf = read(LogicalDatastoreType.OPERATIONAL, id); org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface; @@ -198,7 +180,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl ifaceBuilder.setOperStatus(getOperStatus(nodeConn)); ifaceBuilder.setIfIndex(getIfIndex(ifName)).setName(ifName).setType(interf.getType()); - ifaceBuilder.setKey(getStateInterfaceKeyFromName(ifName)); + ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName)); stateIface = ifaceBuilder.build(); LOG.trace("Adding stateIface {} and id {} to OPERATIONAL DS", stateIface, id); asyncWrite(LogicalDatastoreType.OPERATIONAL, id, stateIface, DEFAULT_CALLBACK); @@ -233,10 +215,8 @@ public class InterfaceManager extends AbstractDataChangeListener impl * TODO: Start-delete-me */ - InstanceIdentifier.InstanceIdentifierBuilder idBuilder = - InstanceIdentifier.builder(Pools.class).child(IdPool.class, new IdPoolKey("interfaces")); - InstanceIdentifier id = idBuilder.build(); - Optional globalPool = read(LogicalDatastoreType.OPERATIONAL, id); + InstanceIdentifier id = IfmUtil.getPoolId(IfmConstants.IFM_IDPOOL_NAME); + Optional globalPool = read(LogicalDatastoreType.OPERATIONAL, id ); Long newIdValue = null; if (globalPool.isPresent()) { IdPool pool = globalPool.get(); @@ -265,11 +245,6 @@ public class InterfaceManager extends AbstractDataChangeListener impl } } - private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey getStateInterfaceKeyFromName( - String name) { - return new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(name); - } - private NodeConnector getNodeConnectorFromDataStore(Interface interf) { NodeConnectorId ncId = interf.getAugmentation(BaseIds.class).getOfPortId(); //TODO: Replace with MDSAL Util method @@ -294,7 +269,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl private void delInterface(final InstanceIdentifier identifier, final Interface delInterface) { InstanceIdentifier id = - buildStateInterfaceId(delInterface.getName()); + IfmUtil.buildStateInterfaceId(delInterface.getName()); Optional stateIf = read(LogicalDatastoreType.OPERATIONAL, id); if(stateIf.isPresent()) { @@ -303,7 +278,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl NodeConnectorId ncId = getNodeConnectorIdFromInterface(delInterface); if(ncId != null) { mapNcToInterfaceName.remove(ncId); - if(delInterface.getType().getClass().isInstance(L3tunnel.class)) { + if(delInterface.getType().isAssignableFrom(L3tunnel.class)) { Node node = getNodeFromDataStore(delInterface); if((node != null) &&(node.getNodeConnector().isEmpty())) { dbDpnEndpoints.remove(node.getId()); @@ -343,7 +318,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl if(nc != null) { // Name doesn't change. Is it present in update? mapNcToInterfaceName.put(nc.getId(), original.getName()); - if(interf.getType().getClass().isInstance(L3tunnel.class)) { + if(interf.getType().isAssignableFrom(L3tunnel.class)) { NodeId nodeId = getNodeIdFromNodeConnectorId(nc.getId()); IfL3tunnel l3Tunnel = interf.getAugmentation(IfL3tunnel.class); dbDpnEndpoints.put(nodeId, l3Tunnel.getLocalIp().getIpv4Address().getValue()); @@ -384,31 +359,31 @@ public class InterfaceManager extends AbstractDataChangeListener impl updateInterface(identifier, original, update); } - private void asyncWrite(LogicalDatastoreType datastoreType, + protected void asyncWrite(LogicalDatastoreType datastoreType, InstanceIdentifier path, T data, FutureCallback callback) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.put(datastoreType, path, data, true); - Futures.addCallback(tx.submit(), callback); + WriteTransaction tx = broker.newWriteOnlyTransaction(); + tx.put(datastoreType, path, data, true); + Futures.addCallback(tx.submit(), callback); } - private void asyncUpdate(LogicalDatastoreType datastoreType, + protected void asyncUpdate(LogicalDatastoreType datastoreType, InstanceIdentifier path, T data, FutureCallback callback) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.merge(datastoreType, path, data, true); - Futures.addCallback(tx.submit(), callback); + WriteTransaction tx = broker.newWriteOnlyTransaction(); + tx.merge(datastoreType, path, data, true); + Futures.addCallback(tx.submit(), callback); } - private void asyncRemove(LogicalDatastoreType datastoreType, + protected void asyncRemove(LogicalDatastoreType datastoreType, InstanceIdentifier path, FutureCallback callback) { - WriteTransaction tx = broker.newWriteOnlyTransaction(); - tx.delete(datastoreType, path); - Futures.addCallback(tx.submit(), callback); + WriteTransaction tx = broker.newWriteOnlyTransaction(); + tx.delete(datastoreType, path); + Futures.addCallback(tx.submit(), callback); } void processPortAdd(NodeConnector port) { NodeConnectorId portId = port.getId(); FlowCapableNodeConnector ofPort = port.getAugmentation(FlowCapableNodeConnector.class); - LOG.debug("PortAdd: PortId { "+portId.getValue()+"} PortName {"+ofPort.getName()+"}"); + LOG.debug("PortAdd: PortId { " + portId.getValue() + "} PortName {" + ofPort.getName() + "}"); String ifName = this.mapNcToInterfaceName.get(portId); setInterfaceOperStatus(ifName, OperStatus.Up); } @@ -429,7 +404,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl private void setInterfaceOperStatus(String ifName, OperStatus opStatus) { if (ifName != null) { InstanceIdentifier id = - buildStateInterfaceId(ifName); + IfmUtil.buildStateInterfaceId(ifName); Optional stateIf = read(LogicalDatastoreType.OPERATIONAL, id); org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface; @@ -482,11 +457,12 @@ public class InterfaceManager extends AbstractDataChangeListener impl long dpn = this.getDpnForInterface(ifName); long portNo = this.getPortNumForInterface(iface).longValue(); matches.add(new MatchInfo(MatchFieldType.in_port, new long[] {dpn, portNo})); + if (ifType.isInstance(L2vlan.class)) { IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class); long vlanVid = vlanIface.getVlanId().longValue(); if (vlanVid != 0) { - matches.add(new MatchInfo(MatchFieldType.vlan_vid, + matches.add(new MatchInfo(MatchFieldType.vlan_vid, new long[] {vlanVid})); LOG.trace("L2Vlan: {}",vlanIface); } @@ -495,10 +471,10 @@ public class InterfaceManager extends AbstractDataChangeListener impl IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class); Class tunnType = ifL3Tunnel.getTunnelType(); LOG.trace("L3Tunnel: {}",ifL3Tunnel); - } else if (ifType.getClass().isInstance(StackedVlan.class)) { + } else if (ifType.isAssignableFrom(StackedVlan.class)) { IfStackedVlan ifStackedVlan = iface.getAugmentation(IfStackedVlan.class); LOG.trace("StackedVlan: {}",ifStackedVlan); - } else if (ifType.getClass().isInstance(Mpls.class)) { + } else if (ifType.isAssignableFrom(Mpls.class)) { IfMpls ifMpls = iface.getAugmentation(IfMpls.class); LOG.trace("Mpls: {}",ifMpls); } @@ -515,7 +491,7 @@ public class InterfaceManager extends AbstractDataChangeListener impl if (iface.isEnabled()) { - if(ifType.isInstance(L2vlan.class)) { + if(ifType.isAssignableFrom(L2vlan.class)) { IfL2vlan vlanIface = iface.getAugmentation(IfL2vlan.class); long vlanVid = vlanIface.getVlanId(); LOG.trace("L2Vlan: {}",vlanIface); @@ -525,23 +501,23 @@ public class InterfaceManager extends AbstractDataChangeListener impl new String[] { Long.toString(vlanVid) })); } listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)})); - - } else if (ifType.isInstance(L3tunnel.class)) { + + } else if (ifType.isAssignableFrom(L3tunnel.class)) { //TODO: Handle different tunnel types IfL3tunnel ifL3Tunnel = iface.getAugmentation(IfL3tunnel.class); Class tunnType = ifL3Tunnel.getTunnelType(); LOG.trace("L3Tunnel: {}",ifL3Tunnel); //TODO: check switch_type and configure accordingly listActionInfo.add(new ActionInfo(ActionType.output, new String[] { Long.toString(portNo)})); - - } else if (ifType.isInstance(StackedVlan.class)) { + + } else if (ifType.isAssignableFrom(StackedVlan.class)) { IfStackedVlan ifStackedVlan = iface.getAugmentation(IfStackedVlan.class); LOG.trace("StackedVlan: {}",ifStackedVlan); - // TBD - } else if (ifType.isInstance(Mpls.class)) { + // TODO: TBD + } else if (ifType.isAssignableFrom(Mpls.class)) { IfMpls ifMpls = iface.getAugmentation(IfMpls.class); LOG.trace("Mpls: {}",ifMpls); - // TBD + // TODO: TBD } } return listActionInfo; diff --git a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java index 01bf1f7c..9a04dae5 100644 --- a/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java +++ b/interfacemgr/interfacemgr-impl/src/main/java/org/opendaylight/vpnservice/interfacemgr/InterfacemgrProvider.java @@ -7,18 +7,16 @@ */ package org.opendaylight.vpnservice.interfacemgr; -import java.util.concurrent.ExecutionException; import java.math.BigInteger; import java.util.List; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import org.opendaylight.vpnservice.mdsalutil.ActionInfo; -import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; import org.opendaylight.controller.sal.binding.api.BindingAwareProvider; import org.opendaylight.idmanager.IdManager; import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager; -import org.opendaylight.vpnservice.mdsalutil.InstructionInfo; +import org.opendaylight.vpnservice.mdsalutil.ActionInfo; import org.opendaylight.vpnservice.mdsalutil.MatchInfo; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.CreateIdPoolInputBuilder; @@ -50,14 +48,14 @@ public class InterfacemgrProvider implements BindingAwareProvider, AutoCloseable private void createIdPool() { CreateIdPoolInput createPool = new CreateIdPoolInputBuilder() - .setPoolName("interfaces") - .setIdStart(1L) - .setPoolSize(new BigInteger("65535")) - .build(); + .setPoolName(IfmConstants.IFM_IDPOOL_NAME) + .setIdStart(IfmConstants.IFM_IDPOOL_START) + .setPoolSize(new BigInteger(IfmConstants.IFM_IDPOOL_SIZE)) + .build(); //TODO: Error handling Future> result = idManager.createIdPool(createPool); try { - if((result != null) && (result.get().isSuccessful())) { + if ((result != null) && (result.get().isSuccessful())) { LOG.debug("Created IdPool for InterfaceMgr"); } } catch (InterruptedException | ExecutionException e) { diff --git a/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/IfmUtilTest.java b/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/IfmUtilTest.java new file mode 100644 index 00000000..74e11dff --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/IfmUtilTest.java @@ -0,0 +1,31 @@ +package org.opendaylight.vpnservice.interfacemgr.test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; + +public class IfmUtilTest { + + @Mock NodeConnectorId ncId; + MockDataChangedEvent event; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testDpnConversions() { + String NodeId = IfmUtil.buildDpnNodeId(101L).getValue(); + assertEquals("openflow:101", NodeId); + when(ncId.getValue()).thenReturn("openflow:101:11"); + assertEquals("101",IfmUtil.getDpnFromNodeConnectorId(ncId)); + } + +} diff --git a/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/InterfaceManagerTest.java b/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/InterfaceManagerTest.java new file mode 100644 index 00000000..1cae1760 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/InterfaceManagerTest.java @@ -0,0 +1,209 @@ +package org.opendaylight.vpnservice.interfacemgr.test; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.idmanager.IdManager; +import org.opendaylight.vpnservice.interfacemgr.IfmUtil; +import org.opendaylight.vpnservice.interfacemgr.InterfaceManager; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.L2vlan; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.OperStatus; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.IdPool; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.BaseIdsBuilder; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +@RunWith(MockitoJUnitRunner.class) +public class InterfaceManagerTest { + + private String ifName = "dpn1-if0"; + Map,DataObject> written = new HashMap<>(); + Map,DataObject> updated = new HashMap<>(); + Set> removed = new HashSet<>(); + + @Mock DataBroker dataBroker; + @Mock IdManager idManager; + @Mock ListenerRegistration dataChangeListenerRegistration; + @Mock ReadOnlyTransaction mockReadTx; + @Mock WriteTransaction mockWriteTx; + + MockDataChangedEvent dataChangeEvent; + InterfaceManager imgr; + + NodeConnectorId ncId; + NodeConnector nc; + Interface interf; + InstanceIdentifier ifIdent; + InstanceIdentifier ncIdent; + InstanceIdentifier ifsIdent; + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface stateIface; + InstanceIdentifier poolIdent; + + @Before + public void setUp() throws Exception { + when(dataBroker.registerDataChangeListener( + any(LogicalDatastoreType.class), + any(InstanceIdentifier.class), + any(DataChangeListener.class), + any(DataChangeScope.class))) + .thenReturn(dataChangeListenerRegistration); + dataChangeEvent = new MockDataChangedEvent(); + imgr = new InterfaceManager(dataBroker, idManager) { + protected void asyncWrite(LogicalDatastoreType datastoreType, + InstanceIdentifier path, T data, FutureCallback callback) { + /* + * Do nothing for now. Ideally we should capture this information + * and use it to verify results. + */ + written.put(path, data); + } + protected void asyncUpdate(LogicalDatastoreType datastoreType, + InstanceIdentifier path, T data, FutureCallback callback) { + updated.put(path, data); + } + + protected void asyncRemove(LogicalDatastoreType datastoreType, + InstanceIdentifier path, FutureCallback callback) { + removed.add(path); + } + + }; + setupMocks(); + } + + private void setupMocks() { + ncId = new NodeConnectorId("openflow:10:111"); + nc = buildNodeConnector(ncId); + interf = buildInterface(ifName, "Test Interface1", true, L2vlan.class, ncId); + ifIdent = IfmUtil.buildId(ifName); + ncIdent = getNcIdent("openflow:10",ncId); + ifsIdent = IfmUtil.buildStateInterfaceId(interf.getName()); + stateIface = buildStateInterface(ifName); + poolIdent = IfmUtil.getPoolId("interfaces"); + + // Setup mocks + when(dataBroker.newReadOnlyTransaction()).thenReturn(mockReadTx); + when(dataBroker.newWriteOnlyTransaction()).thenReturn(mockWriteTx); + } + + @Test + public void testAdd() { + Optional expected = Optional.of(interf); + Optional expectedNc = Optional.of(nc); + doReturn(Futures.immediateCheckedFuture(expected)).when(mockReadTx).read( + LogicalDatastoreType.CONFIGURATION, ifIdent); + doReturn(Futures.immediateCheckedFuture(expectedNc)).when(mockReadTx).read( + LogicalDatastoreType.OPERATIONAL, ncIdent); + doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read( + LogicalDatastoreType.OPERATIONAL, ifsIdent); + doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read( + LogicalDatastoreType.OPERATIONAL, poolIdent); + + dataChangeEvent.created.put(IfmUtil.buildId(ifName), interf); + imgr.onDataChanged(dataChangeEvent); + //Add some verifications + assertEquals(1,written.size()); + assertEquals(0,updated.size()); + assertEquals(0, removed.size()); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface writtenIface = + (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface)written.get(ifsIdent); + assertEquals(stateIface.getKey(), writtenIface.getKey()); + assertEquals(65536, writtenIface.getIfIndex().intValue()); + assertEquals(OperStatus.Up, writtenIface.getOperStatus()); + } + + @Test + public void testUpdate() { + Optional expected = Optional.of(interf); + Optional expectedNc = Optional.of(nc); + Optional expectedStateIf = Optional.of(stateIface); + doReturn(Futures.immediateCheckedFuture(expected)).when(mockReadTx).read( + LogicalDatastoreType.CONFIGURATION, ifIdent); + doReturn(Futures.immediateCheckedFuture(expectedNc)).when(mockReadTx).read( + LogicalDatastoreType.OPERATIONAL, ncIdent); + doReturn(Futures.immediateCheckedFuture(expectedStateIf)).when(mockReadTx).read( + LogicalDatastoreType.OPERATIONAL, ifsIdent); + doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockReadTx).read( + LogicalDatastoreType.OPERATIONAL, poolIdent); + dataChangeEvent.original.put(IfmUtil.buildId(ifName), interf); + dataChangeEvent.updated.put(IfmUtil.buildId(ifName), interf); + imgr.onDataChanged(dataChangeEvent); + //Add some verifications + + assertEquals(0,written.size()); + assertEquals(1,updated.size()); + assertEquals(0, removed.size()); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface updatedIface = + (org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface)updated.get(ifsIdent); + assertNotEquals(stateIface.getKey(),updatedIface.getKey()); + assertNull(updatedIface.getIfIndex()); + assertEquals(OperStatus.Up, updatedIface.getOperStatus()); + } + + private org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface buildStateInterface( + String ifName) { + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder ifaceBuilder = + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder(); + ifaceBuilder.setKey(IfmUtil.getStateInterfaceKeyFromName(ifName)); + return ifaceBuilder.build(); + } + + private InstanceIdentifier getNcIdent(String nodeKey, NodeConnectorId ncId) { + return InstanceIdentifier.builder(Nodes.class) + .child(Node.class, new NodeKey(new NodeId(nodeKey))) + .child(NodeConnector.class, new NodeConnectorKey(ncId)) + .build(); + } + + private Interface buildInterface(String ifName, String desc, boolean enabled, Class ifType, NodeConnectorId ncId) { + InterfaceBuilder builder = new InterfaceBuilder().setKey(new InterfaceKey(ifName)).setName(ifName) + .setDescription(desc).setEnabled(enabled).setType(ifType); + + BaseIds baseId = new BaseIdsBuilder().setOfPortId(ncId).build(); + builder.addAugmentation(BaseIds.class, baseId); + return builder.build(); + } + + private NodeConnector buildNodeConnector(NodeConnectorId ncId) { + NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder() + .setId(ncId) + .setKey(new NodeConnectorKey(ncId)); + return ncBuilder.build(); + } + +} diff --git a/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/MockDataChangedEvent.java b/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/MockDataChangedEvent.java new file mode 100644 index 00000000..3c95c901 --- /dev/null +++ b/interfacemgr/interfacemgr-impl/src/test/java/org/opendaylight/vpnservice/interfacemgr/test/MockDataChangedEvent.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.vpnservice.interfacemgr.test; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +class MockDataChangedEvent implements AsyncDataChangeEvent, DataObject> { + Map,DataObject> created = new HashMap<>(); + Map,DataObject> updated = new HashMap<>(); + Map,DataObject> original = new HashMap<>(); + Set> removed = new HashSet<>(); + + @Override + public Map, DataObject> getCreatedData() { + return created; + } + + @Override + public Map, DataObject> getUpdatedData() { + return updated; + } + + @Override + public Set> getRemovedPaths() { + return removed; + } + + @Override + public Map, DataObject> getOriginalData() { + return original; + } + + @Override + public DataObject getOriginalSubtree() { + throw new UnsupportedOperationException("Not implemented by mock"); + } + + @Override + public DataObject getUpdatedSubtree() { + throw new UnsupportedOperationException("Not implemented by mock"); + } +} -- 2.36.6