add some tests for LinkStorageImpl
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java
index d62d65b..ef61611 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java
@@ -5,8 +5,6 @@
import net.floodlightcontroller.core.INetMapTopologyObjects.IPortObject;
import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.core.INetMapTopologyService.ITopoSwitchService;
-import net.floodlightcontroller.core.internal.TopoSwitchServiceImpl;
import net.floodlightcontroller.linkdiscovery.ILinkStorage;
import net.floodlightcontroller.linkdiscovery.LinkInfo;
import net.floodlightcontroller.routing.Link;
@@ -84,10 +82,12 @@
}
if (currLinks.contains(vportDst)) {
- // TODO: update linkinfo
if (op.equals(DM_OPERATION.INSERT) || op.equals(DM_OPERATION.CREATE)) {
log.debug("addOrUpdateLink(): failed link exists {} {} src {} dst {}",
new Object[]{op, lt, vportSrc, vportDst});
+ } else if (op.equals(DM_OPERATION.UPDATE)) {
+ // TODO: update linkinfo
+ // GraphDB seems to have no KeyIndex for LinkInfo data
}
} else {
vportSrc.setLinkPort(vportDst);
@@ -166,24 +166,34 @@
}
}
- // TODO: Fix me
@Override
public List<Link> getLinks(Long dpid, short port) {
GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
- IPortObject vportSrc, vportDst;
- List<Link> links = null;
- Link lt;
+ IPortObject vportSrc;
+
+ List<Link> links = new ArrayList<Link>();
vportSrc = conn.utils().searchPort(conn, HexString.toHexString(dpid), port);
if (vportSrc != null) {
-
- for (Edge e : vportSrc.asVertex().getEdges(Direction.OUT)) {
- if (e.getLabel().equals("link")) {
- break;
- }
- }
+
+ for (Edge e : vportSrc.asVertex().getEdges(Direction.IN)) {
+ if(e.getLabel().equals("link")) {
+ Vertex v = e.getVertex(Direction.OUT);
+ short dst_port = v.getProperty("number");
+ for(Edge e2 : v.getEdges(Direction.IN)) {
+ if(e2.getLabel().equals("on")) {
+ Vertex v2 = e2.getVertex(Direction.OUT);
+ long dst_dpid = HexString.toLong((String) v2.getProperty("dpid"));
+
+ Link lt = new Link(dpid, port, dst_dpid, dst_port);
+ links.add(lt);
+ }
+ }
+ }
+ }
}
- return null;
+
+ return links;
}
@Override
@@ -196,14 +206,28 @@
@Override
public void deleteLinksOnPort(Long dpid, short port) {
- // TODO Auto-generated method stub
+ List<Link> linksToDelete = getLinks(dpid,port);
+ for(Link l : linksToDelete) {
+ deleteLink(l);
+ }
}
@Override
public List<Link> getLinks(String dpid) {
- // TODO Auto-generated method stub
- return null;
+ GraphDBConnection conn = GraphDBConnection.getInstance(this.conf);
+ ISwitchObject vswitch;
+ List<Link> links = new ArrayList<Link>();
+
+ vswitch = conn.utils().searchSwitch(conn, dpid);
+
+ for(IPortObject vportSrc : vswitch.getPorts()) {
+ // TODO array concatenation may be heavy
+ List<Link> sublinks = getLinks(HexString.toLong(dpid), vportSrc.getNumber());
+ links.addAll(sublinks);
+ }
+
+ return links;
}
public List<Link> getActiveLinks() {
diff --git a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
index 3cd7bd1..431db71 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
@@ -5,18 +5,25 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
import java.util.Set;
import junit.framework.Assert;
+import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
+
import org.apache.commons.io.FileUtils;
import com.thinkaurelius.titan.core.TitanFactory;
import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.util.io.graphml.GraphMLReader;
+import com.tinkerpop.frames.FramedGraph;
public class TestDatabaseManager {
private static final String testDbLocation = "/tmp/onos-testdb";
@@ -63,6 +70,15 @@
port.setProperty("number", portNum.shortValue());
}
}
+
+ FramedGraph<TitanGraph> fg = new FramedGraph<TitanGraph>(titanGraph);
+ Iterable<ISwitchObject> switches = fg.getVertices("type","switch",ISwitchObject.class);
+ List<ISwitchObject> activeSwitches = new ArrayList<ISwitchObject>();
+
+ for (ISwitchObject sw: switches) {
+ sw.setState(SwitchState.ACTIVE.toString());
+ }
+
titanGraph.stopTransaction(Conclusion.SUCCESS);
}
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
index 307447c..4c19d0a 100644
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
@@ -4,15 +4,15 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.floodlightcontroller.core.INetMapStorage.DM_OPERATION;
import net.floodlightcontroller.core.internal.TestDatabaseManager;
import net.floodlightcontroller.linkdiscovery.ILinkStorage;
+import net.floodlightcontroller.linkdiscovery.LinkInfo;
import net.floodlightcontroller.routing.Link;
-import net.onrc.onos.util.GraphDBConnection;
-import net.onrc.onos.util.IDBUtils;
import org.easymock.EasyMock;
import org.junit.After;
@@ -20,6 +20,7 @@
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.openflow.util.HexString;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@@ -43,108 +44,379 @@
@Before
public void setUp() throws Exception{
+ TestDatabaseManager.deleteTestDatabase();
+
titanGraph = TestDatabaseManager.getTestDatabase();
TestDatabaseManager.populateTestData(titanGraph);
- linkStorage = new LinkStorageImpl();
-
- // replace TitanFactory.open() to mock method
+ // replace TitanFactory.open() return value to dummy DB
PowerMock.mockStatic(TitanFactory.class);
EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
PowerMock.replay(TitanFactory.class);
+ linkStorage = new LinkStorageImpl();
+
+ // initialize with dummy string
linkStorage.init("/dummy/path/to/db");
}
@After
- public void tearDown() throws Exception {
-// dbConnection.close();
+ public void tearDown() throws Exception {
+ // finish code
+ linkStorage.close();
+
titanGraph.shutdown();
TestDatabaseManager.deleteTestDatabase();
}
+ // TODO: remove @Ignore after UPDATE method will be implemented
+ @Ignore @Test
+ public void testUpdate_UpdateSingleLink() {
+ Link linkToUpdate= createExistingLink();
+ LinkInfo infoToUpdate = new LinkInfo(
+ System.currentTimeMillis(),
+ System.currentTimeMillis(),
+ System.currentTimeMillis(),
+ 0, 0);
+
+ linkStorage.update(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
+
+ // TODO: get LinkInfo from titanGraph and verify
+ }
+
+ @Test
+ public void testUpdate_CreateSingleLink() {
+ Link linkToCreate = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
+
+ //Use the link storage API to add the link
+ linkStorage.update(linkToCreate, ILinkStorage.DM_OPERATION.CREATE);
+ doTestLinkIsInGraph(linkToVerify);
+
+ // Add same link
+ Link linkToCreateTwice = createFeasibleLink();
+ linkStorage.update(linkToCreateTwice, ILinkStorage.DM_OPERATION.CREATE);
+
+ // this occurs assertion failure if there are two links in titanGraph
+ doTestLinkIsInGraph(linkToVerify);
+ }
+
/*
* Add a link between port 1.102 and 2.104
* i.e SEA switch port 3 to LAX switch port 1
*/
@Test
- public void testAddSingleLink(){
- Link linkToAdd = new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a02"), 1);
+ public void testUpdate_InsertSingleLink(){
+ Link linkToInsert = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
//Use the link storage API to add the link
- linkStorage.update(linkToAdd, ILinkStorage.DM_OPERATION.INSERT);
+ linkStorage.update(linkToInsert, ILinkStorage.DM_OPERATION.INSERT);
+
+ doTestLinkIsInGraph(linkToVerify);
- //Test if it was added correctly with the Gremlin API
- GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
- Iterator<Vertex> it = titanGraph.getVertices("dpid", "00:00:00:00:00:00:0a:01").iterator();
-
- assertTrue(it.hasNext());
- Vertex sw1 = it.next();
- assertFalse(it.hasNext());
-
- pipe.start(sw1).out("on").has("number", (short)3).out("link").in("on");
-
- assertTrue(pipe.hasNext());
- Vertex sw2 = pipe.next();
- assertFalse(pipe.hasNext());
-
- //Check we ended up at the right vertex
- assertEquals((String)sw2.getProperty("dpid"), "00:00:00:00:00:00:0a:02");
+ // Add same link
+ Link linkToInsertTwice = createFeasibleLink();
+ linkStorage.update(linkToInsertTwice, ILinkStorage.DM_OPERATION.INSERT);
+
+ // this occurs assertion failure if there are two links in titanGraph
+ doTestLinkIsInGraph(linkToVerify);
}
- //TODO enable once method is written
+ @Test
+ public void testUpdate_DeleteSingleLink(){
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ // Test deletion of existing link
+ linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
+ doTestLinkIsNotInGraph(linkToVerify);
+
+ linkToDelete = createFeasibleLink();
+ linkToVerify = createFeasibleLink();
+
+ // Test deletion of not-existing link
+ linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
+ doTestLinkIsNotInGraph(linkToVerify);
+ }
+
+ // TODO: remove @Ignore after UPDATE method will be implemented
@Ignore @Test
+ public void testUpdate_UpdateLinks(){
+ List<Link> linksToUpdate= createExistingLinks();
+
+ // Who calls this method like this way?
+ linkStorage.update(linksToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
+
+ // TODO: verification of update result
+ }
+
+ @Test
+ public void testUpdate_CreateLinks(){
+ List<Link> linksToCreate = createFeasibleLinks();
+ List<Link> linksToVerify = createFeasibleLinks();
+
+ // Test creation of new links
+ linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
+ for(Link l : linksToVerify) {
+ doTestLinkIsInGraph(l);
+ }
+
+ // Test creation of existing links
+ linksToCreate = createFeasibleLinks();
+ linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
+ for(Link l : linksToVerify) {
+ doTestLinkIsInGraph(l);
+ }
+ }
+
+ @Test
+ public void testUpdate_CreateLinksMixuture(){
+ List<Link> linksToCreate = new ArrayList<Link>();
+ linksToCreate.add(createFeasibleLink());
+ linksToCreate.add(createExistingLink());
+
+ // Test creation of mixture of new/existing links
+ linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
+ doTestLinkIsInGraph(createFeasibleLink());
+ doTestLinkIsInGraph(createExistingLink());
+ }
+
+ @Test
+ public void testUpdate_InsertLinks(){
+ List<Link> linksToInsert = createFeasibleLinks();
+ List<Link> linksToVerify = createFeasibleLinks();
+
+ // Test insertion of new links
+ linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
+ for(Link l : linksToVerify) {
+ doTestLinkIsInGraph(l);
+ }
+
+ // Test insertion of existing links
+ linksToInsert = createFeasibleLinks();
+ linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
+ for(Link l : linksToVerify) {
+ doTestLinkIsInGraph(l);
+ }
+ }
+
+ @Test
+ public void testUpdate_InsertLinksMixuture(){
+ List<Link> linksToInsert = new ArrayList<Link>();
+ linksToInsert.add(createFeasibleLink());
+ linksToInsert.add(createExistingLink());
+
+ // Test insertion of mixture of new/existing links
+ linkStorage.update(linksToInsert, ILinkStorage.DM_OPERATION.INSERT);
+ doTestLinkIsInGraph(createFeasibleLink());
+ doTestLinkIsInGraph(createExistingLink());
+ }
+
+
+ @Test
+ public void testUpdate_DeleteLinks(){
+ List<Link> linksToDelete = createExistingLinks();
+ List<Link> linksToVerify = createExistingLinks();
+
+ // Test deletion of existing links
+ linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
+ for(Link l : linksToVerify) {
+ doTestLinkIsNotInGraph(l);
+ }
+
+ // Test deletion of not-existing links
+ linksToDelete = createExistingLinks();
+ linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
+ for(Link l : linksToVerify) {
+ doTestLinkIsNotInGraph(l);
+ }
+ }
+
+ @Test
+ public void testUpdate_DeleteLinksMixuture(){
+ List<Link> linksToDelete = new ArrayList<Link>();
+ linksToDelete.add(createFeasibleLink());
+ linksToDelete.add(createExistingLink());
+
+ // Test deletion of mixture of new/existing links
+ linkStorage.update(linksToDelete, ILinkStorage.DM_OPERATION.DELETE);
+ doTestLinkIsNotInGraph(createFeasibleLink());
+ doTestLinkIsNotInGraph(createExistingLink());
+ }
+
+ @Test
+ public void testAddOrUpdateLink() {
+ Link linkToDelete = createExistingLink();
+
+ }
+
+ @Test
+ public void testUpdateInsertMultipleLinks() {
+ List<Link> linksToAdd = createFeasibleLinks();
+ List<Link> linksToVerify = createFeasibleLinks();
+
+ linkStorage.update(linksToAdd, ILinkStorage.DM_OPERATION.INSERT);
+
+ for(Link l : linksToVerify) {
+ doTestLinkIsInGraph(l);
+ }
+ }
+
+ @Test
public void testGetLinks(){
- //TODO Make sure this works when the implementation is written
- List<Link> list = linkStorage.getLinks(Long.decode("0x0000000000000a01"), (short)2);
+ Link linkToVerify = createExistingLink();
+
+ List<Link> list = linkStorage.getLinks(linkToVerify.getSrc(), (short)linkToVerify.getSrcPort());
assertEquals(list.size(), 1);
Link l = list.get(0);
- assertEquals(l.getSrc(), 2561L);
- assertEquals(l.getSrcPort(), (short)2);
- assertEquals(l.getDst(), 2563L);
- assertEquals(l.getDstPort(), (short)1);
+ assertEquals(l.getSrc(), linkToVerify.getSrc());
+ assertEquals(l.getSrcPort(), linkToVerify.getSrcPort());
+ assertEquals(l.getDst(), linkToVerify.getDst());
+ assertEquals(l.getDstPort(), linkToVerify.getDstPort());
+
+ Link linkToVerifyNot = createFeasibleLink();
+
+ List<Link> list2 = linkStorage.getLinks(linkToVerifyNot.getSrc(), (short)linkToVerifyNot.getSrcPort());
+
+ assertEquals(list2.size(), 0);
}
- //TODO enable once method is written
- @Ignore @Test
- public void testUpdateDelete(){
- Link linkToDelete = new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a03"), 1);
+ @Test
+ public void testGetLinksByDpid() {
+ Link linkToVeryfy = createExistingLink();
- linkStorage.update(linkToDelete, DM_OPERATION.DELETE);
-
- //Test if it was deleted correctly with the Gremlin API
- GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
- Iterator<Vertex> it = titanGraph.getVertices("dpid", "00:00:00:00:00:00:0a:01").iterator();
-
- assertTrue(it.hasNext());
- Vertex sw1 = it.next();
- assertFalse(it.hasNext());
-
- pipe.start(sw1).out("on").has("number", 2).out("link");
-
- assertFalse(pipe.hasNext());
+ List<Link> links = linkStorage.getLinks(HexString.toHexString(linkToVeryfy.getSrc()));
+ assertTrue(links.contains(linkToVeryfy));
+
+ Link linkToVerifyNot = createFeasibleLink();
+ assertFalse(links.contains(linkToVerifyNot));
}
- //TODO enable once method is written
- @Ignore @Test
+ @Test
+ public void testDeleteLink() {
+ // Deletion of existing link
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ linkStorage.deleteLink(linkToDelete);
+ doTestLinkIsNotInGraph(linkToVerify);
+
+ // Deletion of not existing link
+ linkToDelete = createFeasibleLink();
+ linkToVerify = createFeasibleLink();
+
+ linkStorage.deleteLink(linkToDelete);
+ doTestLinkIsNotInGraph(linkToVerify);
+ }
+
+ @Test
public void testDeleteLinks(){
- //TODO Make sure this works when the implementation is written
+ List<Link> linksToDelete = createExistingLinks();
+ List<Link> linksToVerify = createExistingLinks();
- linkStorage.deleteLinksOnPort(Long.decode("0x0000000000000a01"), (short)2);
+ linkStorage.deleteLinks(linksToDelete);
+ for(Link l : linksToVerify) {
+ doTestLinkIsNotInGraph(l);
+ }
+ }
+
+ @Test
+ public void testGetActiveLinks() {
+ Link existingLink = createExistingLink();
+ Link notExistingLink = createFeasibleLink();
+
+ List<Link> links = linkStorage.getActiveLinks();
- //Test if it was deleted correctly with the Gremlin API
+ assertTrue(links.contains(existingLink));
+ assertFalse(links.contains(notExistingLink));
+ }
+
+ @Test
+ public void testDeleteLinksOnPort() {
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ linkStorage.deleteLinksOnPort(linkToDelete.getSrc(), linkToDelete.getSrcPort());
+
+ doTestLinkIsNotInGraph(linkToVerify);
+ }
+
+ /**
+ * Test if titanGraph has specific link (no more than one link)
+ * @param link
+ */
+ private void doTestLinkIsInGraph(Link link) {
+ String src_dpid = HexString.toHexString(link.getSrc());
+ String dst_dpid = HexString.toHexString(link.getDst());
+ short src_port = link.getSrcPort();
+ short dst_port = link.getDstPort();
+
GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
- Iterator<Vertex> it = titanGraph.getVertices("dpid", "00:00:00:00:00:00:0a:01").iterator();
+ Iterator<Vertex> it = titanGraph.getVertices("dpid", src_dpid).iterator();
assertTrue(it.hasNext());
- Vertex sw1 = it.next();
+ Vertex sw = it.next();
assertFalse(it.hasNext());
- pipe.start(sw1).out("on").has("number", 2).out("link");
+ pipe.start(sw).out("on").has("number", src_port).out("link").has("number", dst_port).in("on").has("dpid", dst_dpid);
+ assertTrue(pipe.hasNext());
+ pipe.next();
assertFalse(pipe.hasNext());
}
+ /**
+ * Test if titanGraph doesn't have specific link
+ * @param link
+ */
+ private void doTestLinkIsNotInGraph(Link link) {
+ String src_dpid = HexString.toHexString(link.getSrc());
+ String dst_dpid = HexString.toHexString(link.getDst());
+ short src_port = link.getSrcPort();
+ short dst_port = link.getDstPort();
+
+ GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
+ Iterator<Vertex> it = titanGraph.getVertices("dpid", src_dpid).iterator();
+
+ assertTrue(it.hasNext());
+ Vertex sw = it.next();
+ assertFalse(it.hasNext());
+
+ pipe.start(sw).out("on").has("number", src_port).out("link").has("number", dst_port).in("on").has("dpid", dst_dpid);
+
+ assertFalse(pipe.hasNext());
+ }
+
+ //----------------- Creation of test data -----------------------
+ private Link createExistingLink() {
+ return new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a03"), 1);
+ }
+
+ private Link createFeasibleLink() {
+ return new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a02"), 1);
+ }
+
+ // make NO sense while test-network data doesn't define physical network
+ @SuppressWarnings("unused")
+ private Link createInfeasibleLink() {
+ return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1);
+ }
+
+ private List<Link> createExistingLinks() {
+ List<Link> links = new ArrayList<Link>();
+ links.add(new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a03"), 1));
+ links.add(new Link(Long.decode("0x0000000000000a02"), 1, Long.decode("0x0000000000000a01"), 3));
+ return links;
+ }
+
+ private List<Link> createFeasibleLinks() {
+ List<Link> links = new ArrayList<Link>();
+ links.add(new Link(Long.decode("0x0000000000000a03"), 4, Long.decode("0x0000000000000a05"), 3));
+ links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a02"), 1));
+ return links;
+ }
+ //---------------------------------------------------------------
}