Refactor LinkStorageImplTest to use TestGraphDBOperation
diff --git a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
index 431db71..2b93298 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/TestDatabaseManager.java
@@ -11,15 +11,13 @@
 import java.util.Set;
 
 import junit.framework.Assert;
-
-import net.floodlightcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.floodlightcontroller.core.ISwitchStorage.SwitchState;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.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;
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
index a030744..2c459de 100644
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/LinkStorageImplTest.java
@@ -5,15 +5,12 @@
 import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 
 import net.floodlightcontroller.linkdiscovery.LinkInfo;
+import net.floodlightcontroller.linkdiscovery.internal.TestGraphDBOperation.TestPortObject;
 import net.floodlightcontroller.routing.Link;
 import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.onrc.onos.ofcontroller.linkdiscovery.ILinkStorage;
 import net.onrc.onos.util.GraphDBConnection;
 import net.onrc.onos.util.GraphDBOperation;
@@ -43,75 +40,7 @@
 	private static GraphDBConnection conn;
 	
 	// Mock GraphDBOperation (mocks port-related methods only)
-	private static GraphDBOperation ope;
-	
-	// Uncommitted actions executed in LinkStorageImpl
-	private static ArrayList<LinkEvent> actions;
-	
-	// Dictionary of mock IPortObject to information of port
-	// -> Used to refer DPID from IPortObject
-	private static Map<Object,PortInfo> mockToPortInfoMap;
-	
-	// Links existing in virtual graph
-	private List<Link> links;
-	
-	
-	//================ Utility classes for logging actions in LinkStorageImpl ===========
-	// Not used for now
-	private enum LinkEventType {
-		ADD("ADD", 1),
-		DELETE("DELETE", 2);
-		
-		private String name;
-		private int number;
-
-		LinkEventType(String name, int number) {
-			this.name = name;
-			this.number = number;
-		}
-		public String getName() { return name; }
-		public int getNumber() { return number; }
-	}
-	
-	private class LinkEvent {
-		private Long src_dpid = null;
-		private Long dst_dpid = null;
-		private Short src_port = null;
-		private Short dst_port = null;
-		
-		public LinkEventType type;
-		
-		public LinkEvent(Link link, LinkEventType type) {
-			this.src_dpid = link.getSrc();
-			this.src_port = link.getSrcPort();
-			this.dst_dpid = link.getDst();
-			this.dst_port = link.getDstPort();
-			
-			this.type = type;
-		}
-		
-		public LinkEvent(Long src_dpid, Short src_port, Long dst_dpid, Short dst_port, LinkEventType type) {
-			this.src_dpid = src_dpid;
-			this.src_port = src_port;
-			this.dst_dpid = dst_dpid;
-			this.dst_port = dst_port;
-			
-			this.type = type;
-		}
-
-		public Long getSrcDpid() { return src_dpid; }
-		public Short getSrcPort() { return src_port; }
-		public Long getDstDpid() { return dst_dpid; }
-		public Short getDstPort() { return dst_port; }
-		public LinkEventType getType() { return type; }
-	}
-	
-	private class PortInfo {
-		public Long dpid = null;
-		public Short port = null;
-		
-		public PortInfo(Long dpid, Short port) { this.dpid = dpid; this.port = port; }
-	}
+	private static TestGraphDBOperation ope;
 
 	/**
 	 * Setup code called before each tests.
@@ -126,13 +55,10 @@
 		EasyMock.expect(GraphDBConnection.getInstance((String)EasyMock.anyObject())).andReturn(conn).anyTimes();
 		PowerMock.replay(GraphDBConnection.class);
 		
-		ope = createMockGraphDBOperation();
+		ope = new TestGraphDBOperation();
 		PowerMock.expectNew(GraphDBOperation.class, (GraphDBConnection)EasyMock.anyObject()).andReturn(ope).anyTimes();
 		PowerMock.replay(GraphDBOperation.class);
-		
-		actions = new ArrayList<LinkEvent>();
-		mockToPortInfoMap = new HashMap<Object,PortInfo>();
-		
+
 		linkStorage = new LinkStorageImpl();
 		linkStorage.init("/dummy/path/to/conf");
 		
@@ -148,6 +74,7 @@
 	public void tearDown() throws Exception {
 		// finish code
 		linkStorage.close();
+		ope.close();
 	}
 	
 	// TODO: remove @Ignore after UPDATE method is implemented
@@ -177,14 +104,6 @@
 		//Use the link storage API to add the link
 		linkStorage.update(linkToCreate, ILinkStorage.DM_OPERATION.CREATE);
 		doTestLinkExist(linkToVerify);
-
-		// Avoiding duplication is out of scope. DBOperation is responsible for this.
-//		// 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);
 	}
 
 	/**
@@ -226,14 +145,6 @@
 		for(Link l : linksToVerify) {
 			doTestLinkExist(l);
 		}
-	
-		// Out of scope: DBOperation is responsible for avoiding duplication.
-//		// Test creation of existing links
-//		linksToCreate = createFeasibleLinks();
-//		linkStorage.update(linksToCreate, ILinkStorage.DM_OPERATION.CREATE);
-//		for(Link l : linksToVerify) {
-//			doTestLinkIsInGraph(l);
-//		}
 	}
 	
 	/**
@@ -491,14 +402,10 @@
 	 * @param link 
 	 */
 	private void doTestLinkExist(Link link) {
-		int count = 0;
-		for(Link lt : links) {
-			if(lt.equals(link)) {
-				++count;
-			}
-		}
-		
-		assertTrue(count == 1);
+		assertTrue(ope.hasLinkBetween(HexString.toHexString(link.getSrc()),
+				link.getSrcPort(),
+				HexString.toHexString(link.getDst()),
+				link.getDstPort()));
 	}
 	
 	/**
@@ -506,7 +413,10 @@
 	 * @param link
 	 */
 	private void doTestLinkNotExist(Link link) {
-		assertFalse(links.contains(link));
+		assertFalse(ope.hasLinkBetween(HexString.toHexString(link.getSrc()),
+				link.getSrcPort(),
+				HexString.toHexString(link.getDst()),
+				link.getDstPort()));
 	}
 	
 	/**
@@ -516,152 +426,6 @@
 	private void doTestLinkHasStateOf(Link link, LinkInfo info) {
 	}
 	
-	/**
-	 * Class defines a function called back when IPortObject::removeLink is called.
-	 * @author Naoki Shiota
-	 *
-	 */
-	private class RemoveLinkCallback implements IAnswer<Object> {
-		private long dpid;
-		private short port;
-		public RemoveLinkCallback(long dpid, short port) {
-			this.dpid = dpid; this.port = port;
-		}
-		
-		@Override
-		public Object answer() throws Throwable {
-			IPortObject dstPort = (IPortObject) EasyMock.getCurrentArguments()[0];
-			PortInfo dst = mockToPortInfoMap.get(dstPort);
-
-			Link linkToRemove = new Link(this.dpid,this.port,dst.dpid,dst.port);
-			actions.add(new LinkEvent(linkToRemove,LinkEventType.DELETE));
-			
-			return null;
-		}
-	}
-	
-	/**
-	 * Class defines a function called back when IPortObject::setLinkPort is called.
-	 * @author Naoki Shiota
-	 *
-	 */
-	private class SetLinkPortCallback implements IAnswer<Object> {
-		private long dpid;
-		private short port;
-		public SetLinkPortCallback(long dpid, short port) {
-			this.dpid = dpid; this.port = port;
-		}
-
-		@Override
-		public Object answer() throws Throwable {
-			IPortObject dstPort = (IPortObject) EasyMock.getCurrentArguments()[0];
-			PortInfo dst = mockToPortInfoMap.get(dstPort);
-
-			Link linkToAdd = new Link(this.dpid,this.port,dst.dpid,dst.port);
-			actions.add(new LinkEvent(linkToAdd,LinkEventType.ADD));
-
-			return null;
-		}
-		
-	}
-	
-	// ------------------------Creation of Mock-----------------------------
-	/**
-	 * Create a mock GraphDBOperation which hooks port-related methods.
-	 * @return EasyMock-wrapped GraphDBOperation object.
-	 */
-	private GraphDBOperation createMockGraphDBOperation() {
-		GraphDBOperation mockDBOpe = EasyMock.createNiceMock(GraphDBOperation.class);
-		
-		// Mock searchPort() method to create new mock IPortObject.
-		EasyMock.expect(mockDBOpe.searchPort((String)EasyMock.anyObject(), EasyMock.anyShort())).
-			andAnswer(new IAnswer<IPortObject>() {
-			@Override
-			public IPortObject answer() throws Throwable {
-				long dpid = HexString.toLong((String)EasyMock.getCurrentArguments()[0]);
-				short port = (Short) EasyMock.getCurrentArguments()[1];
-				
-				IPortObject ret = createMockPort(dpid,port);
-				
-				return ret;
-			}
-		}).anyTimes();
-		
-		// Mock commit() method to commit change of link information
-		mockDBOpe.commit();
-		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
-			@Override
-			public Object answer() throws Throwable {
-				for(LinkEvent action : actions) {
-					if(action.getType().equals(LinkEventType.ADD)) {
-						Link linkToAdd = new Link(
-								action.getSrcDpid(),
-								action.getSrcPort(),
-								action.getDstDpid(),
-								action.getDstPort());
-						links.add(linkToAdd);
-					} else if(action.getType().equals(LinkEventType.DELETE)) {
-						Link linkToRemove = new Link(
-								action.getSrcDpid(),
-								action.getSrcPort(),
-								action.getDstDpid(),
-								action.getDstPort());
-						links.remove(linkToRemove);
-					} else {
-						log.error("mock commit(): unexpected action {}", new Object[]{action.getType()});
-					}
-				}
-				actions.clear();
-				return null;
-			}
-		}).atLeastOnce();
-		
-		EasyMock.replay(mockDBOpe);
-		return mockDBOpe;
-	}
-	
-	/**
-	 * Create a mock IPortObject using given DPID and port number.
-	 * IPortObject can't store DPID, so DPID is stored to mockToPortInfoMap for later use.
-	 * @param dpid DPID of a port
-	 * @param number Port Number
-	 * @return EasyMock-wrapped IPortObject
-	 */
-	private IPortObject createMockPort(long dpid, short number) {
-		IPortObject mockPort = EasyMock.createNiceMock(IPortObject.class);
-		
-		EasyMock.expect(mockPort.getNumber()).andReturn(number);
-		
-		// Mock removeLink() method
-		mockPort.removeLink((IPortObject) EasyMock.anyObject());
-		EasyMock.expectLastCall().andAnswer(new RemoveLinkCallback(dpid, number)).anyTimes();
-		
-		// Mock setLinkPort() method
-		mockPort.setLinkPort((IPortObject) EasyMock.anyObject());
-		EasyMock.expectLastCall().andAnswer(new SetLinkPortCallback(dpid, number)).anyTimes();
-		
-		// Mock getLinkPorts() method
-		// -> Always empty list for now
-		EasyMock.expect(mockPort.getLinkedPorts()).andAnswer(new IAnswer< Iterable<IPortObject> >() {
-			@Override
-			public Iterable<IPortObject> answer() throws Throwable {
-				return new Iterable<IPortObject> () {
-					@Override
-					public Iterator<IPortObject> iterator() {
-						// create empty list and returns its iterator
-						return new ArrayList<IPortObject>().iterator();
-					}
-				};
-			}
-		}).anyTimes();
-		
-		mockToPortInfoMap.put(mockPort, new PortInfo(dpid,number));
-		EasyMock.replay(mockPort);
-		
-		return mockPort;
-	}
-
-
 	//----------------- Creation of test data -----------------------
 	// Assume a network shown below.
 	//
