Gather topology element info to TopologyImpl
- Moved all the self-contained topology elements (*Event) to
TopologyImpl. (ONOS-1651)
Now {Switch, Port, Link, Host}Impl is just a handler attached to
TopologyImpl.
- BugFix: TopologyManager.addHost(HostEvent)
HostEvent could be pushed to reorder queue multiple times,
if multiple attachment point was given.
- BugFix: TopologyManager.{addLink, removePort}
Properly handle if Host attachment point was removed as side-effect.
- BugFix: Copy HostEvent#lastSeenTime
- BugFix: Event instance notified to listeners (api*Events) should be
the event which was/will be in the replica. (TopologyManager)
- Added/Modified debug log in TopologyManager so that log will be in
same format for each event type.
"{Added, Update, Removed} <Self-contained>"
- Removed backdoor method and use TestUtils instead.
Change-Id: If053d6f11f39574a188e7a52cb6194114f8afe5d
diff --git a/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java b/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java
index e4f6c8c..309bfb4 100644
--- a/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java
+++ b/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java
@@ -6,6 +6,8 @@
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.*;
+import static org.hamcrest.Matchers.*;
import java.util.ArrayList;
import java.util.Collection;
@@ -20,6 +22,7 @@
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.PortNumber;
import net.onrc.onos.core.util.SwitchPort;
+import net.onrc.onos.core.util.TestUtils;
import org.easymock.EasyMock;
import org.junit.After;
@@ -111,8 +114,14 @@
// Create a topologyManager object for testing
topologyListeners = new CopyOnWriteArrayList<>();
theTopologyManager = new TopologyManager(registryService, topologyListeners);
+
+ // replace EventHandler to avoid thread from starting
+ TestUtils.setField(theTopologyManager, "eventHandler",
+ EasyMock.createNiceMock(TopologyManager.EventHandler.class));
theTopologyManager.startup(datagridService);
- theTopologyManager.debugReplaceDataStore(dataStoreService);
+
+ // replace data store with Mocked object
+ TestUtils.setField(theTopologyManager, "datastore", dataStoreService);
}
@After
@@ -335,4 +344,621 @@
verify(eventChannel);
}
+ /**
+ * Test to confirm topology replica transformation.
+ */
+ @Test
+ public void testAddSwitch() {
+ setupTopologyManager();
+
+ final Dpid dpid = new Dpid(1);
+ SwitchEvent sw = new SwitchEvent(dpid);
+ sw.createStringAttribute("foo", "bar");
+
+ TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchEvent.class, sw);
+
+ // check topology structure
+ TopologyInternal topology = (TopologyInternal) theTopologyManager.getTopology();
+ SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+ assertEquals(sw, swInTopo);
+ assertTrue(swInTopo.isFrozen());
+ assertEquals("bar", swInTopo.getStringAttribute("foo"));
+
+ // check events to be fired
+ List<SwitchEvent> apiAddedSwitchEvents
+ = TestUtils.getField(theTopologyManager, "apiAddedSwitchEvents");
+ assertThat(apiAddedSwitchEvents, hasItem(sw));
+ }
+
+ /**
+ * Test to confirm topology replica transformation.
+ */
+ @Test
+ public void testAddPort() {
+ setupTopologyManager();
+
+ final Dpid dpid = new Dpid(1);
+ SwitchEvent sw = new SwitchEvent(dpid);
+ sw.createStringAttribute("foo", "bar");
+
+ final PortNumber portNumber = new PortNumber((short) 2);
+ PortEvent port = new PortEvent(dpid, portNumber);
+ port.createStringAttribute("fuzz", "buzz");
+
+ TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchEvent.class, sw);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, port);
+
+ // check topology structure
+ TopologyInternal topology = (TopologyInternal) theTopologyManager.getTopology();
+ SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+ assertEquals(sw, swInTopo);
+ assertTrue(swInTopo.isFrozen());
+ assertEquals("bar", swInTopo.getStringAttribute("foo"));
+
+ final SwitchPort portId = new SwitchPort(dpid, portNumber);
+ PortEvent portInTopo = topology.getPortEvent(portId);
+ assertEquals(port, portInTopo);
+ assertTrue(portInTopo.isFrozen());
+ assertEquals("buzz", portInTopo.getStringAttribute("fuzz"));
+
+ // check events to be fired
+ List<PortEvent> apiAddedPortEvents
+ = TestUtils.getField(theTopologyManager, "apiAddedPortEvents");
+ assertThat(apiAddedPortEvents, hasItem(port));
+ }
+
+ /**
+ * Test to confirm topology replica transformation.
+ */
+ @Test
+ public void testRemovePortThenSwitch() {
+ setupTopologyManager();
+
+ final Dpid dpid = new Dpid(1);
+ SwitchEvent sw = new SwitchEvent(dpid);
+ sw.createStringAttribute("foo", "bar");
+
+ final PortNumber portNumber = new PortNumber((short) 2);
+ PortEvent port = new PortEvent(dpid, portNumber);
+ port.createStringAttribute("fuzz", "buzz");
+
+ TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchEvent.class, sw);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, port);
+
+ // check topology structure
+ TopologyInternal topology = (TopologyInternal) theTopologyManager.getTopology();
+ SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+ assertEquals(sw, swInTopo);
+ assertTrue(swInTopo.isFrozen());
+ assertEquals("bar", swInTopo.getStringAttribute("foo"));
+
+ final SwitchPort portId = new SwitchPort(dpid, portNumber);
+ PortEvent portInTopo = topology.getPortEvent(portId);
+ assertEquals(port, portInTopo);
+ assertTrue(portInTopo.isFrozen());
+ assertEquals("buzz", portInTopo.getStringAttribute("fuzz"));
+
+ // remove in proper order
+ TestUtils.callMethod(theTopologyManager, "removePort",
+ PortEvent.class, new PortEvent(port));
+ TestUtils.callMethod(theTopologyManager, "removeSwitch",
+ SwitchEvent.class, new SwitchEvent(sw));
+
+
+ // check events to be fired
+ List<PortEvent> apiRemovedPortEvents
+ = TestUtils.getField(theTopologyManager, "apiRemovedPortEvents");
+ assertThat(apiRemovedPortEvents, hasItem(port));
+ List<SwitchEvent> apiRemovedSwitchEvents
+ = TestUtils.getField(theTopologyManager, "apiRemovedSwitchEvents");
+ assertThat(apiRemovedSwitchEvents, hasItem(sw));
+ }
+
+ /**
+ * Test to confirm topology replica transformation.
+ */
+ @Test
+ public void testRemoveSwitch() {
+ setupTopologyManager();
+
+ final Dpid dpid = new Dpid(1);
+ SwitchEvent sw = new SwitchEvent(dpid);
+ sw.createStringAttribute("foo", "bar");
+
+ final PortNumber portNumber = new PortNumber((short) 2);
+ PortEvent port = new PortEvent(dpid, portNumber);
+ port.createStringAttribute("fuzz", "buzz");
+
+ TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchEvent.class, sw);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, port);
+
+ // check topology structure
+ TopologyInternal topology = (TopologyInternal) theTopologyManager.getTopology();
+ SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+ assertEquals(sw, swInTopo);
+ assertTrue(swInTopo.isFrozen());
+ assertEquals("bar", swInTopo.getStringAttribute("foo"));
+
+ final SwitchPort portId = new SwitchPort(dpid, portNumber);
+ PortEvent portInTopo = topology.getPortEvent(portId);
+ assertEquals(port, portInTopo);
+ assertTrue(portInTopo.isFrozen());
+ assertEquals("buzz", portInTopo.getStringAttribute("fuzz"));
+
+ // remove in in-proper order
+// TestUtils.callMethod(theTopologyManager, "removePort",
+// PortEvent.class, new PortEvent(port));
+ TestUtils.callMethod(theTopologyManager, "removeSwitch",
+ SwitchEvent.class, new SwitchEvent(sw));
+
+
+ // check events to be fired
+ // outcome should be the same as #testRemovePortThenSwitch
+ List<PortEvent> apiRemovedPortEvents
+ = TestUtils.getField(theTopologyManager, "apiRemovedPortEvents");
+ assertThat(apiRemovedPortEvents, hasItem(port));
+ List<SwitchEvent> apiRemovedSwitchEvents
+ = TestUtils.getField(theTopologyManager, "apiRemovedSwitchEvents");
+ assertThat(apiRemovedSwitchEvents, hasItem(sw));
+ }
+
+ /**
+ * Test to confirm topology replica transformation.
+ */
+ @Test
+ public void testAddLink() {
+ setupTopologyManager();
+
+ final Dpid dpid = new Dpid(1);
+ SwitchEvent sw = new SwitchEvent(dpid);
+ sw.createStringAttribute("foo", "bar");
+
+ final PortNumber portNumberA = new PortNumber((short) 2);
+ PortEvent portA = new PortEvent(dpid, portNumberA);
+ portA.createStringAttribute("fuzz", "buzz");
+
+ final PortNumber portNumberB = new PortNumber((short) 3);
+ PortEvent portB = new PortEvent(dpid, portNumberB);
+ portB.createStringAttribute("fizz", "buz");
+
+ LinkEvent linkA = new LinkEvent(portA.getSwitchPort(), portB.getSwitchPort());
+ linkA.createStringAttribute(TopologyElement.TYPE,
+ TopologyElement.TYPE_OPTICAL_LAYER);
+ LinkEvent linkB = new LinkEvent(portB.getSwitchPort(), portA.getSwitchPort());
+ linkB.createStringAttribute(TopologyElement.TYPE,
+ TopologyElement.TYPE_OPTICAL_LAYER);
+
+ TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchEvent.class, sw);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portA);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portB);
+ TestUtils.callMethod(theTopologyManager, "addLink", LinkEvent.class, linkA);
+ TestUtils.callMethod(theTopologyManager, "addLink", LinkEvent.class, linkB);
+
+ // check topology structure
+ TopologyInternal topology = (TopologyInternal) theTopologyManager.getTopology();
+ SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+ assertEquals(sw, swInTopo);
+ assertTrue(swInTopo.isFrozen());
+ assertEquals("bar", swInTopo.getStringAttribute("foo"));
+
+ final SwitchPort portIdA = new SwitchPort(dpid, portNumberA);
+ PortEvent portAInTopo = topology.getPortEvent(portIdA);
+ assertEquals(portA, portAInTopo);
+ assertTrue(portAInTopo.isFrozen());
+ assertEquals("buzz", portAInTopo.getStringAttribute("fuzz"));
+
+ final SwitchPort portIdB = new SwitchPort(dpid, portNumberB);
+ PortEvent portBInTopo = topology.getPortEvent(portIdB);
+ assertEquals(portB, portBInTopo);
+ assertTrue(portBInTopo.isFrozen());
+ assertEquals("buz", portBInTopo.getStringAttribute("fizz"));
+
+ LinkEvent linkAInTopo = topology.getLinkEvent(linkA.getLinkTuple());
+ assertEquals(linkA, linkAInTopo);
+ assertTrue(linkAInTopo.isFrozen());
+ assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkAInTopo.getType());
+
+ LinkEvent linkBInTopo = topology.getLinkEvent(linkB.getLinkTuple());
+ assertEquals(linkB, linkBInTopo);
+ assertTrue(linkBInTopo.isFrozen());
+ assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkBInTopo.getType());
+
+ // check events to be fired
+ List<LinkEvent> apiAddedLinkEvents
+ = TestUtils.getField(theTopologyManager, "apiAddedLinkEvents");
+ assertThat(apiAddedLinkEvents, containsInAnyOrder(linkA, linkB));
+ }
+
+ /**
+ * Test to confirm topology replica transformation.
+ */
+ @Test
+ public void testAddLinkKickingOffHost() {
+ setupTopologyManager();
+
+ final Dpid dpid = new Dpid(1);
+ SwitchEvent sw = new SwitchEvent(dpid);
+ sw.createStringAttribute("foo", "bar");
+
+ final PortNumber portNumberA = new PortNumber((short) 2);
+ PortEvent portA = new PortEvent(dpid, portNumberA);
+ portA.createStringAttribute("fuzz", "buzz");
+
+ final PortNumber portNumberB = new PortNumber((short) 3);
+ PortEvent portB = new PortEvent(dpid, portNumberB);
+ portB.createStringAttribute("fizz", "buz");
+
+ final PortNumber portNumberC = new PortNumber((short) 4);
+ PortEvent portC = new PortEvent(dpid, portNumberC);
+ portC.createStringAttribute("fizz", "buz");
+
+ final MACAddress macA = MACAddress.valueOf(666L);
+ HostEvent hostA = new HostEvent(macA);
+ hostA.addAttachmentPoint(portA.getSwitchPort());
+ final long timestampA = 392893200L;
+ hostA.setLastSeenTime(timestampA);
+
+ final MACAddress macB = MACAddress.valueOf(999L);
+ HostEvent hostB = new HostEvent(macB);
+ hostB.addAttachmentPoint(portB.getSwitchPort());
+ hostB.addAttachmentPoint(portC.getSwitchPort());
+ final long timestampB = 392893201L;
+ hostB.setLastSeenTime(timestampB);
+
+
+ LinkEvent linkA = new LinkEvent(portA.getSwitchPort(), portB.getSwitchPort());
+ linkA.createStringAttribute(TopologyElement.TYPE,
+ TopologyElement.TYPE_OPTICAL_LAYER);
+ LinkEvent linkB = new LinkEvent(portB.getSwitchPort(), portA.getSwitchPort());
+ linkB.createStringAttribute(TopologyElement.TYPE,
+ TopologyElement.TYPE_OPTICAL_LAYER);
+
+ TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchEvent.class, sw);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portA);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portB);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portC);
+ TestUtils.callMethod(theTopologyManager, "addHost", HostEvent.class, hostA);
+ TestUtils.callMethod(theTopologyManager, "addHost", HostEvent.class, hostB);
+
+ TestUtils.callMethod(theTopologyManager, "addLink", LinkEvent.class, linkA);
+ TestUtils.callMethod(theTopologyManager, "addLink", LinkEvent.class, linkB);
+
+ // check topology structure
+ TopologyInternal topology = (TopologyInternal) theTopologyManager.getTopology();
+ SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+ assertEquals(sw, swInTopo);
+ assertTrue(swInTopo.isFrozen());
+ assertEquals("bar", swInTopo.getStringAttribute("foo"));
+
+ final SwitchPort portIdA = new SwitchPort(dpid, portNumberA);
+ PortEvent portAInTopo = topology.getPortEvent(portIdA);
+ assertEquals(portA, portAInTopo);
+ assertTrue(portAInTopo.isFrozen());
+ assertEquals("buzz", portAInTopo.getStringAttribute("fuzz"));
+
+ final SwitchPort portIdB = new SwitchPort(dpid, portNumberB);
+ PortEvent portBInTopo = topology.getPortEvent(portIdB);
+ assertEquals(portB, portBInTopo);
+ assertTrue(portBInTopo.isFrozen());
+ assertEquals("buz", portBInTopo.getStringAttribute("fizz"));
+
+ // hostA expected to be removed
+ assertNull(topology.getHostEvent(macA));
+ // hostB expected to be there with reduced attachment point
+ HostEvent hostBrev = new HostEvent(macB);
+ hostBrev.addAttachmentPoint(portC.getSwitchPort());
+ hostBrev.setLastSeenTime(timestampB);
+ hostBrev.freeze();
+ assertEquals(hostBrev, topology.getHostEvent(macB));
+
+
+ LinkEvent linkAInTopo = topology.getLinkEvent(linkA.getLinkTuple());
+ assertEquals(linkA, linkAInTopo);
+ assertTrue(linkAInTopo.isFrozen());
+ assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkAInTopo.getType());
+
+ LinkEvent linkBInTopo = topology.getLinkEvent(linkB.getLinkTuple());
+ assertEquals(linkB, linkBInTopo);
+ assertTrue(linkBInTopo.isFrozen());
+ assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkBInTopo.getType());
+
+ // check events to be fired
+ List<HostEvent> apiAddedHostEvents
+ = TestUtils.getField(theTopologyManager, "apiAddedHostEvents");
+ assertThat(apiAddedHostEvents, hasItem(hostBrev));
+
+ List<HostEvent> apiRemovedHostEvents
+ = TestUtils.getField(theTopologyManager, "apiRemovedHostEvents");
+ assertThat(apiRemovedHostEvents, hasItem(hostA));
+ List<LinkEvent> apiAddedLinkEvents
+ = TestUtils.getField(theTopologyManager, "apiAddedLinkEvents");
+ assertThat(apiAddedLinkEvents, containsInAnyOrder(linkA, linkB));
+ }
+
+ /**
+ * Test to confirm topology replica transformation.
+ */
+ @Test
+ public void testRemoveLink() {
+ setupTopologyManager();
+
+ final Dpid dpid = new Dpid(1);
+ SwitchEvent sw = new SwitchEvent(dpid);
+ sw.createStringAttribute("foo", "bar");
+
+ final PortNumber portNumberA = new PortNumber((short) 2);
+ PortEvent portA = new PortEvent(dpid, portNumberA);
+ portA.createStringAttribute("fuzz", "buzz");
+
+ final PortNumber portNumberB = new PortNumber((short) 3);
+ PortEvent portB = new PortEvent(dpid, portNumberB);
+ portB.createStringAttribute("fizz", "buz");
+
+ LinkEvent linkA = new LinkEvent(portA.getSwitchPort(), portB.getSwitchPort());
+ linkA.createStringAttribute(TopologyElement.TYPE,
+ TopologyElement.TYPE_OPTICAL_LAYER);
+ LinkEvent linkB = new LinkEvent(portB.getSwitchPort(), portA.getSwitchPort());
+ linkB.createStringAttribute(TopologyElement.TYPE,
+ TopologyElement.TYPE_OPTICAL_LAYER);
+
+ TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchEvent.class, sw);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portA);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portB);
+ TestUtils.callMethod(theTopologyManager, "addLink", LinkEvent.class, linkA);
+ TestUtils.callMethod(theTopologyManager, "addLink", LinkEvent.class, linkB);
+
+ // check topology structure
+ TopologyInternal topology = (TopologyInternal) theTopologyManager.getTopology();
+ SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+ assertEquals(sw, swInTopo);
+ assertTrue(swInTopo.isFrozen());
+ assertEquals("bar", swInTopo.getStringAttribute("foo"));
+
+ final SwitchPort portIdA = new SwitchPort(dpid, portNumberA);
+ PortEvent portAInTopo = topology.getPortEvent(portIdA);
+ assertEquals(portA, portAInTopo);
+ assertTrue(portAInTopo.isFrozen());
+ assertEquals("buzz", portAInTopo.getStringAttribute("fuzz"));
+
+ final SwitchPort portIdB = new SwitchPort(dpid, portNumberB);
+ PortEvent portBInTopo = topology.getPortEvent(portIdB);
+ assertEquals(portB, portBInTopo);
+ assertTrue(portBInTopo.isFrozen());
+ assertEquals("buz", portBInTopo.getStringAttribute("fizz"));
+
+ LinkEvent linkAInTopo = topology.getLinkEvent(linkA.getLinkTuple());
+ assertEquals(linkA, linkAInTopo);
+ assertTrue(linkAInTopo.isFrozen());
+ assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkAInTopo.getType());
+
+
+ LinkEvent linkBInTopo = topology.getLinkEvent(linkB.getLinkTuple());
+ assertEquals(linkB, linkBInTopo);
+ assertTrue(linkBInTopo.isFrozen());
+ assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkBInTopo.getType());
+
+ // check events to be fired
+ // FIXME if link flapped (linkA in this scenario),
+ // linkA appears in both removed and added is this expected behavior?
+ List<LinkEvent> apiAddedLinkEvents
+ = TestUtils.getField(theTopologyManager, "apiAddedLinkEvents");
+ assertThat(apiAddedLinkEvents, containsInAnyOrder(linkA, linkB));
+
+ // clear event before removing Link
+ apiAddedLinkEvents.clear();
+
+ // remove link
+ TestUtils.callMethod(theTopologyManager, "removeLink", LinkEvent.class, new LinkEvent(linkA));
+
+ LinkEvent linkANotInTopo = topology.getLinkEvent(linkA.getLinkTuple());
+ assertNull(linkANotInTopo);
+
+ List<LinkEvent> apiRemovedLinkEvents
+ = TestUtils.getField(theTopologyManager, "apiRemovedLinkEvents");
+ assertThat(apiRemovedLinkEvents, hasItem(linkA));
+ }
+
+ /**
+ * Test to confirm topology replica transformation.
+ */
+ @Test
+ public void testAddHostIgnoredByLink() {
+ setupTopologyManager();
+
+ final Dpid dpid = new Dpid(1);
+ SwitchEvent sw = new SwitchEvent(dpid);
+ sw.createStringAttribute("foo", "bar");
+
+ final PortNumber portNumberA = new PortNumber((short) 2);
+ PortEvent portA = new PortEvent(dpid, portNumberA);
+ portA.createStringAttribute("fuzz", "buzz");
+
+ final PortNumber portNumberB = new PortNumber((short) 3);
+ PortEvent portB = new PortEvent(dpid, portNumberB);
+ portB.createStringAttribute("fizz", "buz");
+
+ final PortNumber portNumberC = new PortNumber((short) 4);
+ PortEvent portC = new PortEvent(dpid, portNumberC);
+ portC.createStringAttribute("fizz", "buz");
+
+ LinkEvent linkA = new LinkEvent(portA.getSwitchPort(), portB.getSwitchPort());
+ linkA.createStringAttribute(TopologyElement.TYPE,
+ TopologyElement.TYPE_OPTICAL_LAYER);
+ LinkEvent linkB = new LinkEvent(portB.getSwitchPort(), portA.getSwitchPort());
+ linkB.createStringAttribute(TopologyElement.TYPE,
+ TopologyElement.TYPE_OPTICAL_LAYER);
+
+ TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchEvent.class, sw);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portA);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portB);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portC);
+ TestUtils.callMethod(theTopologyManager, "addLink", LinkEvent.class, linkA);
+ TestUtils.callMethod(theTopologyManager, "addLink", LinkEvent.class, linkB);
+
+ // Add hostA attached to a port which already has a link
+ final MACAddress macA = MACAddress.valueOf(666L);
+ HostEvent hostA = new HostEvent(macA);
+ hostA.addAttachmentPoint(portA.getSwitchPort());
+ final long timestampA = 392893200L;
+ hostA.setLastSeenTime(timestampA);
+
+ TestUtils.callMethod(theTopologyManager, "addHost", HostEvent.class, hostA);
+
+ // Add hostB attached to multiple ports,
+ // some of them which already has a link
+ final MACAddress macB = MACAddress.valueOf(999L);
+ HostEvent hostB = new HostEvent(macB);
+ hostB.addAttachmentPoint(portB.getSwitchPort());
+ hostB.addAttachmentPoint(portC.getSwitchPort());
+ final long timestampB = 392893201L;
+ hostB.setLastSeenTime(timestampB);
+
+ TestUtils.callMethod(theTopologyManager, "addHost", HostEvent.class, hostB);
+
+ // check topology structure
+ TopologyInternal topology = (TopologyInternal) theTopologyManager.getTopology();
+ SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+ assertEquals(sw, swInTopo);
+ assertTrue(swInTopo.isFrozen());
+ assertEquals("bar", swInTopo.getStringAttribute("foo"));
+
+ final SwitchPort portIdA = new SwitchPort(dpid, portNumberA);
+ PortEvent portAInTopo = topology.getPortEvent(portIdA);
+ assertEquals(portA, portAInTopo);
+ assertTrue(portAInTopo.isFrozen());
+ assertEquals("buzz", portAInTopo.getStringAttribute("fuzz"));
+
+ final SwitchPort portIdB = new SwitchPort(dpid, portNumberB);
+ PortEvent portBInTopo = topology.getPortEvent(portIdB);
+ assertEquals(portB, portBInTopo);
+ assertTrue(portBInTopo.isFrozen());
+ assertEquals("buz", portBInTopo.getStringAttribute("fizz"));
+
+ // hostA expected to be completely ignored
+ assertNull(topology.getHostEvent(macA));
+ // hostB expected to be there with reduced attachment point
+ HostEvent hostBrev = new HostEvent(macB);
+ hostBrev.addAttachmentPoint(portC.getSwitchPort());
+ hostBrev.setLastSeenTime(timestampB);
+ hostBrev.freeze();
+ assertEquals(hostBrev, topology.getHostEvent(macB));
+
+
+ LinkEvent linkAInTopo = topology.getLinkEvent(linkA.getLinkTuple());
+ assertEquals(linkA, linkAInTopo);
+ assertTrue(linkAInTopo.isFrozen());
+ assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkAInTopo.getType());
+
+ LinkEvent linkBInTopo = topology.getLinkEvent(linkB.getLinkTuple());
+ assertEquals(linkB, linkBInTopo);
+ assertTrue(linkBInTopo.isFrozen());
+ assertEquals(TopologyElement.TYPE_OPTICAL_LAYER, linkBInTopo.getType());
+
+ // check events to be fired
+ // hostB should be added with reduced attachment points
+ List<HostEvent> apiAddedHostEvents
+ = TestUtils.getField(theTopologyManager, "apiAddedHostEvents");
+ assertThat(apiAddedHostEvents, hasItem(hostBrev));
+
+ // hostA should not be ignored
+ List<HostEvent> apiRemovedHostEvents
+ = TestUtils.getField(theTopologyManager, "apiRemovedHostEvents");
+ assertThat(apiRemovedHostEvents, not(hasItem(hostA)));
+
+ List<LinkEvent> apiAddedLinkEvents
+ = TestUtils.getField(theTopologyManager, "apiAddedLinkEvents");
+ assertThat(apiAddedLinkEvents, containsInAnyOrder(linkA, linkB));
+ }
+
+ /**
+ * Test to confirm topology replica transformation.
+ */
+ @Test
+ public void testAddHostMove() {
+ setupTopologyManager();
+
+ final Dpid dpid = new Dpid(1);
+ SwitchEvent sw = new SwitchEvent(dpid);
+ sw.createStringAttribute("foo", "bar");
+
+ final PortNumber portNumberA = new PortNumber((short) 2);
+ PortEvent portA = new PortEvent(dpid, portNumberA);
+ portA.createStringAttribute("fuzz", "buzz");
+
+ final PortNumber portNumberB = new PortNumber((short) 3);
+ PortEvent portB = new PortEvent(dpid, portNumberB);
+ portB.createStringAttribute("fizz", "buz");
+
+ final PortNumber portNumberC = new PortNumber((short) 4);
+ PortEvent portC = new PortEvent(dpid, portNumberC);
+ portC.createStringAttribute("fizz", "buz");
+
+ TestUtils.callMethod(theTopologyManager, "addSwitch", SwitchEvent.class, sw);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portA);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portB);
+ TestUtils.callMethod(theTopologyManager, "addPort", PortEvent.class, portC);
+
+ // Add hostA attached to a port which already has a link
+ final MACAddress macA = MACAddress.valueOf(666L);
+ HostEvent hostA = new HostEvent(macA);
+ hostA.addAttachmentPoint(portA.getSwitchPort());
+ final long timestampA = 392893200L;
+ hostA.setLastSeenTime(timestampA);
+
+ TestUtils.callMethod(theTopologyManager, "addHost", HostEvent.class, hostA);
+
+
+ // check topology structure
+ TopologyInternal topology = (TopologyInternal) theTopologyManager.getTopology();
+ SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+ assertEquals(sw, swInTopo);
+ assertTrue(swInTopo.isFrozen());
+ assertEquals("bar", swInTopo.getStringAttribute("foo"));
+
+ final SwitchPort portIdA = new SwitchPort(dpid, portNumberA);
+ PortEvent portAInTopo = topology.getPortEvent(portIdA);
+ assertEquals(portA, portAInTopo);
+ assertTrue(portAInTopo.isFrozen());
+ assertEquals("buzz", portAInTopo.getStringAttribute("fuzz"));
+
+ final SwitchPort portIdB = new SwitchPort(dpid, portNumberB);
+ PortEvent portBInTopo = topology.getPortEvent(portIdB);
+ assertEquals(portB, portBInTopo);
+ assertTrue(portBInTopo.isFrozen());
+ assertEquals("buz", portBInTopo.getStringAttribute("fizz"));
+
+ // hostA expected to be there
+ assertEquals(hostA, topology.getHostEvent(macA));
+ assertEquals(timestampA, topology.getHostEvent(macA).getLastSeenTime());
+
+ // check events to be fired
+ // hostA should be added
+ List<HostEvent> apiAddedHostEvents
+ = TestUtils.getField(theTopologyManager, "apiAddedHostEvents");
+ assertThat(apiAddedHostEvents, hasItem(hostA));
+
+
+ // clear event before moving host
+ apiAddedHostEvents.clear();
+
+ HostEvent hostAmoved = new HostEvent(macA);
+ hostAmoved.addAttachmentPoint(portB.getSwitchPort());
+ final long timestampAmoved = 392893201L;
+ hostAmoved.setLastSeenTime(timestampAmoved);
+
+ TestUtils.callMethod(theTopologyManager, "addHost", HostEvent.class, hostAmoved);
+
+ assertEquals(hostAmoved, topology.getHostEvent(macA));
+ assertEquals(timestampAmoved, topology.getHostEvent(macA).getLastSeenTime());
+
+ // hostA expected to be there with new attachment point
+ apiAddedHostEvents
+ = TestUtils.getField(theTopologyManager, "apiAddedHostEvents");
+ assertThat(apiAddedHostEvents, hasItem(hostAmoved));
+
+ // hostA is updated not removed
+ List<HostEvent> apiRemovedHostEvents
+ = TestUtils.getField(theTopologyManager, "apiRemovedHostEvents");
+ assertThat(apiRemovedHostEvents, not(hasItem(hostA)));
+ }
}