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