package net.onrc.onos.core.topology;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
import net.floodlightcontroller.core.IFloodlightProviderService.Role;
import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.core.topology.ImmutableTopologySnapshot.Builder;
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.LinkTuple;
import net.onrc.onos.core.util.OnosInstanceId;
import net.onrc.onos.core.util.PortNumber;
import net.onrc.onos.core.util.SwitchPort;
import org.apache.commons.math3.random.RandomDataGenerator;
import org.junit.BeforeClass;
import org.junit.Test;
import com.google.common.collect.Iterators;
/**
* Tests for {@link ImmutableTopologySnapshot}.
*/
public class ImmutableTopologySnapshotTest {
// randomly generated topology
private static ImmutableTopologySnapshot ss;
// randomly generated topology size
private static final int NUM_HOSTS = 12;
private static final int NUM_LINKS = 11;
private static final int NUM_PORTS = 48;
private static final int NUM_SWITCH = 10;
// a link that is assured to be in topology
private static final LinkTuple LINK_IN_TOPOLOGY = new LinkTuple(
new Dpid(1), PortNumber.uint32(1),
new Dpid(2), PortNumber.uint32(1));
// invalid port number, etc. which should not appear in topology
private static final int PORT_NUM_NA = NUM_PORTS + 2;
private static final long MAC_NA = NUM_HOSTS + 1L;
// master instance of all the switches in ramdomly generated topology
private static final OnosInstanceId INSTANCE_ID
= new OnosInstanceId("TheInstance");
/**
* Generate topology to test.
*/
@BeforeClass
public static void setUpBeforeClass() {
ss = createTopology(NUM_SWITCH, NUM_PORTS, NUM_LINKS, NUM_HOSTS);
}
/**
* InitialBuilder should contains empty topology.
*/
@Test
public void testInitialBuilder() {
final Builder builder = ImmutableTopologySnapshot.initialBuilder();
assertTrue("Topology should be empty",
builder.getCurrentInternal().getAllSwitchDataEntries().isEmpty());
assertTrue("Topology should be empty",
builder.build().getAllSwitchDataEntries().isEmpty());
}
/**
* Builder should create a copy of the parent topology.
*/
@Test
public void testBuilder() {
final Builder builder = ss.builder();
assertEquals("Number of switch", NUM_SWITCH,
builder.getCurrentInternal().getAllSwitchDataEntries().size());
assertEquals("Number of ports", NUM_PORTS * NUM_SWITCH,
builder.getCurrentInternal().getAllPortDataEntries().size());
assertEquals("Number of links", NUM_LINKS,
builder.getCurrentInternal().getAllLinkDataEntries().size());
assertEquals("Number of hosts", NUM_HOSTS,
builder.getCurrentInternal().getAllHostDataEntries().size());
final ImmutableTopologySnapshot clone = builder.build();
assertEquals("Number of switch", NUM_SWITCH,
clone.getAllSwitchDataEntries().size());
assertEquals("Number of ports", NUM_PORTS * NUM_SWITCH,
clone.getAllPortDataEntries().size());
assertEquals("Number of links", NUM_LINKS,
clone.getAllLinkDataEntries().size());
assertEquals("Number of hosts", NUM_HOSTS,
clone.getAllHostDataEntries().size());
}
/**
* Test for {@link ImmutableTopologySnapshot#getSwitchData(Dpid)}.
*/
@Test
public void testGetSwitchData() {
final Dpid dpid1 = new Dpid(1);
assertNotNull("Switch 1 should exist",
ss.getSwitchData(dpid1));
final Dpid dpidNa = new Dpid(NUM_SWITCH + 1);
assertNull("Switch NUM_SWITCH + 1 should not exist",
ss.getSwitchData(dpidNa));
}
/**
* Test for {@link ImmutableTopologySnapshot#getAllSwitchDataEntries()}.
*/
@Test
public void testGetAllSwitchDataEntries() {
assertEquals("Number of switch", NUM_SWITCH,
ss.getAllSwitchDataEntries().size());
}
/**
* Test for {@link ImmutableTopologySnapshot#getPortData(SwitchPort)}.
*/
@Test
public void testGetPortDataSwitchPort() {
final Dpid dpid1 = new Dpid(1);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Switch 1 Port 1 should exist",
ss.getPortData(new SwitchPort(dpid1, port1)));
final PortNumber portNa = PortNumber.uint32(PORT_NUM_NA);
assertNull("Switch 1 Port PORT_NUM_NA should not exist",
ss.getPortData(new SwitchPort(dpid1, portNa)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getPortData(Dpid, PortNumber)}.
*/
@Test
public void testGetPortDataDpidPortNumber() {
final Dpid dpid1 = new Dpid(1);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Switch 1 Port 1 should exist",
ss.getPortData(dpid1, port1));
final PortNumber portNa = PortNumber.uint32(PORT_NUM_NA);
assertNull("Switch 1 Port PORT_NUM_NA should not exist",
ss.getPortData(dpid1, portNa));
}
/**
* Test for {@link ImmutableTopologySnapshot#getPortDataEntries(Dpid)}.
*/
@Test
public void testGetPortDataEntries() {
final Dpid dpid1 = new Dpid(1);
assertEquals("Number of ports", NUM_PORTS,
ss.getPortDataEntries(dpid1).size());
}
/**
* Test for {@link ImmutableTopologySnapshot#getAllPortDataEntries()}.
*/
@Test
public void testGetAllPortDataEntries() {
assertEquals("Number of ports", NUM_PORTS * NUM_SWITCH,
ss.getAllPortDataEntries().size());
}
/**
* Test for {@link ImmutableTopologySnapshot#getLinkData(LinkTuple)}.
*/
@Test
public void testGetLinkDataLinkTuple() {
assertNotNull("Link (1:1 -> 2:1) should exist",
ss.getLinkData(LINK_IN_TOPOLOGY));
final Dpid dpid1 = new Dpid(1);
final Dpid dpid2 = new Dpid(2);
final PortNumber port1 = PortNumber.uint32(1);
final PortNumber portNa = PortNumber.uint32(PORT_NUM_NA);
assertNull("Link (1:1 -> 2:PORT_NUM_NA) should not exist",
ss.getLinkData(new LinkTuple(dpid1, port1, dpid2, portNa)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getLinkData(LinkTuple, String)}.
*/
@Test
public void testGetLinkDataLinkTupleString() {
assertNotNull("Link (1:1 -> 2:1) should exist",
ss.getLinkData(LINK_IN_TOPOLOGY,
TopologyElement.TYPE_PACKET_LAYER));
final Dpid dpid1 = new Dpid(1);
final Dpid dpid2 = new Dpid(2);
final PortNumber port1 = PortNumber.uint32(1);
final PortNumber portNa = PortNumber.uint32(PORT_NUM_NA);
assertNull("Link (1:1 -> 2:PORT_NUM_NA) should not exist",
ss.getLinkData(new LinkTuple(dpid1, port1, dpid2, portNa),
TopologyElement.TYPE_PACKET_LAYER));
}
/**
* Test for {@link ImmutableTopologySnapshot#getLinkDataEntriesFrom(SwitchPort)}.
*/
@Test
public void testGetLinkDataEntriesFrom() {
assertThat("Port 1:1 should at least have 1 outgoing link",
ss.getLinkDataEntriesFrom(LINK_IN_TOPOLOGY.getSrc()).size(),
is(greaterThanOrEqualTo(1)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getLinkDataEntriesTo(SwitchPort)}.
*/
@Test
public void testGetLinkDataEntriesTo() {
assertThat("Port 2:1 should at least have 1 incoming link",
ss.getLinkDataEntriesTo(LINK_IN_TOPOLOGY.getDst()).size(),
is(greaterThanOrEqualTo(1)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getLinkDataEntries(LinkTuple)}.
*/
@Test
public void testGetLinkDataEntries() {
assertFalse("Link (1:1 -> 2:1) should exist",
ss.getLinkDataEntries(LINK_IN_TOPOLOGY).isEmpty());
final Dpid dpid1 = new Dpid(1);
final Dpid dpid2 = new Dpid(2);
final PortNumber port1 = PortNumber.uint32(1);
final PortNumber portNa = PortNumber.uint32(PORT_NUM_NA);
assertTrue("Link (1:1 -> 2:PORT_NUM_NA) should not exist",
ss.getLinkDataEntries(new LinkTuple(dpid1, port1, dpid2, portNa)).isEmpty());
}
/**
* Test for {@link ImmutableTopologySnapshot#getAllLinkDataEntries()}.
*/
@Test
public void testGetAllLinkDataEntries() {
assertEquals("Number of links", NUM_LINKS,
ss.getAllLinkDataEntries().size());
}
/**
* Test for {@link ImmutableTopologySnapshot#getHostData(MACAddress)}.
*/
@Test
public void testGetHostData() {
assertNotNull("Host 0:..:0 should exist",
ss.getHostData(MACAddress.valueOf(0L)));
assertNull("Host MAC_NA should exist",
ss.getHostData(MACAddress.valueOf(MAC_NA)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getHostDataEntries(SwitchPort)}.
*/
@Test
public void testGetHostDataEntries() {
final HostData host = ss.getHostData(MACAddress.valueOf(0L));
final SwitchPort attachment = host.getAttachmentPoints().get(0);
assertThat("should at least have 1 host attached",
ss.getHostDataEntries(attachment).size(),
is(greaterThanOrEqualTo(1)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getAllHostDataEntries()}.
*/
@Test
public void testGetAllHostDataEntries() {
assertEquals("Number of hosts", NUM_HOSTS,
ss.getAllHostDataEntries().size());
}
/**
* Test for {@link ImmutableTopologySnapshot#getSwitchMaster(Dpid)}.
*/
@Test
public void testGetSwitchMaster() {
assertEquals("Master is stored", INSTANCE_ID, ss.getSwitchMaster(new Dpid(1)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getSwitch(Dpid)}.
*/
@Test
public void testGetSwitch() {
final Dpid dpid1 = new Dpid(1);
assertNotNull("Switch 1 should exist",
ss.getSwitch(dpid1));
final Dpid dpidNa = new Dpid(NUM_SWITCH + 1);
assertNull("Switch NUM_SWITCH + 1 should not exist",
ss.getSwitch(dpidNa));
}
/**
* Test for {@link ImmutableTopologySnapshot#getSwitches()}.
*/
@Test
public void testGetSwitches() {
assertEquals("Number of switch", NUM_SWITCH,
Iterators.size(ss.getSwitches().iterator()));
}
/**
* Test for {@link ImmutableTopologySnapshot#getPort(Dpid, PortNumber)}.
*/
@Test
public void testGetPortDpidPortNumber() {
final Dpid dpid1 = new Dpid(1);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Switch 1 Port 1 should exist",
ss.getPort(dpid1, port1));
final PortNumber portNa = PortNumber.uint32(PORT_NUM_NA);
assertNull("Switch 1 Port PORT_NUM_NA should not exist",
ss.getPort(dpid1, portNa));
}
/**
* Test for {@link ImmutableTopologySnapshot#getPort(SwitchPort)}.
*/
@Test
public void testGetPortSwitchPort() {
final Dpid dpid1 = new Dpid(1);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Switch 1 Port 1 should exist",
ss.getPort(new SwitchPort(dpid1, port1)));
final PortNumber portNa = PortNumber.uint32(PORT_NUM_NA);
assertNull("Switch 1 Port PORT_NUM_NA should not exist",
ss.getPort(new SwitchPort(dpid1, portNa)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getPorts(Dpid)}.
*/
@Test
public void testGetPorts() {
final Dpid dpid1 = new Dpid(1);
assertEquals("Number of ports", NUM_PORTS,
ss.getPorts(dpid1).size());
}
/**
* Test for {@link ImmutableTopologySnapshot#getOutgoingLink(Dpid, PortNumber)}.
*/
@Test
public void testGetOutgoingLinkDpidPortNumber() {
final Dpid dpid1 = new Dpid(1);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Port 1:1 should at least have 1 outgoing link",
ss.getOutgoingLink(dpid1, port1));
}
/**
* Test for {@link ImmutableTopologySnapshot#getOutgoingLink(SwitchPort)}.
*/
@Test
public void testGetOutgoingLinkSwitchPort() {
final Dpid dpid1 = new Dpid(1);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Port 1:1 should at least have 1 outgoing link",
ss.getOutgoingLink(new SwitchPort(dpid1, port1)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getOutgoingLink(Dpid, PortNumber, String)}.
*/
@Test
public void testGetOutgoingLinkDpidPortNumberString() {
final Dpid dpid1 = new Dpid(1);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Port 1:1 should at least have 1 outgoing link",
ss.getOutgoingLink(dpid1, port1,
TopologyElement.TYPE_PACKET_LAYER));
}
/**
* Test for {@link ImmutableTopologySnapshot#getOutgoingLink(SwitchPort, String)}.
*/
@Test
public void testGetOutgoingLinkSwitchPortString() {
final Dpid dpid1 = new Dpid(1);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Port 1:1 should at least have 1 outgoing link",
ss.getOutgoingLink(new SwitchPort(dpid1, port1),
TopologyElement.TYPE_PACKET_LAYER));
}
/**
* Test for {@link ImmutableTopologySnapshot#getOutgoingLinks(SwitchPort)}.
*/
@Test
public void testGetOutgoingLinks() {
final Dpid dpid1 = new Dpid(1);
final PortNumber port1 = PortNumber.uint32(1);
assertThat("Port 1:1 should at least have 1 outgoing link",
ss.getOutgoingLinks(new SwitchPort(dpid1, port1)).size(),
is(greaterThanOrEqualTo(1)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getIncomingLink(Dpid, PortNumber)}.
*/
@Test
public void testGetIncomingLinkDpidPortNumber() {
final Dpid dpid2 = new Dpid(2);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Port 2:1 should at least have 1 outgoing link",
ss.getIncomingLink(dpid2, port1));
}
/**
* Test for {@link ImmutableTopologySnapshot#getIncomingLink(SwitchPort)}.
*/
@Test
public void testGetIncomingLinkSwitchPort() {
final Dpid dpid2 = new Dpid(2);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Port 2:1 should at least have 1 outgoing link",
ss.getIncomingLink(new SwitchPort(dpid2, port1)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getIncomingLink(Dpid, PortNumber, String)}.
*/
@Test
public void testGetIncomingLinkDpidPortNumberString() {
final Dpid dpid2 = new Dpid(2);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Port 2:1 should at least have 1 outgoing link",
ss.getIncomingLink(dpid2, port1,
TopologyElement.TYPE_PACKET_LAYER));
}
/**
* Test for {@link ImmutableTopologySnapshot#getIncomingLink(SwitchPort, String)}.
*/
@Test
public void testGetIncomingLinkSwitchPortString() {
final Dpid dpid2 = new Dpid(2);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Port 2:1 should at least have 1 outgoing link",
ss.getIncomingLink(new SwitchPort(dpid2, port1),
TopologyElement.TYPE_PACKET_LAYER));
}
/**
* Test for {@link ImmutableTopologySnapshot#getIncomingLinks(SwitchPort)}.
*/
@Test
public void testGetIncomingLinks() {
final Dpid dpid2 = new Dpid(2);
final PortNumber port1 = PortNumber.uint32(1);
assertThat("Port 2:1 should at least have 1 outgoing link",
ss.getIncomingLinks(new SwitchPort(dpid2, port1)).size(),
is(greaterThanOrEqualTo(1)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getLink(Dpid, PortNumber, Dpid, PortNumber)}.
*/
@Test
public void testGetLinkDpidPortNumberDpidPortNumber() {
final Dpid dpid1 = new Dpid(1);
final Dpid dpid2 = new Dpid(2);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Link (1:1 -> 2:1) should exist",
ss.getLink(dpid1, port1, dpid2, port1));
final PortNumber portNa = PortNumber.uint32(PORT_NUM_NA);
assertNull("Link (1:1 -> 2:PORT_NUM_NA) should not exist",
ss.getLink(dpid1, port1, dpid2, portNa));
}
/**
* Test for {@link ImmutableTopologySnapshot#getLink(Dpid, PortNumber, Dpid, PortNumber, String)}.
*/
@Test
public void testGetLinkDpidPortNumberDpidPortNumberString() {
final Dpid dpid1 = new Dpid(1);
final Dpid dpid2 = new Dpid(2);
final PortNumber port1 = PortNumber.uint32(1);
assertNotNull("Link (1:1 -> 2:1) should exist",
ss.getLink(dpid1, port1, dpid2, port1,
TopologyElement.TYPE_PACKET_LAYER));
final PortNumber portNa = PortNumber.uint32(PORT_NUM_NA);
assertNull("Link (1:1 -> 2:PORT_NUM_NA) should not exist",
ss.getLink(dpid1, port1, dpid2, portNa,
TopologyElement.TYPE_PACKET_LAYER));
}
/**
* Test for {@link ImmutableTopologySnapshot#getLinks()}.
*/
@Test
public void testGetLinks() {
assertEquals("Number of links", NUM_LINKS,
Iterators.size(ss.getLinks().iterator()));
}
/**
* Test for {@link ImmutableTopologySnapshot#getHostByMac(MACAddress)}.
*/
@Test
public void testGetHostByMac() {
assertNotNull("Host 0:..:0 should exist",
ss.getHostByMac(MACAddress.valueOf(0L)));
assertNull("Host MAC_NA should exist",
ss.getHostByMac(MACAddress.valueOf(MAC_NA)));
}
/**
* Test for {@link ImmutableTopologySnapshot#getHosts()}.
*/
@Test
public void testGetHosts() {
assertEquals("Number of host", NUM_HOSTS,
Iterators.size(ss.getHosts().iterator()));
}
/**
* Test for {@link ImmutableTopologySnapshot#getHosts(SwitchPort)}.
*/
@Test
public void testGetHostsSwitchPort() {
final HostData host = ss.getHostData(MACAddress.valueOf(0L));
final SwitchPort attachment = host.getAttachmentPoints().get(0);
assertThat("should at least have 1 host attached",
ss.getHosts(attachment).size(),
is(greaterThanOrEqualTo(1)));
}
/**
* Create random topology with specified number of elements.
*
* @param switches number of switches
* @param ports number of ports
* @param links number of links
* @param hosts number of hosts
* @return created topology
*/
private static ImmutableTopologySnapshot createTopology(
final int switches,
final int ports,
final int links,
final int hosts) {
Builder builder = ImmutableTopologySnapshot.initialBuilder();
for (int i = 0; i < switches; ++i) {
final Dpid dpid = new Dpid(i + 1);
builder.putSwitchMastershipData(new MastershipData(dpid,
INSTANCE_ID,
Role.MASTER));
builder.putSwitch(new SwitchData(dpid));
for (int j = 0; j < ports; ++j) {
builder.putPort(new PortData(dpid, PortNumber.uint32(j + 1)));
}
}
final RandomDataGenerator rand = new RandomDataGenerator();
int l = 0;
// Always add Link (1:1 -> 2:1)
builder.putLink(new LinkData(LINK_IN_TOPOLOGY));
++l;
while (l < links) {
int sw1 = rand.nextInt(1, switches);
int port1 = rand.nextInt(1, ports);
int sw2 = rand.nextInt(1, switches);
int port2 = rand.nextInt(1, ports);
if (sw1 == sw2 && port1 == port2) {
continue;
}
LinkTuple linkId = new LinkTuple(
new Dpid(sw1), PortNumber.uint32(port1),
new Dpid(sw2), PortNumber.uint32(port2));
final BaseInternalTopology current = builder.getCurrentInternal();
if (!current.getLinkDataEntriesFrom(linkId.getSrc()).isEmpty() ||
!current.getLinkDataEntriesTo(linkId.getSrc()).isEmpty()) {
// src port already has a link
continue;
}
if (!current.getLinkDataEntriesFrom(linkId.getDst()).isEmpty() ||
!current.getLinkDataEntriesTo(linkId.getDst()).isEmpty()) {
// dst port already has a link
continue;
}
// add only if both port doesn't have any link
builder.putLink(new LinkData(linkId));
++l;
}
// Add host with mac 0 -> hosts
int h = 0;
while (h < hosts) {
HostData host = new HostData(MACAddress.valueOf(h));
SwitchPort swp = new SwitchPort(
new Dpid(rand.nextInt(1, switches)),
PortNumber.uint32(rand.nextInt(1, ports)));
if (builder.getCurrent().getIncomingLinks(swp).isEmpty() &&
builder.getCurrent().getOutgoingLinks(swp).isEmpty()) {
// add only if link doesn't exist
host.addAttachmentPoint(swp);
builder.putHost(host);
++h;
}
}
return builder.build();
}
}