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