b4b7b7b6563187fc7d3ea4fdf4a70bd70727c75a
[onosfw.git] /
1 /*
2  * Copyright 2014-2015 Open Networking Laboratory
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package org.onosproject.provider.lldp.impl;
17
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;
60
61 import java.nio.ByteBuffer;
62 import java.util.Collections;
63 import java.util.HashMap;
64 import java.util.List;
65 import java.util.Map;
66 import java.util.Set;
67 import java.util.concurrent.CompletableFuture;
68
69 import static org.easymock.EasyMock.*;
70 import static org.junit.Assert.*;
71
72 public class LLDPLinkProviderTest {
73
74     private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
75     private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
76
77     private static Port pd1;
78     private static Port pd2;
79     private static Port pd3;
80     private static Port pd4;
81
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();
88
89     private CoreService coreService;
90     private TestLinkProviderService providerService;
91
92     private PacketProcessor testProcessor;
93     private DeviceListener deviceListener;
94
95     private ApplicationId appId =
96             new DefaultApplicationId(100, "org.onosproject.provider.lldp");
97
98     @Before
99     public void setUp() {
100         coreService = createMock(CoreService.class);
101         expect(coreService.registerApplication(appId.name()))
102             .andReturn(appId).anyTimes();
103         replay(coreService);
104
105         provider.cfgService = new ComponentConfigAdapter();
106         provider.coreService = coreService;
107
108         provider.deviceService = deviceService;
109         provider.linkService = linkService;
110         provider.packetService = packetService;
111         provider.providerRegistry = linkRegistry;
112         provider.masterService = masterService;
113
114         provider.activate(null);
115     }
116
117     @Test
118     public void basics() {
119         assertNotNull("registration expected", providerService);
120         assertEquals("incorrect provider", provider, providerService.provider());
121     }
122
123     @Test
124     public void switchAdd() {
125         DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1);
126         deviceListener.event(de);
127
128         assertFalse("Device not added", provider.discoverers.isEmpty());
129     }
130
131     @Test
132     public void switchRemove() {
133         deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
134         deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
135
136         assertTrue("Discoverer is not gone", provider.discoverers.get(DID1).isStopped());
137         assertTrue("Device is not gone.", vanishedDpid(DID1));
138     }
139
140     @Test
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)));
144
145         assertTrue("Port not added to discoverer",
146                    provider.discoverers.get(DID1).containsPort(3L));
147     }
148
149     @Test
150     public void portDown() {
151
152         deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
153         deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
154
155
156
157         assertFalse("Port added to discoverer",
158                     provider.discoverers.get(DID1).containsPort(1L));
159         assertTrue("Port is not gone.", vanishedPort(1L));
160     }
161
162     @Test
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)));
166
167
168         assertNull("DeviceId exists",
169                    provider.discoverers.get(DID2));
170     }
171
172     @Test
173     public void unknownPktCtx() {
174
175         PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
176
177         testProcessor.process(pktCtx);
178         assertFalse("Context should still be free", pktCtx.isHandled());
179     }
180
181     @Test
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));
186
187
188         testProcessor.process(pktCtx);
189
190         assertTrue("Link not detected", detectedLink(DID1, DID2));
191
192     }
193
194
195     @After
196     public void tearDown() {
197         provider.deactivate();
198         provider.coreService = null;
199         provider.providerRegistry = null;
200         provider.deviceService = null;
201         provider.packetService = null;
202     }
203
204     private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
205         return new DeviceEvent(type, deviceService.getDevice(did));
206
207     }
208
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));
213     }
214
215     private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
216         return new  DeviceEvent(type, deviceService.getDevice(did), port);
217     }
218
219     private Port port(DeviceId did, long port, boolean enabled) {
220         return new DefaultPort(deviceService.getDevice(did),
221                                PortNumber.portNumber(port), enabled);
222     }
223
224
225     private boolean vanishedDpid(DeviceId... dids) {
226         for (int i = 0; i < dids.length; i++) {
227             if (!providerService.vanishedDpid.contains(dids[i])) {
228                 return false;
229             }
230         }
231         return true;
232     }
233
234     private boolean vanishedPort(Long... ports) {
235         for (int i = 0; i < ports.length; i++) {
236             if (!providerService.vanishedPort.contains(ports[i])) {
237                 return false;
238             }
239         }
240         return true;
241     }
242
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);
247             }
248         }
249         return false;
250     }
251
252
253     private class TestLinkRegistry implements LinkProviderRegistry {
254
255         @Override
256         public LinkProviderService register(LinkProvider provider) {
257             providerService = new TestLinkProviderService(provider);
258             return providerService;
259         }
260
261         @Override
262         public void unregister(LinkProvider provider) {
263         }
264
265         @Override
266         public Set<ProviderId> getProviders() {
267             return null;
268         }
269
270     }
271
272     private class TestLinkProviderService
273             extends AbstractProviderService<LinkProvider>
274             implements LinkProviderService {
275
276         List<DeviceId> vanishedDpid = Lists.newLinkedList();
277         List<Long> vanishedPort = Lists.newLinkedList();
278         Map<DeviceId, DeviceId> discoveredLinks = Maps.newHashMap();
279
280         protected TestLinkProviderService(LinkProvider provider) {
281             super(provider);
282         }
283
284         @Override
285         public void linkDetected(LinkDescription linkDescription) {
286             DeviceId sDid = linkDescription.src().deviceId();
287             DeviceId dDid = linkDescription.dst().deviceId();
288             discoveredLinks.put(sDid, dDid);
289         }
290
291         @Override
292         public void linkVanished(LinkDescription linkDescription) {
293         }
294
295         @Override
296         public void linksVanished(ConnectPoint connectPoint) {
297             vanishedPort.add(connectPoint.port().toLong());
298
299         }
300
301         @Override
302         public void linksVanished(DeviceId deviceId) {
303             vanishedDpid.add(deviceId);
304         }
305
306
307     }
308
309
310
311     private class TestPacketContext implements PacketContext {
312
313         protected Device device;
314         protected boolean blocked = false;
315
316         public TestPacketContext(Device dev) {
317             device = dev;
318         }
319
320         @Override
321         public long time() {
322             return 0;
323         }
324
325         @Override
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());
331
332
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);
338
339
340
341             ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
342
343             ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
344
345             return new DefaultInboundPacket(cp, ethPacket,
346                                             ByteBuffer.wrap(ethPacket.serialize()));
347
348         }
349
350         @Override
351         public OutboundPacket outPacket() {
352             return null;
353         }
354
355         @Override
356         public TrafficTreatment.Builder treatmentBuilder() {
357             return null;
358         }
359
360         @Override
361         public void send() {
362
363         }
364
365         @Override
366         public boolean block() {
367             blocked = true;
368             return blocked;
369         }
370
371         @Override
372         public boolean isHandled() {
373             return blocked;
374         }
375
376     }
377
378     private class TestPacketService extends PacketServiceAdapter {
379         @Override
380         public void addProcessor(PacketProcessor processor, int priority) {
381             testProcessor = processor;
382         }
383     }
384
385     private class TestDeviceService extends DeviceServiceAdapter {
386
387         private Map<DeviceId, Device> devices = new HashMap<>();
388         private final ArrayListMultimap<DeviceId, Port> ports =
389                 ArrayListMultimap.create();
390
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);
398
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);
403
404             ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
405             ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
406         }
407
408         @Override
409         public int getDeviceCount() {
410             return devices.values().size();
411         }
412
413         @Override
414         public Iterable<Device> getDevices() {
415             return Collections.emptyList();
416         }
417
418         @Override
419         public Device getDevice(DeviceId deviceId) {
420             return devices.get(deviceId);
421         }
422
423         @Override
424         public MastershipRole getRole(DeviceId deviceId) {
425             return MastershipRole.MASTER;
426         }
427
428         @Override
429         public List<Port> getPorts(DeviceId deviceId) {
430             return ports.get(deviceId);
431         }
432
433         @Override
434         public Port getPort(DeviceId deviceId, PortNumber portNumber) {
435             for (Port p : ports.get(deviceId)) {
436                 if (p.number().equals(portNumber)) {
437                     return p;
438                 }
439             }
440             return null;
441         }
442
443         @Override
444         public boolean isAvailable(DeviceId deviceId) {
445             return true;
446         }
447
448         @Override
449         public void addListener(DeviceListener listener) {
450             deviceListener = listener;
451
452         }
453
454         @Override
455         public void removeListener(DeviceListener listener) {
456
457         }
458     }
459
460     private final class TestMasterShipService implements MastershipService {
461
462         @Override
463         public MastershipRole getLocalRole(DeviceId deviceId) {
464             return MastershipRole.MASTER;
465         }
466
467         @Override
468         public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
469             return CompletableFuture.completedFuture(null);
470         }
471
472         @Override
473         public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
474             return null;
475         }
476
477         @Override
478         public NodeId getMasterFor(DeviceId deviceId) {
479             return null;
480         }
481
482         @Override
483         public Set<DeviceId> getDevicesOf(NodeId nodeId) {
484             return null;
485         }
486
487         @Override
488         public void addListener(MastershipListener listener) {
489
490         }
491
492         @Override
493         public void removeListener(MastershipListener listener) {
494
495         }
496
497         @Override
498         public RoleInfo getNodesFor(DeviceId deviceId) {
499             return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
500         }
501     }
502
503
504     private class TestLinkService extends LinkServiceAdapter {
505     }
506 }