blob: 1d63a15dd26a91aae2873c4f7be920ee11eed516 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.lldp.impl;
alshabib0ed6a202014-10-19 12:42:57 -070017
Thomas Vachuska27bee092015-06-23 19:03:10 -070018import com.google.common.collect.ArrayListMultimap;
19import com.google.common.collect.Lists;
20import com.google.common.collect.Maps;
alshabib0ed6a202014-10-19 12:42:57 -070021import org.junit.After;
22import org.junit.Before;
23import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080024import org.onlab.packet.ChassisId;
25import org.onlab.packet.Ethernet;
26import org.onlab.packet.ONOSLLDP;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070027import org.onosproject.cfg.ComponentConfigAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080028import org.onosproject.cluster.NodeId;
29import org.onosproject.cluster.RoleInfo;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080030import org.onosproject.core.ApplicationId;
31import org.onosproject.core.CoreService;
32import org.onosproject.core.DefaultApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.mastership.MastershipListener;
34import org.onosproject.mastership.MastershipService;
35import org.onosproject.net.ConnectPoint;
36import org.onosproject.net.DefaultDevice;
37import org.onosproject.net.DefaultPort;
38import org.onosproject.net.Device;
39import org.onosproject.net.DeviceId;
40import org.onosproject.net.MastershipRole;
41import org.onosproject.net.Port;
42import org.onosproject.net.PortNumber;
43import org.onosproject.net.device.DeviceEvent;
44import org.onosproject.net.device.DeviceListener;
45import org.onosproject.net.device.DeviceServiceAdapter;
46import org.onosproject.net.flow.TrafficTreatment;
47import org.onosproject.net.link.LinkDescription;
48import org.onosproject.net.link.LinkProvider;
49import org.onosproject.net.link.LinkProviderRegistry;
50import org.onosproject.net.link.LinkProviderService;
51import org.onosproject.net.packet.DefaultInboundPacket;
52import org.onosproject.net.packet.InboundPacket;
53import org.onosproject.net.packet.OutboundPacket;
54import org.onosproject.net.packet.PacketContext;
55import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070056import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080057import org.onosproject.net.provider.AbstractProviderService;
58import org.onosproject.net.provider.ProviderId;
alshabib0ed6a202014-10-19 12:42:57 -070059
Thomas Vachuska27bee092015-06-23 19:03:10 -070060import java.nio.ByteBuffer;
61import java.util.Collections;
62import java.util.HashMap;
63import java.util.List;
64import java.util.Map;
65import java.util.Set;
66import java.util.concurrent.CompletableFuture;
67
68import static org.easymock.EasyMock.*;
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
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080087 private CoreService coreService;
alshabib0ed6a202014-10-19 12:42:57 -070088 private TestLinkProviderService providerService;
89
90 private PacketProcessor testProcessor;
91 private DeviceListener deviceListener;
92
Thomas Vachuska02aeb032015-01-06 22:36:30 -080093 private ApplicationId appId =
94 new DefaultApplicationId(100, "org.onosproject.provider.lldp");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080095
alshabib0ed6a202014-10-19 12:42:57 -070096 @Before
97 public void setUp() {
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080098 coreService = createMock(CoreService.class);
99 expect(coreService.registerApplication(appId.name()))
100 .andReturn(appId).anyTimes();
101 replay(coreService);
102
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700103 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800104 provider.coreService = coreService;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800105
alshabib0ed6a202014-10-19 12:42:57 -0700106 provider.deviceService = deviceService;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800107 provider.packetService = packetService;
alshabib0ed6a202014-10-19 12:42:57 -0700108 provider.providerRegistry = linkService;
109 provider.masterService = masterService;
110
111
Saurav Dasc313c402015-02-27 10:09:47 -0800112 provider.activate(null);
alshabib0ed6a202014-10-19 12:42:57 -0700113 }
114
115 @Test
116 public void basics() {
117 assertNotNull("registration expected", providerService);
118 assertEquals("incorrect provider", provider, providerService.provider());
119 }
120
121 @Test
122 public void switchAdd() {
123 DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1);
124 deviceListener.event(de);
125
126 assertFalse("Device not added", provider.discoverers.isEmpty());
127 }
128
129 @Test
130 public void switchRemove() {
131 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
132 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
133
134 assertTrue("Discoverer is not gone", provider.discoverers.get(DID1).isStopped());
135 assertTrue("Device is not gone.", vanishedDpid(DID1));
136 }
137
138 @Test
139 public void portUp() {
140 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
141 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
142
143 assertTrue("Port not added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700144 provider.discoverers.get(DID1).containsPort(3L));
alshabib0ed6a202014-10-19 12:42:57 -0700145 }
146
147 @Test
148 public void portDown() {
149
150 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
151 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
152
153
154
155 assertFalse("Port added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700156 provider.discoverers.get(DID1).containsPort(1L));
157 assertTrue("Port is not gone.", vanishedPort(1L));
alshabib0ed6a202014-10-19 12:42:57 -0700158 }
159
160 @Test
161 public void portUnknown() {
162 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
163 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, 1, false)));
164
165
alshabibdfc7afb2014-10-21 20:13:27 -0700166 assertNull("DeviceId exists",
alshabib0ed6a202014-10-19 12:42:57 -0700167 provider.discoverers.get(DID2));
168 }
169
170 @Test
171 public void unknownPktCtx() {
172
173 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
174
175 testProcessor.process(pktCtx);
176 assertFalse("Context should still be free", pktCtx.isHandled());
177 }
178
179 @Test
180 public void knownPktCtx() {
181 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
182 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
183 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
184
185
186 testProcessor.process(pktCtx);
187
188 assertTrue("Link not detected", detectedLink(DID1, DID2));
189
190 }
191
192
193 @After
194 public void tearDown() {
195 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800196 provider.coreService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700197 provider.providerRegistry = null;
198 provider.deviceService = null;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800199 provider.packetService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700200 }
201
202 private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
203 return new DeviceEvent(type, deviceService.getDevice(did));
204
205 }
206
Saurav Dasc313c402015-02-27 10:09:47 -0800207 @SuppressWarnings(value = { "unused" })
alshabib0ed6a202014-10-19 12:42:57 -0700208 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
209 return new DeviceEvent(type, deviceService.getDevice(did),
210 deviceService.getPort(did, port));
211 }
212
213 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
214 return new DeviceEvent(type, deviceService.getDevice(did), port);
215 }
216
217 private Port port(DeviceId did, long port, boolean enabled) {
218 return new DefaultPort(deviceService.getDevice(did),
219 PortNumber.portNumber(port), enabled);
220 }
221
222
223 private boolean vanishedDpid(DeviceId... dids) {
224 for (int i = 0; i < dids.length; i++) {
225 if (!providerService.vanishedDpid.contains(dids[i])) {
226 return false;
227 }
228 }
229 return true;
230 }
231
232 private boolean vanishedPort(Long... ports) {
233 for (int i = 0; i < ports.length; i++) {
234 if (!providerService.vanishedPort.contains(ports[i])) {
235 return false;
236 }
237 }
238 return true;
239 }
240
241 private boolean detectedLink(DeviceId src, DeviceId dst) {
242 for (DeviceId key : providerService.discoveredLinks.keySet()) {
243 if (key.equals(src)) {
244 return providerService.discoveredLinks.get(src).equals(dst);
245 }
246 }
247 return false;
248 }
249
250
251 private class TestLinkRegistry implements LinkProviderRegistry {
252
253 @Override
254 public LinkProviderService register(LinkProvider provider) {
255 providerService = new TestLinkProviderService(provider);
256 return providerService;
257 }
258
259 @Override
260 public void unregister(LinkProvider provider) {
261 }
262
263 @Override
264 public Set<ProviderId> getProviders() {
265 return null;
266 }
267
268 }
269
270 private class TestLinkProviderService
271 extends AbstractProviderService<LinkProvider>
272 implements LinkProviderService {
273
274 List<DeviceId> vanishedDpid = Lists.newLinkedList();
275 List<Long> vanishedPort = Lists.newLinkedList();
276 Map<DeviceId, DeviceId> discoveredLinks = Maps.newHashMap();
277
278 protected TestLinkProviderService(LinkProvider provider) {
279 super(provider);
280 }
281
282 @Override
283 public void linkDetected(LinkDescription linkDescription) {
284 DeviceId sDid = linkDescription.src().deviceId();
285 DeviceId dDid = linkDescription.dst().deviceId();
286 discoveredLinks.put(sDid, dDid);
287 }
288
289 @Override
290 public void linkVanished(LinkDescription linkDescription) {
alshabib0ed6a202014-10-19 12:42:57 -0700291 }
292
293 @Override
294 public void linksVanished(ConnectPoint connectPoint) {
295 vanishedPort.add(connectPoint.port().toLong());
296
297 }
298
299 @Override
300 public void linksVanished(DeviceId deviceId) {
301 vanishedDpid.add(deviceId);
302 }
303
304
305 }
306
307
308
309 private class TestPacketContext implements PacketContext {
310
311 protected Device device;
312 protected boolean blocked = false;
313
314 public TestPacketContext(Device dev) {
315 device = dev;
316 }
317
318 @Override
319 public long time() {
320 return 0;
321 }
322
323 @Override
324 public InboundPacket inPacket() {
325 ONOSLLDP lldp = new ONOSLLDP();
326 lldp.setChassisId(device.chassisId());
327 lldp.setPortId((int) pd1.number().toLong());
328 lldp.setDevice(deviceService.getDevice(DID1).id().toString());
329
330
331 Ethernet ethPacket = new Ethernet();
332 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
333 ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA);
334 ethPacket.setPayload(lldp);
335 ethPacket.setPad(true);
336
337
338
339 ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
340
341 ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
342
343 return new DefaultInboundPacket(cp, ethPacket,
344 ByteBuffer.wrap(ethPacket.serialize()));
345
346 }
347
348 @Override
349 public OutboundPacket outPacket() {
350 return null;
351 }
352
353 @Override
354 public TrafficTreatment.Builder treatmentBuilder() {
355 return null;
356 }
357
358 @Override
359 public void send() {
360
361 }
362
363 @Override
364 public boolean block() {
365 blocked = true;
366 return blocked;
367 }
368
369 @Override
370 public boolean isHandled() {
371 return blocked;
372 }
373
374 }
375
Thomas Vachuska27bee092015-06-23 19:03:10 -0700376 private class TestPacketService extends PacketServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700377 @Override
378 public void addProcessor(PacketProcessor processor, int priority) {
379 testProcessor = processor;
380 }
alshabib0ed6a202014-10-19 12:42:57 -0700381 }
382
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800383 private class TestDeviceService extends DeviceServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700384
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));
alshabib0ed6a202014-10-19 12:42:57 -0700404 }
405
406 @Override
407 public int getDeviceCount() {
408 return devices.values().size();
409 }
410
411 @Override
412 public Iterable<Device> getDevices() {
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800413 return Collections.emptyList();
alshabib0ed6a202014-10-19 12:42:57 -0700414 }
415
416 @Override
417 public Device getDevice(DeviceId deviceId) {
418 return devices.get(deviceId);
419 }
420
421 @Override
422 public MastershipRole getRole(DeviceId deviceId) {
423 return MastershipRole.MASTER;
424 }
425
426 @Override
427 public List<Port> getPorts(DeviceId deviceId) {
428 return ports.get(deviceId);
429 }
430
431 @Override
432 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
433 for (Port p : ports.get(deviceId)) {
434 if (p.number().equals(portNumber)) {
435 return p;
436 }
437 }
438 return null;
439 }
440
441 @Override
442 public boolean isAvailable(DeviceId deviceId) {
443 return true;
444 }
445
446 @Override
447 public void addListener(DeviceListener listener) {
448 deviceListener = listener;
449
450 }
451
452 @Override
453 public void removeListener(DeviceListener listener) {
454
455 }
456 }
457
458 private final class TestMasterShipService implements MastershipService {
459
460 @Override
461 public MastershipRole getLocalRole(DeviceId deviceId) {
462 return MastershipRole.MASTER;
463 }
464
465 @Override
Madan Jampanide003d92015-05-11 17:14:20 -0700466 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
467 return CompletableFuture.completedFuture(null);
alshabib0ed6a202014-10-19 12:42:57 -0700468 }
469
470 @Override
Madan Jampanic6e574f2015-05-29 13:41:52 -0700471 public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
472 return null;
alshabib0ed6a202014-10-19 12:42:57 -0700473 }
474
475 @Override
476 public NodeId getMasterFor(DeviceId deviceId) {
477 return null;
478 }
479
480 @Override
481 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
482 return null;
483 }
484
485 @Override
alshabib0ed6a202014-10-19 12:42:57 -0700486 public void addListener(MastershipListener listener) {
487
488 }
489
490 @Override
491 public void removeListener(MastershipListener listener) {
492
493 }
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700494
495 @Override
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700496 public RoleInfo getNodesFor(DeviceId deviceId) {
497 return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700498 }
alshabib0ed6a202014-10-19 12:42:57 -0700499 }
500
501
502}