From cfcf4c6d9d81ad607513761b5077eb6ffb0ae917 Mon Sep 17 00:00:00 2001
From: Srinivasan Ramasubramanian <srini@bigswitch.com>
Date: Sun, 24 Jun 2012 07:49:37 -0700
Subject: [PATCH] Refactoring Route class and getRoute() methods to maintain
 and provide a sequence of switch-ports, rather than links.  Update unit tests
 accordingly.

---
 .../forwarding/Forwarding.java                |  10 +-
 .../routing/ForwardingBase.java               | 177 +++++++-----------
 .../floodlightcontroller/routing/Route.java   |  64 ++-----
 .../topology/TopologyInstance.java            |  37 +++-
 .../forwarding/ForwardingTest.java            |  20 +-
 .../routing/RouteTest.java                    |  28 +--
 6 files changed, 151 insertions(+), 185 deletions(-)

diff --git a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
index e8aeeca05..59c4e3925 100644
--- a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
@@ -160,8 +160,10 @@ public class Forwarding extends ForwardingBase implements IFloodlightModule {
                         (srcCluster != null) && 
                         (dstCluster != null)) {
                         Route route = 
-                                routingEngine.getRoute(srcDap.getSwitchDPID(), 
-                                                       dstDap.getSwitchDPID());
+                                routingEngine.getRoute(srcDap.getSwitchDPID(),
+                                                       (short)srcDap.getPort(),
+                                                       dstDap.getSwitchDPID(),
+                                                       (short)dstDap.getPort());
                         if ((route != null) || validLocalHop(srcDap, dstDap)) {
                             int bufferId = OFPacketOut.BUFFER_ID_NONE;
                             if (log.isTraceEnabled()) {
@@ -174,8 +176,8 @@ public class Forwarding extends ForwardingBase implements IFloodlightModule {
                             long cookie = 
                                     AppCookie.makeCookie(FORWARDING_APP_ID, 0);
                             pushRoute(route, match, 0,
-                                      srcDap, dstDap, bufferId,
-                                      sw, pi, cookie, cntx, 
+                                      bufferId,
+                                      pi, sw.getId(), cookie, cntx, 
                                       requestFlowRemovedNotifn, false,
                                       OFFlowMod.OFPFC_ADD);
                         }
diff --git a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
index a0158bd5c..595c1ef86 100644
--- a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
+++ b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
@@ -23,7 +23,6 @@ import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 
 import net.floodlightcontroller.core.FloodlightContext;
 import net.floodlightcontroller.core.IFloodlightProviderService;
@@ -38,9 +37,9 @@ import net.floodlightcontroller.devicemanager.SwitchPort;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.routing.IRoutingService;
 import net.floodlightcontroller.routing.IRoutingDecision;
-import net.floodlightcontroller.routing.Link;
 import net.floodlightcontroller.routing.Route;
 import net.floodlightcontroller.topology.ITopologyService;
+import net.floodlightcontroller.topology.NodePortTuple;
 import net.floodlightcontroller.util.TimedCache;
 
 import org.openflow.protocol.OFFlowMod;
@@ -52,7 +51,6 @@ import org.openflow.protocol.OFPort;
 import org.openflow.protocol.OFType;
 import org.openflow.protocol.action.OFAction;
 import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.util.HexString;
 import org.openflow.util.U16;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -168,9 +166,10 @@ public abstract class ForwardingBase implements
      */
     public boolean pushRoute(Route route, OFMatch match, 
                              Integer wildcard_hints,
-                             SwitchPort srcSwPort,
-                             SwitchPort dstSwPort, int bufferId,
-                             IOFSwitch srcSwitch, OFPacketIn pi, long cookie, 
+                             int bufferId,
+                             OFPacketIn pi,
+                             long pinSwitch,
+                             long cookie, 
                              FloodlightContext cntx,
                              boolean reqeustFlowRemovedNotifn,
                              boolean doFlush,
@@ -183,6 +182,7 @@ public abstract class ForwardingBase implements
         OFActionOutput action = new OFActionOutput();
         List<OFAction> actions = new ArrayList<OFAction>();
         actions.add(action);
+
         fm.setIdleTimeout((short)5)
             .setBufferId(OFPacketOut.BUFFER_ID_NONE)
             .setCookie(cookie)
@@ -191,116 +191,79 @@ public abstract class ForwardingBase implements
             .setActions(actions)
             .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
 
-        Map<Long, IOFSwitch> switches = floodlightProvider.getSwitches();
-        IOFSwitch sw = switches.get(dstSwPort.getSwitchDPID());
-        ((OFActionOutput)fm.getActions().get(0)).
-            setPort((short)dstSwPort.getPort());
-
-        if (route != null) {
-            for (int routeIndx = route.getPath().size() - 1; routeIndx >= 0; --routeIndx) {
-                Link link = route.getPath().get(routeIndx);
-                fm.setMatch(wildcard(match, sw, wildcard_hints));
-                fm.getMatch().setInputPort(link.getDstPort());
-                try {
-                    counterStore.updatePktOutFMCounterStore(sw, fm);
-                    if (log.isTraceEnabled()) {
-                        log.trace("Pushing Route flowmod routeIndx={} " + 
-                                  "sw={} inPort={} outPort={}",
-                                  new Object[] {routeIndx,
-                                                sw,
-                                                fm.getMatch().getInputPort(),
-                                                ((OFActionOutput)
-                                                        fm.getActions()
-                                                        .get(0)).getPort() });
-                    }
-                    sw.write(fm, cntx);
-                    if (doFlush) {
-                        sw.flush();
-                    }
-
-                    // Push the packet out the source switch
-                    if (sw.getId() == srcSwitch.getId()) {
-                        pushPacket(srcSwitch,
-                                   match,
-                                   pi,
-                                   ((OFActionOutput) fm.getActions().get(0)).getPort(),
-                                   cntx);
-                        srcSwitchIncluded = true;
-                    }
-                } catch (IOException e) {
-                    log.error("Failure writing flow mod", e);
-                }
-                try {
-                    fm = fm.clone();
-                } catch (CloneNotSupportedException e) {
-                    log.error("Failure cloning flow mod", e);
-                }
+        List<NodePortTuple> switchPortList = route.getPath();
 
-                // setup for the next loop iteration
-                ((OFActionOutput)fm.getActions().get(0)).setPort(link.getSrcPort());
-                if (routeIndx > 0) {
-                    sw =
-                            floodlightProvider.getSwitches()
-                                              .get(route.getPath()
-                                                        .get(routeIndx - 1)
-                                                        .getDst());
-                } else {
-                    sw =
-                            floodlightProvider.getSwitches()
-                                              .get(route.getId().getSrc());
+        for (int indx = switchPortList.size()-1; indx > 0; indx -= 2) {
+            // indx and indx-1 will always have the same switch DPID.
+            long switchDPID = switchPortList.get(indx).getNodeId();
+            IOFSwitch sw = floodlightProvider.getSwitches().get(switchDPID);
+            if (sw == null) {
+                if (log.isWarnEnabled()) {
+                    log.warn("Unable to push route, switch at DPID {} " +
+                            "not available", switchDPID);
                 }
-                if (sw == null) {
-                    if (log.isWarnEnabled()) {
-                        log.warn("Unable to push route, switch at DPID {} not available",
-                                 (routeIndx > 0)
-                                         ? HexString.toHexString(route.getPath()
-                                                                      .get(routeIndx - 1)
-                                                                      .getDst())
-                                         : HexString.toHexString(route.getId()
-                                                                      .getSrc()));
-                    }
-                    return srcSwitchIncluded;
+                return srcSwitchIncluded;
+            }
+
+            // set the match.
+            fm.setMatch(wildcard(match, sw, wildcard_hints));
+
+            // set buffer id if it is the source switch
+            if (1 == indx) {
+                //fm.setMatch(match);
+                fm.setBufferId(bufferId);
+                //fm.setMatch(wildcard(match, sw, wildcard_hints));
+                // Set the flag to request flow-mod removal notifications only for the
+                // source switch. The removal message is used to maintain the flow
+                // cache. Don't set the flag for ARP messages - TODO generalize check
+                if ((reqeustFlowRemovedNotifn)
+                        && (match.getDataLayerType() != Ethernet.TYPE_ARP)) {
+                    fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
+                    match.setWildcards(fm.getMatch().getWildcards());
                 }
             }
-        }
 
-        // set the original match for the first switch, and buffer id
-        fm.setMatch(match);
-        fm.setBufferId(bufferId);
-        fm.setMatch(wildcard(match, sw, wildcard_hints));
-        fm.getMatch().setInputPort((short) srcSwPort.getPort());
-        // Set the flag to request flow-mod removal notifications only for the
-        // source switch. The removal message is used to maintain the flow
-        // cache. Don't set the flag for ARP messages - TODO generalize check
-        if ((reqeustFlowRemovedNotifn)
-                && (match.getDataLayerType() != Ethernet.TYPE_ARP)) {
-            fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
-            match.setWildcards(fm.getMatch().getWildcards());
-        }
+            short outPort = switchPortList.get(indx).getPortId();
+            short inPort = switchPortList.get(indx-1).getPortId();
+            // set input and output ports on the switch
+            fm.getMatch().setInputPort(inPort);
+            ((OFActionOutput)fm.getActions().get(0)).setPort(outPort);
 
-        try {
-            counterStore.updatePktOutFMCounterStore(sw, fm);
-            if (log.isDebugEnabled()) {
-                log.debug("pushRoute flowmod sw={} inPort={} outPort={}",
-                      new Object[] { sw, fm.getMatch().getInputPort(), 
-                                    ((OFActionOutput)fm.getActions().get(0)).getPort() });
-            }
-            sw.write(fm, cntx);
-            if (doFlush) {
-                sw.flush();
+            try {
+                counterStore.updatePktOutFMCounterStore(sw, fm);
+                if (log.isTraceEnabled()) {
+                    log.trace("Pushing Route flowmod routeIndx={} " + 
+                            "sw={} inPort={} outPort={}",
+                            new Object[] {indx,
+                                          sw,
+                                          fm.getMatch().getInputPort(),
+                                          ((OFActionOutput)
+                                                  fm.getActions()
+                                                  .get(0)).getPort() });
+                }
+                sw.write(fm, cntx);
+                if (doFlush) {
+                    sw.flush();
+                }
+
+                // Push the packet out the source switch
+                if (sw.getId() == pinSwitch) {
+                    pushPacket(sw,
+                               match,
+                               pi,
+                               ((OFActionOutput) fm.getActions().get(0)).getPort(),
+                               cntx);
+                    srcSwitchIncluded = true;
+                }
+            } catch (IOException e) {
+                log.error("Failure writing flow mod", e);
             }
 
-            if (sw.getId() == srcSwitch.getId()) {
-                pushPacket(srcSwitch,
-                           match,
-                           pi,
-                           ((OFActionOutput) fm.getActions().get(0)).getPort(),
-                           cntx);
-                srcSwitchIncluded = true;
+            try {
+                fm = fm.clone();
+            } catch (CloneNotSupportedException e) {
+                log.error("Failure cloning flow mod", e);
             }
-            match = fm.getMatch();
-        } catch (IOException e) {
-            log.error("Failure writing flow mod", e);
         }
 
         return srcSwitchIncluded;
diff --git a/src/main/java/net/floodlightcontroller/routing/Route.java b/src/main/java/net/floodlightcontroller/routing/Route.java
index 865ec97f1..211a924f7 100755
--- a/src/main/java/net/floodlightcontroller/routing/Route.java
+++ b/src/main/java/net/floodlightcontroller/routing/Route.java
@@ -20,6 +20,8 @@ package net.floodlightcontroller.routing;
 import java.util.ArrayList;
 import java.util.List;
 
+import net.floodlightcontroller.topology.NodePortTuple;
+
 /**
  * Represents a route between two switches
  *
@@ -27,52 +29,18 @@ import java.util.List;
  */
 public class Route implements Comparable<Route> {
     protected RouteId id;
-    protected List<Link> path;
+    protected List<NodePortTuple> switchPorts;
 
-    public Route(RouteId id, List<Link> path) {
+    public Route(RouteId id, List<NodePortTuple> switchPorts) {
         super();
         this.id = id;
-        this.path = path;
+        this.switchPorts = switchPorts;
     }
 
     public Route(Long src, Long dst) {
         super();
         this.id = new RouteId(src, dst);
-        this.path = new ArrayList<Link>();
-    }
-
-    /**
-     * Concise way to instantiate a route.  The format of objects must be:
-     *  (Short/Integer outPort, Short/Integer inPort, Long dstDpid)*
-     * @param srcDpid
-     * @param objects
-     */
-    public Route(Long srcId, Object... routeElements) {
-        super();
-        this.path = new ArrayList<Link>();
-        if (routeElements.length % 3 > 0)
-            throw new RuntimeException("routeElements must be a multiple of 3");
-        long s; 
-        Short srcPort, dstPort;
-
-        s = srcId;
-        for (int i = 0; i < routeElements.length; i += 3) {
-            if (routeElements[i] instanceof Short)
-                srcPort = (Short) routeElements[i];
-            else
-                srcPort = ((Integer)routeElements[i]).shortValue();
-
-            if (routeElements[i+1] instanceof Short)
-                dstPort = (Short) routeElements[i+1];
-            else
-                dstPort = ((Integer)routeElements[i+1]).shortValue();
-
-            this.path.add(new Link(s, srcPort, ((Long) routeElements[i + 2]), dstPort));
-            
-            s = (Long) routeElements[i + 2];
-        }
-        this.id = new RouteId(srcId, (this.path.size() == 0) ? srcId
-                : this.path.get(this.path.size() - 1).getDst());
+        this.switchPorts = new ArrayList<NodePortTuple>();
     }
 
     /**
@@ -92,15 +60,15 @@ public class Route implements Comparable<Route> {
     /**
      * @return the path
      */
-    public List<Link> getPath() {
-        return path;
+    public List<NodePortTuple> getPath() {
+        return switchPorts;
     }
 
     /**
      * @param path the path to set
      */
-    public void setPath(List<Link> path) {
-        this.path = path;
+    public void setPath(List<NodePortTuple> switchPorts) {
+        this.switchPorts = switchPorts;
     }
 
     @Override
@@ -108,7 +76,7 @@ public class Route implements Comparable<Route> {
         final int prime = 5791;
         int result = 1;
         result = prime * result + ((id == null) ? 0 : id.hashCode());
-        result = prime * result + ((path == null) ? 0 : path.hashCode());
+        result = prime * result + ((switchPorts == null) ? 0 : switchPorts.hashCode());
         return result;
     }
 
@@ -126,17 +94,17 @@ public class Route implements Comparable<Route> {
                 return false;
         } else if (!id.equals(other.id))
             return false;
-        if (path == null) {
-            if (other.path != null)
+        if (switchPorts == null) {
+            if (other.switchPorts != null)
                 return false;
-        } else if (!path.equals(other.path))
+        } else if (!switchPorts.equals(other.switchPorts))
             return false;
         return true;
     }
 
     @Override
     public String toString() {
-        return "Route [id=" + id + ", path=" + path + "]";
+        return "Route [id=" + id + ", switchPorts=" + switchPorts + "]";
     }
 
     /**
@@ -144,6 +112,6 @@ public class Route implements Comparable<Route> {
      */
     @Override
     public int compareTo(Route o) {
-        return ((Integer)path.size()).compareTo(o.path.size());
+        return ((Integer)switchPorts.size()).compareTo(o.switchPorts.size());
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java b/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java
index d2ea16d6a..906ab25ce 100644
--- a/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java
+++ b/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java
@@ -4,6 +4,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.PriorityQueue;
 import java.util.Set;
@@ -534,16 +535,21 @@ public class TopologyInstance {
     }
 
     protected Route buildroute(RouteId id, long srcId, long dstId) {
-        LinkedList<Link> path =  new LinkedList<Link>();
+        NodePortTuple npt;
+
+        LinkedList<NodePortTuple> switchPorts =
+                new LinkedList<NodePortTuple>();
 
         if (destinationRootedTrees == null) return null;
         if (destinationRootedTrees.get(dstId) == null) return null;
 
-        Map<Long, Link> nexthoplinks = destinationRootedTrees.get(dstId).getLinks();
+        Map<Long, Link> nexthoplinks =
+                destinationRootedTrees.get(dstId).getLinks();
 
         if (!switches.contains(srcId) || !switches.contains(dstId)) {
             // This is a switch that is not connected to any other switch
-            // hence there was no update for links (and hence it is not in the network)
+            // hence there was no update for links (and hence it is not
+            // in the network)
             log.debug("buildroute: Standalone switch: {}", srcId);
 
             // The only possible non-null path for this case is
@@ -552,14 +558,19 @@ public class TopologyInstance {
         } else if ((nexthoplinks!=null) && (nexthoplinks.get(srcId)!=null)) {
             while (srcId != dstId) {
                 Link l = nexthoplinks.get(srcId);
-                path.addLast(l);
+
+                npt = new NodePortTuple(l.getSrc(), l.getSrcPort());
+                switchPorts.addLast(npt);
+                npt = new NodePortTuple(l.getDst(), l.getDstPort());
+                switchPorts.addLast(npt);
                 srcId = nexthoplinks.get(srcId).getDst();
             }
         }
         // else, no path exists, and path equals null
 
         Route result = null;
-        if (path != null && !path.isEmpty()) result = new Route(id, path);
+        if (switchPorts != null && !switchPorts.isEmpty()) 
+            result = new Route(id, switchPorts);
         if (log.isTraceEnabled()) {
             log.trace("buildroute: {}", result);
         }
@@ -591,9 +602,19 @@ public class TopologyInstance {
 
     protected Route getRoute(long srcId, short srcPort,
                              long dstId, short dstPort) {
-        // currently ignores source and dst ports.
-        // if needed we can get different paths.
-        return getRoute(srcId, dstId);
+        NodePortTuple npt;
+        Route r = getRoute(srcId, dstId);
+        if (r == null && srcId != dstId) return null;
+
+        RouteId id = new RouteId(srcId, dstId);
+
+        List<NodePortTuple> nptList= r.getPath();
+        npt = new NodePortTuple(srcId, srcPort);
+        nptList.add(0, npt); // add src port to the front
+        npt = new NodePortTuple(dstId, dstPort);
+        nptList.add(npt); // add dst port to the end
+
+        return new Route(id, nptList);
     }
 
     protected Route getRoute(long srcId, long dstId) {
diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
index bdaf264b3..96f1a2bc3 100644
--- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
+++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
@@ -49,11 +49,11 @@ import net.floodlightcontroller.packet.IPacket;
 import net.floodlightcontroller.packet.IPv4;
 import net.floodlightcontroller.packet.UDP;
 import net.floodlightcontroller.routing.IRoutingService;
-import net.floodlightcontroller.routing.Link;
 import net.floodlightcontroller.routing.Route;
 import net.floodlightcontroller.test.FloodlightTestCase;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.floodlightcontroller.topology.ITopologyService;
+import net.floodlightcontroller.topology.NodePortTuple;
 import net.floodlightcontroller.flowcache.FlowReconcileManager;
 import net.floodlightcontroller.flowcache.IFlowReconcileService;
 import net.floodlightcontroller.forwarding.Forwarding;
@@ -257,9 +257,13 @@ public class ForwardingTest extends FloodlightTestCase {
                 dstDevice1);
 
         Route route = new Route(1L, 2L);
-        route.setPath(new ArrayList<Link>());
-        route.getPath().add(new Link(1L, (short)3, 2L, (short)1));
-        expect(routingEngine.getRoute(1L, 2L)).andReturn(route).atLeastOnce();
+        List<NodePortTuple> nptList = new ArrayList<NodePortTuple>();
+        nptList.add(new NodePortTuple(1L, (short)1));
+        nptList.add(new NodePortTuple(1L, (short)3));
+        nptList.add(new NodePortTuple(2L, (short)1));
+        nptList.add(new NodePortTuple(2L, (short)3));
+        route.setPath(nptList);
+        expect(routingEngine.getRoute(1L, (short)1, 2L, (short)3)).andReturn(route).atLeastOnce();
 
         // Expected Flow-mods
         OFMatch match = new OFMatch();
@@ -337,8 +341,12 @@ public class ForwardingTest extends FloodlightTestCase {
             put(cntx, 
                 IDeviceService.CONTEXT_DST_DEVICE, 
                 dstDevice2);
-        expect(routingEngine.getRoute(1L, 1L)).andReturn(null).atLeastOnce();
-        
+
+        Route route = new  Route(1L, 1L);
+        route.getPath().add(new NodePortTuple(1L, (short)1));
+        route.getPath().add(new NodePortTuple(1L, (short)3));
+        expect(routingEngine.getRoute(1L, (short)1, 1L, (short)3)).andReturn(route).atLeastOnce();
+
         // Expected Flow-mods
         OFMatch match = new OFMatch();
         match.loadFromPacket(testPacketSerialized, (short) 1);
diff --git a/src/test/java/net/floodlightcontroller/routing/RouteTest.java b/src/test/java/net/floodlightcontroller/routing/RouteTest.java
index 433ab7c23..3bd039898 100644
--- a/src/test/java/net/floodlightcontroller/routing/RouteTest.java
+++ b/src/test/java/net/floodlightcontroller/routing/RouteTest.java
@@ -19,9 +19,9 @@ package net.floodlightcontroller.routing;
 
 import org.junit.Test;
 
-import net.floodlightcontroller.routing.Link;
 import net.floodlightcontroller.routing.Route;
 import net.floodlightcontroller.test.FloodlightTestCase;
+import net.floodlightcontroller.topology.NodePortTuple;
 
 /**
  *
@@ -32,28 +32,32 @@ public class RouteTest extends FloodlightTestCase {
     public void testCloneable() throws Exception {
         Route r1 = new Route(1L, 2L);
         Route r2 = new Route(1L, 3L);
-        
+
         assertNotSame(r1, r2);
         assertNotSame(r1.getId(), r2.getId());
 
         r1 = new Route(1L, 3L);
-        r1.getPath().add(new Link(1L, (short)1, 2L, (short)1));
-        r1.getPath().add(new Link(2L, (short)2, 3L, (short)1));
-        
-        r2.getPath().add(new Link(1L, (short)1, 2L, (short)1));
-        r2.getPath().add(new Link(2L, (short)2, 3L, (short)1));
-        
+        r1.getPath().add(new NodePortTuple(1L, (short)1));
+        r1.getPath().add(new NodePortTuple(2L, (short)1));
+        r1.getPath().add(new NodePortTuple(2L, (short)2));
+        r1.getPath().add(new NodePortTuple(3L, (short)1));
+
+        r2.getPath().add(new NodePortTuple(1L, (short)1));
+        r2.getPath().add(new NodePortTuple(2L, (short)1));
+        r2.getPath().add(new NodePortTuple(2L, (short)2));
+        r2.getPath().add(new NodePortTuple(3L, (short)1));
+
         assertEquals(r1, r2);
 
-        Link temp = r2.getPath().remove(0);
+        NodePortTuple temp = r2.getPath().remove(0);
         assertNotSame(r1, r2);
 
         r2.getPath().add(0, temp);
         assertEquals(r1, r2);
 
-        r2.getPath().remove(0);
-        temp = new Link(1L, (short)1, 2L, (short)5);
-        r2.getPath().add(0, temp);
+        r2.getPath().remove(1);
+        temp = new NodePortTuple(2L, (short)5);
+        r2.getPath().add(1, temp);
         assertNotSame(r1, r2);
     }
 }
-- 
GitLab