package net.onrc.onos.core.topology; import net.floodlightcontroller.core.IFloodlightProviderService.Role; 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.registry.RegistryException; import net.onrc.onos.core.util.Dpid; import net.onrc.onos.core.util.EventEntry; import static net.onrc.onos.core.util.ImmutableClassChecker.assertThatClassIsImmutable; import net.onrc.onos.core.util.OnosInstanceId; import net.onrc.onos.core.util.PortNumber; import net.onrc.onos.core.util.SwitchPort; import net.onrc.onos.core.util.TestUtils; import net.onrc.onos.core.util.UnitTest; import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createNiceMock; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.reset; import static org.easymock.EasyMock.verify; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; /** * 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, eventChannel, and controllerRegistryService are mocked out. */ public class TopologyManagerTest extends UnitTest { private TopologyPublisher theTopologyPublisher; private TopologyManager theTopologyManager; private TopologyManager.EventHandler theEventHandler; private TopologyListenerTest theTopologyListener = new TopologyListenerTest(); private final String eventChannelName = "onos.topology"; private IEventChannel<byte[], TopologyEvent> eventChannel; private IDatagridService datagridService; private IControllerRegistryService registryService; private Collection<TopologyEvent> allTopologyEvents; private static final OnosInstanceId ONOS_INSTANCE_ID_1 = new OnosInstanceId("ONOS-Instance-ID-1"); private static final OnosInstanceId ONOS_INSTANCE_ID_2 = new OnosInstanceId("ONOS-Instance-ID-2"); private static final Dpid DPID_1 = new Dpid(1); private static final Dpid DPID_2 = new Dpid(2); /** * Topology events listener. */ private class TopologyListenerTest implements ITopologyListener { private TopologyEvents topologyEvents; @Override public void topologyEvents(TopologyEvents events) { this.topologyEvents = events; } /** * Clears the Topology Listener state. */ public void clear() { this.topologyEvents = null; } } @SuppressWarnings("unchecked") @Before public void setUp() throws Exception { // Mock objects for testing datagridService = createNiceMock(IDatagridService.class); registryService = createMock(IControllerRegistryService.class); eventChannel = 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(); // Setup the Registry Service expect(registryService.getOnosInstanceId()).andReturn(ONOS_INSTANCE_ID_1).anyTimes(); expect(registryService.getControllerForSwitch(DPID_1.value())) .andReturn(ONOS_INSTANCE_ID_1.toString()).anyTimes(); expect(registryService.getControllerForSwitch(DPID_2.value())) .andReturn(ONOS_INSTANCE_ID_2.toString()).anyTimes(); expect(registryService.hasControl(DPID_1.value())) .andReturn(true).anyTimes(); expect(registryService.hasControl(DPID_2.value())) .andReturn(false).anyTimes(); allTopologyEvents = new CopyOnWriteArrayList<>(); expect(eventChannel.getAllEntries()) .andReturn(allTopologyEvents).anyTimes(); replay(datagridService); replay(registryService); // replay(eventChannel); } /** * Setup the Topology Publisher. */ private void setupTopologyPublisher() throws RegistryException { // Create a TopologyPublisher object for testing theTopologyPublisher = new TopologyPublisher(); // Setup the registry service TestUtils.setField(theTopologyPublisher, "registryService", registryService); // // Update the Registry Service, so the ONOS instance is the // Master for both switches. // reset(registryService); expect(registryService.getOnosInstanceId()).andReturn(ONOS_INSTANCE_ID_1).anyTimes(); expect(registryService.getControllerForSwitch(DPID_1.value())) .andReturn(ONOS_INSTANCE_ID_1.toString()).anyTimes(); expect(registryService.getControllerForSwitch(DPID_2.value())) .andReturn(ONOS_INSTANCE_ID_2.toString()).anyTimes(); expect(registryService.hasControl(DPID_1.value())) .andReturn(true).anyTimes(); expect(registryService.hasControl(DPID_2.value())) .andReturn(true).anyTimes(); replay(registryService); // Setup the event channel TestUtils.setField(theTopologyPublisher, "eventChannel", eventChannel); } /** * Setup the Topology Manager. */ private void setupTopologyManager() { // Create a TopologyManager object for testing theTopologyManager = new TopologyManager(registryService); // Replace the eventHandler to prevent the thread from starting TestUtils.setField(theTopologyManager, "eventHandler", createNiceMock(TopologyManager.EventHandler.class)); theTopologyManager.startup(datagridService); } /** * Setup the Topology Manager with the Event Handler. */ private void setupTopologyManagerWithEventHandler() { // Create a TopologyManager object for testing theTopologyManager = new TopologyManager(registryService); theTopologyManager.addListener(theTopologyListener, true); // Allocate the Event Handler, so we can have direct access to it theEventHandler = theTopologyManager.new EventHandler(); TestUtils.setField(theTopologyManager, "eventHandler", theEventHandler); replay(eventChannel); // // NOTE: Uncomment-out the line below if the startup() method needs // to be called for some of the unit tests. For now it is commented-out // to avoid any side effects of starting the eventHandler thread. // // theTopologyManager.startup(datagridService); } /** * Tests the immutability of {@link TopologyEvents}. */ @Test public void testImmutableTopologyEvents() { assertThatClassIsImmutable(TopologyEvents.class); } /** * Tests the publishing of Add Switch Mastership Event. */ @Test public void testPublishAddSwitchMastershipEvent() throws RegistryException { setupTopologyPublisher(); // Mock the eventChannel functions eventChannel.addEntry(anyObject(byte[].class), anyObject(TopologyEvent.class)); expectLastCall().times(1, 1); // 1 event replay(eventChannel); // Generate the Switch Mastership event Role role = Role.MASTER; MastershipData mastershipData = new MastershipData(DPID_1, ONOS_INSTANCE_ID_1, role); // Call the TopologyPublisher function for adding the event TestUtils.callMethod(theTopologyPublisher, "publishAddSwitchMastershipEvent", MastershipData.class, mastershipData); // Verify the function calls verify(eventChannel); } /** * Tests the publishing of Remove Switch Mastership Event. */ @Test public void testPublishRemoveSwitchMastershipEvent() throws RegistryException { setupTopologyPublisher(); // Mock the eventChannel functions eventChannel.removeEntry(anyObject(byte[].class)); expectLastCall().times(1, 1); // 1 event replay(eventChannel); // Generate the Switch Mastership Event Role role = Role.MASTER; MastershipData mastershipData = new MastershipData(DPID_1, ONOS_INSTANCE_ID_1, role); // Call the TopologyPublisher function for adding the event TestUtils.callMethod(theTopologyPublisher, "publishAddSwitchMastershipEvent", MastershipData.class, mastershipData); // Call the TopologyPublisher function for removing the event TestUtils.callMethod(theTopologyPublisher, "publishRemoveSwitchMastershipEvent", MastershipData.class, mastershipData); // Verify the function calls verify(eventChannel); } /** * Tests the publishing of Add Switch and Port Events. */ @Test public void testPublishAddSwitchAndPortEvent() throws RegistryException { setupTopologyPublisher(); // Mock the eventChannel functions eventChannel.addEntry(anyObject(byte[].class), anyObject(TopologyEvent.class)); expectLastCall().times(3, 3); // (1 Switch + 1 Port), 1 Port replay(eventChannel); // Mock Switch has one Port PortNumber portNumber = PortNumber.uint32(1); // Generate the Switch Event along with a Port Event SwitchData switchData = new SwitchData(DPID_1); Collection<PortData> portDataEntries = new ArrayList<PortData>(); portDataEntries.add(new PortData(DPID_1, portNumber)); // Call the TopologyPublisher function for adding a Switch TestUtils.callMethod(theTopologyPublisher, "publishAddSwitchEvent", new Class<?>[] {SwitchData.class, Collection.class}, switchData, portDataEntries); // Call the TopologyPublisher function for adding a Port for (PortData portData : portDataEntries) { TestUtils.callMethod(theTopologyPublisher, "publishAddPortEvent", PortData.class, portData); } // Verify the function calls verify(eventChannel); } /** * Tests the publishing of Remove Switch and Port Events. */ @Test public void testPublishRemoveSwitchAndPortEvent() throws RegistryException { setupTopologyPublisher(); // Mock the eventChannel functions eventChannel.removeEntry(anyObject(byte[].class)); expectLastCall().times(2, 2); // 1 Switch, 1 Port replay(eventChannel); PortNumber portNumber = PortNumber.uint32(1); // Generate the Switch Event along with a Port Event SwitchData switchData = new SwitchData(DPID_1); Collection<PortData> portDataEntries = new ArrayList<PortData>(); portDataEntries.add(new PortData(DPID_1, portNumber)); // Call the TopologyPublisher function for adding a Switch and Ports TestUtils.callMethod(theTopologyPublisher, "publishAddSwitchEvent", new Class<?>[] {SwitchData.class, Collection.class}, switchData, portDataEntries); // Call the TopologyPublisher function for removing a Port for (PortData portData : portDataEntries) { TestUtils.callMethod(theTopologyPublisher, "publishRemovePortEvent", PortData.class, portData); } // Call the TopologyPublisher function for removing a Switch TestUtils.callMethod(theTopologyPublisher, "publishRemoveSwitchEvent", SwitchData.class, switchData); // Verify the function calls verify(eventChannel); } /** * Tests the publishing of Add Link Event. */ @Test public void testPublishAddLinkEvent() throws RegistryException { setupTopologyPublisher(); // Mock the eventChannel functions eventChannel.addEntry(anyObject(byte[].class), anyObject(TopologyEvent.class)); expectLastCall().times(5, 5); // (2 Switch + 2 Port + 1 Link) replay(eventChannel); // Generate the Switch and Port Events PortNumber portNumber1 = PortNumber.uint32(1); SwitchData switchData1 = new SwitchData(DPID_1); Collection<PortData> portDataEntries1 = new ArrayList<PortData>(); portDataEntries1.add(new PortData(DPID_1, portNumber1)); // Call the TopologyPublisher function for adding a Switch TestUtils.callMethod(theTopologyPublisher, "publishAddSwitchEvent", new Class<?>[] {SwitchData.class, Collection.class}, switchData1, portDataEntries1); // Generate the Switch and Port Events PortNumber portNumber2 = PortNumber.uint32(2); SwitchData switchData2 = new SwitchData(DPID_2); Collection<PortData> portDataEntries2 = new ArrayList<PortData>(); portDataEntries2.add(new PortData(DPID_2, portNumber2)); // Call the TopologyPublisher function for adding a Switch TestUtils.callMethod(theTopologyPublisher, "publishAddSwitchEvent", new Class<?>[] {SwitchData.class, Collection.class}, switchData2, portDataEntries2); // Generate the Link Event LinkData linkData = new LinkData(new SwitchPort(DPID_1, portNumber1), new SwitchPort(DPID_2, portNumber2)); // Call the TopologyPublisher function for adding a Link TestUtils.callMethod(theTopologyPublisher, "publishAddLinkEvent", LinkData.class, linkData); // Verify the function calls verify(eventChannel); } /** * Tests the publishing of Remove Link Event. */ @Test public void testPublishRemoveLinkEvent() throws RegistryException { setupTopologyPublisher(); // Mock the eventChannel functions eventChannel.removeEntry(anyObject(byte[].class)); expectLastCall().times(1, 1); // (1 Link) replay(eventChannel); // Generate the Switch and Port Events PortNumber portNumber1 = PortNumber.uint32(1); SwitchData switchData1 = new SwitchData(DPID_1); Collection<PortData> portDataEntries1 = new ArrayList<PortData>(); portDataEntries1.add(new PortData(DPID_1, portNumber1)); // Call the TopologyPublisher function for adding a Switch TestUtils.callMethod(theTopologyPublisher, "publishAddSwitchEvent", new Class<?>[] {SwitchData.class, Collection.class}, switchData1, portDataEntries1); // Generate the Switch and Port Events PortNumber portNumber2 = PortNumber.uint32(2); SwitchData switchData2 = new SwitchData(DPID_2); Collection<PortData> portDataEntries2 = new ArrayList<PortData>(); portDataEntries2.add(new PortData(DPID_2, portNumber2)); // Call the TopologyPublisher function for adding a Switch TestUtils.callMethod(theTopologyPublisher, "publishAddSwitchEvent", new Class<?>[] {SwitchData.class, Collection.class}, switchData2, portDataEntries2); // Generate the Link Event LinkData linkData = new LinkData(new SwitchPort(DPID_1, portNumber1), new SwitchPort(DPID_2, portNumber2)); // Call the TopologyPublisher function for adding a Link TestUtils.callMethod(theTopologyPublisher, "publishAddLinkEvent", LinkData.class, linkData); // Call the TopologyPublisher function for removing a Link TestUtils.callMethod(theTopologyPublisher, "publishRemoveLinkEvent", LinkData.class, linkData); // Verify the function calls verify(eventChannel); } /** * Tests the publishing of Add Host Event. */ @Test public void testPublishAddHostEvent() throws RegistryException { setupTopologyPublisher(); // Mock the eventChannel functions eventChannel.addEntry(anyObject(byte[].class), anyObject(TopologyEvent.class)); expectLastCall().times(3, 3); // (1 Switch + 1 Port + 1 Host) replay(eventChannel); // Generate the Switch and Port Events PortNumber portNumber1 = PortNumber.uint32(1); SwitchData switchData1 = new SwitchData(DPID_1); Collection<PortData> portDataEntries1 = new ArrayList<PortData>(); portDataEntries1.add(new PortData(DPID_1, portNumber1)); // Call the TopologyPublisher function for adding a Switch TestUtils.callMethod(theTopologyPublisher, "publishAddSwitchEvent", new Class<?>[] {SwitchData.class, Collection.class}, switchData1, portDataEntries1); // Generate the Host Event PortNumber portNumber = PortNumber.uint32(1); MACAddress hostMac = MACAddress.valueOf("00:AA:11:BB:33:CC"); SwitchPort sp = new SwitchPort(DPID_1, portNumber); List<SwitchPort> spLists = new ArrayList<SwitchPort>(); spLists.add(sp); HostData hostData = new HostData(hostMac); hostData.setAttachmentPoints(spLists); // Call the TopologyPublisher function for adding a Host TestUtils.callMethod(theTopologyPublisher, "publishAddHostEvent", HostData.class, hostData); // Verify the function calls verify(eventChannel); } /** * Tests the publising of Remove Host Event. */ @Test public void testPublishRemoveHostEvent() throws RegistryException { setupTopologyPublisher(); // Mock the eventChannel functions eventChannel.removeEntry(anyObject(byte[].class)); expectLastCall().times(1, 1); // 1 Host replay(eventChannel); // Generate the Switch and Port Events PortNumber portNumber1 = PortNumber.uint32(1); SwitchData switchData1 = new SwitchData(DPID_1); Collection<PortData> portDataEntries1 = new ArrayList<PortData>(); portDataEntries1.add(new PortData(DPID_1, portNumber1)); // Call the TopologyPublisher function for adding a Switch TestUtils.callMethod(theTopologyPublisher, "publishAddSwitchEvent", new Class<?>[] {SwitchData.class, Collection.class}, switchData1, portDataEntries1); // Generate the Host Event PortNumber portNumber = PortNumber.uint32(1); MACAddress hostMac = MACAddress.valueOf("00:AA:11:BB:33:CC"); SwitchPort sp = new SwitchPort(DPID_1, portNumber); List<SwitchPort> spLists = new ArrayList<SwitchPort>(); spLists.add(sp); HostData hostData = new HostData(hostMac); hostData.setAttachmentPoints(spLists); // Call the TopologyPublisher function for adding a Host TestUtils.callMethod(theTopologyPublisher, "publishAddHostEvent", HostData.class, hostData); // Call the TopologyPublisher function for removing a Host TestUtils.callMethod(theTopologyPublisher, "publishRemoveHostEvent", HostData.class, hostData); // Verify the function calls verify(eventChannel); } /** * Tests adding of a Switch Mastership event and the topology replica * transformation. */ @Test public void testAddMastershipData() { setupTopologyManager(); // Prepare the event Role role = Role.MASTER; MastershipData mastershipData = new MastershipData(DPID_1, ONOS_INSTANCE_ID_1, role); // Add the event TestUtils.callMethod(theTopologyManager, "addMastershipData", MastershipData.class, mastershipData); // // NOTE: The topology itself doesn't contain the Mastership Events, // hence we don't check the topology. // // Check the events to be fired List<MastershipData> apiAddedMastershipDataEntries = TestUtils.getField(theTopologyManager, "apiAddedMastershipDataEntries"); assertThat(apiAddedMastershipDataEntries, hasItem(mastershipData)); } /** * Tests removing of a Switch Mastership event and the topology replica * transformation. */ @Test public void testRemoveMastershipData() { setupTopologyManager(); // Prepare the event Role role = Role.MASTER; MastershipData mastershipData = new MastershipData(DPID_1, ONOS_INSTANCE_ID_1, role); // Add the event TestUtils.callMethod(theTopologyManager, "addMastershipData", MastershipData.class, mastershipData); // Check the events to be fired List<MastershipData> apiAddedMastershipDataEntries = TestUtils.getField(theTopologyManager, "apiAddedMastershipDataEntries"); assertThat(apiAddedMastershipDataEntries, hasItem(mastershipData)); // Remove the event TestUtils.callMethod(theTopologyManager, "removeMastershipData", MastershipData.class, new MastershipData(mastershipData)); // Check the events to be fired List<MastershipData> apiRemovedMastershipDataEntries = TestUtils.getField(theTopologyManager, "apiRemovedMastershipDataEntries"); assertThat(apiRemovedMastershipDataEntries, hasItem(mastershipData)); } /** * Tests adding of a Switch and the topology replica transformation. */ @Test public void testAddSwitch() { setupTopologyManager(); SwitchData sw = new SwitchData(DPID_1); sw.createStringAttribute("foo", "bar"); TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchData.class, sw); // Check the topology structure BaseInternalTopology topology = (BaseInternalTopology) theTopologyManager.getTopology(); SwitchData swInTopo = topology.getSwitchData(DPID_1); assertEquals(sw, swInTopo); assertTrue(swInTopo.isFrozen()); assertEquals("bar", swInTopo.getStringAttribute("foo")); // Check the events to be fired List<SwitchData> apiAddedSwitchDataEntries = TestUtils.getField(theTopologyManager, "apiAddedSwitchDataEntries"); assertThat(apiAddedSwitchDataEntries, hasItem(sw)); } /** * Tests adding of a Port and the topology replica transformation. */ @Test public void testAddPort() { setupTopologyManager(); SwitchData sw = new SwitchData(DPID_1); sw.createStringAttribute("foo", "bar"); final PortNumber portNumber = PortNumber.uint32(2); PortData port = new PortData(DPID_1, portNumber); port.createStringAttribute("fuzz", "buzz"); TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchData.class, sw); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, port); // Check the topology structure BaseInternalTopology topology = (BaseInternalTopology) theTopologyManager.getTopology(); SwitchData swInTopo = topology.getSwitchData(DPID_1); assertEquals(sw, swInTopo); assertTrue(swInTopo.isFrozen()); assertEquals("bar", swInTopo.getStringAttribute("foo")); final SwitchPort switchPort = new SwitchPort(DPID_1, portNumber); PortData portInTopo = topology.getPortData(switchPort); assertEquals(port, portInTopo); assertTrue(portInTopo.isFrozen()); assertEquals("buzz", portInTopo.getStringAttribute("fuzz")); // Check the events to be fired List<PortData> apiAddedPortDataEntries = TestUtils.getField(theTopologyManager, "apiAddedPortDataEntries"); assertThat(apiAddedPortDataEntries, hasItem(port)); } /** * Tests removing of a Port followed by removing of a Switch, * and the topology replica transformation. */ @Test public void testRemovePortThenSwitch() { setupTopologyManager(); SwitchData sw = new SwitchData(DPID_1); sw.createStringAttribute("foo", "bar"); final PortNumber portNumber = PortNumber.uint32(2); PortData port = new PortData(DPID_1, portNumber); port.createStringAttribute("fuzz", "buzz"); TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchData.class, sw); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, port); // Check the topology structure BaseInternalTopology topology = (BaseInternalTopology) theTopologyManager.getTopology(); SwitchData swInTopo = topology.getSwitchData(DPID_1); assertEquals(sw, swInTopo); assertTrue(swInTopo.isFrozen()); assertEquals("bar", swInTopo.getStringAttribute("foo")); final SwitchPort switchPort = new SwitchPort(DPID_1, portNumber); PortData portInTopo = topology.getPortData(switchPort); assertEquals(port, portInTopo); assertTrue(portInTopo.isFrozen()); assertEquals("buzz", portInTopo.getStringAttribute("fuzz")); // Remove in proper order TestUtils.callMethod(theTopologyManager, "removePort", PortData.class, new PortData(port)); TestUtils.callMethod(theTopologyManager, "removeSwitch", SwitchData.class, new SwitchData(sw)); // Check the events to be fired List<PortData> apiRemovedPortDataEntries = TestUtils.getField(theTopologyManager, "apiRemovedPortDataEntries"); assertThat(apiRemovedPortDataEntries, hasItem(port)); List<SwitchData> apiRemovedSwitchDataEntries = TestUtils.getField(theTopologyManager, "apiRemovedSwitchDataEntries"); assertThat(apiRemovedSwitchDataEntries, hasItem(sw)); } /** * Tests removing of a Switch without removing of a Port, * and the topology replica transformation. */ @Test public void testRemoveSwitchWithoutPortRemoval() { setupTopologyManager(); SwitchData sw = new SwitchData(DPID_1); sw.createStringAttribute("foo", "bar"); final PortNumber portNumber = PortNumber.uint32(2); PortData port = new PortData(DPID_1, portNumber); port.createStringAttribute("fuzz", "buzz"); TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchData.class, sw); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, port); // Check the topology structure BaseInternalTopology topology = (BaseInternalTopology) theTopologyManager.getTopology(); SwitchData swInTopo = topology.getSwitchData(DPID_1); assertEquals(sw, swInTopo); assertTrue(swInTopo.isFrozen()); assertEquals("bar", swInTopo.getStringAttribute("foo")); final SwitchPort switchPort = new SwitchPort(DPID_1, portNumber); PortData portInTopo = topology.getPortData(switchPort); assertEquals(port, portInTopo); assertTrue(portInTopo.isFrozen()); assertEquals("buzz", portInTopo.getStringAttribute("fuzz")); // Remove in in-proper order // TestUtils.callMethod(theTopologyManager, "removePort", // PortData.class, new PortData(port)); TestUtils.callMethod(theTopologyManager, "removeSwitch", SwitchData.class, new SwitchData(sw)); // Check the events to be fired // The outcome should be the same as #testRemovePortThenSwitch List<PortData> apiRemovedPortDataEntries = TestUtils.getField(theTopologyManager, "apiRemovedPortDataEntries"); assertThat(apiRemovedPortDataEntries, hasItem(port)); List<SwitchData> apiRemovedSwitchDataEntries = TestUtils.getField(theTopologyManager, "apiRemovedSwitchDataEntries"); assertThat(apiRemovedSwitchDataEntries, hasItem(sw)); } /** * Tests adding of a Link and the topology replica transformation. */ @Test public void testAddLink() { setupTopologyManager(); SwitchData sw = new SwitchData(DPID_1); sw.createStringAttribute("foo", "bar"); final PortNumber portNumberA = PortNumber.uint32(2); PortData portA = new PortData(DPID_1, portNumberA); portA.createStringAttribute("fuzz", "buzz"); final PortNumber portNumberB = PortNumber.uint32(3); PortData portB = new PortData(DPID_1, portNumberB); portB.createStringAttribute("fizz", "buz"); LinkData linkA = new LinkData(portA.getSwitchPort(), portB.getSwitchPort()); linkA.createStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_OPTICAL_LAYER); LinkData linkB = new LinkData(portB.getSwitchPort(), portA.getSwitchPort()); linkB.createStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_OPTICAL_LAYER); TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchData.class, sw); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portA); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portB); TestUtils.callMethod(theTopologyManager, "addLink", LinkData.class, linkA); TestUtils.callMethod(theTopologyManager, "addLink", LinkData.class, linkB); // Check the topology structure BaseInternalTopology topology = (BaseInternalTopology) theTopologyManager.getTopology(); SwitchData swInTopo = topology.getSwitchData(DPID_1); assertEquals(sw, swInTopo); assertTrue(swInTopo.isFrozen()); assertEquals("bar", swInTopo.getStringAttribute("foo")); final SwitchPort switchPortA = new SwitchPort(DPID_1, portNumberA); PortData portAInTopo = topology.getPortData(switchPortA); assertEquals(portA, portAInTopo); assertTrue(portAInTopo.isFrozen()); assertEquals("buzz", portAInTopo.getStringAttribute("fuzz")); final SwitchPort switchPortB = new SwitchPort(DPID_1, portNumberB); PortData portBInTopo = topology.getPortData(switchPortB); assertEquals(portB, portBInTopo); assertTrue(portBInTopo.isFrozen()); assertEquals("buz", portBInTopo.getStringAttribute("fizz")); LinkData linkAInTopo = topology.getLinkData(linkA.getLinkTuple()); assertEquals(linkA, linkAInTopo); assertTrue(linkAInTopo.isFrozen()); assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkAInTopo.getType()); LinkData linkBInTopo = topology.getLinkData(linkB.getLinkTuple()); assertEquals(linkB, linkBInTopo); assertTrue(linkBInTopo.isFrozen()); assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkBInTopo.getType()); // Check the events to be fired List<LinkData> apiAddedLinkDataEntries = TestUtils.getField(theTopologyManager, "apiAddedLinkDataEntries"); assertThat(apiAddedLinkDataEntries, containsInAnyOrder(linkA, linkB)); } /** * Tests removing of a Link without removing of a Host, and the topology * replica transformation. */ @Test public void testAddLinkKickingOffHost() { setupTopologyManager(); SwitchData sw = new SwitchData(DPID_1); sw.createStringAttribute("foo", "bar"); final PortNumber portNumberA = PortNumber.uint32(2); PortData portA = new PortData(DPID_1, portNumberA); portA.createStringAttribute("fuzz", "buzz"); final PortNumber portNumberB = PortNumber.uint32(3); PortData portB = new PortData(DPID_1, portNumberB); portB.createStringAttribute("fizz", "buz"); final PortNumber portNumberC = PortNumber.uint32(4); PortData portC = new PortData(DPID_1, portNumberC); portC.createStringAttribute("fizz", "buz"); final MACAddress macA = MACAddress.valueOf(666L); HostData hostA = new HostData(macA); hostA.addAttachmentPoint(portA.getSwitchPort()); final long timestampA = 392893200L; hostA.setLastSeenTime(timestampA); final MACAddress macB = MACAddress.valueOf(999L); HostData hostB = new HostData(macB); hostB.addAttachmentPoint(portB.getSwitchPort()); hostB.addAttachmentPoint(portC.getSwitchPort()); final long timestampB = 392893201L; hostB.setLastSeenTime(timestampB); LinkData linkA = new LinkData(portA.getSwitchPort(), portB.getSwitchPort()); linkA.createStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_OPTICAL_LAYER); LinkData linkB = new LinkData(portB.getSwitchPort(), portA.getSwitchPort()); linkB.createStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_OPTICAL_LAYER); TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchData.class, sw); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portA); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portB); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portC); TestUtils.callMethod(theTopologyManager, "addHost", HostData.class, hostA); TestUtils.callMethod(theTopologyManager, "addHost", HostData.class, hostB); TestUtils.callMethod(theTopologyManager, "addLink", LinkData.class, linkA); TestUtils.callMethod(theTopologyManager, "addLink", LinkData.class, linkB); // Check the topology structure BaseInternalTopology topology = (BaseInternalTopology) theTopologyManager.getTopology(); SwitchData swInTopo = topology.getSwitchData(DPID_1); assertEquals(sw, swInTopo); assertTrue(swInTopo.isFrozen()); assertEquals("bar", swInTopo.getStringAttribute("foo")); final SwitchPort switchPortA = new SwitchPort(DPID_1, portNumberA); PortData portAInTopo = topology.getPortData(switchPortA); assertEquals(portA, portAInTopo); assertTrue(portAInTopo.isFrozen()); assertEquals("buzz", portAInTopo.getStringAttribute("fuzz")); final SwitchPort switchPortB = new SwitchPort(DPID_1, portNumberB); PortData portBInTopo = topology.getPortData(switchPortB); assertEquals(portB, portBInTopo); assertTrue(portBInTopo.isFrozen()); assertEquals("buz", portBInTopo.getStringAttribute("fizz")); // hostA expected to be removed assertNull(topology.getHostData(macA)); // hostB expected to be there with reduced attachment point HostData hostBrev = new HostData(macB); hostBrev.addAttachmentPoint(portC.getSwitchPort()); hostBrev.setLastSeenTime(timestampB); hostBrev.freeze(); assertEquals(hostBrev, topology.getHostData(macB)); LinkData linkAInTopo = topology.getLinkData(linkA.getLinkTuple()); assertEquals(linkA, linkAInTopo); assertTrue(linkAInTopo.isFrozen()); assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkAInTopo.getType()); LinkData linkBInTopo = topology.getLinkData(linkB.getLinkTuple()); assertEquals(linkB, linkBInTopo); assertTrue(linkBInTopo.isFrozen()); assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkBInTopo.getType()); // Check the events to be fired List<HostData> apiAddedHostDataEntries = TestUtils.getField(theTopologyManager, "apiAddedHostDataEntries"); assertThat(apiAddedHostDataEntries, hasItem(hostBrev)); List<HostData> apiRemovedHostDataEntries = TestUtils.getField(theTopologyManager, "apiRemovedHostDataEntries"); assertThat(apiRemovedHostDataEntries, hasItem(hostA)); List<LinkData> apiAddedLinkDataEntries = TestUtils.getField(theTopologyManager, "apiAddedLinkDataEntries"); assertThat(apiAddedLinkDataEntries, containsInAnyOrder(linkA, linkB)); } /** * Tests removing of a Link and the topology replica transformation. */ @Test public void testRemoveLink() { setupTopologyManager(); SwitchData sw = new SwitchData(DPID_1); sw.createStringAttribute("foo", "bar"); final PortNumber portNumberA = PortNumber.uint32(2); PortData portA = new PortData(DPID_1, portNumberA); portA.createStringAttribute("fuzz", "buzz"); final PortNumber portNumberB = PortNumber.uint32(3); PortData portB = new PortData(DPID_1, portNumberB); portB.createStringAttribute("fizz", "buz"); LinkData linkA = new LinkData(portA.getSwitchPort(), portB.getSwitchPort()); linkA.createStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_OPTICAL_LAYER); LinkData linkB = new LinkData(portB.getSwitchPort(), portA.getSwitchPort()); linkB.createStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_OPTICAL_LAYER); TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchData.class, sw); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portA); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portB); TestUtils.callMethod(theTopologyManager, "addLink", LinkData.class, linkA); TestUtils.callMethod(theTopologyManager, "addLink", LinkData.class, linkB); // Check the topology structure BaseInternalTopology topology = (BaseInternalTopology) theTopologyManager.getTopology(); SwitchData swInTopo = topology.getSwitchData(DPID_1); assertEquals(sw, swInTopo); assertTrue(swInTopo.isFrozen()); assertEquals("bar", swInTopo.getStringAttribute("foo")); final SwitchPort switchPortA = new SwitchPort(DPID_1, portNumberA); PortData portAInTopo = topology.getPortData(switchPortA); assertEquals(portA, portAInTopo); assertTrue(portAInTopo.isFrozen()); assertEquals("buzz", portAInTopo.getStringAttribute("fuzz")); final SwitchPort switchPortB = new SwitchPort(DPID_1, portNumberB); PortData portBInTopo = topology.getPortData(switchPortB); assertEquals(portB, portBInTopo); assertTrue(portBInTopo.isFrozen()); assertEquals("buz", portBInTopo.getStringAttribute("fizz")); LinkData linkAInTopo = topology.getLinkData(linkA.getLinkTuple()); assertEquals(linkA, linkAInTopo); assertTrue(linkAInTopo.isFrozen()); assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkAInTopo.getType()); LinkData linkBInTopo = topology.getLinkData(linkB.getLinkTuple()); assertEquals(linkB, linkBInTopo); assertTrue(linkBInTopo.isFrozen()); assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkBInTopo.getType()); // Check the events to be fired // FIXME if link flapped (linkA in this scenario), // linkA appears in both removed and added is this expected behavior? List<LinkData> apiAddedLinkDataEntries = TestUtils.getField(theTopologyManager, "apiAddedLinkDataEntries"); assertThat(apiAddedLinkDataEntries, containsInAnyOrder(linkA, linkB)); // Clear the events before removing the link apiAddedLinkDataEntries.clear(); // Remove the link TestUtils.callMethod(theTopologyManager, "removeLink", LinkData.class, new LinkData(linkA)); LinkData linkANotInTopo = topology.getLinkData(linkA.getLinkTuple()); assertNull(linkANotInTopo); List<LinkData> apiRemovedLinkDataEntries = TestUtils.getField(theTopologyManager, "apiRemovedLinkDataEntries"); assertThat(apiRemovedLinkDataEntries, hasItem(linkA)); } /** * Tests adding of a Host without adding of a Link, and the topology * replica transformation. */ @Test public void testAddHostIgnoredByLink() { setupTopologyManager(); SwitchData sw = new SwitchData(DPID_1); sw.createStringAttribute("foo", "bar"); final PortNumber portNumberA = PortNumber.uint32(2); PortData portA = new PortData(DPID_1, portNumberA); portA.createStringAttribute("fuzz", "buzz"); final PortNumber portNumberB = PortNumber.uint32(3); PortData portB = new PortData(DPID_1, portNumberB); portB.createStringAttribute("fizz", "buz"); final PortNumber portNumberC = PortNumber.uint32(4); PortData portC = new PortData(DPID_1, portNumberC); portC.createStringAttribute("fizz", "buz"); LinkData linkA = new LinkData(portA.getSwitchPort(), portB.getSwitchPort()); linkA.createStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_OPTICAL_LAYER); LinkData linkB = new LinkData(portB.getSwitchPort(), portA.getSwitchPort()); linkB.createStringAttribute(TopologyElement.TYPE, TopologyElement.TYPE_OPTICAL_LAYER); TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchData.class, sw); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portA); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portB); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portC); TestUtils.callMethod(theTopologyManager, "addLink", LinkData.class, linkA); TestUtils.callMethod(theTopologyManager, "addLink", LinkData.class, linkB); // Add hostA attached to a port which already has a link final MACAddress macA = MACAddress.valueOf(666L); HostData hostA = new HostData(macA); hostA.addAttachmentPoint(portA.getSwitchPort()); final long timestampA = 392893200L; hostA.setLastSeenTime(timestampA); TestUtils.callMethod(theTopologyManager, "addHost", HostData.class, hostA); // Add hostB attached to multiple ports, // some of them which already has a link final MACAddress macB = MACAddress.valueOf(999L); HostData hostB = new HostData(macB); hostB.addAttachmentPoint(portB.getSwitchPort()); hostB.addAttachmentPoint(portC.getSwitchPort()); final long timestampB = 392893201L; hostB.setLastSeenTime(timestampB); TestUtils.callMethod(theTopologyManager, "addHost", HostData.class, hostB); // Check the topology structure BaseInternalTopology topology = (BaseInternalTopology) theTopologyManager.getTopology(); SwitchData swInTopo = topology.getSwitchData(DPID_1); assertEquals(sw, swInTopo); assertTrue(swInTopo.isFrozen()); assertEquals("bar", swInTopo.getStringAttribute("foo")); final SwitchPort switchPortA = new SwitchPort(DPID_1, portNumberA); PortData portAInTopo = topology.getPortData(switchPortA); assertEquals(portA, portAInTopo); assertTrue(portAInTopo.isFrozen()); assertEquals("buzz", portAInTopo.getStringAttribute("fuzz")); final SwitchPort switchPortB = new SwitchPort(DPID_1, portNumberB); PortData portBInTopo = topology.getPortData(switchPortB); assertEquals(portB, portBInTopo); assertTrue(portBInTopo.isFrozen()); assertEquals("buz", portBInTopo.getStringAttribute("fizz")); // hostA expected to be completely ignored assertNull(topology.getHostData(macA)); // hostB expected to be there with reduced attachment point HostData hostBrev = new HostData(macB); hostBrev.addAttachmentPoint(portC.getSwitchPort()); hostBrev.setLastSeenTime(timestampB); hostBrev.freeze(); assertEquals(hostBrev, topology.getHostData(macB)); LinkData linkAInTopo = topology.getLinkData(linkA.getLinkTuple()); assertEquals(linkA, linkAInTopo); assertTrue(linkAInTopo.isFrozen()); assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkAInTopo.getType()); LinkData linkBInTopo = topology.getLinkData(linkB.getLinkTuple()); assertEquals(linkB, linkBInTopo); assertTrue(linkBInTopo.isFrozen()); assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkBInTopo.getType()); // Check the events to be fired // hostB should be added with reduced attachment points List<HostData> apiAddedHostDataEntries = TestUtils.getField(theTopologyManager, "apiAddedHostDataEntries"); assertThat(apiAddedHostDataEntries, hasItem(hostBrev)); // hostA should not be ignored List<HostData> apiRemovedHostDataEntries = TestUtils.getField(theTopologyManager, "apiRemovedHostDataEntries"); assertThat(apiRemovedHostDataEntries, not(hasItem(hostA))); List<LinkData> apiAddedLinkDataEntries = TestUtils.getField(theTopologyManager, "apiAddedLinkDataEntries"); assertThat(apiAddedLinkDataEntries, containsInAnyOrder(linkA, linkB)); } /** * Tests adding and moving of a Host, and the topology replica * transformation. */ @Test public void testAddHostMove() { setupTopologyManager(); SwitchData sw = new SwitchData(DPID_1); sw.createStringAttribute("foo", "bar"); final PortNumber portNumberA = PortNumber.uint32(2); PortData portA = new PortData(DPID_1, portNumberA); portA.createStringAttribute("fuzz", "buzz"); final PortNumber portNumberB = PortNumber.uint32(3); PortData portB = new PortData(DPID_1, portNumberB); portB.createStringAttribute("fizz", "buz"); final PortNumber portNumberC = PortNumber.uint32(4); PortData portC = new PortData(DPID_1, portNumberC); portC.createStringAttribute("fizz", "buz"); TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchData.class, sw); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portA); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portB); TestUtils.callMethod(theTopologyManager, "addPort", PortData.class, portC); // Add hostA attached to a Port which already has a Link final MACAddress macA = MACAddress.valueOf(666L); HostData hostA = new HostData(macA); hostA.addAttachmentPoint(portA.getSwitchPort()); final long timestampA = 392893200L; hostA.setLastSeenTime(timestampA); TestUtils.callMethod(theTopologyManager, "addHost", HostData.class, hostA); // Check the topology structure BaseInternalTopology topology = (BaseInternalTopology) theTopologyManager.getTopology(); SwitchData swInTopo = topology.getSwitchData(DPID_1); assertEquals(sw, swInTopo); assertTrue(swInTopo.isFrozen()); assertEquals("bar", swInTopo.getStringAttribute("foo")); final SwitchPort switchPortA = new SwitchPort(DPID_1, portNumberA); PortData portAInTopo = topology.getPortData(switchPortA); assertEquals(portA, portAInTopo); assertTrue(portAInTopo.isFrozen()); assertEquals("buzz", portAInTopo.getStringAttribute("fuzz")); final SwitchPort switchPortB = new SwitchPort(DPID_1, portNumberB); PortData portBInTopo = topology.getPortData(switchPortB); assertEquals(portB, portBInTopo); assertTrue(portBInTopo.isFrozen()); assertEquals("buz", portBInTopo.getStringAttribute("fizz")); // hostA expected to be there assertEquals(hostA, topology.getHostData(macA)); assertEquals(timestampA, topology.getHostData(macA).getLastSeenTime()); // Check the events to be fired // hostA should be added List<HostData> apiAddedHostDataEntries = TestUtils.getField(theTopologyManager, "apiAddedHostDataEntries"); assertThat(apiAddedHostDataEntries, hasItem(hostA)); // Clear the events before moving the Host apiAddedHostDataEntries.clear(); HostData hostAmoved = new HostData(macA); hostAmoved.addAttachmentPoint(portB.getSwitchPort()); final long timestampAmoved = 392893201L; hostAmoved.setLastSeenTime(timestampAmoved); TestUtils.callMethod(theTopologyManager, "addHost", HostData.class, hostAmoved); assertEquals(hostAmoved, topology.getHostData(macA)); assertEquals(timestampAmoved, topology.getHostData(macA).getLastSeenTime()); // hostA expected to be there with new attachment point apiAddedHostDataEntries = TestUtils.getField(theTopologyManager, "apiAddedHostDataEntries"); assertThat(apiAddedHostDataEntries, hasItem(hostAmoved)); // hostA is updated not removed List<HostData> apiRemovedHostDataEntries = TestUtils.getField(theTopologyManager, "apiRemovedHostDataEntries"); assertThat(apiRemovedHostDataEntries, not(hasItem(hostA))); } /** * Tests processing of a Switch Mastership Event and the delivery of the * topology events. */ @Test public void testProcessMastershipData() { List<EventEntry<TopologyEvent>> events = new LinkedList<>(); EventEntry<TopologyEvent> eventEntry; TopologyEvent topologyEvent; setupTopologyManagerWithEventHandler(); // Prepare the Mastership Event Role role = Role.MASTER; MastershipData mastershipData = new MastershipData(DPID_1, ONOS_INSTANCE_ID_1, role); topologyEvent = new TopologyEvent(mastershipData, ONOS_INSTANCE_ID_1); // Add the Mastership Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologyEvent); events.add(eventEntry); // Process the events TestUtils.callMethod(theEventHandler, "processEvents", List.class, events); // Check the fired events TopologyEvents topologyEvents = theTopologyListener.topologyEvents; assertNotNull(topologyEvents); assertThat(topologyEvents.getAddedMastershipDataEntries(), hasItem(mastershipData)); theTopologyListener.clear(); } /** * Tests processing of a Switch Event, and the delivery of the topology * events. * * We test the following scenario: * - Switch Mastership Event is processed along with a Switch Event - both * events should be delivered. */ @Test public void testProcessSwitchData() { TopologyEvents topologyEvents; List<EventEntry<TopologyEvent>> events = new LinkedList<>(); EventEntry<TopologyEvent> eventEntry; TopologyEvent topologyMastershipData; TopologyEvent topologySwitchData; setupTopologyManagerWithEventHandler(); // Prepare the Mastership Event Role role = Role.MASTER; MastershipData mastershipData = new MastershipData(DPID_1, ONOS_INSTANCE_ID_1, role); topologyMastershipData = new TopologyEvent(mastershipData, ONOS_INSTANCE_ID_1); // Prepare the Switch Event SwitchData switchData = new SwitchData(DPID_1); topologySwitchData = new TopologyEvent(switchData, ONOS_INSTANCE_ID_1); // Add the Mastership Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologyMastershipData); events.add(eventEntry); // Add the Switch Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologySwitchData); events.add(eventEntry); // Process the events TestUtils.callMethod(theEventHandler, "processEvents", List.class, events); // Check the fired events topologyEvents = theTopologyListener.topologyEvents; assertNotNull(topologyEvents); assertThat(topologyEvents.getAddedMastershipDataEntries(), hasItem(mastershipData)); assertThat(topologyEvents.getAddedSwitchDataEntries(), hasItem(switchData)); theTopologyListener.clear(); } /** * Tests processing of a misordered Switch Event, and the delivery of the * topology events. * * We test the following scenario: * - Only a Switch Event is processed first, later followed by a Switch * Mastership Event - the Switch Event should be delivered after the * Switch Mastership Event is processed. */ @Test public void testProcessMisorderedSwitchData() { TopologyEvents topologyEvents; List<EventEntry<TopologyEvent>> events = new LinkedList<>(); EventEntry<TopologyEvent> eventEntry; TopologyEvent topologyMastershipData; TopologyEvent topologySwitchData; setupTopologyManagerWithEventHandler(); // Prepare the Mastership Event Role role = Role.MASTER; MastershipData mastershipData = new MastershipData(DPID_1, ONOS_INSTANCE_ID_1, role); topologyMastershipData = new TopologyEvent(mastershipData, ONOS_INSTANCE_ID_1); // Prepare the Switch Event SwitchData switchData = new SwitchData(DPID_1); topologySwitchData = new TopologyEvent(switchData, ONOS_INSTANCE_ID_1); // Add the Switch Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologySwitchData); events.add(eventEntry); // Process the events TestUtils.callMethod(theEventHandler, "processEvents", List.class, events); // Check the fired events: no events should be fired topologyEvents = theTopologyListener.topologyEvents; assertNull(topologyEvents); theTopologyListener.clear(); events.clear(); // Add the Mastership Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologyMastershipData); events.add(eventEntry); // Process the events TestUtils.callMethod(theEventHandler, "processEvents", List.class, events); // Check the fired events: both events should be fired topologyEvents = theTopologyListener.topologyEvents; assertNotNull(topologyEvents); assertThat(topologyEvents.getAddedMastershipDataEntries(), hasItem(mastershipData)); assertThat(topologyEvents.getAddedSwitchDataEntries(), hasItem(switchData)); theTopologyListener.clear(); } /** * Tests processing of a Switch Event with Mastership Event from * another ONOS instance, and the delivery of the topology events. * * We test the following scenario: * - Only a Switch Event is processed first, later followed by a Switch * Mastership Event from another ONOS instance - only the Switch * Mastership Event should be delivered. */ @Test public void testProcessSwitchDataNoMastership() { TopologyEvents topologyEvents; List<EventEntry<TopologyEvent>> events = new LinkedList<>(); EventEntry<TopologyEvent> eventEntry; TopologyEvent topologyMastershipData; TopologyEvent topologySwitchData; setupTopologyManagerWithEventHandler(); // Prepare the Mastership Event Role role = Role.MASTER; MastershipData mastershipData = new MastershipData(DPID_2, ONOS_INSTANCE_ID_2, role); topologyMastershipData = new TopologyEvent(mastershipData, ONOS_INSTANCE_ID_2); // Prepare the Switch Event // NOTE: The originator (ONOS_INSTANCE_ID_1) is NOT the Master SwitchData switchData = new SwitchData(DPID_2); topologySwitchData = new TopologyEvent(switchData, ONOS_INSTANCE_ID_1); // Add the Switch Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologySwitchData); events.add(eventEntry); // Process the events TestUtils.callMethod(theEventHandler, "processEvents", List.class, events); // Check the fired events: no events should be fired topologyEvents = theTopologyListener.topologyEvents; assertNull(topologyEvents); theTopologyListener.clear(); events.clear(); // Add the Mastership Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologyMastershipData); events.add(eventEntry); // Process the events TestUtils.callMethod(theEventHandler, "processEvents", List.class, events); // Check the fired events: only the Mastership event should be fired topologyEvents = theTopologyListener.topologyEvents; assertNotNull(topologyEvents); assertThat(topologyEvents.getAddedMastershipDataEntries(), hasItem(mastershipData)); assertThat(topologyEvents.getAddedSwitchDataEntries(), is(empty())); theTopologyListener.clear(); } /** * Tests processing of Switch Events with Mastership switchover between * two ONOS instance, and the delivery of the topology events. * * We test the following scenario: * - Initially, a Mastership Event and a Switch Event from one ONOS * instance are processed - both events should be delivered. * - Later, a Mastership Event and a Switch event from another ONOS * instances are processed - both events should be delivered. * - Finally, a REMOVE Switch Event is received from the first ONOS * instance - no event should be delivered. * * @throws RegistryException */ @Test public void testProcessSwitchMastershipSwitchover() throws RegistryException { TopologyEvents topologyEvents; List<EventEntry<TopologyEvent>> events = new LinkedList<>(); EventEntry<TopologyEvent> eventEntry; TopologyEvent topologyMastershipData; TopologyEvent topologySwitchData; setupTopologyManagerWithEventHandler(); // Prepare the Mastership Event from the first ONOS instance Role role = Role.MASTER; MastershipData mastershipData = new MastershipData(DPID_1, ONOS_INSTANCE_ID_1, role); topologyMastershipData = new TopologyEvent(mastershipData, ONOS_INSTANCE_ID_1); // Prepare the Switch Event from the first ONOS instance SwitchData switchData = new SwitchData(DPID_1); topologySwitchData = new TopologyEvent(switchData, ONOS_INSTANCE_ID_1); // Add the Mastership Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologyMastershipData); events.add(eventEntry); // Add the Switch Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologySwitchData); events.add(eventEntry); // Process the events TestUtils.callMethod(theEventHandler, "processEvents", List.class, events); // Check the fired events: both events should be fired topologyEvents = theTopologyListener.topologyEvents; assertNotNull(topologyEvents); assertThat(topologyEvents.getAddedMastershipDataEntries(), hasItem(mastershipData)); assertThat(topologyEvents.getAddedSwitchDataEntries(), hasItem(switchData)); theTopologyListener.clear(); events.clear(); // // Update the Registry Service, so the second ONOS instance is the // Master. // reset(registryService); expect(registryService.getControllerForSwitch(DPID_1.value())) .andReturn(ONOS_INSTANCE_ID_2.toString()).anyTimes(); replay(registryService); // Prepare the Mastership Event from the second ONOS instance role = Role.MASTER; mastershipData = new MastershipData(DPID_1, ONOS_INSTANCE_ID_2, role); topologyMastershipData = new TopologyEvent(mastershipData, ONOS_INSTANCE_ID_2); // Prepare the Switch Event from second ONOS instance switchData = new SwitchData(DPID_1); topologySwitchData = new TopologyEvent(switchData, ONOS_INSTANCE_ID_2); // Add the Mastership Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologyMastershipData); events.add(eventEntry); // Add the Switch Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologySwitchData); events.add(eventEntry); // Process the events TestUtils.callMethod(theEventHandler, "processEvents", List.class, events); // Check the fired events: both events should be fired topologyEvents = theTopologyListener.topologyEvents; assertNotNull(topologyEvents); assertThat(topologyEvents.getAddedMastershipDataEntries(), hasItem(mastershipData)); assertThat(topologyEvents.getAddedSwitchDataEntries(), hasItem(switchData)); theTopologyListener.clear(); events.clear(); // Prepare the REMOVE Switch Event from first ONOS instance switchData = new SwitchData(DPID_1); topologySwitchData = new TopologyEvent(switchData, ONOS_INSTANCE_ID_1); // Add the Switch Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_REMOVE, topologySwitchData); events.add(eventEntry); // Process the events TestUtils.callMethod(theEventHandler, "processEvents", List.class, events); // Check the fired events: no events should be fired topologyEvents = theTopologyListener.topologyEvents; assertNull(topologyEvents); theTopologyListener.clear(); events.clear(); } /** * Tests processing of Configured Switch Events with Mastership switchover * between two ONOS instance, and the delivery of the topology events. * <p/> * NOTE: This test is similar to testProcessSwitchMastershipSwitchover() * except that the topology and all events are considered as statically * configured. * <p/> * We test the following scenario: * - Initially, a Mastership Event and a Switch Event from one ONOS * instance are processed - both events should be delivered. * - Later, a Mastership Event and a Switch event from another ONOS * instances are processed - both events should be delivered. */ @Test public void testProcessConfiguredSwitchMastershipSwitchover() { TopologyEvents topologyEvents; List<EventEntry<TopologyEvent>> events = new LinkedList<>(); EventEntry<TopologyEvent> eventEntry; TopologyEvent topologyMastershipData; TopologyEvent topologySwitchData; setupTopologyManagerWithEventHandler(); // Reset the Registry Service so it is not used reset(registryService); // Prepare the Mastership Event from the first ONOS instance Role role = Role.MASTER; MastershipData mastershipData = new MastershipData(DPID_1, ONOS_INSTANCE_ID_1, role); mastershipData.createStringAttribute( TopologyElement.ELEMENT_CONFIG_STATE, ConfigState.CONFIGURED.toString()); topologyMastershipData = new TopologyEvent(mastershipData, ONOS_INSTANCE_ID_1); // Prepare the Switch Event from the first ONOS instance SwitchData switchData = new SwitchData(DPID_1); switchData.createStringAttribute( TopologyElement.ELEMENT_CONFIG_STATE, ConfigState.CONFIGURED.toString()); topologySwitchData = new TopologyEvent(switchData, ONOS_INSTANCE_ID_1); // Add the Mastership Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologyMastershipData); events.add(eventEntry); // Add the Switch Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologySwitchData); events.add(eventEntry); // Process the events TestUtils.callMethod(theEventHandler, "processEvents", List.class, events); // Check the fired events: both events should be fired topologyEvents = theTopologyListener.topologyEvents; assertNotNull(topologyEvents); assertThat(topologyEvents.getAddedMastershipDataEntries(), hasItem(mastershipData)); assertThat(topologyEvents.getAddedSwitchDataEntries(), hasItem(switchData)); theTopologyListener.clear(); events.clear(); // Prepare the Mastership Event from the second ONOS instance role = Role.MASTER; mastershipData = new MastershipData(DPID_1, ONOS_INSTANCE_ID_2, role); mastershipData.createStringAttribute( TopologyElement.ELEMENT_CONFIG_STATE, ConfigState.CONFIGURED.toString()); topologyMastershipData = new TopologyEvent(mastershipData, ONOS_INSTANCE_ID_2); // Prepare the Switch Event from second ONOS instance switchData = new SwitchData(DPID_1); switchData.createStringAttribute( TopologyElement.ELEMENT_CONFIG_STATE, ConfigState.CONFIGURED.toString()); topologySwitchData = new TopologyEvent(switchData, ONOS_INSTANCE_ID_2); // Add the Mastership Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologyMastershipData); events.add(eventEntry); // Add the Switch Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD, topologySwitchData); events.add(eventEntry); // Process the events TestUtils.callMethod(theEventHandler, "processEvents", List.class, events); // Check the fired events: both events should be fired topologyEvents = theTopologyListener.topologyEvents; assertNotNull(topologyEvents); assertThat(topologyEvents.getAddedMastershipDataEntries(), hasItem(mastershipData)); assertThat(topologyEvents.getAddedSwitchDataEntries(), hasItem(switchData)); theTopologyListener.clear(); events.clear(); // Prepare the REMOVE Switch Event from first ONOS instance // // NOTE: This event only is explicitly marked as NOT_CONFIGURED, // otherwise it will override the previous configuration events. // switchData = new SwitchData(DPID_1); switchData.createStringAttribute( TopologyElement.ELEMENT_CONFIG_STATE, ConfigState.NOT_CONFIGURED.toString()); topologySwitchData = new TopologyEvent(switchData, ONOS_INSTANCE_ID_1); // Add the Switch Event eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_REMOVE, topologySwitchData); events.add(eventEntry); // Process the events TestUtils.callMethod(theEventHandler, "processEvents", List.class, events); // Check the fired events: no events should be fired topologyEvents = theTopologyListener.topologyEvents; assertNull(topologyEvents); theTopologyListener.clear(); events.clear(); } }