Unit tests for the topologymanager class
Change-Id: I4258957f72e17da737d707faab3f360ee642062e
diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyManager.java b/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
index 2e95c6c..d57613b 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
@@ -59,7 +59,7 @@
public static final String EVENT_CHANNEL_NAME = "onos.topology";
private EventHandler eventHandler = new EventHandler();
- private final TopologyDatastore datastore;
+ private TopologyDatastore datastore;
private final TopologyImpl topology = new TopologyImpl();
private final IControllerRegistryService registryService;
private CopyOnWriteArrayList<ITopologyListener> topologyListeners;
@@ -1241,4 +1241,14 @@
return collection;
}
+ /**
+ * Replaces the internal datastore instance.
+ *
+ * @param dataStore instance
+ *
+ * @exclude Backdoor for unit testing purpose only, do not use.
+ */
+ void debugReplaceDataStore(final TopologyDatastore dataStoreService) {
+ this.datastore = dataStoreService;
+ }
}
diff --git a/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java b/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java
new file mode 100644
index 0000000..934ce7d
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java
@@ -0,0 +1,324 @@
+package net.onrc.onos.core.topology;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.datagrid.IDatagridService;
+import net.onrc.onos.core.datagrid.IEventChannel;
+import net.onrc.onos.core.datagrid.IEventChannelListener;
+import net.onrc.onos.core.registry.IControllerRegistryService;
+import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.PortNumber;
+import net.onrc.onos.core.util.SwitchPort;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for the TopologyManager class in the Topology module.
+ * These test cases only check the sanity of functions in the TopologyManager.
+ * Note that we do not test the eventHandler functions in the TopologyManager class.
+ * DatagridService, DataStoreService, eventChannel, and controllerRegistryService are mocked out.
+ */
+public class TopologyManagerTest {
+ private TopologyManager theTopologyManager;
+ private final String eventChannelName = "onos.topology";
+ private IEventChannel<byte[], TopologyEvent> eventChannel;
+ private IDatagridService datagridService;
+ private TopologyDatastore dataStoreService;
+ private IControllerRegistryService registryService;
+ private CopyOnWriteArrayList<ITopologyListener> topologyListeners;
+ private Collection<TopologyEvent> allTopologyEvents;
+
+ @SuppressWarnings("unchecked")
+ @Before
+ public void setUp() throws Exception {
+ // Mock objects for testing
+ datagridService = EasyMock.createNiceMock(IDatagridService.class);
+ dataStoreService = EasyMock.createNiceMock(TopologyDatastore.class);
+ registryService = createMock(IControllerRegistryService.class);
+ eventChannel = EasyMock.createNiceMock(IEventChannel.class);
+
+ expect(datagridService.createChannel(
+ eq(eventChannelName),
+ eq(byte[].class),
+ eq(TopologyEvent.class)))
+ .andReturn(eventChannel).once();
+
+ expect(datagridService.addListener(
+ eq(eventChannelName),
+ anyObject(IEventChannelListener.class),
+ eq(byte[].class),
+ eq(TopologyEvent.class)))
+ .andReturn(eventChannel).once();
+
+ expect(dataStoreService.addSwitch(
+ anyObject(SwitchEvent.class),
+ anyObject(Collection.class)))
+ .andReturn(true).anyTimes();
+
+ expect(dataStoreService.deactivateSwitch(
+ anyObject(SwitchEvent.class),
+ anyObject(Collection.class)))
+ .andReturn(true).anyTimes();
+
+ expect(dataStoreService.addPort(
+ anyObject(PortEvent.class)))
+ .andReturn(true).anyTimes();
+
+ expect(dataStoreService.deactivatePort(
+ anyObject(PortEvent.class)))
+ .andReturn(true).anyTimes();
+
+ expect(dataStoreService.addDevice(
+ anyObject(DeviceEvent.class)))
+ .andReturn(true).anyTimes();
+
+ expect(dataStoreService.removeDevice(
+ anyObject(DeviceEvent.class)))
+ .andReturn(true).anyTimes();
+
+ expect(dataStoreService.addLink(
+ anyObject(LinkEvent.class)))
+ .andReturn(true).anyTimes();
+
+ expect(dataStoreService.removeLink(
+ anyObject(LinkEvent.class)))
+ .andReturn(true).anyTimes();
+
+ replay(datagridService);
+ replay(registryService);
+ replay(dataStoreService);
+
+ allTopologyEvents = new CopyOnWriteArrayList<>();
+ expect(eventChannel.getAllEntries()).andReturn(allTopologyEvents);
+ EasyMock.expectLastCall().anyTimes();
+
+ // Create a topologyManager object for testing
+ topologyListeners = new CopyOnWriteArrayList<>();
+ theTopologyManager = new TopologyManager(registryService, topologyListeners);
+ theTopologyManager.startup(datagridService);
+ theTopologyManager.debugReplaceDataStore(dataStoreService);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ }
+
+ /**
+ * Test the Switch discovered and Port discovered functions.
+ */
+ @Test
+ public void testPutSwitchAndPortDiscoveryEvent() {
+ // Mock the eventChannel functions first
+ eventChannel.addEntry(anyObject(byte[].class),
+ anyObject(TopologyEvent.class));
+ EasyMock.expectLastCall().times(3, 3); // (1 switch + 1 port), 1 port
+ replay(eventChannel);
+
+ // mockSwitch has one port
+ Dpid swDPId = new Dpid(100L);
+ PortNumber portId = new PortNumber((short) 1);
+
+ // Generate a new switch event along with a port event
+ SwitchEvent switchEvent = new SwitchEvent(swDPId);
+
+ Collection<PortEvent> portEvents = new ArrayList<PortEvent>();
+ portEvents.add(new PortEvent(swDPId, portId));
+
+ // Call the topologyManager function for adding a switch
+ theTopologyManager.putSwitchDiscoveryEvent(switchEvent, portEvents);
+
+ for (PortEvent portEvent : portEvents) {
+ // Call the topologyManager function for adding a port
+ theTopologyManager.putPortDiscoveryEvent(portEvent);
+ }
+
+ // Verify the function calls
+ verify(eventChannel);
+
+ }
+
+ /**
+ * Test the switch and port removed functions.
+ */
+ @Test
+ public void testRemoveSwitchAndPortDiscoveryEvent() {
+ // Mock the eventChannel functions first
+ eventChannel.removeEntry(anyObject(byte[].class));
+ EasyMock.expectLastCall().times(2, 2); //1 switch, 1 port
+ replay(eventChannel);
+
+ Dpid swDPId = new Dpid(100L);
+ PortNumber portId = new PortNumber((short) 1);
+
+ // Generate a port event
+ Collection<PortEvent> portEvents = new ArrayList<PortEvent>();
+ portEvents.add(new PortEvent(swDPId, portId));
+
+ // Call the topologyManager function for removing a port
+ for (PortEvent portEvent : portEvents) {
+ theTopologyManager.removePortDiscoveryEvent(portEvent);
+ }
+
+ // Call the topologyManager function for removing a switch
+ SwitchEvent switchEvent = new SwitchEvent(swDPId);
+ theTopologyManager.removeSwitchDiscoveryEvent(switchEvent);
+
+ // Verify the function calls
+ verify(eventChannel);
+
+ }
+
+ /**
+ * Test the device discovered function.
+ */
+ @Test
+ public void testPutDeviceDiscoveryEvent() {
+ // Mock the eventChannel functions first
+ eventChannel.addEntry(anyObject(byte[].class),
+ anyObject(TopologyEvent.class));
+ EasyMock.expectLastCall().times(1, 1); // 1 device
+ replay(eventChannel);
+
+ long swDPId = 100L;
+ long portId = 1L;
+
+ // Generate a new device event
+ MACAddress devMac = MACAddress.valueOf("00:AA:11:BB:33:CC");
+ SwitchPort sp = new SwitchPort(swDPId, portId);
+ List<SwitchPort> spLists = new ArrayList<SwitchPort>();
+ spLists.add(sp);
+ DeviceEvent deviceEvent = new DeviceEvent(devMac);
+ deviceEvent.setAttachmentPoints(spLists);
+
+ // Call the topologyManager function for adding a device
+ theTopologyManager.putDeviceDiscoveryEvent(deviceEvent);
+
+ // Verify the function calls
+ verify(eventChannel);
+ }
+
+ /**
+ * Test the device removed function.
+ */
+ @Test
+ public void testRemoveDeviceDiscoveryEvent() {
+ // Mock the eventChannel functions first
+ eventChannel.removeEntry(anyObject(byte[].class));
+ EasyMock.expectLastCall().times(1, 1); // 1 device
+ replay(eventChannel);
+
+ long swDPId = 100L;
+ long portId = 1L;
+
+ // Generate a new device event
+ MACAddress devMac = MACAddress.valueOf("00:AA:11:BB:33:CC");
+ SwitchPort sp = new SwitchPort(swDPId, portId);
+ List<SwitchPort> spLists = new ArrayList<SwitchPort>();
+ spLists.add(sp);
+ DeviceEvent deviceEvent = new DeviceEvent(devMac);
+ deviceEvent.setAttachmentPoints(spLists);
+
+ // Call the topologyManager function for removing a device
+ theTopologyManager.removeDeviceDiscoveryEvent(deviceEvent);
+
+ // Verify the function calls
+ verify(eventChannel);
+ }
+
+ /**
+ * Test the link discovered function.
+ */
+ @Test
+ public void testPutLinkDiscoveryEvent() {
+ // Mock the eventChannel functions first
+ eventChannel.addEntry(anyObject(byte[].class),
+ anyObject(TopologyEvent.class));
+ EasyMock.expectLastCall().times(5, 5); // (2 switch + 2 port + 1 link)
+ replay(eventChannel);
+
+ // Assign the switch and port IDs
+ Dpid sw1DPId = new Dpid(100L);
+ PortNumber port1Id = new PortNumber((short) 1);
+ Dpid sw2DPId = new Dpid(200L);
+ PortNumber port2Id = new PortNumber((short) 2);
+
+ // Generate the switch and port events
+ SwitchEvent switchEvent1 = new SwitchEvent(sw1DPId);
+ Collection<PortEvent> portEvents1 = new ArrayList<PortEvent>();
+ portEvents1.add(new PortEvent(sw1DPId, port1Id));
+
+ // Call the topologyManager function for adding a switch
+ theTopologyManager.putSwitchDiscoveryEvent(switchEvent1, portEvents1);
+
+ // Generate the switch and port events
+ SwitchEvent switchEvent2 = new SwitchEvent(sw2DPId);
+ Collection<PortEvent> portEvents2 = new ArrayList<PortEvent>();
+ portEvents2.add(new PortEvent(sw2DPId, port2Id));
+
+ // Call the topologyManager function for adding a switch
+ theTopologyManager.putSwitchDiscoveryEvent(switchEvent2, portEvents2);
+
+ // Create the link
+ LinkEvent linkEvent = new LinkEvent(sw1DPId, port1Id, sw2DPId, port2Id);
+ theTopologyManager.putLinkDiscoveryEvent(linkEvent);
+
+ // Verify the function calls
+ verify(eventChannel);
+ }
+
+ /**
+ * Test the link removed function.
+ */
+ @Test
+ public void testRemoveLinkDiscoveryEvent() {
+ // Mock the eventChannel functions first
+ eventChannel.removeEntry(anyObject(byte[].class));
+ EasyMock.expectLastCall().times(1, 1); // (1 link)
+ replay(eventChannel);
+
+ // Assign the switch and port IDs
+ Dpid sw1DPId = new Dpid(100L);
+ PortNumber port1Id = new PortNumber((short) 1);
+ Dpid sw2DPId = new Dpid(200L);
+ PortNumber port2Id = new PortNumber((short) 2);
+
+ // Generate the switch and port events
+ SwitchEvent switchEvent1 = new SwitchEvent(sw1DPId);
+ Collection<PortEvent> portEvents1 = new ArrayList<PortEvent>();
+ portEvents1.add(new PortEvent(sw1DPId, port1Id));
+
+ // Call the topologyManager function for adding a switch
+ theTopologyManager.putSwitchDiscoveryEvent(switchEvent1, portEvents1);
+
+ // Generate the switch and port events
+ SwitchEvent switchEvent2 = new SwitchEvent(sw2DPId);
+ Collection<PortEvent> portEvents2 = new ArrayList<PortEvent>();
+ portEvents2.add(new PortEvent(sw2DPId, port2Id));
+
+ // Call the topologyManager function for adding a switch
+ theTopologyManager.putSwitchDiscoveryEvent(switchEvent2, portEvents2);
+
+ // Remove the link
+ LinkEvent linkEventRemove = new LinkEvent(sw1DPId, port1Id, sw2DPId, port2Id);
+ theTopologyManager.removeLinkDiscoveryEvent(linkEventRemove);
+
+ // Verify the function calls
+ verify(eventChannel);
+ }
+
+}