blob: 4410aaf86167fc7d496e0075f8fcf552ffe9aa6f [file] [log] [blame]
alshabib0ed6a202014-10-19 12:42:57 -07001package org.onlab.onos.provider.lldp.impl;
2
3
4import com.google.common.collect.ArrayListMultimap;
5import com.google.common.collect.Lists;
6import com.google.common.collect.Maps;
Yuta HIGUCHI376d7502014-10-19 15:57:52 -07007
alshabib0ed6a202014-10-19 12:42:57 -07008import org.junit.After;
9import org.junit.Before;
10import org.junit.Test;
11import org.onlab.onos.cluster.NodeId;
Ayaka Koshibeabedb092014-10-20 17:01:31 -070012import org.onlab.onos.cluster.RoleInfo;
alshabib0ed6a202014-10-19 12:42:57 -070013import org.onlab.onos.mastership.MastershipListener;
14import org.onlab.onos.mastership.MastershipService;
15import org.onlab.onos.mastership.MastershipTermService;
16import org.onlab.onos.net.ConnectPoint;
17import org.onlab.onos.net.DefaultDevice;
18import org.onlab.onos.net.DefaultPort;
19import org.onlab.onos.net.Device;
20import org.onlab.onos.net.DeviceId;
21import org.onlab.onos.net.MastershipRole;
22import org.onlab.onos.net.Port;
23import org.onlab.onos.net.PortNumber;
24import org.onlab.onos.net.device.DeviceEvent;
25import org.onlab.onos.net.device.DeviceListener;
26import org.onlab.onos.net.device.DeviceService;
27import org.onlab.onos.net.flow.TrafficTreatment;
28import org.onlab.onos.net.link.LinkDescription;
29import org.onlab.onos.net.link.LinkProvider;
30import org.onlab.onos.net.link.LinkProviderRegistry;
31import org.onlab.onos.net.link.LinkProviderService;
32import org.onlab.onos.net.packet.DefaultInboundPacket;
33import org.onlab.onos.net.packet.InboundPacket;
34import org.onlab.onos.net.packet.OutboundPacket;
35import org.onlab.onos.net.packet.PacketContext;
36import org.onlab.onos.net.packet.PacketProcessor;
37import org.onlab.onos.net.packet.PacketService;
38import org.onlab.onos.net.provider.AbstractProviderService;
39import org.onlab.onos.net.provider.ProviderId;
alshabib0ed6a202014-10-19 12:42:57 -070040import org.onlab.packet.ChassisId;
41import org.onlab.packet.Ethernet;
alshabib0ed6a202014-10-19 12:42:57 -070042import org.onlab.packet.ONOSLLDP;
43
44import java.nio.ByteBuffer;
Yuta HIGUCHI376d7502014-10-19 15:57:52 -070045import java.util.Collections;
alshabib0ed6a202014-10-19 12:42:57 -070046import java.util.HashMap;
alshabib0ed6a202014-10-19 12:42:57 -070047import java.util.List;
48import java.util.Map;
49import java.util.Set;
50
51import static org.junit.Assert.*;
alshabib0ed6a202014-10-19 12:42:57 -070052
53public class LLDPLinkProviderTest {
54
55 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
56 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
57
58 private static Port pd1;
59 private static Port pd2;
60 private static Port pd3;
61 private static Port pd4;
62
63 private final LLDPLinkProvider provider = new LLDPLinkProvider();
64 private final TestLinkRegistry linkService = new TestLinkRegistry();
65 private final TestPacketService packetService = new TestPacketService();
66 private final TestDeviceService deviceService = new TestDeviceService();
67 private final TestMasterShipService masterService = new TestMasterShipService();
68
69 private TestLinkProviderService providerService;
70
71 private PacketProcessor testProcessor;
72 private DeviceListener deviceListener;
73
74 @Before
75 public void setUp() {
76
77 provider.deviceService = deviceService;
78 provider.packetSevice = packetService;
79 provider.providerRegistry = linkService;
80 provider.masterService = masterService;
81
82
83 provider.activate();
84 }
85
86 @Test
87 public void basics() {
88 assertNotNull("registration expected", providerService);
89 assertEquals("incorrect provider", provider, providerService.provider());
90 }
91
92 @Test
93 public void switchAdd() {
94 DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1);
95 deviceListener.event(de);
96
97 assertFalse("Device not added", provider.discoverers.isEmpty());
98 }
99
100 @Test
101 public void switchRemove() {
102 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
103 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
104
105 assertTrue("Discoverer is not gone", provider.discoverers.get(DID1).isStopped());
106 assertTrue("Device is not gone.", vanishedDpid(DID1));
107 }
108
109 @Test
110 public void portUp() {
111 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
112 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
113
114 assertTrue("Port not added to discoverer",
115 provider.discoverers.get(DID1).containsPort((long) 3));
116 }
117
118 @Test
119 public void portDown() {
120
121 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
122 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
123
124
125
126 assertFalse("Port added to discoverer",
127 provider.discoverers.get(DID1).containsPort((long) 1));
128 assertTrue("Port is not gone.", vanishedPort((long) 1));
129 }
130
131 @Test
132 public void portUnknown() {
133 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
134 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, 1, false)));
135
136
137 assertNull("DPID exists",
138 provider.discoverers.get(DID2));
139 }
140
141 @Test
142 public void unknownPktCtx() {
143
144 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
145
146 testProcessor.process(pktCtx);
147 assertFalse("Context should still be free", pktCtx.isHandled());
148 }
149
150 @Test
151 public void knownPktCtx() {
152 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
153 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
154 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
155
156
157 testProcessor.process(pktCtx);
158
159 assertTrue("Link not detected", detectedLink(DID1, DID2));
160
161 }
162
163
164 @After
165 public void tearDown() {
166 provider.deactivate();
167 provider.providerRegistry = null;
168 provider.deviceService = null;
169 provider.packetSevice = null;
170 }
171
172 private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
173 return new DeviceEvent(type, deviceService.getDevice(did));
174
175 }
176
177 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
178 return new DeviceEvent(type, deviceService.getDevice(did),
179 deviceService.getPort(did, port));
180 }
181
182 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
183 return new DeviceEvent(type, deviceService.getDevice(did), port);
184 }
185
186 private Port port(DeviceId did, long port, boolean enabled) {
187 return new DefaultPort(deviceService.getDevice(did),
188 PortNumber.portNumber(port), enabled);
189 }
190
191
192 private boolean vanishedDpid(DeviceId... dids) {
193 for (int i = 0; i < dids.length; i++) {
194 if (!providerService.vanishedDpid.contains(dids[i])) {
195 return false;
196 }
197 }
198 return true;
199 }
200
201 private boolean vanishedPort(Long... ports) {
202 for (int i = 0; i < ports.length; i++) {
203 if (!providerService.vanishedPort.contains(ports[i])) {
204 return false;
205 }
206 }
207 return true;
208 }
209
210 private boolean detectedLink(DeviceId src, DeviceId dst) {
211 for (DeviceId key : providerService.discoveredLinks.keySet()) {
212 if (key.equals(src)) {
213 return providerService.discoveredLinks.get(src).equals(dst);
214 }
215 }
216 return false;
217 }
218
219
220 private class TestLinkRegistry implements LinkProviderRegistry {
221
222 @Override
223 public LinkProviderService register(LinkProvider provider) {
224 providerService = new TestLinkProviderService(provider);
225 return providerService;
226 }
227
228 @Override
229 public void unregister(LinkProvider provider) {
230 }
231
232 @Override
233 public Set<ProviderId> getProviders() {
234 return null;
235 }
236
237 }
238
239 private class TestLinkProviderService
240 extends AbstractProviderService<LinkProvider>
241 implements LinkProviderService {
242
243 List<DeviceId> vanishedDpid = Lists.newLinkedList();
244 List<Long> vanishedPort = Lists.newLinkedList();
245 Map<DeviceId, DeviceId> discoveredLinks = Maps.newHashMap();
246
247 protected TestLinkProviderService(LinkProvider provider) {
248 super(provider);
249 }
250
251 @Override
252 public void linkDetected(LinkDescription linkDescription) {
253 DeviceId sDid = linkDescription.src().deviceId();
254 DeviceId dDid = linkDescription.dst().deviceId();
255 discoveredLinks.put(sDid, dDid);
256 }
257
258 @Override
259 public void linkVanished(LinkDescription linkDescription) {
260 // TODO Auto-generated method stub
261
262 }
263
264 @Override
265 public void linksVanished(ConnectPoint connectPoint) {
266 vanishedPort.add(connectPoint.port().toLong());
267
268 }
269
270 @Override
271 public void linksVanished(DeviceId deviceId) {
272 vanishedDpid.add(deviceId);
273 }
274
275
276 }
277
278
279
280 private class TestPacketContext implements PacketContext {
281
282 protected Device device;
283 protected boolean blocked = false;
284
285 public TestPacketContext(Device dev) {
286 device = dev;
287 }
288
289 @Override
290 public long time() {
291 return 0;
292 }
293
294 @Override
295 public InboundPacket inPacket() {
296 ONOSLLDP lldp = new ONOSLLDP();
297 lldp.setChassisId(device.chassisId());
298 lldp.setPortId((int) pd1.number().toLong());
299 lldp.setDevice(deviceService.getDevice(DID1).id().toString());
300
301
302 Ethernet ethPacket = new Ethernet();
303 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
304 ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA);
305 ethPacket.setPayload(lldp);
306 ethPacket.setPad(true);
307
308
309
310 ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
311
312 ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
313
314 return new DefaultInboundPacket(cp, ethPacket,
315 ByteBuffer.wrap(ethPacket.serialize()));
316
317 }
318
319 @Override
320 public OutboundPacket outPacket() {
321 return null;
322 }
323
324 @Override
325 public TrafficTreatment.Builder treatmentBuilder() {
326 return null;
327 }
328
329 @Override
330 public void send() {
331
332 }
333
334 @Override
335 public boolean block() {
336 blocked = true;
337 return blocked;
338 }
339
340 @Override
341 public boolean isHandled() {
342 return blocked;
343 }
344
345 }
346
347 private class TestPacketService implements PacketService {
348
349 @Override
350 public void addProcessor(PacketProcessor processor, int priority) {
351 testProcessor = processor;
352 }
353
354 @Override
355 public void removeProcessor(PacketProcessor processor) {
356
357 }
358
359 @Override
360 public void emit(OutboundPacket packet) {
361
362 }
363 }
364
365 private class TestDeviceService implements DeviceService {
366
367 private Map<DeviceId, Device> devices = new HashMap<>();
368 private final ArrayListMultimap<DeviceId, Port> ports =
369 ArrayListMultimap.create();
370
371 public TestDeviceService() {
372 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH,
373 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
374 Device d2 = new DefaultDevice(ProviderId.NONE, DID2, Device.Type.SWITCH,
375 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
376 devices.put(DID1, d1);
377 devices.put(DID2, d2);
378
379 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true);
380 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true);
381 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true);
382 pd4 = new DefaultPort(d2, PortNumber.portNumber(2), true);
383
384 ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
385 ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
386
387
388 }
389
390 @Override
391 public int getDeviceCount() {
392 return devices.values().size();
393 }
394
395 @Override
396 public Iterable<Device> getDevices() {
397 return devices.values();
398 }
399
400 @Override
401 public Device getDevice(DeviceId deviceId) {
402 return devices.get(deviceId);
403 }
404
405 @Override
406 public MastershipRole getRole(DeviceId deviceId) {
407 return MastershipRole.MASTER;
408 }
409
410 @Override
411 public List<Port> getPorts(DeviceId deviceId) {
412 return ports.get(deviceId);
413 }
414
415 @Override
416 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
417 for (Port p : ports.get(deviceId)) {
418 if (p.number().equals(portNumber)) {
419 return p;
420 }
421 }
422 return null;
423 }
424
425 @Override
426 public boolean isAvailable(DeviceId deviceId) {
427 return true;
428 }
429
430 @Override
431 public void addListener(DeviceListener listener) {
432 deviceListener = listener;
433
434 }
435
436 @Override
437 public void removeListener(DeviceListener listener) {
438
439 }
440 }
441
442 private final class TestMasterShipService implements MastershipService {
443
444 @Override
445 public MastershipRole getLocalRole(DeviceId deviceId) {
446 return MastershipRole.MASTER;
447 }
448
449 @Override
450 public MastershipRole requestRoleFor(DeviceId deviceId) {
451 return null;
452 }
453
454 @Override
455 public void relinquishMastership(DeviceId deviceId) {
456
457 }
458
459 @Override
460 public NodeId getMasterFor(DeviceId deviceId) {
461 return null;
462 }
463
464 @Override
465 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
466 return null;
467 }
468
469 @Override
470 public MastershipTermService requestTermService() {
471 return null;
472 }
473
474 @Override
475 public void addListener(MastershipListener listener) {
476
477 }
478
479 @Override
480 public void removeListener(MastershipListener listener) {
481
482 }
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700483
484 @Override
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700485 public RoleInfo getNodesFor(DeviceId deviceId) {
486 return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700487 }
alshabib0ed6a202014-10-19 12:42:57 -0700488 }
489
490
491}