blob: 9fd006b70057ec28066a4f6ac92df5ebba142e38 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
alshabib0ed6a202014-10-19 12:42:57 -070019package org.onlab.onos.provider.lldp.impl;
20
21
22import com.google.common.collect.ArrayListMultimap;
23import com.google.common.collect.Lists;
24import com.google.common.collect.Maps;
Yuta HIGUCHI376d7502014-10-19 15:57:52 -070025
alshabib0ed6a202014-10-19 12:42:57 -070026import org.junit.After;
27import org.junit.Before;
28import org.junit.Test;
29import org.onlab.onos.cluster.NodeId;
Ayaka Koshibeabedb092014-10-20 17:01:31 -070030import org.onlab.onos.cluster.RoleInfo;
alshabib0ed6a202014-10-19 12:42:57 -070031import org.onlab.onos.mastership.MastershipListener;
32import org.onlab.onos.mastership.MastershipService;
33import org.onlab.onos.mastership.MastershipTermService;
34import org.onlab.onos.net.ConnectPoint;
35import org.onlab.onos.net.DefaultDevice;
36import org.onlab.onos.net.DefaultPort;
37import org.onlab.onos.net.Device;
38import org.onlab.onos.net.DeviceId;
39import org.onlab.onos.net.MastershipRole;
40import org.onlab.onos.net.Port;
41import org.onlab.onos.net.PortNumber;
42import org.onlab.onos.net.device.DeviceEvent;
43import org.onlab.onos.net.device.DeviceListener;
44import org.onlab.onos.net.device.DeviceService;
45import org.onlab.onos.net.flow.TrafficTreatment;
46import org.onlab.onos.net.link.LinkDescription;
47import org.onlab.onos.net.link.LinkProvider;
48import org.onlab.onos.net.link.LinkProviderRegistry;
49import org.onlab.onos.net.link.LinkProviderService;
50import org.onlab.onos.net.packet.DefaultInboundPacket;
51import org.onlab.onos.net.packet.InboundPacket;
52import org.onlab.onos.net.packet.OutboundPacket;
53import org.onlab.onos.net.packet.PacketContext;
54import org.onlab.onos.net.packet.PacketProcessor;
55import org.onlab.onos.net.packet.PacketService;
56import org.onlab.onos.net.provider.AbstractProviderService;
57import org.onlab.onos.net.provider.ProviderId;
alshabib0ed6a202014-10-19 12:42:57 -070058import org.onlab.packet.ChassisId;
59import org.onlab.packet.Ethernet;
alshabib0ed6a202014-10-19 12:42:57 -070060import org.onlab.packet.ONOSLLDP;
61
62import java.nio.ByteBuffer;
Yuta HIGUCHI376d7502014-10-19 15:57:52 -070063import java.util.Collections;
alshabib0ed6a202014-10-19 12:42:57 -070064import java.util.HashMap;
alshabib0ed6a202014-10-19 12:42:57 -070065import java.util.List;
66import java.util.Map;
67import java.util.Set;
68
69import static org.junit.Assert.*;
alshabib0ed6a202014-10-19 12:42:57 -070070
71public class LLDPLinkProviderTest {
72
73 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
74 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
75
76 private static Port pd1;
77 private static Port pd2;
78 private static Port pd3;
79 private static Port pd4;
80
81 private final LLDPLinkProvider provider = new LLDPLinkProvider();
82 private final TestLinkRegistry linkService = new TestLinkRegistry();
83 private final TestPacketService packetService = new TestPacketService();
84 private final TestDeviceService deviceService = new TestDeviceService();
85 private final TestMasterShipService masterService = new TestMasterShipService();
86
87 private TestLinkProviderService providerService;
88
89 private PacketProcessor testProcessor;
90 private DeviceListener deviceListener;
91
92 @Before
93 public void setUp() {
94
95 provider.deviceService = deviceService;
96 provider.packetSevice = packetService;
97 provider.providerRegistry = linkService;
98 provider.masterService = masterService;
99
100
101 provider.activate();
102 }
103
104 @Test
105 public void basics() {
106 assertNotNull("registration expected", providerService);
107 assertEquals("incorrect provider", provider, providerService.provider());
108 }
109
110 @Test
111 public void switchAdd() {
112 DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1);
113 deviceListener.event(de);
114
115 assertFalse("Device not added", provider.discoverers.isEmpty());
116 }
117
118 @Test
119 public void switchRemove() {
120 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
121 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
122
123 assertTrue("Discoverer is not gone", provider.discoverers.get(DID1).isStopped());
124 assertTrue("Device is not gone.", vanishedDpid(DID1));
125 }
126
127 @Test
128 public void portUp() {
129 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
130 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
131
132 assertTrue("Port not added to discoverer",
133 provider.discoverers.get(DID1).containsPort((long) 3));
134 }
135
136 @Test
137 public void portDown() {
138
139 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
140 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
141
142
143
144 assertFalse("Port added to discoverer",
145 provider.discoverers.get(DID1).containsPort((long) 1));
146 assertTrue("Port is not gone.", vanishedPort((long) 1));
147 }
148
149 @Test
150 public void portUnknown() {
151 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
152 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, 1, false)));
153
154
alshabibdfc7afb2014-10-21 20:13:27 -0700155 assertNull("DeviceId exists",
alshabib0ed6a202014-10-19 12:42:57 -0700156 provider.discoverers.get(DID2));
157 }
158
159 @Test
160 public void unknownPktCtx() {
161
162 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
163
164 testProcessor.process(pktCtx);
165 assertFalse("Context should still be free", pktCtx.isHandled());
166 }
167
168 @Test
169 public void knownPktCtx() {
170 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
171 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
172 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
173
174
175 testProcessor.process(pktCtx);
176
177 assertTrue("Link not detected", detectedLink(DID1, DID2));
178
179 }
180
181
182 @After
183 public void tearDown() {
184 provider.deactivate();
185 provider.providerRegistry = null;
186 provider.deviceService = null;
187 provider.packetSevice = null;
188 }
189
190 private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
191 return new DeviceEvent(type, deviceService.getDevice(did));
192
193 }
194
195 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
196 return new DeviceEvent(type, deviceService.getDevice(did),
197 deviceService.getPort(did, port));
198 }
199
200 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
201 return new DeviceEvent(type, deviceService.getDevice(did), port);
202 }
203
204 private Port port(DeviceId did, long port, boolean enabled) {
205 return new DefaultPort(deviceService.getDevice(did),
206 PortNumber.portNumber(port), enabled);
207 }
208
209
210 private boolean vanishedDpid(DeviceId... dids) {
211 for (int i = 0; i < dids.length; i++) {
212 if (!providerService.vanishedDpid.contains(dids[i])) {
213 return false;
214 }
215 }
216 return true;
217 }
218
219 private boolean vanishedPort(Long... ports) {
220 for (int i = 0; i < ports.length; i++) {
221 if (!providerService.vanishedPort.contains(ports[i])) {
222 return false;
223 }
224 }
225 return true;
226 }
227
228 private boolean detectedLink(DeviceId src, DeviceId dst) {
229 for (DeviceId key : providerService.discoveredLinks.keySet()) {
230 if (key.equals(src)) {
231 return providerService.discoveredLinks.get(src).equals(dst);
232 }
233 }
234 return false;
235 }
236
237
238 private class TestLinkRegistry implements LinkProviderRegistry {
239
240 @Override
241 public LinkProviderService register(LinkProvider provider) {
242 providerService = new TestLinkProviderService(provider);
243 return providerService;
244 }
245
246 @Override
247 public void unregister(LinkProvider provider) {
248 }
249
250 @Override
251 public Set<ProviderId> getProviders() {
252 return null;
253 }
254
255 }
256
257 private class TestLinkProviderService
258 extends AbstractProviderService<LinkProvider>
259 implements LinkProviderService {
260
261 List<DeviceId> vanishedDpid = Lists.newLinkedList();
262 List<Long> vanishedPort = Lists.newLinkedList();
263 Map<DeviceId, DeviceId> discoveredLinks = Maps.newHashMap();
264
265 protected TestLinkProviderService(LinkProvider provider) {
266 super(provider);
267 }
268
269 @Override
270 public void linkDetected(LinkDescription linkDescription) {
271 DeviceId sDid = linkDescription.src().deviceId();
272 DeviceId dDid = linkDescription.dst().deviceId();
273 discoveredLinks.put(sDid, dDid);
274 }
275
276 @Override
277 public void linkVanished(LinkDescription linkDescription) {
278 // TODO Auto-generated method stub
279
280 }
281
282 @Override
283 public void linksVanished(ConnectPoint connectPoint) {
284 vanishedPort.add(connectPoint.port().toLong());
285
286 }
287
288 @Override
289 public void linksVanished(DeviceId deviceId) {
290 vanishedDpid.add(deviceId);
291 }
292
293
294 }
295
296
297
298 private class TestPacketContext implements PacketContext {
299
300 protected Device device;
301 protected boolean blocked = false;
302
303 public TestPacketContext(Device dev) {
304 device = dev;
305 }
306
307 @Override
308 public long time() {
309 return 0;
310 }
311
312 @Override
313 public InboundPacket inPacket() {
314 ONOSLLDP lldp = new ONOSLLDP();
315 lldp.setChassisId(device.chassisId());
316 lldp.setPortId((int) pd1.number().toLong());
317 lldp.setDevice(deviceService.getDevice(DID1).id().toString());
318
319
320 Ethernet ethPacket = new Ethernet();
321 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
322 ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA);
323 ethPacket.setPayload(lldp);
324 ethPacket.setPad(true);
325
326
327
328 ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
329
330 ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
331
332 return new DefaultInboundPacket(cp, ethPacket,
333 ByteBuffer.wrap(ethPacket.serialize()));
334
335 }
336
337 @Override
338 public OutboundPacket outPacket() {
339 return null;
340 }
341
342 @Override
343 public TrafficTreatment.Builder treatmentBuilder() {
344 return null;
345 }
346
347 @Override
348 public void send() {
349
350 }
351
352 @Override
353 public boolean block() {
354 blocked = true;
355 return blocked;
356 }
357
358 @Override
359 public boolean isHandled() {
360 return blocked;
361 }
362
363 }
364
365 private class TestPacketService implements PacketService {
366
367 @Override
368 public void addProcessor(PacketProcessor processor, int priority) {
369 testProcessor = processor;
370 }
371
372 @Override
373 public void removeProcessor(PacketProcessor processor) {
374
375 }
376
377 @Override
378 public void emit(OutboundPacket packet) {
379
380 }
381 }
382
383 private class TestDeviceService implements DeviceService {
384
385 private Map<DeviceId, Device> devices = new HashMap<>();
386 private final ArrayListMultimap<DeviceId, Port> ports =
387 ArrayListMultimap.create();
388
389 public TestDeviceService() {
390 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH,
391 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
392 Device d2 = new DefaultDevice(ProviderId.NONE, DID2, Device.Type.SWITCH,
393 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
394 devices.put(DID1, d1);
395 devices.put(DID2, d2);
396
397 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true);
398 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true);
399 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true);
400 pd4 = new DefaultPort(d2, PortNumber.portNumber(2), true);
401
402 ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
403 ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
404
405
406 }
407
408 @Override
409 public int getDeviceCount() {
410 return devices.values().size();
411 }
412
413 @Override
414 public Iterable<Device> getDevices() {
alshabibdfc7afb2014-10-21 20:13:27 -0700415 return Collections.EMPTY_LIST;
alshabib0ed6a202014-10-19 12:42:57 -0700416 }
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 MastershipRole requestRoleFor(DeviceId deviceId) {
469 return null;
470 }
471
472 @Override
473 public void relinquishMastership(DeviceId deviceId) {
474
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 MastershipTermService requestTermService() {
489 return null;
490 }
491
492 @Override
493 public void addListener(MastershipListener listener) {
494
495 }
496
497 @Override
498 public void removeListener(MastershipListener listener) {
499
500 }
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700501
502 @Override
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700503 public RoleInfo getNodesFor(DeviceId deviceId) {
504 return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700505 }
alshabib0ed6a202014-10-19 12:42:57 -0700506 }
507
508
509}