Merge branch 'master' of https://github.com/OPENNETWORKINGLAB/ONOS
Conflicts:
src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
index 839d3e7..6628bcc 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImpl.java
@@ -28,11 +28,21 @@
protected static Logger log = LoggerFactory.getLogger(LinkStorageImpl.class);
protected GraphDBOperation dbop;
+ /**
+ * Update a record in the LinkStorage in a way provided by op.
+ * @param link Record of a link to be updated.
+ * @param op Operation to be done.
+ */
@Override
public void update(Link link, DM_OPERATION op) {
update(link, (LinkInfo)null, op);
}
+ /**
+ * Update multiple records in the LinkStorage in a way provided by op.
+ * @param links List of records to be updated.
+ * @param op Operation to be done.
+ */
@Override
public void update(List<Link> links, DM_OPERATION op) {
for (Link lt: links) {
@@ -40,6 +50,12 @@
}
}
+ /**
+ * Update a record of link with meta-information in the LinkStorage in a way provided by op.
+ * @param link Record of a link to update.
+ * @param linkinfo Meta-information of a link to be updated.
+ * @param op Operation to be done.
+ */
@Override
public void update(Link link, LinkInfo linkinfo, DM_OPERATION op) {
switch (op) {
@@ -54,6 +70,12 @@
}
}
+ /**
+ * Perform INSERT/CREATE/UPDATE operation to update the LinkStorage.
+ * @param lt Record of a link to be updated.
+ * @param linkinfo Meta-information of a link to be updated.
+ * @param op Operation to be done. (only INSERT/CREATE/UPDATE is acceptable)
+ */
public void updateLink(Link lt, LinkInfo linkinfo, DM_OPERATION op) {
IPortObject vportSrc = null, vportDst = null;
@@ -71,7 +93,6 @@
vportDst = dbop.searchPort(dpid, port);
if (vportSrc != null && vportDst != null) {
-
// check if the link exists
Iterable<IPortObject> currPorts = vportSrc.getLinkedPorts();
@@ -79,7 +100,7 @@
for (IPortObject V : currPorts) {
currLinks.add(V);
}
-
+
if (currLinks.contains(vportDst)) {
// TODO: update linkinfo
if (op.equals(DM_OPERATION.INSERT) || op.equals(DM_OPERATION.CREATE)) {
@@ -105,6 +126,10 @@
}
}
+ /**
+ * Delete multiple records in the LinkStorage.
+ * @param links List of records to be deleted.
+ */
@Override
public void deleteLinks(List<Link> links) {
@@ -113,7 +138,10 @@
}
}
-
+ /**
+ * Delete a record in the LinkStorage.
+ * @param link Record to be deleted.
+ */
@Override
public void deleteLink(Link lt) {
IPortObject vportSrc = null, vportDst = null;
@@ -163,43 +191,64 @@
}
}
+ /**
+ * Get list of all links connected to the port specified by given DPID and port number.
+ * @param dpid DPID of desired port.
+ * @param port Port number of desired port.
+ * @return List of links. Empty list if no port was found.
+ */
// TODO: Fix me
@Override
public List<Link> getLinks(Long dpid, short port) {
- IPortObject vportSrc, vportDst;
List<Link> links = null;
- Link lt;
-
- vportSrc = dbop.searchPort(HexString.toHexString(dpid), port);
- if (vportSrc != null) {
-
- for (Edge e : vportSrc.asVertex().getEdges(Direction.OUT)) {
- if (e.getLabel().equals("link")) {
- break;
- }
- }
- }
- return null;
+ return links;
}
+ /**
+ * Initialize the object. Open LinkStorage using given configuration file.
+ * @param conf Path (absolute path for now) to configuration file.
+ */
@Override
public void init(String conf) {
//TODO extract the DB location from properties
this.dbop = new GraphDBOperation(GraphDBConnection.getInstance(conf));
}
+ /**
+ * Delete records of the links connected to the port specified by given DPID and port number.
+ * @param dpid DPID of desired port.
+ * @param port Port number of desired port.
+ */
+ // TODO: Fix me
@Override
public void deleteLinksOnPort(Long dpid, short port) {
- // TODO Auto-generated method stub
+ // BEGIN: Trial code
+ // author: Naoki Shiota
+ List<Link> linksToDelete = getLinks(dpid,port);
+ for(Link l : linksToDelete) {
+ deleteLink(l);
+ }
+ // END: Trial code
}
+ /**
+ * Get list of all links connected to the switch specified by given DPID.
+ * @param dpid DPID of desired switch.
+ * @return List of links. Empty list if no port was found.
+ */
+ // TODO: Fix me
@Override
public List<Link> getLinks(String dpid) {
- // TODO Auto-generated method stub
- return null;
+ List<Link> links = new ArrayList<Link>();
+
+ return links;
}
+ /**
+ * Get list of all links whose state is ACTIVE.
+ * @return List of active links. Empty list if no port was found.
+ */
public List<Link> getActiveLinks() {
Iterable<ISwitchObject> switches = dbop.getActiveSwitches();
@@ -247,10 +296,16 @@
}
}
+ /**
+ * Finalize the object.
+ */
public void finalize() {
close();
}
+ /**
+ * Close LinkStorage.
+ */
@Override
public void close() {
// TODO Auto-generated method stub
diff --git a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
new file mode 100644
index 0000000..3d5e03b
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
@@ -0,0 +1,76 @@
+package net.floodlightcontroller.core.internal;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.Set;
+
+import junit.framework.Assert;
+
+import org.apache.commons.io.FileUtils;
+
+import com.thinkaurelius.titan.core.TitanFactory;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.util.io.graphml.GraphMLReader;
+
+public class TestDatabaseManager {
+ private static final String testDbLocation = "/tmp/onos-testdb";
+
+ //private static final String testDbGraphML = "<?xml version=\"1.0\" ?><graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"> <key id=\"id\" for=\"node\" attr.name=\"id\" attr.type=\"string\"></key> <key id=\"type\" for=\"node\" attr.name=\"type\" attr.type=\"string\"></key> <key id=\"dpid\" for=\"node\" attr.name=\"dpid\" attr.type=\"string\"></key> <key id=\"desc\" for=\"node\" attr.name=\"desc\" attr.type=\"string\"></key> <key id=\"number\" for=\"node\" attr.name=\"number\" attr.type=\"int\"></key> <key id=\"dl_addr\" for=\"node\" attr.name=\"dl_addr\" attr.type=\"string\"></key> <key id=\"nw_addr\" for=\"node\" attr.name=\"nw_addr\" attr.type=\"string\"></key> <key id=\"id\" for=\"edge\" attr.name=\"id\" attr.type=\"string\"></key> <key id=\"source\" for=\"edge\" attr.name=\"source\" attr.type=\"string\"></key> <key id=\"target\" for=\"edge\" attr.name=\"target\" attr.type=\"string\"></key> <key id=\"label\" for=\"edge\" attr.name=\"label\" attr.type=\"string\"></key> <graph id=\"G\" edgedefault=\"directed\"> <node id=\"1\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:01</data> <data key=\"desc\">OpenFlow Switch at SEA</data> </node> <node id=\"2\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:02</data> <data key=\"desc\">OpenFlow Switch at LAX</data> </node> <node id=\"3\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:03</data> <data key=\"desc\">OpenFlow Switch at CHI</data> </node> <node id=\"4\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:04</data> <data key=\"desc\">OpenFlow Switch at IAH</data> </node> <node id=\"5\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:05</data> <data key=\"desc\">OpenFlow Switch at NYC</data> </node> <node id=\"6\"> <data key=\"type\">switch</data> <data key=\"dpid\">00:00:00:00:00:00:0a:06</data> <data key=\"desc\">OpenFlow Switch at ATL</data> </node> <node id=\"100\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at SEA Switch</data> </node> <node id=\"101\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at SEA Switch</data> </node> <node id=\"102\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at SEA Switch</data> </node> <node id=\"103\"> <data key=\"type\">port</data> <data key=\"number\">4</data> <data key=\"desc\">port 4 at SEA Switch</data> </node> <node id=\"104\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at LAX Switch</data> </node> <node id=\"105\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at LAX Switch</data> </node> <node id=\"106\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at LAX Switch</data> </node> <node id=\"107\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at CHI Switch</data> </node> <node id=\"108\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at CHI Switch</data> </node> <node id=\"109\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at CHI Switch</data> </node> <node id=\"110\"> <data key=\"type\">port</data> <data key=\"number\">4</data> <data key=\"desc\">port 4 at CHI Switch</data> </node> <node id=\"111\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at IAH Switch</data> </node> <node id=\"112\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at IAH Switch</data> </node> <node id=\"113\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at IAH Switch</data> </node> <node id=\"114\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at NYC Switch</data> </node> <node id=\"115\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at NYC Switch</data> </node> <node id=\"116\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at NYC Switch</data> </node> <node id=\"117\"> <data key=\"type\">port</data> <data key=\"number\">1</data> <data key=\"desc\">port 1 at ATL Switch</data> </node> <node id=\"118\"> <data key=\"type\">port</data> <data key=\"number\">2</data> <data key=\"desc\">port 2 at ATL Switch</data> </node> <node id=\"119\"> <data key=\"type\">port</data> <data key=\"number\">3</data> <data key=\"desc\">port 3 at ATL Switch</data> </node> <node id=\"1000\"> <data key=\"type\">device</data> <data key=\"dl_addr\">20:c9:d0:4a:e1:73</data> <data key=\"nw_addr\">192.168.10.101</data> </node> <node id=\"1001\"> <data key=\"type\">device</data> <data key=\"dl_addr\">20:c9:d0:4a:e1:62</data> <data key=\"nw_addr\">192.168.20.101</data> </node> <node id=\"1002\"> <data key=\"type\">device</data> <data key=\"dl_addr\">10:40:f3:e6:8d:55</data> <data key=\"nw_addr\">192.168.10.1</data> </node> <node id=\"1003\"> <data key=\"type\">device</data> <data key=\"dl_addr\">a0:b3:cc:9c:c6:88</data> <data key=\"nw_addr\">192.168.20.1</data> </node> <node id=\"1004\"> <data key=\"type\">device</data> <data key=\"dl_addr\">00:04:20:e2:50:a2</data> <data key=\"nw_addr\">192.168.30.1</data> </node> <node id=\"1005\"> <data key=\"type\">device</data> <data key=\"dl_addr\">58:55:ca:c4:1b:a0</data> <data key=\"nw_addr\">192.168.40.1</data> </node> <edge id=\"10000\" source=\"1\" target=\"101\" label=\"on\"></edge> <edge id=\"10001\" source=\"1\" target=\"102\" label=\"on\"></edge> <edge id=\"10002\" source=\"1\" target=\"103\" label=\"on\"></edge> <edge id=\"10003\" source=\"2\" target=\"104\" label=\"on\"></edge> <edge id=\"10004\" source=\"2\" target=\"105\" label=\"on\"></edge> <edge id=\"10005\" source=\"2\" target=\"106\" label=\"on\"></edge> <edge id=\"10006\" source=\"3\" target=\"107\" label=\"on\"></edge> <edge id=\"10007\" source=\"3\" target=\"108\" label=\"on\"></edge> <edge id=\"10008\" source=\"3\" target=\"109\" label=\"on\"></edge> <edge id=\"10009\" source=\"3\" target=\"110\" label=\"on\"></edge> <edge id=\"10010\" source=\"4\" target=\"111\" label=\"on\"></edge> <edge id=\"10011\" source=\"4\" target=\"112\" label=\"on\"></edge> <edge id=\"10012\" source=\"4\" target=\"113\" label=\"on\"></edge> <edge id=\"10013\" source=\"5\" target=\"114\" label=\"on\"></edge> <edge id=\"10014\" source=\"5\" target=\"115\" label=\"on\"></edge> <edge id=\"10015\" source=\"5\" target=\"116\" label=\"on\"></edge> <edge id=\"10016\" source=\"6\" target=\"117\" label=\"on\"></edge> <edge id=\"10017\" source=\"6\" target=\"118\" label=\"on\"></edge> <edge id=\"10018\" source=\"6\" target=\"119\" label=\"on\"></edge> <edge id=\"11000\" source=\"101\" target=\"107\" label=\"link\"></edge> <edge id=\"11003\" source=\"105\" target=\"111\" label=\"link\"></edge> <edge id=\"11004\" source=\"107\" target=\"101\" label=\"link\"></edge> <edge id=\"11005\" source=\"108\" target=\"112\" label=\"link\"></edge> <edge id=\"11006\" source=\"109\" target=\"114\" label=\"link\"></edge> <edge id=\"11007\" source=\"111\" target=\"105\" label=\"link\"></edge> <edge id=\"11008\" source=\"112\" target=\"108\" label=\"link\"></edge> <edge id=\"11009\" source=\"113\" target=\"117\" label=\"link\"></edge> <edge id=\"11010\" source=\"114\" target=\"109\" label=\"link\"></edge> <edge id=\"11011\" source=\"115\" target=\"118\" label=\"link\"></edge> <edge id=\"11012\" source=\"117\" target=\"113\" label=\"link\"></edge> <edge id=\"11013\" source=\"118\" target=\"115\" label=\"link\"></edge> <edge id=\"12000\" source=\"103\" target=\"1000\" label=\"host\"></edge> <edge id=\"12001\" source=\"103\" target=\"1001\" label=\"host\"></edge> <edge id=\"12002\" source=\"110\" target=\"1002\" label=\"host\"></edge> <edge id=\"12003\" source=\"116\" target=\"1003\" label=\"host\"></edge> <edge id=\"12004\" source=\"106\" target=\"1004\" label=\"host\"></edge> <edge id=\"12005\" source=\"119\" target=\"1005\" label=\"host\"></edge> </graph> </graphml>";
+
+ private static final String testDataLocation = "titan/schema/test-network.xml";
+
+ public static TitanGraph getTestDatabase(){
+ //return TitanFactory.open(testDbLocation);
+// return TitanFactory.openInMemoryGraph();
+ return TitanFactory.open(testDbLocation);
+ }
+
+ public static void populateTestData(TitanGraph titanGraph){
+ Set<String> s = titanGraph.getIndexedKeys(Vertex.class);
+ if (!s.contains("dpid")) {
+ titanGraph.createKeyIndex("dpid", Vertex.class);
+ titanGraph.stopTransaction(Conclusion.SUCCESS);
+ }
+ if (!s.contains("type")) {
+ titanGraph.createKeyIndex("type", Vertex.class);
+ titanGraph.stopTransaction(Conclusion.SUCCESS);
+ }
+
+ //InputStream graphMLStream = new ByteArrayInputStream(testDbGraphML.getBytes());
+
+ try {
+ InputStream graphMLStream = new FileInputStream(testDataLocation);
+ GraphMLReader.inputGraph(titanGraph, graphMLStream);
+ } catch (FileNotFoundException e) {
+ Assert.fail("Test data file not found: " + testDataLocation);
+ } catch (IOException e) {
+ e.printStackTrace();
+ Assert.fail("IOException thrown");
+ }
+
+ //Change the type of all port numbers to short in the database
+ Iterator<Vertex> it = titanGraph.getVertices("type", "port").iterator();
+ while (it.hasNext()){
+ Vertex port = it.next();
+ Integer portNum = (Integer) port.getProperty("number");
+ port.setProperty("number", portNum.shortValue());
+ }
+ titanGraph.stopTransaction(Conclusion.SUCCESS);
+ }
+
+ public static void deleteTestDatabase(){
+ try {
+ FileUtils.deleteDirectory(new File(testDbLocation));
+ } catch (IOException e) {
+ System.out.println("delete failed");
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
index b03af4e..29151c3 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
@@ -4,125 +4,631 @@
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.routing.Link;
import net.onrc.onos.ofcontroller.core.ILinkStorage;
import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
+import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
+import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openflow.protocol.OFPhysicalPort;
+import org.openflow.util.HexString;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import com.thinkaurelius.titan.core.TitanFactory;
import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Direction;
+import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.gremlin.java.GremlinPipeline;
+import com.tinkerpop.pipes.PipeFunction;
+import com.tinkerpop.pipes.transform.PathPipe;
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({TitanFactory.class})
public class LinkStorageImplTest {
private static ILinkStorage linkStorage;
private static TitanGraph titanGraph;
- //TODO Future ideas:
- //Test add links with CREATE and UPDATE
- //Test adding existing link again
-
+ //private static IController
+
+ /**
+ * Setup code called before each tests.
+ * Read test graph data and replace DB access by test graph data.
+ * @throws Exception
+ */
@Before
public void setUp() throws Exception{
+ TestDatabaseManager.deleteTestDatabase();
+
titanGraph = TestDatabaseManager.getTestDatabase();
TestDatabaseManager.populateTestData(titanGraph);
+
+ // replace return value of TitanFactory.open() to dummy DB created above
+ PowerMock.mockStatic(TitanFactory.class);
+ EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
+ PowerMock.replay(TitanFactory.class);
- linkStorage = new TestableLinkStorageImpl(titanGraph);
+ linkStorage = new LinkStorageImpl();
+
+ // initialize with dummy string
+ linkStorage.init("/dummy/path/to/db");
}
+ /**
+ * Closing code called after each tests.
+ * Discard test graph data.
+ * @throws Exception
+ */
@After
- public void tearDown() throws Exception {
+ public void tearDown() throws Exception {
+ // finish code
+ linkStorage.close();
+
titanGraph.shutdown();
+ TestDatabaseManager.deleteTestDatabase();
}
- /*
- * Add a link between port 1.102 and 2.104
- * i.e SEA switch port 3 to LAX switch port 1
+ // TODO: remove @Ignore after UPDATE method is implemented
+ /**
+ * Test if update() can correctly updates LinkInfo for a Link.
+ */
+ @Ignore @Test
+ public void testUpdate_UpdateSingleLink() {
+ Link linkToUpdate= createExistingLink();
+ long currentTime = System.currentTimeMillis();
+ LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
+ LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
+
+ linkStorage.update(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
+
+ doTestLinkHasStateOf(linkToUpdate, infoToVerify);
+ }
+
+ /**
+ * Test if update() can correctly creates a Link.
*/
@Test
- public void testAddSingleLink(){
- Link linkToAdd = new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a02"), 1);
+ public void testUpdate_CreateSingleLink() {
+ Link linkToCreate = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
//Use the link storage API to add the link
- linkStorage.update(linkToAdd, ILinkStorage.DM_OPERATION.INSERT);
+ linkStorage.update(linkToCreate, ILinkStorage.DM_OPERATION.CREATE);
+ doTestLinkIsInGraph(linkToVerify);
+
+ // Add same link
+ Link linkToCreateTwice = createFeasibleLink();
+ linkStorage.update(linkToCreateTwice, ILinkStorage.DM_OPERATION.CREATE);
- //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();
+ // this occurs assertion failure if there are two links in titanGraph
+ doTestLinkIsInGraph(linkToVerify);
+ }
+
+ /**
+ * Test if update() can correctly inserts a Link.
+ */
+ @Test
+ public void testUpdate_InsertSingleLink(){
+ Link linkToInsert = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
- assertTrue(it.hasNext());
- Vertex sw1 = it.next();
- assertFalse(it.hasNext());
+ //Use the link storage API to add the link
+ linkStorage.update(linkToInsert, ILinkStorage.DM_OPERATION.INSERT);
+
+ doTestLinkIsInGraph(linkToVerify);
- 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 if update() can correctly deletes a Link.
+ */
+ @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);
+ }
+
+ /**
+ * Test if update() can correctly creates multiple Links.
+ */
+ @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 if update() can handle mixture of normal/abnormal input for creation of Links.
+ */
+ @Test
+ public void testUpdate_CreateLinks_Mixuture(){
+ 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 if update() can correctly inserts multiple Links.
+ */
+ @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 if update() can handle mixture of normal/abnormal input for creation of Links.
+ */
+ @Test
+ public void testUpdate_InsertLinks_Mixuture(){
+ 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 if update() can correctly deletes multiple Links.
+ */
+ @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 if update() can handle mixture of normal/abnormal input for deletion of Links.
+ */
+ @Test
+ public void testUpdate_DeleteLinks_Mixuture(){
+ 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());
+ }
+
+ // TODO: remove @Ignore after UPDATE method is implemented
+ /**
+ * Test if updateLink() can correctly updates LinkInfo for a Link.
+ */
@Ignore @Test
- public void testGetLinks(){
- //TODO Make sure this works when the implementation is written
- List<Link> list = linkStorage.getLinks(Long.decode("0x0000000000000a01"), (short)2);
+ public void testUpdateLink_Update() {
+ Link linkToUpdate= createExistingLink();
+ long currentTime = System.currentTimeMillis();
+ LinkInfo infoToUpdate = createFeasibleLinkInfo(currentTime);
+ LinkInfo infoToVerify = createFeasibleLinkInfo(currentTime);
+
+ linkStorage.updateLink(linkToUpdate, infoToUpdate, ILinkStorage.DM_OPERATION.UPDATE);
+
+ doTestLinkHasStateOf(linkToUpdate, infoToVerify);
+ }
+
+ /**
+ * Test if updateLink() can correctly creates a Link.
+ */
+ @Test
+ public void testUpdateLink_Create() {
+ Link linkToCreate = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
+
+ //Use the link storage API to add the link
+ linkStorage.updateLink(linkToCreate, null, ILinkStorage.DM_OPERATION.CREATE);
+ doTestLinkIsInGraph(linkToVerify);
+
+ // Add same link
+ Link linkToCreateTwice = createFeasibleLink();
+ linkStorage.updateLink(linkToCreateTwice, null, ILinkStorage.DM_OPERATION.CREATE);
+
+ // this occurs assertion failure if there are two links in titanGraph
+ doTestLinkIsInGraph(linkToVerify);
+ }
+
+ /**
+ * Test if updateLink() can correctly inserts a Link.
+ */
+ @Test
+ public void testUpdateLink_Insert() {
+ Link linkToInsert = createFeasibleLink();
+ Link linkToVerify = createFeasibleLink();
+
+ //Use the link storage API to add the link
+ linkStorage.updateLink(linkToInsert, null, ILinkStorage.DM_OPERATION.INSERT);
+
+ doTestLinkIsInGraph(linkToVerify);
+
+ // Add same link
+ Link linkToInsertTwice = createFeasibleLink();
+ linkStorage.updateLink(linkToInsertTwice, null, ILinkStorage.DM_OPERATION.INSERT);
+
+ // this occurs assertion failure if there are two links in titanGraph
+ doTestLinkIsInGraph(linkToVerify);
+ }
+
+ // TODO: Check if addOrUpdateLink() should accept DELETE operation. If not, remove this test.
+ /**
+ * Test if updateLink() can correctly deletes a Link.
+ */
+ @Ignore @Test
+ public void testUpdateLink_Delete() {
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ // Test deletion of existing link
+ linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
+ doTestLinkIsNotInGraph(linkToVerify);
+
+ linkToDelete = createFeasibleLink();
+ linkToVerify = createFeasibleLink();
+
+ // Test deletion of not-existing link
+ linkStorage.updateLink(linkToDelete, null, DM_OPERATION.DELETE);
+ doTestLinkIsNotInGraph(linkToVerify);
+ }
+
+ /**
+ * Test if getLinks() can correctly return Links connected to specific DPID and port.
+ */
+ @Test
+ public void testGetLinks_ByDpidPort(){
+ Link linkToVerify = createExistingLink();
+ Long dpid = linkToVerify.getSrc();
+ short port = (short)linkToVerify.getSrcPort();
+
+ List<Link> list = linkStorage.getLinks(dpid, port);
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 if getLinks() can correctly return Links connected to specific MAC address.
+ */
+ @Test
+ public void testGetLinks_ByString() {
+ Link linkToVeryfy = createExistingLink();
+ String dpid = HexString.toHexString(linkToVeryfy.getSrc());
- 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(dpid);
+ assertTrue(links.contains(linkToVeryfy));
+
+ Link linkToVerifyNot = createFeasibleLink();
+ assertFalse(links.contains(linkToVerifyNot));
}
- //TODO enable once method is written
- @Ignore @Test
+ /**
+ * Test if deleteLink() can correctly delete a Link.
+ */
+ @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 if deleteLinks() can correctly delete Links.
+ */
+ @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 if deleteLinks() can handle mixture of normal/abnormal input.
+ */
+ @Test
+ public void testDeleteLinks_Mixture(){
+ List<Link> linksToDelete = new ArrayList<Link>();
+ linksToDelete.add(createFeasibleLink());
+ linksToDelete.add(createExistingLink());
- //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();
+ // Test deletion of mixture of new/existing links
+ linkStorage.deleteLinks(linksToDelete);
+ doTestLinkIsNotInGraph(createFeasibleLink());
+ doTestLinkIsNotInGraph(createExistingLink());
+ }
+
+ /**
+ * Test if getActiveLinks() can correctly return active Links.
+ */
+ @Test
+ public void testGetActiveLinks() {
+ Link existingLink = createExistingLink();
+ Link notExistingLink = createFeasibleLink();
+
+ List<Link> links = linkStorage.getActiveLinks();
+ assertTrue(links.contains(existingLink));
+ assertFalse(links.contains(notExistingLink));
+ }
+
+ /**
+ * Test if deleteLinksOnPort() can delete Links.
+ */
+ @Test
+ public void testDeleteLinksOnPort() {
+ Link linkToDelete = createExistingLink();
+ Link linkToVerify = createExistingLink();
+
+ linkStorage.deleteLinksOnPort(linkToDelete.getSrc(), linkToDelete.getSrcPort());
+
+ doTestLinkIsNotInGraph(linkToVerify);
+ }
+
+ /**
+ * Test if titanGraph has specific 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();
+
+ Iterator<Vertex> it = titanGraph.getVertices("dpid", src_dpid).iterator();
+
+ // Test if just one switch is found in the graph
assertTrue(it.hasNext());
- Vertex sw1 = it.next();
+ Vertex sw = it.next();
assertFalse(it.hasNext());
- pipe.start(sw1).out("on").has("number", 2).out("link");
+ GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
+ pipe.start(sw).out("on").has("number", src_port).out("link").has("number", dst_port).in("on").has("dpid", dst_dpid);
+ // Test if just one link is found in the graph
+ 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();
+
+ Iterator<Vertex> it = titanGraph.getVertices("dpid", src_dpid).iterator();
+
+ // Test if just one switch is found in the graph
+ assertTrue(it.hasNext());
+ Vertex sw = it.next();
+ assertFalse(it.hasNext());
+
+ GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
+ pipe.start(sw).out("on").has("number", src_port).out("link").has("number", dst_port).in("on").has("dpid", dst_dpid);
+
+ // Test if no link is found in the graph
+ assertFalse(pipe.hasNext());
+ }
+
+ /**
+ * Test if titanGraph has specific Link with specific LinkInfo
+ * @param link
+ */
+ private void doTestLinkHasStateOf(Link link, LinkInfo info) {
+ String src_dpid = HexString.toHexString(link.getSrc());
+ String dst_dpid = HexString.toHexString(link.getDst());
+ short src_port = link.getSrcPort();
+ short dst_port = link.getDstPort();
+
+ Iterator<Vertex> it = titanGraph.getVertices("dpid", src_dpid).iterator();
+
+ // Test if just one switch is found in the graph
+ assertTrue(it.hasNext());
+ Vertex sw = it.next();
+ assertFalse(it.hasNext());
+
+ GremlinPipeline<Vertex, Edge> pipe = new GremlinPipeline<Vertex, Edge>();
+ pipe.start(sw);
+ pipe.enablePath();
+ pipe.out("on").has("number", src_port).out("link").has("number", dst_port).in("on").has("dpid", dst_dpid)
+ .path().step(new PipeFunction<PathPipe<Vertex>, Edge>() {
+ @Override
+ public Edge compute(PathPipe<Vertex> pipepath) {
+ List<Vertex> V = pipepath.next();
+
+ Vertex port_src = V.get(1);
+ Vertex port_dst = V.get(2);
+
+ for(Edge e : port_src.getEdges(Direction.OUT)) {
+ if(e.getVertex(Direction.IN).equals(port_dst)) {
+ return e;
+ }
+ }
+
+ return null;
+ }
+ });
+
+ // Test if just one link is found in the graph
+ assertTrue(pipe.hasNext());
+ Edge edge = pipe.next();
+ assertTrue(edge != null);
+ assertFalse(pipe.hasNext());
+
+ // TODO: implement test code to check if update is correctly done.
+ assertTrue(false);
+ }
+
+
+ //----------------- Creation of test data -----------------------
+ /**
+ * Returns new Link object which has information of existing link in titanGraph
+ * @return new Link object
+ */
+ private Link createExistingLink() {
+ // Link from SEA switch port 2 to CHI switch port 1
+ return new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a03"), 1);
+ }
+
+ /**
+ * Returns new Link object which has information of not-existing but feasible link in titanGraph
+ * @return new Link object
+ */
+ private Link createFeasibleLink() {
+ // Link from SEA switch port 1 to LAX switch port 1
+ return new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a02"), 1);
+ }
+
+ // make NO sense while test-network data doesn't define physical network (i.e. any link is feasible)
+ @SuppressWarnings("unused")
+ private Link createInfeasibleLink() {
+ return new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1);
+ }
+
+ /**
+ * Returns list of Link objects which all has information of existing link in titanGraph
+ * @return ArrayList of new Link objects
+ */
+ private List<Link> createExistingLinks() {
+ List<Link> links = new ArrayList<Link>();
+ // Link from SEA switch port 2 to CHI switch port 1
+ links.add(new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a03"), 1));
+ // Link from LAX switch port 1 to SEA switch port 3
+ links.add(new Link(Long.decode("0x0000000000000a02"), 1, Long.decode("0x0000000000000a01"), 3));
+ return links;
+ }
+
+ /**
+ * Returns list of Link objects which all has information of not-existing but feasible link
+ * @return ArrayList of new Link objects
+ */
+ private List<Link> createFeasibleLinks() {
+ List<Link> links = new ArrayList<Link>();
+ // Link from CHI switch port 4 to NYC switch port 3
+ links.add(new Link(Long.decode("0x0000000000000a03"), 4, Long.decode("0x0000000000000a05"), 3));
+ // Link from SEA switch port 4 to LAX switch port 1
+ links.add(new Link(Long.decode("0x0000000000000a01"), 4, Long.decode("0x0000000000000a02"), 1));
+ return links;
+ }
+
+ /**
+ * Returns new LinkInfo object with convenient values.
+ * @return LinkInfo object
+ */
+ private LinkInfo createFeasibleLinkInfo(long time) {
+ long time_first = time;
+ long time_last_lldp = time + 50;
+ long time_last_bddp = time + 100;
+ int state_src = OFPhysicalPort.OFPortState.OFPPS_STP_FORWARD.getValue();
+ int state_dst = OFPhysicalPort.OFPortState.OFPPS_STP_LISTEN.getValue();
+
+ return new LinkInfo(time_first,
+ time_last_lldp,
+ time_last_bddp,
+ state_src,
+ state_dst);
+ }
+ //---------------------------------------------------------------
}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
index eea586b..b4cfc31 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
@@ -73,4 +73,4 @@
}
}
-}
+}
\ No newline at end of file
diff --git a/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
index 87b48b2..b780c2b 100644
--- a/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
+++ b/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
@@ -46,6 +46,8 @@
import net.floodlightcontroller.topology.ITopologyService;
import net.floodlightcontroller.topology.NodePortTuple;
import net.floodlightcontroller.topology.TopologyManager;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
+import net.onrc.onos.registry.controller.StandaloneRegistry;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
@@ -58,6 +60,7 @@
public class LinkDiscoveryManagerTest extends FloodlightTestCase {
private TestLinkDiscoveryManager ldm;
+ private StandaloneRegistry srs;
protected static Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
@@ -99,6 +102,7 @@
ldm = new TestLinkDiscoveryManager();
TopologyManager routingEngine = new TopologyManager();
ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
+ srs = new StandaloneRegistry();
MockThreadPoolService tp = new MockThreadPoolService();
RestApiServer restApi = new RestApiServer();
cntx.addService(IRestApiService.class, restApi);
@@ -108,13 +112,17 @@
cntx.addService(ITopologyService.class, ldm);
cntx.addService(IStorageSourceService.class, new MemoryStorageSource());
cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
+ cntx.addService(IControllerRegistryService.class, srs);
+
restApi.init(cntx);
tp.init(cntx);
routingEngine.init(cntx);
+ srs.init(cntx);
ldm.init(cntx);
restApi.startUp(cntx);
tp.startUp(cntx);
routingEngine.startUp(cntx);
+ srs.startUp(cntx);
ldm.startUp(cntx);
IOFSwitch sw1 = createMockSwitch(1L);