blob: bba031fc2986ce5b87453ef7232ad4757acf8bc1 [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
Saurav Dasc313c402015-02-27 10:09:47 -0800111 provider.activate(null);
alshabib0ed6a202014-10-19 12:42:57 -0700112 }
113
114 @Test
115 public void basics() {
116 assertNotNull("registration expected", providerService);
117 assertEquals("incorrect provider", provider, providerService.provider());
118 }
119
120 @Test
121 public void switchAdd() {
122 DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1);
123 deviceListener.event(de);
124
125 assertFalse("Device not added", provider.discoverers.isEmpty());
126 }
127
128 @Test
129 public void switchRemove() {
130 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
131 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
132
133 assertTrue("Discoverer is not gone", provider.discoverers.get(DID1).isStopped());
134 assertTrue("Device is not gone.", vanishedDpid(DID1));
135 }
136
137 @Test
138 public void portUp() {
139 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
140 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
141
142 assertTrue("Port not added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700143 provider.discoverers.get(DID1).containsPort(3L));
alshabib0ed6a202014-10-19 12:42:57 -0700144 }
145
146 @Test
147 public void portDown() {
148
149 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
150 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
151
152
153
154 assertFalse("Port added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700155 provider.discoverers.get(DID1).containsPort(1L));
156 assertTrue("Port is not gone.", vanishedPort(1L));
alshabib0ed6a202014-10-19 12:42:57 -0700157 }
158
159 @Test
160 public void portUnknown() {
161 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
162 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, 1, false)));
163
164
alshabibdfc7afb2014-10-21 20:13:27 -0700165 assertNull("DeviceId exists",
alshabib0ed6a202014-10-19 12:42:57 -0700166 provider.discoverers.get(DID2));
167 }
168
169 @Test
170 public void unknownPktCtx() {
171
172 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
173
174 testProcessor.process(pktCtx);
175 assertFalse("Context should still be free", pktCtx.isHandled());
176 }
177
178 @Test
179 public void knownPktCtx() {
180 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
181 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
182 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
183
184
185 testProcessor.process(pktCtx);
186
187 assertTrue("Link not detected", detectedLink(DID1, DID2));
188
189 }
190
191
192 @After
193 public void tearDown() {
194 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800195 provider.coreService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700196 provider.providerRegistry = null;
197 provider.deviceService = null;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800198 provider.packetService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700199 }
200
201 private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
202 return new DeviceEvent(type, deviceService.getDevice(did));
203
204 }
205
Saurav Dasc313c402015-02-27 10:09:47 -0800206 @SuppressWarnings(value = { "unused" })
alshabib0ed6a202014-10-19 12:42:57 -0700207 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
208 return new DeviceEvent(type, deviceService.getDevice(did),
209 deviceService.getPort(did, port));
210 }
211
212 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
213 return new DeviceEvent(type, deviceService.getDevice(did), port);
214 }
215
216 private Port port(DeviceId did, long port, boolean enabled) {
217 return new DefaultPort(deviceService.getDevice(did),
218 PortNumber.portNumber(port), enabled);
219 }
220
221
222 private boolean vanishedDpid(DeviceId... dids) {
223 for (int i = 0; i < dids.length; i++) {
224 if (!providerService.vanishedDpid.contains(dids[i])) {
225 return false;
226 }
227 }
228 return true;
229 }
230
231 private boolean vanishedPort(Long... ports) {
232 for (int i = 0; i < ports.length; i++) {
233 if (!providerService.vanishedPort.contains(ports[i])) {
234 return false;
235 }
236 }
237 return true;
238 }
239
240 private boolean detectedLink(DeviceId src, DeviceId dst) {
241 for (DeviceId key : providerService.discoveredLinks.keySet()) {
242 if (key.equals(src)) {
243 return providerService.discoveredLinks.get(src).equals(dst);
244 }
245 }
246 return false;
247 }
248
249
250 private class TestLinkRegistry implements LinkProviderRegistry {
251
252 @Override
253 public LinkProviderService register(LinkProvider provider) {
254 providerService = new TestLinkProviderService(provider);
255 return providerService;
256 }
257
258 @Override
259 public void unregister(LinkProvider provider) {
260 }
261
262 @Override
263 public Set<ProviderId> getProviders() {
264 return null;
265 }
266
267 }
268
269 private class TestLinkProviderService
270 extends AbstractProviderService<LinkProvider>
271 implements LinkProviderService {
272
273 List<DeviceId> vanishedDpid = Lists.newLinkedList();
274 List<Long> vanishedPort = Lists.newLinkedList();
275 Map<DeviceId, DeviceId> discoveredLinks = Maps.newHashMap();
276
277 protected TestLinkProviderService(LinkProvider provider) {
278 super(provider);
279 }
280
281 @Override
282 public void linkDetected(LinkDescription linkDescription) {
283 DeviceId sDid = linkDescription.src().deviceId();
284 DeviceId dDid = linkDescription.dst().deviceId();
285 discoveredLinks.put(sDid, dDid);
286 }
287
288 @Override
289 public void linkVanished(LinkDescription linkDescription) {
alshabib0ed6a202014-10-19 12:42:57 -0700290 }
291
292 @Override
293 public void linksVanished(ConnectPoint connectPoint) {
294 vanishedPort.add(connectPoint.port().toLong());
295
296 }
297
298 @Override
299 public void linksVanished(DeviceId deviceId) {
300 vanishedDpid.add(deviceId);
301 }
302
303
304 }
305
306
307
308 private class TestPacketContext implements PacketContext {
309
310 protected Device device;
311 protected boolean blocked = false;
312
313 public TestPacketContext(Device dev) {
314 device = dev;
315 }
316
317 @Override
318 public long time() {
319 return 0;
320 }
321
322 @Override
323 public InboundPacket inPacket() {
324 ONOSLLDP lldp = new ONOSLLDP();
325 lldp.setChassisId(device.chassisId());
326 lldp.setPortId((int) pd1.number().toLong());
327 lldp.setDevice(deviceService.getDevice(DID1).id().toString());
328
329
330 Ethernet ethPacket = new Ethernet();
331 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
332 ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA);
333 ethPacket.setPayload(lldp);
334 ethPacket.setPad(true);
335
336
337
338 ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
339
340 ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
341
342 return new DefaultInboundPacket(cp, ethPacket,
343 ByteBuffer.wrap(ethPacket.serialize()));
344
345 }
346
347 @Override
348 public OutboundPacket outPacket() {
349 return null;
350 }
351
352 @Override
353 public TrafficTreatment.Builder treatmentBuilder() {
354 return null;
355 }
356
357 @Override
358 public void send() {
359
360 }
361
362 @Override
363 public boolean block() {
364 blocked = true;
365 return blocked;
366 }
367
368 @Override
369 public boolean isHandled() {
370 return blocked;
371 }
372
373 }
374
Thomas Vachuska27bee092015-06-23 19:03:10 -0700375 private class TestPacketService extends PacketServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700376 @Override
377 public void addProcessor(PacketProcessor processor, int priority) {
378 testProcessor = processor;
379 }
alshabib0ed6a202014-10-19 12:42:57 -0700380 }
381
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800382 private class TestDeviceService extends DeviceServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700383
384 private Map<DeviceId, Device> devices = new HashMap<>();
385 private final ArrayListMultimap<DeviceId, Port> ports =
386 ArrayListMultimap.create();
387
388 public TestDeviceService() {
389 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH,
390 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
391 Device d2 = new DefaultDevice(ProviderId.NONE, DID2, Device.Type.SWITCH,
392 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
393 devices.put(DID1, d1);
394 devices.put(DID2, d2);
395
396 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true);
397 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true);
398 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true);
399 pd4 = new DefaultPort(d2, PortNumber.portNumber(2), true);
400
401 ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
402 ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
alshabib0ed6a202014-10-19 12:42:57 -0700403 }
404
405 @Override
406 public int getDeviceCount() {
407 return devices.values().size();
408 }
409
410 @Override
411 public Iterable<Device> getDevices() {
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800412 return Collections.emptyList();
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
Madan Jampanide003d92015-05-11 17:14:20 -0700465 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
466 return CompletableFuture.completedFuture(null);
alshabib0ed6a202014-10-19 12:42:57 -0700467 }
468
469 @Override
Madan Jampanic6e574f2015-05-29 13:41:52 -0700470 public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
471 return null;
alshabib0ed6a202014-10-19 12:42:57 -0700472 }
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
alshabib0ed6a202014-10-19 12:42:57 -0700485 public void addListener(MastershipListener listener) {
486
487 }
488
489 @Override
490 public void removeListener(MastershipListener listener) {
491
492 }
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700493
494 @Override
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700495 public RoleInfo getNodesFor(DeviceId deviceId) {
496 return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700497 }
alshabib0ed6a202014-10-19 12:42:57 -0700498 }
499
500
501}