/** * Copyright 2013, Big Switch Networks, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. **/ package net.floodlightcontroller.topology; import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.internal.IOFSwitchService; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.test.MockFloodlightProvider; import net.floodlightcontroller.core.test.MockSwitchManager; import net.floodlightcontroller.core.test.MockThreadPoolService; import net.floodlightcontroller.core.types.NodePortTuple; import net.floodlightcontroller.debugcounter.IDebugCounterService; import net.floodlightcontroller.debugcounter.MockDebugCounterService; import net.floodlightcontroller.linkdiscovery.ILinkDiscovery; import net.floodlightcontroller.linkdiscovery.ILinkDiscoveryService; import net.floodlightcontroller.routing.IRoutingService; import net.floodlightcontroller.routing.Path; import net.floodlightcontroller.routing.RoutingManager; import net.floodlightcontroller.threadpool.IThreadPoolService; import org.easymock.EasyMock; import org.junit.Before; import org.junit.Test; import org.projectfloodlight.openflow.types.DatapathId; import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.U64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import static net.floodlightcontroller.routing.IRoutingService.PATH_METRIC.HOPCOUNT; import static net.floodlightcontroller.routing.IRoutingService.PATH_METRIC.LATENCY; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class TopologyInstanceTest { protected static Logger log = LoggerFactory.getLogger(TopologyInstanceTest.class); protected TopologyManager topologyManager; protected RoutingManager routingManager; protected FloodlightModuleContext fmc; protected ILinkDiscoveryService linkDiscovery; protected MockFloodlightProvider mockFloodlightProvider; protected int DIRECT_LINK = 1; protected int MULTIHOP_LINK = 2; protected int TUNNEL_LINK = 3; @Before public void SetUp() throws Exception { fmc = new FloodlightModuleContext(); linkDiscovery = EasyMock.createMock(ILinkDiscoveryService.class); mockFloodlightProvider = new MockFloodlightProvider(); fmc.addService(IFloodlightProviderService.class, mockFloodlightProvider); fmc.addService(IOFSwitchService.class, new MockSwitchManager()); fmc.addService(ILinkDiscoveryService.class, linkDiscovery); fmc.addService(IDebugCounterService.class, new MockDebugCounterService()); MockThreadPoolService tp = new MockThreadPoolService(); topologyManager = new TopologyManager(); routingManager = new RoutingManager(); fmc.addService(IRoutingService.class, routingManager); fmc.addService(IThreadPoolService.class, tp); fmc.addService(ITopologyService.class, topologyManager); topologyManager.init(fmc); routingManager.init(fmc); routingManager.startUp(fmc); tp.init(fmc); tp.startUp(fmc); } protected void verifyClusters(int[][] clusters) { List<DatapathId> verifiedSwitches = new ArrayList<DatapathId>(); // Make sure the expected cluster arrays are sorted so we can // use binarySearch to test for membership for (int i = 0; i < clusters.length; i++) Arrays.sort(clusters[i]); TopologyInstance ti = topologyManager.getCurrentInstance(); Set<DatapathId> switches = ti.getSwitches(); for (DatapathId sw: switches) { if (!verifiedSwitches.contains(sw)) { int[] expectedCluster = null; for (int j = 0; j < clusters.length; j++) { if (Arrays.binarySearch(clusters[j], (int)sw.getLong()) >= 0) { expectedCluster = clusters[j]; break; } } if (expectedCluster != null) { Set<DatapathId> cluster = ti.getSwitchesInCluster(sw); assertEquals(expectedCluster.length, cluster.size()); for (DatapathId sw2: cluster) { assertTrue(Arrays.binarySearch(expectedCluster, (int)sw2.getLong()) >= 0); verifiedSwitches.add(sw2); } } } } } /*protected void verifyExpectedBroadcastPortsInClusters(int [][][] ebp) { NodePortTuple npt = null; Set<NodePortTuple> expected = new HashSet<NodePortTuple>(); for(int i=0; i<ebp.length; ++i) { int [][] nptList = ebp[i]; expected.clear(); for(int j=0; j<nptList.length; ++j) { npt = new NodePortTuple(DatapathId.of(nptList[j][0]), OFPort.of(nptList[j][1])); expected.add(npt); } TopologyInstance ti = topologyManager.getCurrentInstance(); Set<NodePortTuple> computed = ti.getBroadcastNodePortsInCluster(npt.getNodeId()); log.info("computed: {}", computed); log.info("expected: {}", expected); if (computed != null) assertTrue(computed.equals(expected)); else if (computed == null) assertTrue(expected.isEmpty()); } }*/ public void createTopologyFromLinks(int [][] linkArray) throws Exception { ILinkDiscovery.LinkType type = ILinkDiscovery.LinkType.DIRECT_LINK; // Use topologymanager to write this test, it will make it a lot easier. for (int i = 0; i < linkArray.length; i++) { int [] r = linkArray[i]; if (r[4] == DIRECT_LINK) type= ILinkDiscovery.LinkType.DIRECT_LINK; else if (r[4] == MULTIHOP_LINK) type= ILinkDiscovery.LinkType.MULTIHOP_LINK; else if (r[4] == TUNNEL_LINK) type = ILinkDiscovery.LinkType.TUNNEL; topologyManager.addOrUpdateLink(DatapathId.of(r[0]), OFPort.of(r[1]), DatapathId.of(r[2]), OFPort.of(r[3]), U64.ZERO, type); } topologyManager.createNewInstance(); } private void configureTopology(int [][] linkArray, int [] latency) throws Exception { ILinkDiscovery.LinkType type = ILinkDiscovery.LinkType.DIRECT_LINK; // Use topologymanager to write this test, it will make it a lot easier. for (int i = 0; i < linkArray.length; i++) { int [] r = linkArray[i]; if (r[4] == DIRECT_LINK) type= ILinkDiscovery.LinkType.DIRECT_LINK; else if (r[4] == MULTIHOP_LINK) type= ILinkDiscovery.LinkType.MULTIHOP_LINK; else if (r[4] == TUNNEL_LINK) type = ILinkDiscovery.LinkType.TUNNEL; //Check for valid latency int lat = latency[i]; if(lat < 0 || lat > 10000) lat = 10000; topologyManager.addOrUpdateLink(DatapathId.of(r[0]), OFPort.of(r[1]), DatapathId.of(r[2]), OFPort.of(r[3]), U64.of(lat), type); } topologyManager.createNewInstance(); } public TopologyManager getTopologyManager() { return topologyManager; } @Test public void testClusters() throws Exception { TopologyManager tm = getTopologyManager(); { int [][] linkArray = { {1, 1, 2, 1, DIRECT_LINK}, {2, 2, 3, 2, DIRECT_LINK}, {3, 1, 1, 2, DIRECT_LINK}, {2, 3, 4, 2, DIRECT_LINK}, {3, 3, 4, 1, DIRECT_LINK} }; int [][] expectedClusters = { {1,2,3}, {4} }; createTopologyFromLinks(linkArray); verifyClusters(expectedClusters); } { int [][] linkArray = { {5, 3, 6, 1, DIRECT_LINK} }; int [][] expectedClusters = { {1,2,3}, {4}, {5}, {6} }; createTopologyFromLinks(linkArray); verifyClusters(expectedClusters); } { int [][] linkArray = { {6, 1, 5, 3, DIRECT_LINK} }; int [][] expectedClusters = { {1,2,3}, {4}, {5,6} }; createTopologyFromLinks(linkArray); verifyClusters(expectedClusters); } { int [][] linkArray = { {4, 2, 2, 3, DIRECT_LINK} }; int [][] expectedClusters = { {1,2,3,4}, {5,6} }; createTopologyFromLinks(linkArray); verifyClusters(expectedClusters); } { int [][] linkArray = { {4, 3, 5, 1, DIRECT_LINK} }; int [][] expectedClusters = { {1,2,3,4}, {5,6} }; createTopologyFromLinks(linkArray); verifyClusters(expectedClusters); } { int [][] linkArray = { {5, 2, 2, 4, DIRECT_LINK} }; int [][] expectedClusters = { {1,2,3,4,5,6} }; createTopologyFromLinks(linkArray); verifyClusters(expectedClusters); } //Test 2. { int [][] linkArray = { {3, 2, 2, 2, DIRECT_LINK}, {2, 1, 1, 1, DIRECT_LINK}, {1, 2, 3, 1, DIRECT_LINK}, {4, 1, 3, 3, DIRECT_LINK}, {5, 1, 4, 3, DIRECT_LINK}, {2, 4, 5, 2, DIRECT_LINK} }; int [][] expectedClusters = { {1,2,3,4,5,6} }; createTopologyFromLinks(linkArray); verifyClusters(expectedClusters); } // Test 3. Remove links { tm.removeLink(DatapathId.of(5), OFPort.of((short)3), DatapathId.of(6), OFPort.of((short)1)); tm.removeLink(DatapathId.of(6), OFPort.of((short)1), DatapathId.of(5), OFPort.of((short)3)); int [][] expectedClusters = { {1,2,3,4,5}, }; topologyManager.createNewInstance(); verifyClusters(expectedClusters); } // Remove Switch { tm.removeSwitch(DatapathId.of(4)); int [][] expectedClusters = { {1,2,3,5}, }; topologyManager.createNewInstance(); verifyClusters(expectedClusters); } } @Test public void testLoopDetectionInSingleIsland() throws Exception { int [][] linkArray = { {1, 1, 2, 1, DIRECT_LINK}, {2, 1, 1, 1, DIRECT_LINK}, {1, 2, 3, 1, DIRECT_LINK}, {3, 1, 1, 2, DIRECT_LINK}, {2, 2, 3, 2, DIRECT_LINK}, {3, 2, 2, 2, DIRECT_LINK}, {3, 3, 4, 1, DIRECT_LINK}, {4, 1, 3, 3, DIRECT_LINK}, {4, 2, 6, 2, DIRECT_LINK}, {6, 2, 4, 2, DIRECT_LINK}, {4, 3, 5, 1, DIRECT_LINK}, {5, 1, 4, 3, DIRECT_LINK}, {5, 2, 6, 1, DIRECT_LINK}, {6, 1, 5, 2, DIRECT_LINK}, }; int [][] expectedClusters = { {1, 2, 3, 4, 5, 6} }; int [][][] expectedBroadcastPorts = { {{1,1}, {2,1}, {1,2}, {3,1}, {3,3}, {4,1}, {4,3}, {5,1}, {4,2}, {6,2}}, }; createTopologyFromLinks(linkArray); topologyManager.createNewInstance(); verifyClusters(expectedClusters); //FIXME verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts); } @Test public void testLoopDetectionWithIslands() throws Exception { // +-------+ +-------+ // | | TUNNEL | | // | 1 1|-------------|1 2 | // | 2 | | 2 | // +-------+ +-------+ // | | // | | // +-------+ | // | 1 | | // | 3 2|-----------------+ // | 3 | // +-------+ // // // +-------+ // | 1 | TUNNEL // | 4 2|----------------+ // | 3 | | // +-------+ | // | | // | | // +-------+ +-------+ // | 1 | | 2 | // | 5 2|-------------|1 6 | // | | | | // +-------+ +-------+ { int [][] linkArray = { {1, 1, 2, 1, DIRECT_LINK}, {2, 1, 1, 1, DIRECT_LINK}, {1, 2, 3, 1, DIRECT_LINK}, {3, 1, 1, 2, DIRECT_LINK}, {2, 2, 3, 2, DIRECT_LINK}, {3, 2, 2, 2, DIRECT_LINK}, {4, 2, 6, 2, DIRECT_LINK}, {6, 2, 4, 2, DIRECT_LINK}, {4, 3, 5, 1, DIRECT_LINK}, {5, 1, 4, 3, DIRECT_LINK}, {5, 2, 6, 1, DIRECT_LINK}, {6, 1, 5, 2, DIRECT_LINK}, }; int [][] expectedClusters = { {1, 2, 3}, {4, 5, 6} }; int [][][] expectedBroadcastPorts = { {{1,1}, {2,1}, {1,2}, {3,1}}, {{4,3}, {5,1}, {4,2}, {6,2}}, }; createTopologyFromLinks(linkArray); topologyManager.createNewInstance(); verifyClusters(expectedClusters); //FIXME verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts); } // +-------+ +-------+ // | | TUNNEL | | // | 1 1|-------------|1 2 | // | 2 | | 2 | // +-------+ +-------+ // | | // | | // +-------+ | // | 1 | | // | 3 2|-----------------+ // | 3 | // +-------+ // | // | TUNNEL // | // +-------+ // | 1 | TUNNEL // | 4 2|----------------+ // | 3 | | // +-------+ | // | | // | | // +-------+ +-------+ // | 1 | | 2 | // | 5 2|-------------|1 6 | // | | | | // +-------+ +-------+ { int [][] linkArray = { {3, 3, 4, 1, DIRECT_LINK}, {4, 1, 3, 3, DIRECT_LINK}, }; int [][] expectedClusters = { {1, 2, 3, 4, 5, 6} }; int [][][] expectedBroadcastPorts = { {{1,1}, {2,1}, {1,2}, {3,1}, {3,3}, {4,1}, {4,3}, {5,1}, {4,2}, {6,2}}, }; createTopologyFromLinks(linkArray); topologyManager.createNewInstance(); verifyClusters(expectedClusters); //FIXMEverifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts); } } @Test public void testLinkRemovalOnBroadcastDomainPorts() throws Exception { { int [][] linkArray = { {1, 1, 2, 1, DIRECT_LINK}, {2, 1, 1, 1, DIRECT_LINK}, {1, 2, 3, 1, DIRECT_LINK}, {3, 1, 1, 2, DIRECT_LINK}, {2, 2, 3, 2, DIRECT_LINK}, {3, 2, 2, 2, DIRECT_LINK}, {1, 1, 3, 2, DIRECT_LINK}, // the last link should make ports // (1,1) and (3,2) to be broadcast // domain ports, hence all links // from these ports must be eliminated. }; int [][] expectedClusters = { {1, 3}, {2}, }; createTopologyFromLinks(linkArray); topologyManager.createNewInstance(); if (topologyManager.getCurrentInstance() instanceof TopologyInstance) verifyClusters(expectedClusters); } { int [][] linkArray = { {1, 2, 3, 2, DIRECT_LINK}, // the last link should make ports // (1,1) and (3,2) to be broadcast // domain ports, hence all links // from these ports must be eliminated. }; int [][] expectedClusters = { {1}, {3}, {2}, }; createTopologyFromLinks(linkArray); topologyManager.createNewInstance(); if (topologyManager.getCurrentInstance() instanceof TopologyInstance) verifyClusters(expectedClusters); } } private void verifyRoute(List<Path> r, Integer size) { ArrayList<Path> paths = new ArrayList<Path>(); DatapathId one = DatapathId.of(1); DatapathId two = DatapathId.of(2); DatapathId three = DatapathId.of(3); DatapathId four = DatapathId.of(4); DatapathId five = DatapathId.of(5); DatapathId six = DatapathId.of(6); NodePortTuple one1 = new NodePortTuple(one, OFPort.of(1)); NodePortTuple one2 = new NodePortTuple(one, OFPort.of(2)); NodePortTuple two1 = new NodePortTuple(two, OFPort.of(1)); NodePortTuple two2 = new NodePortTuple(two, OFPort.of(2)); NodePortTuple two3 = new NodePortTuple(two, OFPort.of(3)); NodePortTuple three1 = new NodePortTuple(three, OFPort.of(1)); NodePortTuple three2 = new NodePortTuple(three, OFPort.of(2)); NodePortTuple three3 = new NodePortTuple(three, OFPort.of(3)); NodePortTuple three4 = new NodePortTuple(three, OFPort.of(4)); NodePortTuple four1 = new NodePortTuple(four, OFPort.of(1)); NodePortTuple four2 = new NodePortTuple(four, OFPort.of(2)); NodePortTuple four3 = new NodePortTuple(four, OFPort.of(3)); NodePortTuple four4 = new NodePortTuple(four, OFPort.of(4)); NodePortTuple five1 = new NodePortTuple(five, OFPort.of(1)); NodePortTuple five2 = new NodePortTuple(five, OFPort.of(2)); NodePortTuple five3 = new NodePortTuple(five, OFPort.of(3)); NodePortTuple six1 = new NodePortTuple(six, OFPort.of(1)); NodePortTuple six2 = new NodePortTuple(six, OFPort.of(2)); List<NodePortTuple> route0 = new ArrayList<NodePortTuple>(); route0.add(one1); route0.add(two1); route0.add(two2); route0.add(three1); route0.add(three4); route0.add(six2); Path root0 = new Path(one, six); root0.setPath(route0); paths.add(root0); //log.info("root0: {}", root0); //log.info("r.get(0) {}:", r.get(0)); ArrayList<NodePortTuple> route1 = new ArrayList<NodePortTuple>(); route1.add(one2); route1.add(four1); route1.add(four3); route1.add(three2); route1.add(three4); route1.add(six2); Path root1 = new Path(one, six); root1.setPath(route1); //log.info("root1: {}", root1); //log.info("r.get(1) {}:", r.get(1)); paths.add(root1); ArrayList<NodePortTuple> route2 = new ArrayList<NodePortTuple>(); route2.add(one2); route2.add(four1); route2.add(four4); route2.add(five1); route2.add(five3); route2.add(six1); Path root2 = new Path(one, six); root2.setPath(route2); //log.info("root2: {}", root2); //log.info("r.get(2) {}:", r.get(2)); paths.add(root2); ArrayList<NodePortTuple> route3 = new ArrayList<NodePortTuple>(); route3.add(one1); route3.add(two1); route3.add(two2); route3.add(three1); route3.add(three3); route3.add(five2); route3.add(five3); route3.add(six1); Path root3 = new Path(one, six); root3.setPath(route3); //log.info("root3: {}", root3); //log.info("r.get(3) {}:", r.get(3)); paths.add(root3); ArrayList<NodePortTuple> route4 = new ArrayList<NodePortTuple>(); route4.add(one2); route4.add(four1); route4.add(four3); route4.add(three2); route4.add(three3); route4.add(five2); route4.add(five3); route4.add(six1); Path root4 = new Path(one, six); root4.setPath(route4); //log.info("root4: {}", root4); //log.info("r.get(4) {}:", r.get(4)); paths.add(root4); ArrayList<NodePortTuple> route5 = new ArrayList<NodePortTuple>(); route5.add(one2); route5.add(four1); route5.add(four2); route5.add(two3); route5.add(two2); route5.add(three1); route5.add(three4); route5.add(six2); Path root5 = new Path(one, six); root5.setPath(route5); //log.info("root5: {}", root5); //log.info("r.get(5) {}:", r.get(5)); paths.add(root5); ArrayList<NodePortTuple> route6 = new ArrayList<NodePortTuple>(); route6.add(one2); route6.add(four1); route6.add(four2); route6.add(two3); route6.add(two2); route6.add(three1); route6.add(three3); route6.add(five2); route6.add(five3); route6.add(six1); Path root6 = new Path(one, six); root6.setPath(route6); //log.info("root6: {}", root6); //log.info("r.get(6) {}:", r.get(6)); paths.add(root6); //The heart of the validate function. //Iterates through list and ensures each entry is present. int count = 0; int path_length = 7; for(int i=0; i<size; i++) { for(int j=0; j<path_length; j++) { //This may be redundant, but bear with me... if(paths.get(j).equals(r.get(i))){ assertTrue((paths.get(j)).equals(r.get(i))); count++; break; } } } assertTrue(count == size); } @Test public void testgetPathsFast() throws Exception{ Integer k = 2; DatapathId one = DatapathId.of(1); DatapathId three = DatapathId.of(3); DatapathId six = DatapathId.of(6); /* * FIRST TOPOLOGY * Both link arrays and corresponding latency * array used in this unit test. Shown below is * a graphical representation of the topology. * This topology is entirely weakly-connected * and will form single-switch clusters despite * each link being an inter-cluster/direct link. * It will be detected as a single archipelago * though, since some nodes can reach others * over the weak links. ------- | | -------->|1 '2' 2|-------- | | | | | ------- | | V ------- ------- | 1 | | 2 | | '1' 2|---------------->|1 '3' | | | | | ------- ------- */ int [][] linkArray = { {1, 1, 2, 1, DIRECT_LINK}, {1, 2, 3, 1, DIRECT_LINK}, {2, 2, 3, 2, DIRECT_LINK}, }; int [] lat = {1,50,1}; /* * NOTE: Output from the next four log.info should be mirrored! * Get paths based on latency. */ topologyManager.setPathMetric(LATENCY); configureTopology(linkArray, lat); List<Path> lat_paths = routingManager.getPathsFast(one, three, k); log.info("Path 1: {}", lat_paths.get(0)); log.info("Path 2: {}", lat_paths.get(1)); //Get paths based on hop count topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(HOPCOUNT); configureTopology(linkArray, lat); topologyManager.createNewInstance(); List<Path> hop_paths = routingManager.getPathsFast(one, three, k); log.info("Path 1: {}", hop_paths.get(0)); log.info("Path 2: {}", hop_paths.get(1)); /* * Check if routes equal what the expected output should be. */ topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(LATENCY); int [] lat1 = {1,50,1}; configureTopology(linkArray, lat1); topologyManager.createNewInstance(); List<Path> r1 = routingManager.getPathsFast(one, three, k); assertTrue((r1.get(0)).equals(lat_paths.get(0))); assertTrue((r1.get(1)).equals(lat_paths.get(1))); /* * Check output with bottom latency = -100. */ topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(LATENCY); int [] lat2 = {1,-100,1}; configureTopology(linkArray, lat2); topologyManager.createNewInstance(); log.info("Latency = (-100) => Links: {}", topologyManager.getAllLinks()); /* * Check output with bottom latency = 25000. */ topologyManager.clearCurrentTopology(); int [] lat3 = {1,25000,1}; configureTopology(linkArray, lat3); topologyManager.createNewInstance(); log.info("Latency = (25000) => Links: {}", topologyManager.getAllLinks()); /* * SECOND TOPOLOGY - Multiple latency arrays used. * Shown below is the topology ------- ------- ------- | | | |----->|1 | | '1' 1|----->|1 '2' 2| | '3' 4|----------| | 2 | | 3 | |->|2 3 | | ------- ------- | ------- | | | | | | | | | | | | V | V V | ------- | ------- ------- | | 2 3|---| | 2 | | 2 | |--------->|1 '4' | | '5' 3|----->|1 '6' | | 4|----->|1 | | | ------- ------- ------- */ int [][] linkArray2 = { {1, 1, 2, 1, DIRECT_LINK}, {1, 2, 4, 1, DIRECT_LINK}, {2, 2, 3, 1, DIRECT_LINK}, {3, 3, 5, 2, DIRECT_LINK}, {3, 4, 6, 2, DIRECT_LINK}, {4, 2, 2, 3, DIRECT_LINK}, {4, 3, 3, 2, DIRECT_LINK}, {4, 4, 5, 1, DIRECT_LINK}, {5, 3, 6, 1, DIRECT_LINK}, }; /* * What happens when k > total paths in topology? * All paths should be found. 7 in this case. */ topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(HOPCOUNT); k = 1000; int [] lat4 = {3,2,4,2,1,1,2,3,2}; configureTopology(linkArray2, lat4); topologyManager.createNewInstance(); List<Path> r = routingManager.getPathsFast(one, six, k); for(int i = 0; i< r.size(); i++) { log.info("k = (1000) => Route: {}", r.get(i)); } verifyRoute(r, r.size()); /* * Checking algorithm to see if all paths are found. * Result should be 7 distinct paths. * Total number of paths in topology is SEVEN. */ topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(HOPCOUNT); k = 7; configureTopology(linkArray2, lat4); topologyManager.createNewInstance(); List<Path> r2 = routingManager.getPathsFast(one, six, k); for(int i = 0; i< r2.size(); i++) { log.info("k = (7) => Route: {}", r2.get(i)); } verifyRoute(r2, r2.size()); /* * Test output with negative input value. * No paths should be output as a result. * Based on HOPCOUNT. */ topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(HOPCOUNT); k = -1; configureTopology(linkArray2, lat4); topologyManager.createNewInstance(); List<Path> r3 = routingManager.getPathsFast(one, six, k); for(int i = 0; i< r3.size(); i++) { log.info("HOPCOUNT.k = (-1) => Route: {}", r3.get(i)); } verifyRoute(r3, r3.size()); /* * Test output with negative input value. * No paths should be output as a result. * Based on LATENCY. */ topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(LATENCY); k = -1; configureTopology(linkArray2, lat4); topologyManager.createNewInstance(); List<Path> r4 = routingManager.getPathsFast(one, six, k); for(int i = 0; i< r4.size(); i++) { log.info("LATENCY.k = (-1) => Route: {}", r4.get(i)); } verifyRoute(r4, r4.size()); /* * Simple route checking with less than max routes requested. * In this case, only 3 were requested. * Based on HOPCOUNT. */ topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(HOPCOUNT); k = 3; configureTopology(linkArray2, lat4); topologyManager.createNewInstance(); List<Path> r5 = routingManager.getPathsFast(one, six, k); for(int i = 0; i< r5.size(); i++) { log.info("HOPCOUNT.k = (3) => Route: {}", r5.get(i)); } verifyRoute(r5, r5.size()); /* * Simple route checking with less than max routes requested. * In this case, just 4 out of 7 possibilities requested. * Based on LATENCY. */ topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(LATENCY); k = 4; configureTopology(linkArray2, lat4); topologyManager.createNewInstance(); List<Path> r6 = routingManager.getPathsFast(one, six, k); for(int i = 0; i< r6.size(); i++) { log.info("LATENCY.k = (4) => Route: {}", r6.get(i)); } verifyRoute(r6, r6.size()); /* * Test output with all latency links set to zero. * Should return four of the first paths that yen's algorithm calculated. * Order of output here is of no concern. */ topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(LATENCY); k = 4; int [] lat5 = {0,0,0,0,0,0,0,0,0}; configureTopology(linkArray2, lat5); topologyManager.createNewInstance(); List<Path> r7 = routingManager.getPathsFast(one, six, k); for(int i = 0; i< r7.size(); i++) { log.info("Route latency all ZERO: {}", r7.get(i)); } verifyRoute(r7, r7.size()); /* * Check topology with same switch input: 1 -> 1. * Should have no output. */ topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(HOPCOUNT); k = 4; configureTopology(linkArray2, lat4); topologyManager.createNewInstance(); List<Path> r8 = routingManager.getPathsFast(one, one, k); for(int i = 0; i< r8.size(); i++) { log.info("(src == dst) => Route: {}", r8.get(i)); } verifyRoute(r8, r8.size()); /* * Check topology with reverse input: 6 -> 1 instead of 1 -> 6 * Should have no output since it is impossible to get from 6 to 1. */ topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(HOPCOUNT); k = 4; configureTopology(linkArray2, lat4); topologyManager.createNewInstance(); List<Path> r9 = routingManager.getPathsFast(six, one, k); for(int i = 0; i< r9.size(); i++) { log.info("Reversed Route (6 -> 1): {}", r9.get(i)); } verifyRoute(r9, r9.size()); /* * Check topology with invalid node numbers. * Try to use src == 7 * Output should indicate no valid route. */ topologyManager.clearCurrentTopology(); topologyManager.setPathMetric(HOPCOUNT); k = 4; configureTopology(linkArray2, lat4); topologyManager.createNewInstance(); List<Path> r10 = routingManager.getPathsFast(one, DatapathId.of(7), k); for(int i = 0; i< r10.size(); i++) { log.info("(src == 7) => Route: {}", r10.get(i)); } verifyRoute(r10, r10.size()); } }