blob: a6c6930623183b8fd368b575e246a5350f7e831d [file] [log] [blame]
alshabib64231d82014-09-25 18:25:31 -07001package org.onlab.onos.provider.of.link.impl;
2
3import static org.junit.Assert.assertEquals;
4import static org.junit.Assert.assertFalse;
5import static org.junit.Assert.assertNotNull;
6import static org.junit.Assert.assertNull;
7import static org.junit.Assert.assertTrue;
8
9import java.util.ArrayList;
10import java.util.Collections;
11import java.util.HashMap;
12import java.util.List;
13import java.util.Map;
14import java.util.Set;
15
16import org.junit.After;
17import org.junit.Before;
18import org.junit.Test;
19import org.onlab.onos.net.ConnectPoint;
20import org.onlab.onos.net.DeviceId;
21import org.onlab.onos.net.link.LinkDescription;
22import org.onlab.onos.net.link.LinkProvider;
23import org.onlab.onos.net.link.LinkProviderRegistry;
24import org.onlab.onos.net.link.LinkProviderService;
25import org.onlab.onos.net.provider.AbstractProviderService;
26import org.onlab.onos.net.provider.ProviderId;
27import org.onlab.onos.openflow.controller.Dpid;
28import org.onlab.onos.openflow.controller.OpenFlowPacketContext;
29import org.onlab.onos.openflow.controller.OpenFlowSwitch;
30import org.onlab.onos.openflow.controller.OpenFlowSwitchListener;
31import org.onlab.onos.openflow.controller.OpenflowControllerAdapter;
32import org.onlab.onos.openflow.controller.PacketListener;
33import org.onlab.onos.openflow.controller.RoleState;
34import org.onlab.packet.Ethernet;
35import org.onlab.packet.ONLabLddp;
36import org.projectfloodlight.openflow.protocol.OFFactory;
37import org.projectfloodlight.openflow.protocol.OFMessage;
38import org.projectfloodlight.openflow.protocol.OFPortConfig;
39import org.projectfloodlight.openflow.protocol.OFPortDesc;
40import org.projectfloodlight.openflow.protocol.OFPortReason;
41import org.projectfloodlight.openflow.protocol.OFPortStatus;
42import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
43import org.projectfloodlight.openflow.types.OFPort;
44
45import com.google.common.collect.Lists;
46import com.google.common.collect.Maps;
47
48public class OpenFlowLinkProviderTest {
49
50
51 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
52 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
53
54 private static final Dpid DPID2 = Dpid.dpid(DID2.uri());
55 private static final Dpid DPID1 = Dpid.dpid(DID1.uri());
56
57 private static final OFPortDesc PD1 = portDesc(1, true);
58 private static final OFPortDesc PD2 = portDesc(2, true);
59 private static final OFPortDesc PD3 = portDesc(1, true);
60 private static final OFPortDesc PD4 = portDesc(2, true);
61
62 private static final List<OFPortDesc> PLIST1 = Lists.newArrayList(PD1, PD2);
63 private static final List<OFPortDesc> PLIST2 = Lists.newArrayList(PD3, PD4);
64
65 private static final TestOpenFlowSwitch SW1 = new TestOpenFlowSwitch(DPID1, PLIST1);
66 private static final TestOpenFlowSwitch SW2 = new TestOpenFlowSwitch(DPID2, PLIST2);
67
68 private final OpenFlowLinkProvider provider = new OpenFlowLinkProvider();
69 private final TestLinkRegistry linkService = new TestLinkRegistry();
70 private final TestController controller = new TestController();
71
72 private TestLinkProviderService providerService;
73 private TestPacketContext pktCtx;
74
75 @Before
76 public void setUp() {
77 pktCtx = new TestPacketContext(DPID2);
78 provider.providerRegistry = linkService;
79 controller.switchMap.put(DPID1, SW1);
80 controller.switchMap.put(DPID2, SW2);
81 provider.controller = controller;
82 provider.activate();
83 }
84
85 @Test
86 public void basics() {
87 assertNotNull("registration expected", providerService);
88 assertEquals("incorrect provider", provider, providerService.provider());
89 }
90
91 @Test
92 public void switchAdd() {
93 controller.listener.switchAdded(DPID1);
94 assertFalse("Device not added", provider.discoverers.isEmpty());
95 }
96
97 @Test
98 public void switchRemove() {
99 controller.listener.switchAdded(DPID1);
100 controller.listener.switchRemoved(DPID1);
101
102 assertTrue("Discoverer is not gone", provider.discoverers.isEmpty());
103 assertTrue("Device is not gone.", vanishedDpid(DPID1));
104 }
105
106 @Test
107 public void portUp() {
108 controller.listener.switchAdded(DPID1);
109 controller.listener.portChanged(DPID1, portStatus(true, 3));
110
111 assertTrue("Port not added to discoverer",
112 provider.discoverers.get(DPID1).ports.containsKey(3));
113 }
114
115 @Test
116 public void portDown() {
117 controller.listener.switchAdded(DPID1);
118 controller.listener.portChanged(DPID1, portStatus(false, 1));
119
120 assertFalse("Port added to discoverer",
121 provider.discoverers.get(DPID1).ports.containsKey(1));
122 assertTrue("Port is not gone.", vanishedPort((long) 1));
123 }
124
125 @Test
126 public void portUnknown() {
127 controller.listener.switchAdded(DPID1);
128 controller.listener.portChanged(DPID2, portStatus(false, 1));
129
130 assertNull("DPID exists",
131 provider.discoverers.get(DPID2));
132 }
133
134 @Test
135 public void unknownPktCtx() {
136 controller.pktListener.handlePacket(pktCtx);
137
138 assertFalse("Context should still be free", pktCtx.isHandled());
139 }
140
141 @Test
142 public void knownPktCtx() {
143 controller.listener.switchAdded(DPID1);
144 controller.listener.switchAdded(DPID2);
145
146 controller.pktListener.handlePacket(pktCtx);
147
148 assertTrue("Link not detected", detectedLink(DPID1, DPID2));
149
150 }
151
152
153 @After
154 public void tearDown() {
155 provider.deactivate();
156 provider.providerRegistry = null;
157 provider.controller = null;
158 }
159
160 private OFPortStatus portStatus(boolean up, int port) {
161 OFPortDesc desc = portDesc(port, up);
162 OFPortStatus status = OFFactoryVer10.INSTANCE.buildPortStatus()
163 .setDesc(desc)
164 .setReason(up ? OFPortReason.ADD : OFPortReason.DELETE).build();
165 return status;
166
167 }
168
169 private static OFPortDesc portDesc(int port, boolean up) {
170 OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc();
171 builder.setPortNo(OFPort.of(port));
172 if (!up) {
173 builder.setConfig(Collections.singleton(OFPortConfig.PORT_DOWN));
174 }
175 return builder.build();
176 }
177
178 private boolean vanishedDpid(Dpid... dpids) {
179 for (int i = 0; i < dpids.length; i++) {
180 if (!providerService.vanishedDpid.contains(dpids[i])) {
181 return false;
182 }
183 }
184 return true;
185 }
186
187 private boolean vanishedPort(Long... ports) {
188 for (int i = 0; i < ports.length; i++) {
189 if (!providerService.vanishedPort.contains(ports[i])) {
190 return false;
191 }
192 }
193 return true;
194 }
195
196 private boolean detectedLink(Dpid src, Dpid dst) {
197 for (Dpid key : providerService.discoveredLinks.keySet()) {
198 if (key.equals(src)) {
199 return providerService.discoveredLinks.get(src).equals(dst);
200 }
201 }
202 return false;
203 }
204
205
206 private class TestLinkRegistry implements LinkProviderRegistry {
207
208 @Override
209 public LinkProviderService register(LinkProvider provider) {
210 providerService = new TestLinkProviderService(provider);
211 return providerService;
212 }
213
214 @Override
215 public void unregister(LinkProvider provider) {
216 }
217
218 @Override
219 public Set<ProviderId> getProviders() {
220 return null;
221 }
222
223 }
224
225 private class TestLinkProviderService
226 extends AbstractProviderService<LinkProvider>
227 implements LinkProviderService {
228
229 List<Dpid> vanishedDpid = Lists.newLinkedList();
230 List<Long> vanishedPort = Lists.newLinkedList();
231 Map<Dpid, Dpid> discoveredLinks = Maps.newHashMap();
232
233 protected TestLinkProviderService(LinkProvider provider) {
234 super(provider);
235 }
236
237 @Override
238 public void linkDetected(LinkDescription linkDescription) {
239 Dpid sDpid = Dpid.dpid(linkDescription.src().deviceId().uri());
240 Dpid dDpid = Dpid.dpid(linkDescription.dst().deviceId().uri());
241 discoveredLinks.put(sDpid, dDpid);
242 }
243
244 @Override
245 public void linkVanished(LinkDescription linkDescription) {
246 // TODO Auto-generated method stub
247
248 }
249
250 @Override
251 public void linksVanished(ConnectPoint connectPoint) {
252 vanishedPort.add(connectPoint.port().toLong());
253
254 }
255
256 @Override
257 public void linksVanished(DeviceId deviceId) {
258 vanishedDpid.add(Dpid.dpid(deviceId.uri()));
259 }
260
261
262 }
263
264 private class TestController extends OpenflowControllerAdapter {
265 PacketListener pktListener;
266 OpenFlowSwitchListener listener;
267 Map<Dpid, OpenFlowSwitch> switchMap = new HashMap<Dpid, OpenFlowSwitch>();
268
269 @Override
270 public void addPacketListener(int priority, PacketListener listener) {
271 pktListener = listener;
272 }
273
274 @Override
275 public void removePacketListener(PacketListener listener) {
276 pktListener = null;
277 }
278
279 @Override
280 public void addListener(OpenFlowSwitchListener listener) {
281 this.listener = listener;
282 }
283
284 @Override
285 public void removeListener(OpenFlowSwitchListener listener) {
286 this.listener = null;
287 }
288
289 @Override
290 public void processPacket(Dpid dpid, OFMessage msg) {
291 OpenFlowPacketContext ctx = new TestPacketContext(dpid);
292 pktListener.handlePacket(ctx);
293 }
294
295 @Override
296 public Iterable<OpenFlowSwitch> getSwitches() {
297 return Collections.emptyList();
298 }
299
300 @Override
301 public OpenFlowSwitch getSwitch(Dpid dpid) {
302 return switchMap.get(dpid);
303 }
304 }
305
306
307
308 private class TestPacketContext implements OpenFlowPacketContext {
309
310 protected Dpid swid;
311 protected boolean blocked = false;
312
313 public TestPacketContext(Dpid dpid) {
314 swid = dpid;
315 }
316
317 @Override
318 public boolean block() {
319 blocked = true;
320 return blocked;
321 }
322
323 @Override
324 public void send() {
325 }
326
327 @Override
328 public void build(OFPort outPort) {
329 }
330
331 @Override
332 public void build(Ethernet ethFrame, OFPort outPort) {
333 }
334
335 @Override
336 public Ethernet parsed() {
337 return null;
338 }
339
340 @Override
341 public byte[] unparsed() {
342 ONLabLddp lldp = new ONLabLddp();
343 lldp.setSwitch(DPID1.value());
344
345 Ethernet ethPacket = new Ethernet();
346 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
347 ethPacket.setDestinationMACAddress(ONLabLddp.LLDP_NICIRA);
348 ethPacket.setPayload(lldp);
349 ethPacket.setPad(true);
350
351
352 lldp.setPort(PD1.getPortNo().getPortNumber());
353 ethPacket.setSourceMACAddress(PD1.getHwAddr().getBytes());
354 return ethPacket.serialize();
355
356 }
357
358 @Override
359 public Dpid dpid() {
360 return swid;
361 }
362
363 @Override
364 public Integer inPort() {
365 return PD3.getPortNo().getPortNumber();
366 }
367
368 @Override
369 public boolean isHandled() {
370 return blocked;
371 }
372
373 @Override
374 public boolean isBuffered() {
375 return false;
376 }
377
378 }
379
380 private static class TestOpenFlowSwitch implements OpenFlowSwitch {
381
382 private final List<OFPortDesc> ports;
383 private final Dpid dpid;
384
385 public TestOpenFlowSwitch(Dpid dpid, List<OFPortDesc> ports) {
386 this.ports = ports;
387 this.dpid = dpid;
388 }
389
390 RoleState state;
391 List<OFMessage> sent = new ArrayList<OFMessage>();
392 OFFactory factory = OFFactoryVer10.INSTANCE;
393
394 @Override
395 public void sendMsg(OFMessage msg) {
396 sent.add(msg);
397 }
398
399 @Override
400 public void sendMsg(List<OFMessage> msgs) {
401 }
402
403 @Override
404 public void handleMessage(OFMessage fromSwitch) {
405 }
406
407 @Override
408 public void setRole(RoleState role) {
409 state = role;
410 }
411
412 @Override
413 public RoleState getRole() {
414 return state;
415 }
416
417 @Override
418 public List<OFPortDesc> getPorts() {
419 return ports;
420 }
421
422 @Override
423 public OFFactory factory() {
424 return factory;
425 }
426
427 @Override
428 public String getStringId() {
429 return null;
430 }
431
432 @Override
433 public long getId() {
434 return dpid.value();
435 }
436
437 @Override
438 public String manfacturerDescription() {
439 return null;
440 }
441
442 @Override
443 public String datapathDescription() {
444 return null;
445 }
446
447 @Override
448 public String hardwareDescription() {
449 return null;
450 }
451
452 @Override
453 public String softwareDescription() {
454 return null;
455 }
456
457 @Override
458 public String serialNumber() {
459 return null;
460 }
461
462 @Override
463 public void disconnectSwitch() {
464 }
465
466 @Override
467 public void returnRoleAssertFailure(RoleState role) {
468 }
469
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700470 @Override
471 public boolean isOptical() {
472 return false;
473 }
474
alshabib64231d82014-09-25 18:25:31 -0700475 }
476}