/* * Copyright (c) 2014 Brocade Communications Systems, Inc. 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.openflowplugin.applications.topology.manager; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newDestTp; import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newInvNodeConnKey; import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newInvNodeKey; import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newLink; import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newNodeConnID; import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newSourceTp; import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.setupStubbedSubmit; import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.waitForSubmit; import com.google.common.base.Optional; import com.google.common.util.concurrent.Futures; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkDiscoveredBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.LinkRemovedBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.LinkId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class FlowCapableTopologyExporterTest { private OperationProcessor processor; private FlowCapableTopologyExporter exporter; private InstanceIdentifier<Topology> topologyIID; private final ExecutorService executor = Executors.newFixedThreadPool(1); @Mock private DataBroker mockDataBroker; @Mock private BindingTransactionChain mockTxChain; @Before public void setUp() { MockitoAnnotations.initMocks(this); doReturn(mockTxChain).when(mockDataBroker) .createTransactionChain(any(TransactionChainListener.class)); processor = new OperationProcessor(mockDataBroker); topologyIID = InstanceIdentifier.create(NetworkTopology.class) .child(Topology.class, new TopologyKey(new TopologyId("flow:1"))); exporter = new FlowCapableTopologyExporter(processor, topologyIID); executor.execute(processor); } @After public void tearDown() { executor.shutdownNow(); } @Test public void testOnLinkDiscovered() { org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey sourceNodeKey = newInvNodeKey("sourceNode"); org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey sourceNodeConnKey = newInvNodeConnKey("sourceTP"); InstanceIdentifier<?> sourceConnID = newNodeConnID(sourceNodeKey, sourceNodeConnKey); org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey destNodeKey = newInvNodeKey("destNode"); org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey destNodeConnKey = newInvNodeConnKey("destTP"); InstanceIdentifier<?> destConnID = newNodeConnID(destNodeKey, destNodeConnKey); ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class); CountDownLatch submitLatch = setupStubbedSubmit(mockTx); doReturn(mockTx).when(mockTxChain).newReadWriteTransaction(); exporter.onLinkDiscovered(new LinkDiscoveredBuilder().setSource( new NodeConnectorRef(sourceConnID)).setDestination( new NodeConnectorRef(destConnID)).build()); waitForSubmit(submitLatch); ArgumentCaptor<Link> mergedNode = ArgumentCaptor.forClass(Link.class); verify(mockTx).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(topologyIID.child( Link.class, new LinkKey(new LinkId(sourceNodeConnKey.getId())))), mergedNode.capture(), eq(true)); assertEquals("Source node ID", "sourceNode", mergedNode.getValue().getSource().getSourceNode().getValue()); assertEquals("Dest TP ID", "sourceTP", mergedNode.getValue().getSource().getSourceTp().getValue()); assertEquals("Dest node ID", "destNode", mergedNode.getValue().getDestination().getDestNode().getValue()); assertEquals("Dest TP ID", "destTP", mergedNode.getValue().getDestination().getDestTp().getValue()); } @Test public void testOnLinkRemoved() { org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey sourceNodeKey = newInvNodeKey("sourceNode"); org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey sourceNodeConnKey = newInvNodeConnKey("sourceTP"); InstanceIdentifier<?> sourceConnID = newNodeConnID(sourceNodeKey, sourceNodeConnKey); org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey destNodeKey = newInvNodeKey("destNode"); org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey destNodeConnKey = newInvNodeConnKey("destTP"); InstanceIdentifier<?> destConnID = newNodeConnID(destNodeKey, destNodeConnKey); Link link = newLink(sourceNodeConnKey.getId().getValue(), newSourceTp(sourceNodeConnKey.getId().getValue()), newDestTp(destNodeConnKey.getId().getValue())); ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class); CountDownLatch submitLatch = setupStubbedSubmit(mockTx); doReturn(mockTx).when(mockTxChain).newReadWriteTransaction(); doReturn(Futures.immediateCheckedFuture(Optional.of(link))).when(mockTx).read(LogicalDatastoreType.OPERATIONAL, topologyIID.child( Link.class, new LinkKey(new LinkId(sourceNodeConnKey.getId())))); exporter.onLinkRemoved(new LinkRemovedBuilder().setSource( new NodeConnectorRef(sourceConnID)).setDestination( new NodeConnectorRef(destConnID)).build()); waitForSubmit(submitLatch); verify(mockTx).delete(LogicalDatastoreType.OPERATIONAL, topologyIID.child( Link.class, new LinkKey(new LinkId(sourceNodeConnKey.getId())))); } @Test public void testOnLinkRemovedLinkDoesNotExist() { org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey sourceNodeKey = newInvNodeKey("sourceNode"); org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey sourceNodeConnKey = newInvNodeConnKey("sourceTP"); InstanceIdentifier<?> sourceConnID = newNodeConnID(sourceNodeKey, sourceNodeConnKey); org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey destNodeKey = newInvNodeKey("destNode"); org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey destNodeConnKey = newInvNodeConnKey("destTP"); InstanceIdentifier<?> destConnID = newNodeConnID(destNodeKey, destNodeConnKey); ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class); CountDownLatch submitLatch = setupStubbedSubmit(mockTx); doReturn(mockTx).when(mockTxChain).newReadWriteTransaction(); doReturn(Futures.immediateCheckedFuture(Optional.<Link>absent())).when(mockTx).read(LogicalDatastoreType.OPERATIONAL, topologyIID.child( Link.class, new LinkKey(new LinkId(sourceNodeConnKey.getId())))); exporter.onLinkRemoved(new LinkRemovedBuilder().setSource( new NodeConnectorRef(sourceConnID)).setDestination( new NodeConnectorRef(destConnID)).build()); waitForSubmit(submitLatch); verify(mockTx, never()).delete(LogicalDatastoreType.OPERATIONAL, topologyIID.child( Link.class, new LinkKey(new LinkId(sourceNodeConnKey.getId())))); } }