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