blob: e50f825db499926a4458aee0ef1d5fa73e15dca2 [file] [log] [blame]
package org.onosproject.rabbitmq.listener;
import static com.google.common.collect.ImmutableSet.of;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.NetTestTools.device;
import static org.onosproject.net.NetTestTools.link;
import static org.onosproject.net.PortNumber.portNumber;
import static org.onosproject.net.topology.TopologyEvent.Type.TOPOLOGY_CHANGED;
import static org.onosproject.net.device.DeviceEvent.Type.*;
import static org.onosproject.net.link.LinkEvent.Type.*;
import static org.onosproject.net.Device.Type.*;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.easymock.EasyMockRunner;
import org.easymock.Mock;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.onlab.packet.ChassisId;
import org.onlab.packet.Ethernet;
import org.onlab.packet.ONOSLLDP;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.event.AbstractEventTest;
import org.onosproject.event.Event;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultDevice;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DefaultPort;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link;
import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.Port;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceServiceAdapter;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.link.LinkListener;
import org.onosproject.net.link.LinkService;
import org.onosproject.net.packet.DefaultInboundPacket;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketServiceAdapter;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.net.topology.DefaultGraphDescription;
import org.onosproject.net.topology.GraphDescription;
import org.onosproject.net.topology.Topology;
import org.onosproject.net.topology.TopologyEvent;
import org.onosproject.net.topology.TopologyListener;
import org.onosproject.net.topology.TopologyProvider;
import org.onosproject.net.topology.TopologyProviderRegistry;
import org.onosproject.net.topology.TopologyProviderService;
import org.onosproject.net.topology.TopologyService;
import org.onosproject.rabbitmq.api.MQService;
import org.onosproject.rabbitmq.api.Manageable;
import org.osgi.service.component.ComponentContext;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.MoreExecutors;
/**
* Junit tests for packet in, device, topology and link events.
*/
@RunWith(EasyMockRunner.class)
public class MQEventHandlerTest extends AbstractEventTest {
private final MQEventHandler mqEventHandler = new MQEventHandler();
private static final DeviceId DID1 = deviceId("of:0000000000000001");
private static final DeviceId DID2 = deviceId("of:0000000000000002");
private static final DeviceId DID3 = deviceId("of:0000000000000003");
private ApplicationId appId = new DefaultApplicationId(100,
"org.onosproject.rabbitmq");
private final TestPacketService packetService = new TestPacketService();
private final TestDeviceService deviceService = new TestDeviceService();
private PacketProcessor testProcessor;
private DeviceListener deviceListener;
private static Port pd1;
private static Port pd2;
private static Port pd3;
private static Port pd4;
private CoreService coreService;
@Mock
ComponentContext context;
@Mock
private Manageable manageSender;
private static final ProviderId PID = new ProviderId("of", "foo");
private TestLinkListener testLinkListener = new TestLinkListener();
@Mock
private LinkService linkService;
@Mock
Topology topology;
@Mock
protected TopologyService service;
protected TopologyProviderRegistry registry;
@Mock
protected TopologyProviderService providerService;
protected TestProvider provider;
protected TestTopologyListener listener = new TestTopologyListener();
@Mock
MQService mqService;
@Before
public void setUp() {
coreService = createMock(CoreService.class);
expect(coreService.registerApplication(appId.name()))
.andReturn(appId).anyTimes();
replay(coreService);
mqEventHandler.deviceService = deviceService;
mqEventHandler.packetService = packetService;
mqEventHandler.eventExecutor = MoreExecutors.newDirectExecutorService();
linkService.addListener(testLinkListener);
mqEventHandler.linkService = linkService;
mqEventHandler.topologyService = service;
mqEventHandler.activate(context);
}
@After
public void tearDown() {
mqEventHandler.deactivate();
mqEventHandler.deviceService = null;
mqEventHandler.packetService = null;
}
private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
return new DeviceEvent(type, deviceService.getDevice(did));
}
private Port port(DeviceId did, long port, boolean enabled) {
return new DefaultPort(deviceService.getDevice(did),
portNumber(port), enabled);
}
private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did,
Port port) {
return new DeviceEvent(type, deviceService.getDevice(did), port);
}
@Test
public void switchAdd() {
DeviceEvent de = deviceEvent(DEVICE_ADDED, DID1);
deviceListener.event(de);
}
@Test
public void switchRemove() {
deviceListener.event(deviceEvent(DEVICE_ADDED, DID1));
deviceListener.event(deviceEvent(DEVICE_REMOVED, DID1));
}
@Test
public void switchUpdate() {
deviceListener.event(deviceEvent(DEVICE_UPDATED, DID1));
deviceListener.event(deviceEvent(DEVICE_REMOVED, DID1));
}
@Test
public void switchSuspend() {
deviceListener.event(deviceEvent(DEVICE_SUSPENDED, DID1));
deviceListener.event(deviceEvent(DEVICE_REMOVED, DID1));
}
@Test
public void portUp() {
deviceListener.event(deviceEvent(DEVICE_ADDED, DID1));
deviceListener.event(portEvent(PORT_ADDED, DID1, port(DID1, 3, true)));
}
@Test
public void portDown() {
deviceListener.event(deviceEvent(DEVICE_ADDED, DID1));
deviceListener.event(portEvent(PORT_ADDED, DID1, port(DID1, 1, false)));
}
@Test
public void portRemoved() {
deviceListener.event(deviceEvent(DEVICE_ADDED, DID1));
deviceListener.event(portEvent(PORT_ADDED, DID1, port(DID1, 3, true)));
deviceListener.event(portEvent(PORT_REMOVED, DID1,
port(DID1, 3, true)));
}
@Test
public void unknownPktCtx() {
// Note: DID3 hasn't been added to TestDeviceService
PacketContext pktCtx = new TestPacketContext(device1(DID3));
testProcessor.process(pktCtx);
assertFalse("Context should still be free", pktCtx.isHandled());
}
private DefaultDevice device1(DeviceId did) {
return new DefaultDevice(ProviderId.NONE, did, SWITCH,
"TESTMF", "TESTHW", "TESTSW", "TESTSN",
new ChassisId());
}
@Test
public void knownPktCtx() {
deviceListener.event(deviceEvent(DEVICE_ADDED, DID1));
deviceListener.event(deviceEvent(DEVICE_ADDED, DID2));
PacketContext pktCtx = new TestPacketContext(
deviceService.getDevice(DID2));
/*
* EasyMock.expectLastCall(); EasyMock.replay(manageSender);
*/
testProcessor.process(pktCtx);
}
private class TestDeviceService extends DeviceServiceAdapter {
private final Map<DeviceId, Device> devices = new HashMap<>();
private final ArrayListMultimap<DeviceId, Port> ports =
ArrayListMultimap.create();
public TestDeviceService() {
Device d1 = new DefaultDevice(ProviderId.NONE, DID1,
SWITCH, "TESTMF", "TESTHW",
"TESTSW", "TESTSN", new ChassisId());
Device d2 = new DefaultDevice(ProviderId.NONE, DID2, SWITCH,
"TESTMF", "TESTHW", "TESTSW",
"TESTSN", new ChassisId());
devices.put(DID1, d1);
devices.put(DID2, d2);
pd1 = new DefaultPort(d1, portNumber(1), true);
pd2 = new DefaultPort(d1, portNumber(2), true);
pd3 = new DefaultPort(d2, portNumber(1), true);
pd4 = new DefaultPort(d2, portNumber(2), true);
ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
}
@Override
public int getDeviceCount() {
return devices.values().size();
}
@Override
public Iterable<Device> getDevices() {
return ImmutableList.copyOf(devices.values());
}
@Override
public Device getDevice(DeviceId deviceId) {
return devices.get(deviceId);
}
@Override
public MastershipRole getRole(DeviceId deviceId) {
return MastershipRole.MASTER;
}
@Override
public boolean isAvailable(DeviceId deviceId) {
return true;
}
@Override
public void addListener(DeviceListener listener) {
deviceListener = listener;
}
@Override
public void removeListener(DeviceListener listener) {
}
}
private class TestPacketService extends PacketServiceAdapter {
@Override
public void addProcessor(PacketProcessor processor, int priority) {
testProcessor = processor;
}
}
private class TestPacketContext implements PacketContext {
protected Device device;
protected boolean blocked = false;
public TestPacketContext(Device dev) {
device = dev;
}
@Override
public long time() {
return 0;
}
@Override
public InboundPacket inPacket() {
ONOSLLDP lldp = ONOSLLDP.onosLLDP(deviceService.getDevice(DID1)
.id().toString(),
device.chassisId(),
(int) pd1.number().toLong());
Ethernet ethPacket = new Ethernet();
ethPacket.setEtherType(Ethernet.TYPE_LLDP);
ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_ONLAB);
ethPacket.setPayload(lldp);
ethPacket.setPad(true);
ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
return new DefaultInboundPacket(cp, ethPacket,
ByteBuffer.wrap(ethPacket
.serialize()));
}
@Override
public OutboundPacket outPacket() {
return null;
}
@Override
public TrafficTreatment.Builder treatmentBuilder() {
return null;
}
@Override
public void send() {
}
@Override
public boolean block() {
blocked = true;
return blocked;
}
@Override
public boolean isHandled() {
return blocked;
}
}
private void submitTopologyGraph() {
Set<Device> devices = of(device("a"), device("b"), device("c"),
device("d"), device("e"), device("f"));
Set<Link> links = of(link("a", 1, "b", 1), link("b", 1, "a", 1),
link("b", 2, "c", 1), link("c", 1, "b", 2),
link("c", 2, "d", 1), link("d", 1, "c", 2),
link("d", 2, "a", 2), link("a", 2, "d", 2),
link("e", 1, "f", 1), link("f", 1, "e", 1));
GraphDescription data = new DefaultGraphDescription(4321L,
System.currentTimeMillis(),
devices, links);
providerService.topologyChanged(data, null);
}
protected void validateEvents(Enum... types) {
int i = 0;
for (Event event : listener.events) {
assertEquals("incorrect event type", types[i], event.type());
i++;
}
listener.events.clear();
}
@Test
public void testCreateTopology() {
submitTopologyGraph();
validateEvents(TOPOLOGY_CHANGED);
}
private class TestProvider extends AbstractProvider
implements TopologyProvider {
public TestProvider() {
super(PID);
}
@Override
public void triggerRecompute() {
}
}
private class TestTopologyListener implements TopologyListener {
final List<TopologyEvent> events = new ArrayList<>();
@Override
public void event(TopologyEvent event) {
mqService.publish(event);
}
}
private Link createLink() {
return DefaultLink.builder().providerId(new ProviderId("of", "foo"))
.src(new ConnectPoint(deviceId("of:foo"), portNumber(1)))
.dst(new ConnectPoint(deviceId("of:bar"), portNumber(2)))
.type(Link.Type.INDIRECT).build();
}
@Test
public void testAddLink() throws Exception {
Link link = createLink();
LinkEvent event = new LinkEvent(LINK_ADDED, link, 123L);
validateEvent(event, LINK_ADDED, link, 123L);
}
@Test
public void testUpdateLink() throws Exception {
Link link = createLink();
LinkEvent event = new LinkEvent(LINK_UPDATED, link, 123L);
validateEvent(event, LINK_UPDATED, link, 123L);
}
@Test
public void testRemoveLink() throws Exception {
Link link = createLink();
LinkEvent event = new LinkEvent(LINK_ADDED, link, 123L);
validateEvent(event, LINK_ADDED, link, 123L);
LinkEvent event1 = new LinkEvent(LINK_REMOVED, link, 123L);
validateEvent(event1, LINK_REMOVED, link, 123L);
}
private class TestLinkListener implements LinkListener {
@Override
public void event(LinkEvent event) {
mqService.publish(event);
}
}
}