2 * Copyright 2014-2015 Open Networking Laboratory
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.onosproject.provider.lldp.impl;
18 import com.google.common.collect.ArrayListMultimap;
19 import com.google.common.collect.Lists;
20 import com.google.common.collect.Maps;
21 import org.junit.After;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.onlab.packet.ChassisId;
25 import org.onlab.packet.Ethernet;
26 import org.onlab.packet.ONOSLLDP;
27 import org.onosproject.cfg.ComponentConfigAdapter;
28 import org.onosproject.cluster.NodeId;
29 import org.onosproject.cluster.RoleInfo;
30 import org.onosproject.core.ApplicationId;
31 import org.onosproject.core.CoreService;
32 import org.onosproject.core.DefaultApplicationId;
33 import org.onosproject.mastership.MastershipListener;
34 import org.onosproject.mastership.MastershipService;
35 import org.onosproject.net.ConnectPoint;
36 import org.onosproject.net.DefaultDevice;
37 import org.onosproject.net.DefaultPort;
38 import org.onosproject.net.Device;
39 import org.onosproject.net.DeviceId;
40 import org.onosproject.net.MastershipRole;
41 import org.onosproject.net.Port;
42 import org.onosproject.net.PortNumber;
43 import org.onosproject.net.device.DeviceEvent;
44 import org.onosproject.net.device.DeviceListener;
45 import org.onosproject.net.device.DeviceServiceAdapter;
46 import org.onosproject.net.flow.TrafficTreatment;
47 import org.onosproject.net.link.LinkDescription;
48 import org.onosproject.net.link.LinkProvider;
49 import org.onosproject.net.link.LinkProviderRegistry;
50 import org.onosproject.net.link.LinkProviderService;
51 import org.onosproject.net.link.LinkServiceAdapter;
52 import org.onosproject.net.packet.DefaultInboundPacket;
53 import org.onosproject.net.packet.InboundPacket;
54 import org.onosproject.net.packet.OutboundPacket;
55 import org.onosproject.net.packet.PacketContext;
56 import org.onosproject.net.packet.PacketProcessor;
57 import org.onosproject.net.packet.PacketServiceAdapter;
58 import org.onosproject.net.provider.AbstractProviderService;
59 import org.onosproject.net.provider.ProviderId;
61 import java.nio.ByteBuffer;
62 import java.util.Collections;
63 import java.util.HashMap;
64 import java.util.List;
67 import java.util.concurrent.CompletableFuture;
69 import static org.easymock.EasyMock.*;
70 import static org.junit.Assert.*;
72 public class LLDPLinkProviderTest {
74 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
75 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
77 private static Port pd1;
78 private static Port pd2;
79 private static Port pd3;
80 private static Port pd4;
82 private final LLDPLinkProvider provider = new LLDPLinkProvider();
83 private final TestLinkRegistry linkRegistry = new TestLinkRegistry();
84 private final TestLinkService linkService = new TestLinkService();
85 private final TestPacketService packetService = new TestPacketService();
86 private final TestDeviceService deviceService = new TestDeviceService();
87 private final TestMasterShipService masterService = new TestMasterShipService();
89 private CoreService coreService;
90 private TestLinkProviderService providerService;
92 private PacketProcessor testProcessor;
93 private DeviceListener deviceListener;
95 private ApplicationId appId =
96 new DefaultApplicationId(100, "org.onosproject.provider.lldp");
100 coreService = createMock(CoreService.class);
101 expect(coreService.registerApplication(appId.name()))
102 .andReturn(appId).anyTimes();
105 provider.cfgService = new ComponentConfigAdapter();
106 provider.coreService = coreService;
108 provider.deviceService = deviceService;
109 provider.linkService = linkService;
110 provider.packetService = packetService;
111 provider.providerRegistry = linkRegistry;
112 provider.masterService = masterService;
114 provider.activate(null);
118 public void basics() {
119 assertNotNull("registration expected", providerService);
120 assertEquals("incorrect provider", provider, providerService.provider());
124 public void switchAdd() {
125 DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1);
126 deviceListener.event(de);
128 assertFalse("Device not added", provider.discoverers.isEmpty());
132 public void switchRemove() {
133 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
134 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
136 assertTrue("Discoverer is not gone", provider.discoverers.get(DID1).isStopped());
137 assertTrue("Device is not gone.", vanishedDpid(DID1));
141 public void portUp() {
142 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
143 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
145 assertTrue("Port not added to discoverer",
146 provider.discoverers.get(DID1).containsPort(3L));
150 public void portDown() {
152 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
153 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
157 assertFalse("Port added to discoverer",
158 provider.discoverers.get(DID1).containsPort(1L));
159 assertTrue("Port is not gone.", vanishedPort(1L));
163 public void portUnknown() {
164 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
165 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, 1, false)));
168 assertNull("DeviceId exists",
169 provider.discoverers.get(DID2));
173 public void unknownPktCtx() {
175 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
177 testProcessor.process(pktCtx);
178 assertFalse("Context should still be free", pktCtx.isHandled());
182 public void knownPktCtx() {
183 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
184 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
185 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
188 testProcessor.process(pktCtx);
190 assertTrue("Link not detected", detectedLink(DID1, DID2));
196 public void tearDown() {
197 provider.deactivate();
198 provider.coreService = null;
199 provider.providerRegistry = null;
200 provider.deviceService = null;
201 provider.packetService = null;
204 private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
205 return new DeviceEvent(type, deviceService.getDevice(did));
209 @SuppressWarnings(value = { "unused" })
210 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
211 return new DeviceEvent(type, deviceService.getDevice(did),
212 deviceService.getPort(did, port));
215 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
216 return new DeviceEvent(type, deviceService.getDevice(did), port);
219 private Port port(DeviceId did, long port, boolean enabled) {
220 return new DefaultPort(deviceService.getDevice(did),
221 PortNumber.portNumber(port), enabled);
225 private boolean vanishedDpid(DeviceId... dids) {
226 for (int i = 0; i < dids.length; i++) {
227 if (!providerService.vanishedDpid.contains(dids[i])) {
234 private boolean vanishedPort(Long... ports) {
235 for (int i = 0; i < ports.length; i++) {
236 if (!providerService.vanishedPort.contains(ports[i])) {
243 private boolean detectedLink(DeviceId src, DeviceId dst) {
244 for (DeviceId key : providerService.discoveredLinks.keySet()) {
245 if (key.equals(src)) {
246 return providerService.discoveredLinks.get(src).equals(dst);
253 private class TestLinkRegistry implements LinkProviderRegistry {
256 public LinkProviderService register(LinkProvider provider) {
257 providerService = new TestLinkProviderService(provider);
258 return providerService;
262 public void unregister(LinkProvider provider) {
266 public Set<ProviderId> getProviders() {
272 private class TestLinkProviderService
273 extends AbstractProviderService<LinkProvider>
274 implements LinkProviderService {
276 List<DeviceId> vanishedDpid = Lists.newLinkedList();
277 List<Long> vanishedPort = Lists.newLinkedList();
278 Map<DeviceId, DeviceId> discoveredLinks = Maps.newHashMap();
280 protected TestLinkProviderService(LinkProvider provider) {
285 public void linkDetected(LinkDescription linkDescription) {
286 DeviceId sDid = linkDescription.src().deviceId();
287 DeviceId dDid = linkDescription.dst().deviceId();
288 discoveredLinks.put(sDid, dDid);
292 public void linkVanished(LinkDescription linkDescription) {
296 public void linksVanished(ConnectPoint connectPoint) {
297 vanishedPort.add(connectPoint.port().toLong());
302 public void linksVanished(DeviceId deviceId) {
303 vanishedDpid.add(deviceId);
311 private class TestPacketContext implements PacketContext {
313 protected Device device;
314 protected boolean blocked = false;
316 public TestPacketContext(Device dev) {
326 public InboundPacket inPacket() {
327 ONOSLLDP lldp = new ONOSLLDP();
328 lldp.setChassisId(device.chassisId());
329 lldp.setPortId((int) pd1.number().toLong());
330 lldp.setDevice(deviceService.getDevice(DID1).id().toString());
333 Ethernet ethPacket = new Ethernet();
334 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
335 ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA);
336 ethPacket.setPayload(lldp);
337 ethPacket.setPad(true);
341 ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
343 ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
345 return new DefaultInboundPacket(cp, ethPacket,
346 ByteBuffer.wrap(ethPacket.serialize()));
351 public OutboundPacket outPacket() {
356 public TrafficTreatment.Builder treatmentBuilder() {
366 public boolean block() {
372 public boolean isHandled() {
378 private class TestPacketService extends PacketServiceAdapter {
380 public void addProcessor(PacketProcessor processor, int priority) {
381 testProcessor = processor;
385 private class TestDeviceService extends DeviceServiceAdapter {
387 private Map<DeviceId, Device> devices = new HashMap<>();
388 private final ArrayListMultimap<DeviceId, Port> ports =
389 ArrayListMultimap.create();
391 public TestDeviceService() {
392 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH,
393 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
394 Device d2 = new DefaultDevice(ProviderId.NONE, DID2, Device.Type.SWITCH,
395 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
396 devices.put(DID1, d1);
397 devices.put(DID2, d2);
399 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true);
400 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true);
401 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true);
402 pd4 = new DefaultPort(d2, PortNumber.portNumber(2), true);
404 ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
405 ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
409 public int getDeviceCount() {
410 return devices.values().size();
414 public Iterable<Device> getDevices() {
415 return Collections.emptyList();
419 public Device getDevice(DeviceId deviceId) {
420 return devices.get(deviceId);
424 public MastershipRole getRole(DeviceId deviceId) {
425 return MastershipRole.MASTER;
429 public List<Port> getPorts(DeviceId deviceId) {
430 return ports.get(deviceId);
434 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
435 for (Port p : ports.get(deviceId)) {
436 if (p.number().equals(portNumber)) {
444 public boolean isAvailable(DeviceId deviceId) {
449 public void addListener(DeviceListener listener) {
450 deviceListener = listener;
455 public void removeListener(DeviceListener listener) {
460 private final class TestMasterShipService implements MastershipService {
463 public MastershipRole getLocalRole(DeviceId deviceId) {
464 return MastershipRole.MASTER;
468 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
469 return CompletableFuture.completedFuture(null);
473 public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
478 public NodeId getMasterFor(DeviceId deviceId) {
483 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
488 public void addListener(MastershipListener listener) {
493 public void removeListener(MastershipListener listener) {
498 public RoleInfo getNodesFor(DeviceId deviceId) {
499 return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
504 private class TestLinkService extends LinkServiceAdapter {