@@ -678,10 +442,33 @@
 	// dpid3 : 00:00:00:00:0a:03
 	
 	private void initLinks() {
-		links = new ArrayList<Link>();
+		final String dpid1 = "00:00:00:00:0a:01";
+		final String dpid2 = "00:00:00:00:0a:02";
+		final String dpid3 = "00:00:00:00:0a:03";
 		
-		links.add(new Link(Long.decode("0x0000000000000a01"), 1, Long.decode("0x0000000000000a02"), 1));
-		links.add(new Link(Long.decode("0x0000000000000a01"), 3, Long.decode("0x0000000000000a03"), 2));
+		ope.createNewSwitchForTest(dpid1);
+		ope.createNewSwitchForTest(dpid2);
+		ope.createNewSwitchForTest(dpid3);
+
+		TestPortObject ports1 [] = {
+				ope.createNewPortForTest(dpid1, (short)1),
+				ope.createNewPortForTest(dpid1, (short)2),
+				ope.createNewPortForTest(dpid1, (short)3),
+				ope.createNewPortForTest(dpid1, (short)4),
+		};
+
+		TestPortObject ports2 [] = {
+				ope.createNewPortForTest(dpid2, (short)1),
+				ope.createNewPortForTest(dpid2, (short)2),
+		};
+
+		TestPortObject ports3 [] = {
+				ope.createNewPortForTest(dpid3, (short)1),
+				ope.createNewPortForTest(dpid3, (short)2),
+		};
+		
+		ope.setLinkBetweenPortsForTest(ports1[0], ports2[0]);
+		ope.setLinkBetweenPortsForTest(ports1[3], ports3[1]);
 	}
 	
 	/**
diff --git a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestGraphDBOperation.java b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestGraphDBOperation.java
index 1a239ed..f4ed4c8 100644
--- a/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestGraphDBOperation.java
+++ b/src/test/java/net/floodlightcontroller/linkdiscovery/internal/TestGraphDBOperation.java
@@ -1,14 +1,14 @@
 package net.floodlightcontroller.linkdiscovery.internal;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.codehaus.jackson.annotate.JsonIgnore;
 import org.codehaus.jackson.annotate.JsonProperty;
 import org.easymock.EasyMock;
 import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.tinkerpop.blueprints.Direction;
 import com.tinkerpop.blueprints.Vertex;
@@ -23,7 +23,6 @@
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
 import net.onrc.onos.ofcontroller.util.FlowEntryId;
 import net.onrc.onos.ofcontroller.util.FlowId;
 import net.onrc.onos.util.GraphDBConnection;
@@ -31,23 +30,141 @@
 import net.onrc.onos.util.IDBConnection;
 
 public class TestGraphDBOperation extends GraphDBOperation {
+	protected static Logger log = LoggerFactory.getLogger(TestGraphDBOperation.class);
+
 	protected List<TestSwitchObject> switches;
 	protected List<TestPortObject> ports;
-//	protected List<TestDeviceObject> devices;
+	protected List<TestDeviceObject> devices;
 //	protected List<TestFlowEntry> flows;
 
 	protected List<TestSwitchObject> switchesToAdd;
 	protected List<TestPortObject> portsToAdd;
-//	protected List<TestDeviceObject> devicesToAdd;
+	protected List<TestDeviceObject> devicesToAdd;
 //	protected List<TestFlowEntry> flowsToAdd;
 
 	protected List<TestSwitchObject> switchesToRemove;
 	protected List<TestPortObject> portsToRemove;
-//	protected List<TestDeviceObject> devicesToRemove;
+	protected List<TestDeviceObject> devicesToRemove;
 //	protected List<TestFlowEntry> flowsToRemove;
 
 
 	// Testable implementations of INetMapTopologyObject interfaces
+	public static class TestDeviceObject implements IDeviceObject {
+		private String state,type,mac,ipaddr;
+		private List<IPortObject> ports;
+		private List<ISwitchObject> switches;
+		
+		private String stateToUpdate,typeToUpdate,macToUpdate,ipaddrToUpdate;
+		private List<IPortObject> portsToAdd;
+		private List<IPortObject> portsToRemove;
+
+		public TestDeviceObject() {
+			ports = new ArrayList<IPortObject>();
+			portsToAdd = new ArrayList<IPortObject>();
+			portsToRemove = new ArrayList<IPortObject>();
+			switches = new ArrayList<ISwitchObject>();
+			
+			clearUncommitedData();
+		}
+		
+		public void commit() {
+			for(IPortObject port : portsToAdd) {
+				ports.add(port);
+			}
+			for(IPortObject port : portsToRemove) {
+				ports.remove(port);
+			}
+			
+			if(stateToUpdate != null) { state = stateToUpdate; }
+			if(typeToUpdate != null) { type = typeToUpdate; }
+			if(macToUpdate != null) { mac = macToUpdate; }
+			if(ipaddrToUpdate != null) { ipaddr = ipaddrToUpdate; }
+			
+			clearUncommitedData();
+		}
+		
+		public void rollback() {
+			clearUncommitedData();
+		}
+		
+		public void clearUncommitedData() {
+			ports.clear();
+			portsToAdd.clear();
+			portsToRemove.clear();
+			
+			stateToUpdate = typeToUpdate = macToUpdate = ipaddrToUpdate = null;
+		}
+		
+		public void addSwitchForTest(ISwitchObject sw) {
+			switches.add(sw);
+		}
+		
+		public void addPortForTest(IPortObject port) {
+			ports.add(port);
+		}
+		
+		@Override
+		@JsonProperty("state")
+		@Property("state")
+		public String getState() { return state; }
+	
+		@Override
+		@Property("state")
+		public void setState(String state) { stateToUpdate = state; }
+	
+		@Override
+		@JsonIgnore
+		@Property("type")
+		public String getType() { return type; }
+	
+		@Override
+		@Property("type")
+		public void setType(String type) { typeToUpdate = type; }
+	
+		@Override
+		public Vertex asVertex() {
+			// TODO Auto-generated method stub
+			return null;
+		}
+	
+		@Override
+		@JsonProperty("mac")
+		@Property("dl_addr")
+		public String getMACAddress() { return mac; }
+	
+		@Override
+		@Property("dl_addr")
+		public void setMACAddress(String macaddr) { macToUpdate = macaddr; }
+	
+		@Override
+		@JsonProperty("ipv4")
+		@Property("nw_addr")
+		public String getIPAddress() { return ipaddr; }
+
+		@Override
+		@Property("dl_addr")
+		public void setIPAddress(String ipaddr) { ipaddrToUpdate = ipaddr; }
+	
+		@Override
+		@JsonIgnore
+		@Incidence(label = "host", direction = Direction.IN)
+		public Iterable<IPortObject> getAttachedPorts() { return ports; }
+	
+		@Override
+		@JsonIgnore
+		@Incidence(label = "host", direction = Direction.IN)
+		public void setHostPort(IPortObject port) { portsToAdd.add(port); }
+	
+		@Override
+		@JsonIgnore
+		@Incidence(label = "host", direction = Direction.IN)
+		public void removeHostPort(IPortObject port) { portsToRemove.add(port); }
+	
+		@Override
+		@JsonIgnore
+		@GremlinGroovy("_().in('host').in('on')")
+		public Iterable<ISwitchObject> getSwitch() { return switches; }
+	}
 	
 	public static class TestSwitchObject implements ISwitchObject {
 		private String state,type,dpid;
@@ -182,6 +299,8 @@
 		private Integer port_stateToUpdate;
 		private List<IPortObject> linkedPortsToAdd;
 		private List<IPortObject> linkedPortsToRemove;
+		private List<IDeviceObject> devicesToAdd;
+		private List<IDeviceObject> devicesToRemove;
 		
 
 		public TestPortObject() {
@@ -192,18 +311,19 @@
 			linkedPortsToAdd = new ArrayList<IPortObject>();
 			linkedPortsToRemove = new ArrayList<IPortObject>();
 			devices = new ArrayList<IDeviceObject>();
+			devicesToAdd = new ArrayList<IDeviceObject>();
+			devicesToRemove = new ArrayList<IDeviceObject>();
 			flows = new ArrayList<IFlowEntry>();
 			
 			clearUncommitedData();
 		}
 		
 		public void commit() {
-			for(IPortObject port : linkedPortsToAdd) {
-				linkedPorts.add(port);
-			}
-			for(IPortObject port : linkedPortsToRemove) {
-				linkedPorts.remove(port);
-			}
+			for(IPortObject port : linkedPortsToAdd) { linkedPorts.add(port); }
+			for(IPortObject port : linkedPortsToRemove) { linkedPorts.remove(port); }
+			for(IDeviceObject dev : devicesToAdd) { devices.add(dev); }
+			for(IDeviceObject dev : devicesToRemove) { devices.remove(dev); }
+			
 			if(stateToUpdate != null) { state = stateToUpdate; }
 			if(typeToUpdate != null) { type = typeToUpdate; }
 			if(descToUpdate != null) { desc = descToUpdate; }
@@ -220,6 +340,8 @@
 		public void clearUncommitedData() {
 			linkedPortsToAdd.clear();
 			linkedPortsToRemove.clear();
+			devicesToAdd.clear();
+			devicesToRemove.clear();
 			stateToUpdate = typeToUpdate = descToUpdate = null;
 			port_stateToUpdate = null;
 			numberToUpdate = null;
@@ -296,11 +418,11 @@
 
 		@Override
 		@Adjacency(label = "host")
-		public void setDevice(IDeviceObject device) { devices.add(device); }
+		public void setDevice(IDeviceObject device) { devicesToAdd.add(device); }
 
 		@Override
 		@Adjacency(label = "host")
-		public void removeDevice(IDeviceObject device) { devices.remove(device); }
+		public void removeDevice(IDeviceObject device) { devicesToRemove.add(device); }
 
 		@Override
 		@JsonIgnore
@@ -321,7 +443,8 @@
 		@Override
 		@JsonIgnore
 		@Adjacency(label = "link")
-		public Iterable<IPortObject> getLinkedPorts() { return linkedPorts; }
+		public Iterable<IPortObject> getLinkedPorts() {
+			return linkedPorts; }
 
 		@Override
 		@Adjacency(label = "link")
@@ -338,23 +461,30 @@
 		
 		switches = new ArrayList<TestSwitchObject>();
 		ports = new ArrayList<TestPortObject>();
-//		devices = new ArrayList<TestDeviceObject>();
+		devices = new ArrayList<TestDeviceObject>();
 //		flows = new ArrayList<TestFlowEntry>();
 		
 		switchesToAdd = new ArrayList<TestSwitchObject>();
 		portsToAdd = new ArrayList<TestPortObject>();
-//		devicesToAdd = new ArrayList<TestDeviceObject>();
+		devicesToAdd = new ArrayList<TestDeviceObject>();
 //		flowsToAdd = new ArrayList<TestFlowEntry>();
 
 		switchesToRemove = new ArrayList<TestSwitchObject>();
 		portsToRemove = new ArrayList<TestPortObject>();
-//		devicesToRemove = new ArrayList<TestDeviceObject>();
+		devicesToRemove = new ArrayList<TestDeviceObject>();
 //		flowsToRemove = new ArrayList<TestFlowEntry>();
 		
-		clear();
+		clearUncommitedData();
 	}
 	
-	private void clear() {
+	private void clearUncommitedData() {
+		for(TestDeviceObject dev : devices) {
+			dev.clearUncommitedData();
+		}
+		for(TestDeviceObject dev : devicesToAdd) {
+			dev.clearUncommitedData();
+		}
+		
 		for(TestSwitchObject sw : switches) {
 			sw.clearUncommitedData();
 		}
@@ -369,6 +499,8 @@
 			port.clearUncommitedData();
 		}
 		
+		devicesToAdd.clear();
+		devicesToRemove.clear();
 		switchesToAdd.clear();
 		switchesToRemove.clear();
 		portsToAdd.clear();
@@ -386,6 +518,7 @@
 		for(TestSwitchObject sw_loop : switches) {
 			if(sw_loop.getDPID().equals(dpid)) {
 				// Already created
+				log.error("switch already exists : " + dpid);
 				return sw_loop;
 			}
 		}
@@ -411,6 +544,9 @@
 			TestPortObject port = new TestPortObject();
 			port.setNumberForTest(number);
 			port.setSwitchForTest(sw);
+			sw.addPortForTest(port);
+			
+			ports.add(port);
 
 			return port;
 		} else {
@@ -422,20 +558,56 @@
 		src.addLinkedPortForTest(dst);
 		//dst.addLinkedPortForTest(src);
 	}
+	
+	public boolean hasLinkBetween(String srcSw_str, Short srcNumber, String dstSw_str, Short dstNumber) {
+		IPortObject srcPort = null, dstPort = null;
+		long srcSw = HexString.toLong(srcSw_str);
+		long dstSw = HexString.toLong(dstSw_str);
+		
+		for(TestSwitchObject sw : switches) {
+			long swLong = HexString.toLong(sw.getDPID());
+			if(swLong == srcSw) {
+				for(IPortObject port : sw.getPorts()) {
+					if(port.getNumber().equals(srcNumber)) {
+						srcPort = port;
+					}
+				}
+			} else if(swLong == dstSw) {
+				for(IPortObject port : sw.getPorts()) {
+					if(port.getNumber().equals(dstNumber)) {
+						dstPort = port;
+					}
+				}
+			}
+		}
+		
+		if(srcPort != null && dstPort != null) {
+			for(IPortObject port : srcPort.getLinkedPorts()) {
+				if(port.equals(dstPort)) {
+					return true;
+				}
+			}
+		}
+		
+		return false;
+	}
 
 	// Overriding methods below are to mock GraphDBOperation class.
 	@Override
 	public ISwitchObject newSwitch(String dpid) {
 		TestSwitchObject sw = new TestSwitchObject();
+		sw.setDPID(dpid);
 		switchesToAdd.add(sw);
 		
 		return sw;
 	}
 
 	@Override
-	public ISwitchObject searchSwitch(String dpid) {
+	public ISwitchObject searchSwitch(String dpid_str) {
+		Long dpid = HexString.toLong(dpid_str);
+		
 		for(ISwitchObject sw : switches) {
-			if(sw.getDPID().equals(dpid)) {
+			if(HexString.toLong(sw.getDPID()) == dpid) {
 				return sw;
 			}
 		}
@@ -443,9 +615,11 @@
 	}
 
 	@Override
-	public ISwitchObject searchActiveSwitch(String dpid) {
+	public ISwitchObject searchActiveSwitch(String dpid_str) {
+		Long dpid = HexString.toLong(dpid_str);
+
 		for(ISwitchObject sw : switches) {
-			if(sw.getDPID().equals(dpid) && sw.getState().equals("ACTIVE")) {
+			if(HexString.toLong(sw.getDPID()) == dpid && sw.getState().equals("ACTIVE")) {
 				return sw;
 			}
 		}
@@ -523,8 +697,10 @@
 	
 	@Override
 	public IPortObject searchPort(String dpid_str, short number) {
+		long dpid = HexString.toLong(dpid_str);
+		
 		for(TestSwitchObject sw : switches) {
-			if(sw.getDPID().equals(dpid_str)) {
+			if(HexString.toLong(sw.getDPID()) == dpid) {
 				for(IPortObject port : sw.getPorts()) {
 					if(port.getNumber().equals(number)) {
 						return port;
@@ -654,12 +830,23 @@
 			port.commit();
 		}
 		
-		clear();
+		for(TestDeviceObject dev : devicesToAdd) {
+			devices.add(dev);
+		}
+		for(TestDeviceObject dev : devicesToRemove) {
+			dev.commit();
+			devices.remove(dev);
+		}
+		for(TestDeviceObject dev : devices) {
+			dev.commit();
+		}
+		
+		clearUncommitedData();
 	}
 
 	@Override
 	public void rollback() {
-		clear();
+		clearUncommitedData();
 	}
 
 	@Override