Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 1 | package net.floodlightcontroller.linkdiscovery.internal; |
| 2 | |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 3 | import java.util.Iterator; |
Jonathan Hart | c86a2ea | 2013-01-15 22:39:42 -0800 | [diff] [blame] | 4 | import java.util.List; |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 5 | |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 6 | import junit.framework.TestCase; |
Jonathan Hart | c86a2ea | 2013-01-15 22:39:42 -0800 | [diff] [blame] | 7 | import net.floodlightcontroller.core.INetMapStorage.DM_OPERATION; |
Jonathan Hart | 627f10c | 2013-01-16 14:20:03 -0800 | [diff] [blame] | 8 | import net.floodlightcontroller.core.internal.TestDatabaseManager; |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 9 | import net.floodlightcontroller.linkdiscovery.ILinkStorage; |
| 10 | import net.floodlightcontroller.routing.Link; |
| 11 | |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 12 | import org.junit.After; |
| 13 | import org.junit.Before; |
| 14 | import org.junit.Test; |
| 15 | |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 16 | import com.thinkaurelius.titan.core.TitanGraph; |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 17 | import com.tinkerpop.blueprints.Vertex; |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 18 | import com.tinkerpop.gremlin.java.GremlinPipeline; |
| 19 | |
| 20 | public class LinkStorageImplTest extends TestCase { |
Jonathan Hart | 627f10c | 2013-01-16 14:20:03 -0800 | [diff] [blame] | 21 | //private static final String testDbLocation = "/tmp/onos-testdb"; |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 22 | |
Jonathan Hart | 627f10c | 2013-01-16 14:20:03 -0800 | [diff] [blame] | 23 | //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>"; |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 24 | |
| 25 | private static ILinkStorage linkStorage; |
| 26 | private static TitanGraph titanGraph; |
| 27 | |
Jonathan Hart | c86a2ea | 2013-01-15 22:39:42 -0800 | [diff] [blame] | 28 | //TODO Future ideas: |
| 29 | //Test add links with CREATE and UPDATE |
| 30 | //Test adding existing link again |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 31 | |
| 32 | @Before |
Jonathan Hart | 627f10c | 2013-01-16 14:20:03 -0800 | [diff] [blame] | 33 | public void setUp() throws Exception{ |
| 34 | super.setUp(); |
| 35 | TestDatabaseManager.deleteTestDatabase(); |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 36 | |
Jonathan Hart | 627f10c | 2013-01-16 14:20:03 -0800 | [diff] [blame] | 37 | //titanGraph = TitanFactory.open(testDbLocation); |
| 38 | titanGraph = TestDatabaseManager.getTestDatabase(); |
| 39 | TestDatabaseManager.populateTestData(titanGraph); |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 40 | |
Jonathan Hart | c86a2ea | 2013-01-15 22:39:42 -0800 | [diff] [blame] | 41 | linkStorage = new TestableLinkStorageImpl(titanGraph); |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 42 | } |
| 43 | |
Jonathan Hart | 627f10c | 2013-01-16 14:20:03 -0800 | [diff] [blame] | 44 | /* |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 45 | private void populateTestData(){ |
| 46 | Set<String> s = titanGraph.getIndexedKeys(Vertex.class); |
| 47 | if (!s.contains("dpid")) { |
| 48 | titanGraph.createKeyIndex("dpid", Vertex.class); |
| 49 | titanGraph.stopTransaction(Conclusion.SUCCESS); |
| 50 | } |
| 51 | if (!s.contains("type")) { |
| 52 | titanGraph.createKeyIndex("type", Vertex.class); |
| 53 | titanGraph.stopTransaction(Conclusion.SUCCESS); |
| 54 | } |
| 55 | |
| 56 | InputStream graphMLStream = new ByteArrayInputStream(testDbGraphML.getBytes()); |
| 57 | try { |
| 58 | GraphMLReader.inputGraph(titanGraph, graphMLStream); |
| 59 | } catch (IOException e) { |
| 60 | e.printStackTrace(); |
| 61 | Assert.fail("IOException thrown"); |
| 62 | } |
| 63 | |
| 64 | } |
Jonathan Hart | 627f10c | 2013-01-16 14:20:03 -0800 | [diff] [blame] | 65 | */ |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 66 | |
| 67 | /* |
| 68 | * Add a link between port 1.102 and 2.104 |
| 69 | * i.e SEA switch port 3 to LAX switch port 1 |
| 70 | */ |
| 71 | @Test |
| 72 | public void testAddSingleLink(){ |
| 73 | Link linkToAdd = new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a02"), 1); |
| 74 | |
| 75 | //Use the link storage API to add the link |
| 76 | linkStorage.update(linkToAdd, ILinkStorage.DM_OPERATION.INSERT); |
| 77 | |
| 78 | //Test if it was added correctly with the Gremlin API |
| 79 | GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>(); |
| 80 | Iterator<Vertex> it = titanGraph.getVertices("dpid", "00:00:00:00:00:00:0a:01").iterator(); |
| 81 | |
| 82 | assertTrue(it.hasNext()); |
| 83 | Vertex sw1 = it.next(); |
| 84 | assertFalse(it.hasNext()); |
| 85 | |
| 86 | pipe.start(sw1).out("on").has("number", 3).out("link").in("on"); |
| 87 | |
| 88 | assertTrue(pipe.hasNext()); |
| 89 | Vertex sw2 = pipe.next(); |
| 90 | assertFalse(pipe.hasNext()); |
| 91 | |
| 92 | //Check we ended up at the right vertex |
| 93 | assertEquals((String)sw2.getProperty("dpid"), "00:00:00:00:00:00:0a:02"); |
| 94 | } |
| 95 | |
| 96 | @Test |
| 97 | public void testGetLinks(){ |
Jonathan Hart | c86a2ea | 2013-01-15 22:39:42 -0800 | [diff] [blame] | 98 | //TODO Make sure this works when the implementation is written |
Umesh Krishnaswamy | f962d64 | 2013-01-23 19:04:23 -0800 | [diff] [blame^] | 99 | List<Link> list = linkStorage.getLinks(Long.decode("0x0000000000000a01"), (short)2); |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 100 | |
Jonathan Hart | c86a2ea | 2013-01-15 22:39:42 -0800 | [diff] [blame] | 101 | assertEquals(list.size(), 1); |
| 102 | |
| 103 | Link l = list.get(0); |
| 104 | assertEquals(l.getSrc(), 2561L); |
| 105 | assertEquals(l.getSrcPort(), (short)2); |
| 106 | assertEquals(l.getDst(), 2563L); |
| 107 | assertEquals(l.getDstPort(), (short)1); |
| 108 | } |
| 109 | |
| 110 | @Test |
| 111 | public void testUpdateDelete(){ |
| 112 | //TODO Make sure this works when the implementation is written |
| 113 | Link linkToDelete = new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a03"), 1); |
| 114 | |
| 115 | linkStorage.update(linkToDelete, DM_OPERATION.DELETE); |
| 116 | |
| 117 | //Test if it was deleted correctly with the Gremlin API |
| 118 | GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>(); |
| 119 | Iterator<Vertex> it = titanGraph.getVertices("dpid", "00:00:00:00:00:00:0a:01").iterator(); |
| 120 | |
| 121 | assertTrue(it.hasNext()); |
| 122 | Vertex sw1 = it.next(); |
| 123 | assertFalse(it.hasNext()); |
| 124 | |
| 125 | pipe.start(sw1).out("on").has("number", 2).out("link"); |
| 126 | |
| 127 | assertFalse(pipe.hasNext()); |
| 128 | } |
| 129 | |
| 130 | @Test |
| 131 | public void testDeleteLinks(){ |
| 132 | //TODO Make sure this works when the implementation is written |
| 133 | |
Umesh Krishnaswamy | f962d64 | 2013-01-23 19:04:23 -0800 | [diff] [blame^] | 134 | linkStorage.deleteLinksOnPort(Long.decode("0x0000000000000a01"), (short)2); |
Jonathan Hart | c86a2ea | 2013-01-15 22:39:42 -0800 | [diff] [blame] | 135 | |
| 136 | //Test if it was deleted correctly with the Gremlin API |
| 137 | GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>(); |
| 138 | Iterator<Vertex> it = titanGraph.getVertices("dpid", "00:00:00:00:00:00:0a:01").iterator(); |
| 139 | |
| 140 | assertTrue(it.hasNext()); |
| 141 | Vertex sw1 = it.next(); |
| 142 | assertFalse(it.hasNext()); |
| 143 | |
| 144 | pipe.start(sw1).out("on").has("number", 2).out("link"); |
| 145 | |
| 146 | assertFalse(pipe.hasNext()); |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 147 | } |
| 148 | |
| 149 | @After |
Jonathan Hart | 627f10c | 2013-01-16 14:20:03 -0800 | [diff] [blame] | 150 | public void tearDown() throws Exception { |
| 151 | super.tearDown(); |
Jonathan Hart | c86a2ea | 2013-01-15 22:39:42 -0800 | [diff] [blame] | 152 | //TODO Reenable this once the tests are written. It's good to clean up afterwards. |
Jonathan Hart | 627f10c | 2013-01-16 14:20:03 -0800 | [diff] [blame] | 153 | //TestDatabaseManager.deleteTestDatabase(); |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 154 | } |
| 155 | |
Jonathan Hart | 627f10c | 2013-01-16 14:20:03 -0800 | [diff] [blame] | 156 | /* |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 157 | private void deleteTestDatabase(){ |
| 158 | try { |
| 159 | FileUtils.deleteDirectory(new File(testDbLocation)); |
| 160 | } catch (IOException e) { |
| 161 | System.out.println("delete failed"); |
| 162 | e.printStackTrace(); |
| 163 | } |
| 164 | } |
Jonathan Hart | 627f10c | 2013-01-16 14:20:03 -0800 | [diff] [blame] | 165 | */ |
Jonathan Hart | b7e3d2c | 2013-01-15 18:45:19 -0800 | [diff] [blame] | 166 | } |