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 c8ca86f..5ea398b 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImpl.java
@@ -82,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);
@@ -165,24 +167,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
@@ -195,14 +207,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;
+	}
+	//---------------------------------------------------------------
 }