blob: 7f848a867e39e3894785f56f47a6581d47347032 [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
Ray Milkey269ffb92014-04-03 14:43:30 -07002 * Copyright 2011, Big Switch Networks, Inc.
3 * Originally created by David Erickson, Stanford University
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations
15 * under the License.
16 **/
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080017
Jonathan Hart284e70f2014-07-05 12:32:51 -070018package net.onrc.onos.core.linkdiscovery;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080019
Jonathan Hart2fa28062013-11-25 20:16:28 -080020import static org.easymock.EasyMock.createNiceMock;
21import static org.easymock.EasyMock.expect;
22import static org.easymock.EasyMock.replay;
23import static org.easymock.EasyMock.verify;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080024
srikanth9f383342014-06-12 11:49:00 -070025import java.io.IOException;
Jonathan Hart2fa28062013-11-25 20:16:28 -080026import java.util.Collections;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080027import java.util.HashMap;
28import java.util.Map;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070029import java.util.Set;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080030
srikanth9f383342014-06-12 11:49:00 -070031import net.floodlightcontroller.core.FloodlightContext;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080032import net.floodlightcontroller.core.IFloodlightProviderService;
Jonathan Hart0f383542014-07-09 11:38:03 -070033import net.floodlightcontroller.core.IListener.Command;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080034import net.floodlightcontroller.core.IOFSwitch;
35import net.floodlightcontroller.core.module.FloodlightModuleContext;
36import net.floodlightcontroller.core.test.MockThreadPoolService;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080037import net.floodlightcontroller.restserver.IRestApiService;
38import net.floodlightcontroller.restserver.RestApiServer;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080039import net.floodlightcontroller.test.FloodlightTestCase;
40import net.floodlightcontroller.threadpool.IThreadPoolService;
Jonathan Hart0f383542014-07-09 11:38:03 -070041import net.onrc.onos.core.packet.Ethernet;
42import net.onrc.onos.core.packet.OnosLldp;
Jonathan Hartcd1ab172014-07-03 14:59:48 -070043import net.onrc.onos.core.registry.IControllerRegistryService;
Jonathan Hart2fa28062013-11-25 20:16:28 -080044
srikanth9f383342014-06-12 11:49:00 -070045import org.easymock.EasyMock;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070046import org.easymock.IArgumentMatcher;
Jonathan Hart2fa28062013-11-25 20:16:28 -080047import org.junit.Before;
48import org.junit.Test;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070049import org.projectfloodlight.openflow.protocol.OFFactories;
50import org.projectfloodlight.openflow.protocol.OFFactory;
51import org.projectfloodlight.openflow.protocol.OFPacketIn;
52import org.projectfloodlight.openflow.protocol.OFPacketOut;
53import org.projectfloodlight.openflow.protocol.OFPortConfig;
54import org.projectfloodlight.openflow.protocol.OFPortDesc;
55import org.projectfloodlight.openflow.protocol.OFPortReason;
56import org.projectfloodlight.openflow.protocol.OFPortState;
57import org.projectfloodlight.openflow.protocol.OFPortStatus;
58import org.projectfloodlight.openflow.protocol.OFVersion;
59import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
60import org.projectfloodlight.openflow.types.MacAddress;
61import org.projectfloodlight.openflow.types.OFPort;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080062
Yuta HIGUCHIaa132f52014-06-26 10:18:39 -070063// CHECKSTYLE IGNORE WriteTag FOR NEXT 2 LINES
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080064/**
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080065 * @author David Erickson (daviderickson@cs.stanford.edu)
66 */
67public class LinkDiscoveryManagerTest extends FloodlightTestCase {
68
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070069 private LinkDiscoveryManager ldm;
Ray Milkey269ffb92014-04-03 14:43:30 -070070
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070071 private static final Set<OFPortState> EMPTY_PORT_STATE =
72 Collections.<OFPortState>emptySet();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080073
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070074 // Arbitrary MAC address that we can feed in to our mock objects. This
75 // value is never actually checked during the tests so it doesn't matter if
76 // all ports have the same MAC address.
77 private static final byte[] DEFAULT_MAC_ADDRESS =
78 new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x1};
79
80 private OFFactory factory10 = OFFactories.getFactory(OFVersion.OF_10);
81
82 /**
83 * EasyMock matcher to verify the value of the output port of a packet out.
84 * This is used to verify that the packet out messages generated by
85 * LinkDiscoveryManager contain the correct output port.
86 *
87 */
88 private static final class PacketOutPortMatcher implements IArgumentMatcher {
89 private final int portNumber;
90
91 public PacketOutPortMatcher(int portNumber) {
92 this.portNumber = portNumber;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080093 }
94
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070095 @Override
96 public void appendTo(StringBuffer strBuffer) {
97 strBuffer.append("PacketOutPortMatcher failed to verify output port");
98 }
99
100 @Override
101 public boolean matches(Object object) {
102 if (!(object instanceof OFPacketOut)) {
103 return false;
104 }
105
106 OFPacketOut po = (OFPacketOut) object;
107
108 if (po.getActions().size() != 1
109 || !(po.getActions().get(0) instanceof OFActionOutput)) {
110 return false;
111 }
112
113 OFActionOutput action = (OFActionOutput) po.getActions().get(0);
114
115 return action.getPort().getPortNumber() == portNumber;
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800116 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800117 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700118
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700119 /**
120 * Matcher method to match a given output port against a packet out message
121 * passed as an argument to a mock switch.
122 *
123 * @param outPort the output port to check in the packet out
124 * @return anything of type OFPacketOut
125 */
126 private static OFPacketOut matchOutPort(int outPort) {
127 EasyMock.reportMatcher(new PacketOutPortMatcher(outPort));
128 return null;
129 }
130
131 private LinkDiscoveryManager getLinkDiscoveryManager() {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800132 return ldm;
133 }
134
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700135 private IOFSwitch createMockSwitch(Long id) {
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800136 IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
137 expect(mockSwitch.getId()).andReturn(id).anyTimes();
Jonathan Hart0f383542014-07-09 11:38:03 -0700138 expect(mockSwitch.portEnabled(EasyMock.anyShort())).andReturn(true).anyTimes();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800139 return mockSwitch;
140 }
141
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700142 private OFPortDesc createMockPort(short portNumber) {
143 return createMockPortWithState(portNumber,
144 Collections.<OFPortState>emptySet());
145 }
146
147 private OFPortDesc createMockPortWithState(short portNumber,
148 Set<OFPortState> state) {
149 OFPort ofPort = EasyMock.createMock(OFPort.class);
150 expect(ofPort.getShortPortNumber()).andReturn(portNumber).anyTimes();
151
152 OFPortDesc ofPortDesc = EasyMock.createMock(OFPortDesc.class);
153 expect(ofPortDesc.getPortNo()).andReturn(ofPort).anyTimes();
154 expect(ofPortDesc.getHwAddr()).andReturn(
155 MacAddress.of(DEFAULT_MAC_ADDRESS)).anyTimes();
156 expect(ofPortDesc.getConfig()).
157 andReturn(Collections.<OFPortConfig>emptySet()).anyTimes();
158 expect(ofPortDesc.getState()).andReturn(state).anyTimes();
159
160 replay(ofPort);
161 replay(ofPortDesc);
162
163 return ofPortDesc;
164 }
165
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700166 @Override
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800167 @Before
168 public void setUp() throws Exception {
169 super.setUp();
170 FloodlightModuleContext cntx = new FloodlightModuleContext();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700171 ldm = new LinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800172 MockThreadPoolService tp = new MockThreadPoolService();
173 RestApiServer restApi = new RestApiServer();
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700174 IControllerRegistryService registry =
175 EasyMock.createMock(IControllerRegistryService.class);
176 expect(registry.hasControl(EasyMock.anyLong())).andReturn(true).anyTimes();
177 replay(registry);
178 cntx.addService(IControllerRegistryService.class, registry);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800179 cntx.addService(IRestApiService.class, restApi);
180 cntx.addService(IThreadPoolService.class, tp);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800181 cntx.addService(ILinkDiscoveryService.class, ldm);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800182 cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
183 restApi.init(cntx);
184 tp.init(cntx);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800185 ldm.init(cntx);
186 restApi.startUp(cntx);
187 tp.startUp(cntx);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800188 ldm.startUp(cntx);
189
190 IOFSwitch sw1 = createMockSwitch(1L);
191 IOFSwitch sw2 = createMockSwitch(2L);
192 Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
193 switches.put(1L, sw1);
194 switches.put(2L, sw2);
195 getMockFloodlightProvider().setSwitches(switches);
196 replay(sw1, sw2);
197 }
198
199 @Test
200 public void testAddOrUpdateLink() throws Exception {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700201 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800202
203 Link lt = new Link(1L, 2, 2L, 1);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700204 long firstSeenTime = System.currentTimeMillis();
205 LinkInfo info = new LinkInfo(firstSeenTime,
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700206 System.currentTimeMillis(), EMPTY_PORT_STATE,
207 EMPTY_PORT_STATE);
208 linkDiscovery.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800209
210 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
211 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
212
213 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700214 assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
215 assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt));
216 assertNotNull(linkDiscovery.portLinks.get(srcNpt));
217 assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt));
218 assertNotNull(linkDiscovery.portLinks.get(dstNpt));
219 assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt));
220 assertTrue(linkDiscovery.links.containsKey(lt));
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700221
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700222 LinkInfo infoToVerify = linkDiscovery.links.get(lt);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700223 assertEquals(firstSeenTime, infoToVerify.getFirstSeenTime());
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700224 assertEquals(EMPTY_PORT_STATE, infoToVerify.getSrcPortState());
225 assertEquals(EMPTY_PORT_STATE, infoToVerify.getDstPortState());
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700226
227 // Arbitrary new port states to verify that the port state is updated
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700228 final Set<OFPortState> newSrcPortState =
229 Collections.singleton(OFPortState.STP_BLOCK);
230 final Set<OFPortState> newDstPortState =
231 Collections.singleton(OFPortState.LINK_DOWN);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700232
233 // Update the last received probe timestamp and the port states
234 LinkInfo infoWithStateChange = new LinkInfo(System.currentTimeMillis(),
235 System.currentTimeMillis(), newSrcPortState, newDstPortState);
236
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700237 linkDiscovery.addOrUpdateLink(lt, infoWithStateChange);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700238
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700239 assertNotNull(linkDiscovery.links.get(lt));
240 infoToVerify = linkDiscovery.links.get(lt);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700241 // First seen time should be the original time, not the second update time
242 assertEquals(firstSeenTime, infoToVerify.getFirstSeenTime());
243 // Both port states should have been updated
244 assertEquals(newSrcPortState, infoToVerify.getSrcPortState());
245 assertEquals(newDstPortState, infoToVerify.getDstPortState());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800246 }
247
248 @Test
249 public void testDeleteLink() throws Exception {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700250 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800251
252 Link lt = new Link(1L, 2, 2L, 1);
253 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700254 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
255 linkDiscovery.addOrUpdateLink(lt, info);
256 linkDiscovery.deleteLinks(Collections.singletonList(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800257
258 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700259 assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
260 assertNull(linkDiscovery.switchLinks.get(lt.getDst()));
261 assertNull(linkDiscovery.portLinks.get(lt.getSrc()));
262 assertNull(linkDiscovery.portLinks.get(lt.getDst()));
263 assertTrue(linkDiscovery.links.isEmpty());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800264 }
265
266 @Test
267 public void testAddOrUpdateLinkToSelf() throws Exception {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700268 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800269
270 Link lt = new Link(1L, 2, 2L, 3);
271 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
272 NodePortTuple dstNpt = new NodePortTuple(2L, 3);
273
274 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700275 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
276 linkDiscovery.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800277
278 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700279 assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
280 assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt));
281 assertNotNull(linkDiscovery.portLinks.get(srcNpt));
282 assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt));
283 assertNotNull(linkDiscovery.portLinks.get(dstNpt));
284 assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt));
285 assertTrue(linkDiscovery.links.containsKey(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800286 }
287
288 @Test
289 public void testDeleteLinkToSelf() throws Exception {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700290 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800291
292 Link lt = new Link(1L, 2, 1L, 3);
293 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
294 NodePortTuple dstNpt = new NodePortTuple(2L, 3);
295
296 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700297 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
298 linkDiscovery.addOrUpdateLink(lt, info);
299 linkDiscovery.deleteLinks(Collections.singletonList(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800300
301 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700302 assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
303 assertNull(linkDiscovery.switchLinks.get(lt.getDst()));
304 assertNull(linkDiscovery.portLinks.get(srcNpt));
305 assertNull(linkDiscovery.portLinks.get(dstNpt));
306 assertTrue(linkDiscovery.links.isEmpty());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800307 }
308
309 @Test
310 public void testRemovedSwitch() {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700311 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800312
313 Link lt = new Link(1L, 2, 2L, 1);
314 NodePortTuple srcNpt = new NodePortTuple(1L, 2);
315 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
316 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700317 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
318 linkDiscovery.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800319
320 IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
321 IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
322 // Mock up our expected behavior
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700323 linkDiscovery.switchDisconnected(sw1.getId());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800324 verify(sw1, sw2);
325
326 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700327 assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
328 assertNull(linkDiscovery.switchLinks.get(lt.getDst()));
329 assertNull(linkDiscovery.portLinks.get(srcNpt));
330 assertNull(linkDiscovery.portLinks.get(dstNpt));
331 assertTrue(linkDiscovery.links.isEmpty());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800332 }
333
334 @Test
335 public void testRemovedSwitchSelf() {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700336 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800337 IOFSwitch sw1 = createMockSwitch(1L);
338 replay(sw1);
339 Link lt = new Link(1L, 2, 1L, 3);
340 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700341 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
342 linkDiscovery.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800343
344 // Mock up our expected behavior
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700345 linkDiscovery.switchDisconnected(sw1.getId());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800346
347 verify(sw1);
348 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700349 assertNull(linkDiscovery.switchLinks.get(lt.getSrc()));
350 assertNull(linkDiscovery.portLinks.get(lt.getSrc()));
351 assertNull(linkDiscovery.portLinks.get(lt.getDst()));
352 assertTrue(linkDiscovery.links.isEmpty());
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800353 }
354
355 @Test
356 public void testAddUpdateLinks() throws Exception {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700357 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800358
359 Link lt = new Link(1L, 1, 2L, 1);
360 NodePortTuple srcNpt = new NodePortTuple(1L, 1);
361 NodePortTuple dstNpt = new NodePortTuple(2L, 1);
Ray Milkey269ffb92014-04-03 14:43:30 -0700362
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800363 LinkInfo info;
364
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700365 // Setting the last LLDP reception time to be 40 seconds old, so we
366 // can use this to test that an old link times out correctly
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800367 info = new LinkInfo(System.currentTimeMillis() - 40000,
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700368 System.currentTimeMillis() - 40000,
369 EMPTY_PORT_STATE, EMPTY_PORT_STATE);
370 linkDiscovery.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800371
372 // check invariants hold
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700373 assertNotNull(linkDiscovery.switchLinks.get(lt.getSrc()));
374 assertTrue(linkDiscovery.switchLinks.get(lt.getSrc()).contains(lt));
375 assertNotNull(linkDiscovery.portLinks.get(srcNpt));
376 assertTrue(linkDiscovery.portLinks.get(srcNpt).contains(lt));
377 assertNotNull(linkDiscovery.portLinks.get(dstNpt));
378 assertTrue(linkDiscovery.portLinks.get(dstNpt).contains(lt));
379 assertTrue(linkDiscovery.links.containsKey(lt));
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800380
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700381 linkDiscovery.timeOutLinks();
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800382
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700383 // Setting the last LLDP reception time to be 40 seconds old, so we
384 // can use this to test that an old link times out correctly
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800385 info = new LinkInfo(System.currentTimeMillis() - 40000,
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700386 System.currentTimeMillis() - 40000,
387 EMPTY_PORT_STATE, EMPTY_PORT_STATE);
388 linkDiscovery.addOrUpdateLink(lt, info);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800389
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700390 // Expect to timeout the unicast Valid Time, so the link should disappear
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700391 linkDiscovery.timeOutLinks();
392 assertTrue(linkDiscovery.links.get(lt) == null);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800393 }
srikanth9f383342014-06-12 11:49:00 -0700394
395 /**
396 * This test case verifies that LinkDiscoveryManager.sendDiscoveryMessage()
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700397 * performs "write" operation on the specified IOFSwitch object
398 * with a LLDP packet.
399 *
srikanth9f383342014-06-12 11:49:00 -0700400 * @throws IOException
401 */
402 @Test
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700403 public void testSendDiscoveryMessage() throws IOException {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700404 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
srikanth9f383342014-06-12 11:49:00 -0700405
406 // Mock up our expected behavior
407 IOFSwitch swTest = createMockSwitch(3L);
408 getMockFloodlightProvider().getSwitches().put(3L, swTest);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700409
srikanth9f383342014-06-12 11:49:00 -0700410 short portNum = 1;
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700411
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700412 OFPortDesc ofPortDesc = createMockPort(portNum);
413
414 expect(swTest.getPort(portNum)).andReturn(ofPortDesc).atLeastOnce();
415 swTest.write(matchOutPort(portNum),
416 EasyMock.anyObject(FloodlightContext.class));
srikanth9f383342014-06-12 11:49:00 -0700417 EasyMock.expectLastCall().times(1);
418 swTest.flush();
419 EasyMock.expectLastCall().once();
420 replay(swTest);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700421
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700422 linkDiscovery.sendDiscoveryMessage(3L, portNum, false);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700423
srikanth9f383342014-06-12 11:49:00 -0700424 verify(swTest);
425 }
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700426
427 @Test
428 public void testHandlePortStatusForNewPort() throws IOException {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700429 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700430
431 long dpid = 3L;
432 IOFSwitch sw = createMockSwitch(dpid);
433 getMockFloodlightProvider().getSwitches().put(dpid, sw);
434
435 short portNum = 1;
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700436
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700437 OFPortDesc ofPortDesc = createMockPort(portNum);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700438
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700439 OFPortStatus portStatus = factory10.buildPortStatus()
440 .setDesc(ofPortDesc)
441 .setReason(OFPortReason.ADD)
442 .build();
443
444 expect(sw.getPort(portNum)).andReturn(ofPortDesc).once();
445
446 sw.write(matchOutPort(portNum),
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700447 EasyMock.anyObject(FloodlightContext.class));
448 sw.flush();
449
450 replay(sw);
451
452 linkDiscovery.handlePortStatus(sw, portStatus);
453
454 verify(sw);
455 }
456
457 @Test
458 public void testHandlePortStatusForExistingPort() {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700459 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700460
461 // Add a link that we can update later during the test
462 Link lt = new Link(1L, 1, 2L, 1);
463 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700464 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700465 linkDiscovery.addOrUpdateLink(lt, info);
466
467 short portNum = 1;
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700468
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700469 // Arbitrary states to test state changes
470 Set<OFPortState> srcPortState =
471 Collections.singleton(OFPortState.STP_FORWARD);
472 Set<OFPortState> dstPortState =
473 Collections.singleton(OFPortState.STP_LISTEN);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700474
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700475 OFPortDesc srcPortDesc = createMockPortWithState(portNum, srcPortState);
476 OFPortDesc dstPortDesc = createMockPortWithState(portNum, dstPortState);
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700477
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700478 OFPortStatus srcPortStatus = factory10.buildPortStatus()
479 .setDesc(srcPortDesc)
480 .setReason(OFPortReason.MODIFY)
481 .build();
482
483 OFPortStatus dstPortStatus = factory10.buildPortStatus()
484 .setDesc(dstPortDesc)
485 .setReason(OFPortReason.MODIFY)
486 .build();
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700487
488 linkDiscovery.handlePortStatus(
489 getMockFloodlightProvider().getSwitches().get(1L), srcPortStatus);
490
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700491 LinkInfo newInfo = linkDiscovery.links.get(lt);
492 assertEquals(srcPortState, newInfo.getSrcPortState());
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700493 assertEquals(EMPTY_PORT_STATE, newInfo.getDstPortState());
Jonathan Hartcd1ab172014-07-03 14:59:48 -0700494
495 linkDiscovery.handlePortStatus(
496 getMockFloodlightProvider().getSwitches().get(2L), dstPortStatus);
497
498 newInfo = linkDiscovery.links.get(lt);
499 assertEquals(srcPortState, newInfo.getSrcPortState());
500 assertEquals(dstPortState, newInfo.getDstPortState());
501 }
Jonathan Hart0f383542014-07-09 11:38:03 -0700502
503 @Test
504 public void testHandlePortStatusForDeletePort() {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700505 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Jonathan Hart0f383542014-07-09 11:38:03 -0700506
507 // Add a link that we can delete later during the test
508 Link lt = new Link(1L, 1, 2L, 2);
509 LinkInfo info = new LinkInfo(System.currentTimeMillis(),
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700510 System.currentTimeMillis(), EMPTY_PORT_STATE, EMPTY_PORT_STATE);
Jonathan Hart0f383542014-07-09 11:38:03 -0700511 linkDiscovery.addOrUpdateLink(lt, info);
512
513 short portNum = 1;
Jonathan Hart0f383542014-07-09 11:38:03 -0700514
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700515 OFPortDesc srcPortDesc = createMockPort(portNum);
516 OFPortStatus srcPortStatus = factory10.buildPortStatus()
517 .setDesc(srcPortDesc)
518 .setReason(OFPortReason.DELETE)
519 .build();
Jonathan Hart0f383542014-07-09 11:38:03 -0700520
521 assertNotNull(linkDiscovery.getLinks().get(lt));
522
523 // Send a delete port status for the source port, which should result
524 // in the link being deleted
525 linkDiscovery.handlePortStatus(
526 getMockFloodlightProvider().getSwitches().get(1L), srcPortStatus);
527
528 assertNull(linkDiscovery.getLinks().get(lt));
529 }
530
531 @Test
532 public void testReceive() {
Jonathan Hart0f383542014-07-09 11:38:03 -0700533 OnosLldp lldpPacket = new OnosLldp();
534 lldpPacket.setPort((short) 1);
535 lldpPacket.setSwitch(1L);
536 lldpPacket.setReverse(false);
537
538 Ethernet ethPacket = new Ethernet();
539 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700540 ethPacket.setSourceMACAddress(DEFAULT_MAC_ADDRESS);
Jonathan Hart0f383542014-07-09 11:38:03 -0700541 ethPacket.setDestinationMACAddress(
542 LinkDiscoveryManager.LLDP_STANDARD_DST_MAC_STRING);
543 ethPacket.setPayload(lldpPacket);
544 ethPacket.setPad(true);
545
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700546 OFPacketIn pi = EasyMock.createMock(OFPacketIn.class);
547 expect(pi.getData()).andReturn(ethPacket.serialize()).anyTimes();
548 replay(pi);
Jonathan Hart0f383542014-07-09 11:38:03 -0700549
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700550 LinkDiscoveryManager linkDiscovery = getLinkDiscoveryManager();
Jonathan Hart0f383542014-07-09 11:38:03 -0700551
552 Link expectedLink = new Link(1L, 1, 2L, 2);
553
554 assertNull(linkDiscovery.links.get(expectedLink));
555
556 // Sending in the LLDP packet should cause the link to be created
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700557 Command command = linkDiscovery.handleLldp(lldpPacket, 2L, pi, (short) 2);
Jonathan Hart0f383542014-07-09 11:38:03 -0700558
559 assertEquals(Command.STOP, command);
560 assertNotNull(linkDiscovery.links.get(expectedLink));
561 }
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -0800562}