Move Test cases to corresponding package namespace
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
new file mode 100644
index 0000000..b03af4e
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/LinkStorageImplTest.java
@@ -0,0 +1,128 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+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 org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+
+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
+	
+	@Before
+	public void setUp() throws Exception{
+		titanGraph = TestDatabaseManager.getTestDatabase();
+		TestDatabaseManager.populateTestData(titanGraph);
+		
+		linkStorage = new TestableLinkStorageImpl(titanGraph);
+	}
+	
+	@After
+	public void tearDown() throws Exception {		
+		titanGraph.shutdown();
+	}
+	
+	/*
+	 * 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);
+		
+		//Use the link storage API to add the link
+		linkStorage.update(linkToAdd, ILinkStorage.DM_OPERATION.INSERT);
+		
+		//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");
+	}
+	
+	//TODO enable once method is written
+	@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);
+		
+		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);
+	}
+	
+	//TODO enable once method is written
+	@Ignore @Test
+	public void testUpdateDelete(){
+		Link linkToDelete = new Link(Long.decode("0x0000000000000a01"), 2, Long.decode("0x0000000000000a03"), 1);
+		
+		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());
+	}
+	
+	//TODO enable once method is written
+	@Ignore @Test
+	public void testDeleteLinks(){
+		//TODO Make sure this works when the implementation is written
+		
+		linkStorage.deleteLinksOnPort(Long.decode("0x0000000000000a01"), (short)2);
+		
+		//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());
+	}
+	
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
new file mode 100644
index 0000000..ebfb532
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImplTest.java
@@ -0,0 +1,278 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import net.onrc.onos.ofcontroller.core.ISwitchStorage;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.openflow.protocol.OFPhysicalPort;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.gremlin.java.GremlinPipeline;
+import com.tinkerpop.pipes.PipeFunction;
+import com.tinkerpop.pipes.branch.LoopPipe.LoopBundle;
+
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+import com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
+
+
+public class SwitchStorageImplTest {
+
+	private ISwitchStorage switchStorage;
+	private TitanGraph titanGraph;
+	
+	@Before
+	public void setUp() throws Exception {
+		titanGraph = TestDatabaseManager.getTestDatabase();
+		TestDatabaseManager.populateTestData(titanGraph);
+		
+		switchStorage = new TestableSwitchStorageImpl();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		titanGraph.shutdown();
+	}
+
+	@Ignore @Test
+	public void testUpdate() {
+		fail("Not yet implemented");
+	}
+
+	@Test
+	public void testAddPort() {
+		
+		String dpid = "00:00:00:00:00:00:0a:01";
+		short portNumber = 5;
+		
+		OFPhysicalPort portToAdd = new OFPhysicalPort();
+		portToAdd.setName("port 5 at SEA switch");
+		portToAdd.setCurrentFeatures(OFPhysicalPort.OFPortFeatures.OFPPF_100MB_FD.getValue());
+		portToAdd.setPortNumber(portNumber);
+		
+		switchStorage.addPort(dpid, portToAdd);
+		
+		Vertex sw = titanGraph.getVertices("dpid", dpid).iterator().next();
+		
+		GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
+		pipe.start(sw).out("on").has("number", portNumber);
+		
+		assertTrue(pipe.hasNext());
+		Vertex addedPort = pipe.next();
+		assertFalse(pipe.hasNext());
+		
+		assertEquals(addedPort.getProperty("number"), portNumber);
+	}
+
+	@Ignore @Test
+	public void testGetPorts() {
+		fail("Not yet implemented");
+	}
+
+	@Ignore @Test
+	public void testGetPortStringShort() {
+		fail("Not yet implemented");
+	}
+
+	@Ignore @Test
+	public void testGetPortStringString() {
+		fail("Not yet implemented");
+	}
+
+	@Test
+	public void testAddSwitch() {
+		String dpid = "00:00:00:00:00:00:0a:07";
+		
+		switchStorage.addSwitch(dpid);
+		
+		Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
+		assertTrue(it.hasNext());
+		Vertex addedSwitch = it.next();
+		assertFalse(it.hasNext());
+		
+		assertEquals(addedSwitch.getProperty("type"), "switch");
+		assertEquals(addedSwitch.getProperty("dpid"), dpid);
+		assertEquals(addedSwitch.getProperty("state"), SwitchState.ACTIVE.toString());
+	}
+
+	
+	@Test
+	public void testDeleteSwitch() {
+		String dpid = "00:00:00:00:00:00:0a:01";
+		
+		switchStorage.deleteSwitch(dpid);
+		
+		Iterator<Vertex> it = titanGraph.getVertices("dpid", dpid).iterator();
+		assertFalse(it.hasNext());
+	}
+
+	@Test
+	public void testDeletePortByPortNum() {
+		//FIXME fails because query for the port is wrong in SwitchStorageImpl
+		
+		String dpid = "00:00:00:00:00:00:0a:01";
+		short portNum = 3;
+		
+		switchStorage.deletePort(dpid, portNum);
+		
+		Vertex sw = titanGraph.getVertices("dpid", dpid).iterator().next();
+		
+		/*
+		Iterator<Vertex> it = sw.getVertices(Direction.OUT, "on").iterator();
+		
+		while (it.hasNext()){
+			System.out.println(it.next());
+		}
+		*/
+		
+		GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
+		pipe.start(sw).out("on").has("number", portNum);
+		assertFalse(pipe.hasNext());
+	}
+
+	@Ignore @Test
+	public void testDeletePortStringString() {
+		fail("Not yet implemented");
+	}
+
+	@Ignore @Test
+	public void testGetActiveSwitches() {
+		fail("Not yet implemented");
+	}
+
+	static class MyLoopFunction implements PipeFunction<LoopBundle<Vertex>, Boolean> {
+	    String dpid;
+	    public MyLoopFunction(String dpid) {
+		super();
+		this.dpid = dpid;
+	    }
+	    public Boolean compute(LoopBundle<Vertex> bundle) {
+		Boolean output = false;
+		if (! bundle.getObject().getProperty("dpid").equals(dpid)) {
+		    output = true;
+		}
+		return output;
+	    }
+	}
+
+	@Test
+	public void testShortestPath() {
+	    String dpid_src = "00:00:00:00:00:00:0a:01";
+	    String dpid_dest = "00:00:00:00:00:00:0a:06";
+
+	    //
+	    // Implement the Shortest Path between two vertices by using
+	    // the following Gremlin CLI code:
+	    //   v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path(){it.dpid}{it.number}{it.number}
+	    // The equivalent code used here is:
+	    //   results = []; v_src.as("x").out("on").out("link").in("on").dedup().loop("x"){it.object.dpid != v_dest.dpid}.path().fill(results)
+	    //
+
+	    // Get the source vertex
+	    Iterator<Vertex> iter = titanGraph.getVertices("dpid", dpid_src).iterator();
+	    if (! iter.hasNext())
+		return;			// Source vertex not found
+	    Vertex v_src = iter.next();
+
+	    // Get the destination vertex
+	    iter = titanGraph.getVertices("dpid", dpid_dest).iterator();
+	    if (! iter.hasNext())
+		return;			// Destination vertex not found
+	    Vertex v_dest = iter.next();
+
+	    //
+	    // Implement the Gremlin script and run it
+	    //
+	    // NOTE: This mechanism is slower. The code is kept here
+	    // for future reference.
+	    //
+	    /*
+	    String gremlin = "v_src.as(\"x\").out(\"on\").out(\"link\").in(\"on\").dedup().loop(\"x\"){it.object.dpid != v_dest.dpid}.path().fill(results)";
+
+	    String gremlin_nopath = "v_src.as(\"x\").out(\"on\").out(\"link\").in(\"on\").dedup().loop(\"x\"){it.object.dpid != \"NO-SUCH-DPID\"}.path().fill(results)";
+
+	    ScriptEngine engine = new GremlinGroovyScriptEngine();
+	    ArrayList<ArrayList<Vertex>> results = new ArrayList<ArrayList<Vertex>>();
+	    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("g", titanGraph);
+	    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_src", v_src);
+	    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("v_dest", v_dest);
+	    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("results", results);
+
+	    try {
+		engine.eval(gremlin);
+	    } catch (ScriptException e) {
+		System.err.println("Caught ScriptException running Gremlin script: " + e.getMessage());
+		return;
+	    }
+
+	    for (ArrayList<Vertex> lv : results) {
+		...
+	    }
+	    */
+
+	    MyLoopFunction whileFunction = new MyLoopFunction(dpid_dest);
+	    GremlinPipeline<Vertex, Vertex> pipe = new GremlinPipeline<Vertex, Vertex>();
+	    Collection<List> results = new ArrayList<List>();
+	    GremlinPipeline<Vertex, List> path;
+	    path = pipe.start(v_src).as("x").out("on").out("link").in("on").dedup().loop("x", whileFunction).path();
+	    path.fill(results);
+
+	    //
+	    // Extract the result and compose it into a string
+	    //
+	    String results_str = "";
+	    // System.out.println("BEGIN " + results.size());
+	    for (List l : results) {
+		for (Object o: l) {
+		    Vertex v = (Vertex)(o);
+		    // System.out.println(v);
+		    String type = v.getProperty("type").toString();
+		    results_str += "[type: " + type;
+		    // System.out.println("type: " + type);
+		    if (type.equals("port")) {
+			String number = v.getProperty("number").toString();
+			// System.out.println("number: " + number);
+			results_str += " number: " + number + "]";
+		    }
+		    if (type.equals("switch")) {
+			String dpid = v.getProperty("dpid").toString();
+			// System.out.println("dpid: " + dpid);
+			results_str += " dpid: " + dpid + "]";
+		    }
+		}
+	    }
+	    // System.out.println("END\n");
+	    System.out.println(results_str);
+
+	    //
+	    // Check the result
+	    //
+	    String expected_result = "[type: switch dpid: 00:00:00:00:00:00:0a:01][type: port number: 2][type: port number: 1][type: switch dpid: 00:00:00:00:00:00:0a:03][type: port number: 2][type: port number: 2][type: switch dpid: 00:00:00:00:00:00:0a:04][type: port number: 3][type: port number: 1][type: switch dpid: 00:00:00:00:00:00:0a:06]";
+
+	    assertEquals(results_str, expected_result);
+
+	    //
+	    // Test Shortest-Path computation to non-existing destination
+	    //
+	    results.clear();
+	    MyLoopFunction noDestWhileFunction = new MyLoopFunction("NO-SUCH-DPID");
+	    path = pipe.start(v_src).as("x").out("on").out("link").in("on").dedup().loop("x", noDestWhileFunction).path();
+	    path.fill(results);
+	    assertTrue(results.size() == 0);
+	}
+}
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
new file mode 100644
index 0000000..eea586b
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestDatabaseManager.java
@@ -0,0 +1,76 @@
+package net.onrc.onos.ofcontroller.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/TestableLinkStorageImpl.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableLinkStorageImpl.java
new file mode 100644
index 0000000..2f90d48
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableLinkStorageImpl.java
@@ -0,0 +1,41 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import java.util.Set;
+
+import net.onrc.onos.ofcontroller.core.internal.LinkStorageImpl;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
+import com.tinkerpop.blueprints.Vertex;
+
+/**
+ * Seam that allows me to set up a testable instance of LinkStorageImpl that 
+ * writes to a file database rather than a Cassandra cluster. 
+ * It seems the init() API on LinkStorageImpl might change so I won't rely
+ * on it yet.
+ * 
+ * @author jono
+ *
+ */
+
+public class TestableLinkStorageImpl extends LinkStorageImpl {
+	protected TitanGraph graph;
+
+	public TestableLinkStorageImpl(TitanGraph graph){
+		this.graph = graph;
+	}
+	
+	@Override
+	public void init(String conf){
+        Set<String> s = graph.getIndexedKeys(Vertex.class);
+        if (!s.contains("dpid")) {
+           graph.createKeyIndex("dpid", Vertex.class);
+           graph.stopTransaction(Conclusion.SUCCESS);
+        }
+        if (!s.contains("type")) {
+        	graph.createKeyIndex("type", Vertex.class);
+        	graph.stopTransaction(Conclusion.SUCCESS);
+        }
+		
+	}
+}
diff --git a/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java
new file mode 100644
index 0000000..e78a1b6
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/core/internal/TestableSwitchStorageImpl.java
@@ -0,0 +1,32 @@
+package net.onrc.onos.ofcontroller.core.internal;
+
+import java.util.Set;
+
+import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
+
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.tinkerpop.blueprints.Vertex;
+import com.tinkerpop.blueprints.TransactionalGraph.Conclusion;
+
+/**
+ * Seam that allows me to set up a testable instance of SwitchStorageImpl that 
+ * writes to a file database rather than a Cassandra cluster. 
+ * It seems the init() API on SwitchStorageImpl might change so I won't rely
+ * on it yet.
+ * 
+ * @author jono
+ *
+ */
+
+public class TestableSwitchStorageImpl extends SwitchStorageImpl {
+	
+	public TestableSwitchStorageImpl(){
+	}
+	
+	@Override
+	public void init(String conf){
+        
+		super.init(conf);
+		
+	}
+}